vite-plugin-react-server
Version:
Vite plugin for React Server Components (RSC)
298 lines (295 loc) • 44.7 kB
JavaScript
/**
* vite-plugin-react-server
* Copyright (c) Nico Brinkkemper
* MIT License
*/
import { handleError } from '../error/handleError.js';
import { fileWriter } from './fileWriter.js';
import { createRenderMetrics } from '../metrics/createRenderMetrics.js';
import { createStreamMetrics } from '../metrics/createStreamMetrics.js';
const DEFAULT_BATCH_SIZE = 8;
function resolvePathWithManifest(path, manifest) {
const entry = manifest[path];
if (entry && entry.file) {
return entry.file;
}
return path;
}
async function renderSingleRoute(route, handlerOptions, renderPage, manifest, failedRoutes) {
const { autoDiscoveredFiles, cssFilesByPage, ...options } = handlerOptions;
const { page, props, root, html } = autoDiscoveredFiles.urlMap?.get(route) || {};
if (!page) {
return { route, results: [], error: new Error(`No page found for route ${route}`) };
}
try {
const resolvedPagePath = page ? resolvePathWithManifest(page, manifest) : void 0;
const resolvedPropsPath = props ? resolvePathWithManifest(props, manifest) : void 0;
const resolvedRootPath = root ? resolvePathWithManifest(root, manifest) : void 0;
const resolvedHtmlPath = html ? resolvePathWithManifest(html, manifest) : void 0;
const routeResults = /* @__PURE__ */ new Map();
const wrapperOnEvent = (event) => {
if (options.onEvent) {
options.onEvent(event);
}
if (event.type === "route.error") {
const detectedPanicError = handleError({
error: event.data.error,
logger: options.logger,
panicThreshold: event.data.panicThreshold,
context: `route.error (${event.data.route})`
});
if (detectedPanicError != null) {
options.logger?.error(
`[renderPagesBatched] Panic error for route ${event.data.route}: ${event.data.error.message}`
);
failedRoutes.set(event.data.route, event.data.error);
} else {
options.logger?.warn(
`[renderPagesBatched] Non-panic error for route ${event.data.route}: ${event.data.error.message}`
);
}
}
if (event.type === "file.write.done" && event.data.route === route) {
const routeResult = routeResults.get(route);
if (routeResult && routeResult.type === "success") {
if (event.data.fileType === "html") {
const endTime = performance.now();
const htmlMetrics = createRenderMetrics({
route,
type: routeResult.metrics.html.type,
fromMainThread: routeResult.metrics.html.fromMainThread,
fromRscWorker: routeResult.metrics.html.fromRscWorker,
fromHtmlWorker: routeResult.metrics.html.fromHtmlWorker,
fileSize: event.data.content.length,
chunks: event.data.chunks || 0,
processingTime: endTime - routeResult.metrics.html.streamMetrics.startTime,
chunkRate: (event.data.chunks || 0) / ((endTime - routeResult.metrics.html.streamMetrics.startTime) / 1e3),
fileName: event.data.fileName,
outputPath: event.data.path,
baseDir: event.data.baseDir,
routePath: event.data.routePath,
streamMetrics: createStreamMetrics({
...routeResult.metrics.html.streamMetrics,
chunks: event.data.chunks || 0,
bytes: event.data.content.length,
duration: endTime - routeResult.metrics.html.streamMetrics.startTime,
endTime
})
});
if (options.onMetrics) {
options.onMetrics(htmlMetrics);
}
if (routeResult.metrics?.rscFull) {
const rscFullEndTime = performance.now();
const rscFullMetrics = createRenderMetrics({
route,
type: routeResult.metrics.rscFull.type,
fromMainThread: routeResult.metrics.rscFull.fromMainThread,
fromRscWorker: routeResult.metrics.rscFull.fromRscWorker,
fromHtmlWorker: routeResult.metrics.rscFull.fromHtmlWorker,
processingTime: rscFullEndTime - routeResult.metrics.rscFull.streamMetrics.startTime,
chunks: routeResult.metrics.rscFull.streamMetrics.chunks,
chunkRate: routeResult.metrics.rscFull.streamMetrics.chunks / ((rscFullEndTime - routeResult.metrics.rscFull.streamMetrics.startTime) / 1e3),
fileName: event.data.fileName,
outputPath: event.data.path,
baseDir: event.data.baseDir,
routePath: event.data.routePath,
streamMetrics: createStreamMetrics({
...routeResult.metrics.rscFull.streamMetrics,
duration: rscFullEndTime - routeResult.metrics.rscFull.streamMetrics.startTime,
endTime: rscFullEndTime
})
});
if (options.onMetrics) {
options.onMetrics(rscFullMetrics);
}
}
} else if (event.data.fileType === "rsc") {
const rscEndTime = performance.now();
const rscMetrics = createRenderMetrics({
route,
type: routeResult.metrics.rscHeadless.type,
fromMainThread: routeResult.metrics.rscHeadless.fromMainThread,
fromRscWorker: routeResult.metrics.rscHeadless.fromRscWorker,
fromHtmlWorker: routeResult.metrics.rscHeadless.fromHtmlWorker,
fileSize: event.data.content.length,
chunks: event.data.chunks || 0,
processingTime: rscEndTime - routeResult.metrics.rscHeadless.streamMetrics.startTime,
chunkRate: (event.data.chunks || 0) / ((rscEndTime - routeResult.metrics.rscHeadless.streamMetrics.startTime) / 1e3),
fileName: event.data.fileName,
outputPath: event.data.path,
baseDir: event.data.baseDir,
routePath: event.data.routePath,
streamMetrics: createStreamMetrics({
...routeResult.metrics.rscHeadless.streamMetrics,
chunks: event.data.chunks || 0,
bytes: event.data.content.length,
duration: rscEndTime - routeResult.metrics.rscHeadless.streamMetrics.startTime,
endTime: rscEndTime
})
});
if (options.onMetrics) {
options.onMetrics(rscMetrics);
}
}
}
}
};
const routeHandlerOptions = {
...options,
manifest,
route,
pagePath: resolvedPagePath,
propsPath: resolvedPropsPath,
rootPath: resolvedRootPath,
htmlPath: resolvedHtmlPath,
cssFiles: cssFilesByPage?.get(route) ?? /* @__PURE__ */ new Map(),
globalCss: options.globalCss ?? /* @__PURE__ */ new Map(),
id: `${route}-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`,
onEvent: wrapperOnEvent
};
const pageRenderer = renderPage(routeHandlerOptions);
const results = [];
let routeError;
for await (const result of pageRenderer) {
results.push(result);
if (result.type === "error" && result.error) {
routeError = result.error instanceof Error ? result.error : new Error(String(result.error));
}
if (result.type === "success" || result.type === "skip") {
routeResults.set(route, result);
const rscWritePromise = fileWriter(
result.rsc,
"rsc",
{ ...options, route, onEvent: wrapperOnEvent, logger: options.logger },
options.signal
);
const htmlWritePromise = fileWriter(
result.html,
"html",
{ ...options, route, onEvent: wrapperOnEvent, logger: options.logger },
options.signal
);
await Promise.all([rscWritePromise, htmlWritePromise]);
}
}
if (routeError) {
return { route, results, error: routeError };
}
return { route, results };
} catch (error) {
return { route, results: [], error };
}
}
function chunk(array, size) {
const chunks = [];
for (let i = 0; i < array.length; i += size) {
chunks.push(array.slice(i, i + size));
}
return chunks;
}
const renderPagesBatched = (routes, handlerOptions, renderPage) => {
const {
autoDiscoveredFiles,
manifest = {},
...options
} = handlerOptions;
const batchSize = options.batchSize ?? DEFAULT_BATCH_SIZE;
const completedRoutes = /* @__PURE__ */ new Set();
const failedRoutes = /* @__PURE__ */ new Map();
const results = /* @__PURE__ */ new Map();
if (!autoDiscoveredFiles?.urlMap) {
return async function* _renderPagesBatched() {
const errorResult = {
type: "error",
error: new Error("No urlMap provided to renderPages"),
route: "",
failedRoutes: /* @__PURE__ */ new Map(),
completedRoutes: /* @__PURE__ */ new Set(),
results: /* @__PURE__ */ new Map()
};
yield errorResult;
return errorResult;
}();
}
return async function* _renderPagesBatched() {
const routeArray = Array.from(routes);
const batches = chunk(routeArray, batchSize);
if (options.verbose) {
options.logger?.info(
`[renderPagesBatched] Rendering ${routeArray.length} pages in ${batches.length} batches of ${batchSize}`
);
}
for (const batch of batches) {
if (options.signal?.aborted) {
const abortResult = {
type: "error",
error: options.signal.reason || new Error("Build aborted"),
route: batch[0] || "",
failedRoutes,
completedRoutes,
results
};
yield abortResult;
return abortResult;
}
const batchPromises = batch.map(
(route) => renderSingleRoute(route, handlerOptions, renderPage, manifest, failedRoutes)
);
const batchResults = await Promise.all(batchPromises);
for (const { route, results: pageResults, error } of batchResults) {
if (error) {
const panicError = handleError({
error,
logger: options.logger,
panicThreshold: options.panicThreshold});
if (panicError != null) {
failedRoutes.set(route, error);
options.logger?.error(`[renderPagesBatched] Panic error for route ${route}: ${error.message}`);
const errorResult = {
type: "error",
error,
route,
failedRoutes,
completedRoutes,
results
};
yield errorResult;
return errorResult;
} else {
options.logger?.warn(`[renderPagesBatched] Non-panic error for route ${route}: ${error.message}`);
}
} else {
completedRoutes.add(route);
for (const result of pageResults) {
if (result.type === "success" || result.type === "skip") {
results.set(route, result);
yield {
type: "success",
route,
failedRoutes,
completedRoutes,
results
};
}
}
}
}
if (options.verbose) {
options.logger?.info(
`[renderPagesBatched] Completed batch: ${completedRoutes.size}/${routeArray.length} pages`
);
}
}
const finalResult = {
type: "success",
route: "",
failedRoutes,
completedRoutes,
results
};
return finalResult;
}();
};
export { renderPagesBatched };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVuZGVyUGFnZXNCYXRjaGVkLmpzIiwic291cmNlcyI6WyIuLi8uLi8uLi9wbHVnaW4vcmVhY3Qtc3RhdGljL3JlbmRlclBhZ2VzQmF0Y2hlZC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIHJlbmRlclBhZ2VzQmF0Y2hlZC50c1xuICpcbiAqIEJhdGNoZWQgdmVyc2lvbiBvZiByZW5kZXJQYWdlcyB0aGF0IHJlbmRlcnMgbXVsdGlwbGUgcGFnZXMgY29uY3VycmVudGx5LlxuICogVXNlcyBQcm9taXNlLmFsbCBvbiBiYXRjaGVzIHRvIHBhcmFsbGVsaXplIHJlbmRlcmluZyB3aGlsZSBwcmVzZXJ2aW5nXG4gKiB0aGUgYXN5bmMgZ2VuZXJhdG9yIGludGVyZmFjZSBmb3IgY29tcGF0aWJpbGl0eS5cbiAqL1xuaW1wb3J0IHR5cGUgeyBSZW5kZXJQYWdlc1Jlc3VsdCwgUmVuZGVyUGFnZVJlc3VsdCB9IGZyb20gXCIuLi90eXBlcy5qc1wiO1xuaW1wb3J0IHR5cGUgeyBSZW5kZXJQYWdlc0ZuLCBSZW5kZXJQYWdlRm4sIFJlbmRlclBhZ2VzSGFuZGxlck9wdGlvbnMgfSBmcm9tIFwiLi90eXBlcy5qc1wiO1xuaW1wb3J0IHsgaGFuZGxlRXJyb3IgfSBmcm9tIFwiLi4vZXJyb3IvaGFuZGxlRXJyb3IuanNcIjtcbmltcG9ydCB7IGZpbGVXcml0ZXIgfSBmcm9tIFwiLi9maWxlV3JpdGVyLmpzXCI7XG5pbXBvcnQgdHlwZSB7IE1hbmlmZXN0IH0gZnJvbSBcInZpdGVcIjtcbmltcG9ydCB7IGNyZWF0ZVJlbmRlck1ldHJpY3MgfSBmcm9tIFwiLi4vbWV0cmljcy9jcmVhdGVSZW5kZXJNZXRyaWNzLmpzXCI7XG5pbXBvcnQgeyBjcmVhdGVTdHJlYW1NZXRyaWNzIH0gZnJvbSBcIi4uL21ldHJpY3MvY3JlYXRlU3RyZWFtTWV0cmljcy5qc1wiO1xuXG5jb25zdCBERUZBVUxUX0JBVENIX1NJWkUgPSA4O1xuXG5mdW5jdGlvbiByZXNvbHZlUGF0aFdpdGhNYW5pZmVzdChwYXRoOiBzdHJpbmcsIG1hbmlmZXN0OiBNYW5pZmVzdCk6IHN0cmluZyB7XG4gIGNvbnN0IGVudHJ5ID0gbWFuaWZlc3RbcGF0aF07XG4gIGlmIChlbnRyeSAmJiBlbnRyeS5maWxlKSB7XG4gICAgcmV0dXJuIGVudHJ5LmZpbGU7XG4gIH1cbiAgcmV0dXJuIHBhdGg7XG59XG5cbi8qKlxuICogUmVuZGVycyBhIHNpbmdsZSByb3V0ZSBjb21wbGV0ZWx5LCBjb25zdW1pbmcgYWxsIHlpZWxkcyBmcm9tIHJlbmRlclBhZ2VcbiAqIGFuZCB3cml0aW5nIHRoZSBSU0MgYW5kIEhUTUwgZmlsZXMuIENvbGxlY3RzIG1ldHJpY3MgYW5kIGhhbmRsZXMgZXZlbnRzXG4gKiBpZGVudGljYWxseSB0byB0aGUgc2VxdWVudGlhbCByZW5kZXJQYWdlcy5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gcmVuZGVyU2luZ2xlUm91dGUoXG4gIHJvdXRlOiBzdHJpbmcsXG4gIGhhbmRsZXJPcHRpb25zOiBSZW5kZXJQYWdlc0hhbmRsZXJPcHRpb25zLFxuICByZW5kZXJQYWdlOiBSZW5kZXJQYWdlRm4sXG4gIG1hbmlmZXN0OiBNYW5pZmVzdCxcbiAgZmFpbGVkUm91dGVzOiBNYXA8c3RyaW5nLCB1bmtub3duPixcbik6IFByb21pc2U8eyByb3V0ZTogc3RyaW5nOyByZXN1bHRzOiBSZW5kZXJQYWdlUmVzdWx0W107IGVycm9yPzogRXJyb3IgfT4ge1xuICBjb25zdCB7IGF1dG9EaXNjb3ZlcmVkRmlsZXMsIGNzc0ZpbGVzQnlQYWdlLCAuLi5vcHRpb25zIH0gPSBoYW5kbGVyT3B0aW9ucztcbiAgY29uc3QgeyBwYWdlLCBwcm9wcywgcm9vdCwgaHRtbCB9ID0gYXV0b0Rpc2NvdmVyZWRGaWxlcy51cmxNYXA/LmdldChyb3V0ZSkgfHwge307XG4gIFxuICBpZiAoIXBhZ2UpIHtcbiAgICByZXR1cm4geyByb3V0ZSwgcmVzdWx0czogW10sIGVycm9yOiBuZXcgRXJyb3IoYE5vIHBhZ2UgZm91bmQgZm9yIHJvdXRlICR7cm91dGV9YCkgfTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgY29uc3QgcmVzb2x2ZWRQYWdlUGF0aCA9IHBhZ2UgPyByZXNvbHZlUGF0aFdpdGhNYW5pZmVzdChwYWdlLCBtYW5pZmVzdCkgOiB1bmRlZmluZWQ7XG4gICAgY29uc3QgcmVzb2x2ZWRQcm9wc1BhdGggPSBwcm9wcyA/IHJlc29sdmVQYXRoV2l0aE1hbmlmZXN0KHByb3BzLCBtYW5pZmVzdCkgOiB1bmRlZmluZWQ7XG4gICAgY29uc3QgcmVzb2x2ZWRSb290UGF0aCA9IHJvb3QgPyByZXNvbHZlUGF0aFdpdGhNYW5pZmVzdChyb290LCBtYW5pZmVzdCkgOiB1bmRlZmluZWQ7XG4gICAgY29uc3QgcmVzb2x2ZWRIdG1sUGF0aCA9IGh0bWwgPyByZXNvbHZlUGF0aFdpdGhNYW5pZmVzdChodG1sLCBtYW5pZmVzdCkgOiB1bmRlZmluZWQ7XG5cbiAgICAvLyBTdG9yZSByZXN1bHRzIGZvciBtZXRyaWNzIHRyYWNraW5nXG4gICAgY29uc3Qgcm91dGVSZXN1bHRzID0gbmV3IE1hcDxzdHJpbmcsIFJlbmRlclBhZ2VSZXN1bHQ+KCk7XG5cbiAgICAvLyBDcmVhdGUgb25FdmVudCB3cmFwcGVyIHRoYXQgaGFuZGxlcyByb3V0ZS5lcnJvciBhbmQgbWV0cmljcyBjb2xsZWN0aW9uXG4gICAgLy8gVGhpcyBtaXJyb3JzIHRoZSBzZXF1ZW50aWFsIHJlbmRlclBhZ2VzIGJlaGF2aW9yIGV4YWN0bHlcbiAgICBjb25zdCB3cmFwcGVyT25FdmVudCA9IChldmVudDogYW55KSA9PiB7XG4gICAgICAvLyBDYWxsIHRoZSBvcmlnaW5hbCBvbkV2ZW50IGZpcnN0XG4gICAgICBpZiAob3B0aW9ucy5vbkV2ZW50KSB7XG4gICAgICAgIG9wdGlvbnMub25FdmVudChldmVudCk7XG4gICAgICB9XG5cbiAgICAgIC8vIEhhbmRsZSByb3V0ZS5lcnJvciBldmVudHNcbiAgICAgIGlmIChldmVudC50eXBlID09PSBcInJvdXRlLmVycm9yXCIpIHtcbiAgICAgICAgY29uc3QgZGV0ZWN0ZWRQYW5pY0Vycm9yID0gaGFuZGxlRXJyb3Ioe1xuICAgICAgICAgIGVycm9yOiBldmVudC5kYXRhLmVycm9yLFxuICAgICAgICAgIGxvZ2dlcjogb3B0aW9ucy5sb2dnZXIsXG4gICAgICAgICAgcGFuaWNUaHJlc2hvbGQ6IGV2ZW50LmRhdGEucGFuaWNUaHJlc2hvbGQsXG4gICAgICAgICAgY29udGV4dDogYHJvdXRlLmVycm9yICgke2V2ZW50LmRhdGEucm91dGV9KWAsXG4gICAgICAgIH0pO1xuICAgICAgICBcbiAgICAgICAgaWYgKGRldGVjdGVkUGFuaWNFcnJvciAhPSBudWxsKSB7XG4gICAgICAgICAgb3B0aW9ucy5sb2dnZXI/LmVycm9yKFxuICAgICAgICAgICAgYFtyZW5kZXJQYWdlc0JhdGNoZWRdIFBhbmljIGVycm9yIGZvciByb3V0ZSAke2V2ZW50LmRhdGEucm91dGV9OiAke2V2ZW50LmRhdGEuZXJyb3IubWVzc2FnZX1gXG4gICAgICAgICAgKTtcbiAgICAgICAgICBmYWlsZWRSb3V0ZXMuc2V0KGV2ZW50LmRhdGEucm91dGUsIGV2ZW50LmRhdGEuZXJyb3IpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG9wdGlvbnMubG9nZ2VyPy53YXJuKFxuICAgICAgICAgICAgYFtyZW5kZXJQYWdlc0JhdGNoZWRdIE5vbi1wYW5pYyBlcnJvciBmb3Igcm91dGUgJHtldmVudC5kYXRhLnJvdXRlfTogJHtldmVudC5kYXRhLmVycm9yLm1lc3NhZ2V9YFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gSGFuZGxlIG1ldHJpY3MgY29sbGVjdGlvbiBvbiBmaWxlLndyaXRlLmRvbmVcbiAgICAgIGlmIChldmVudC50eXBlID09PSBcImZpbGUud3JpdGUuZG9uZVwiICYmIGV2ZW50LmRhdGEucm91dGUgPT09IHJvdXRlKSB7XG4gICAgICAgIGNvbnN0IHJvdXRlUmVzdWx0ID0gcm91dGVSZXN1bHRzLmdldChyb3V0ZSk7XG4gICAgICAgIGlmIChyb3V0ZVJlc3VsdCAmJiByb3V0ZVJlc3VsdC50eXBlID09PSBcInN1Y2Nlc3NcIikge1xuICAgICAgICAgIGlmIChldmVudC5kYXRhLmZpbGVUeXBlID09PSBcImh0bWxcIikge1xuICAgICAgICAgICAgY29uc3QgZW5kVGltZSA9IHBlcmZvcm1hbmNlLm5vdygpO1xuICAgICAgICAgICAgY29uc3QgaHRtbE1ldHJpY3MgPSBjcmVhdGVSZW5kZXJNZXRyaWNzKHtcbiAgICAgICAgICAgICAgcm91dGU6IHJvdXRlLFxuICAgICAgICAgICAgICB0eXBlOiByb3V0ZVJlc3VsdC5tZXRyaWNzLmh0bWwudHlwZSxcbiAgICAgICAgICAgICAgZnJvbU1haW5UaHJlYWQ6IHJvdXRlUmVzdWx0Lm1ldHJpY3MuaHRtbC5mcm9tTWFpblRocmVhZCxcbiAgICAgICAgICAgICAgZnJvbVJzY1dvcmtlcjogcm91dGVSZXN1bHQubWV0cmljcy5odG1sLmZyb21Sc2NXb3JrZXIsXG4gICAgICAgICAgICAgIGZyb21IdG1sV29ya2VyOiByb3V0ZVJlc3VsdC5tZXRyaWNzLmh0bWwuZnJvbUh0bWxXb3JrZXIsXG4gICAgICAgICAgICAgIGZpbGVTaXplOiBldmVudC5kYXRhLmNvbnRlbnQubGVuZ3RoLFxuICAgICAgICAgICAgICBjaHVua3M6IGV2ZW50LmRhdGEuY2h1bmtzIHx8IDAsXG4gICAgICAgICAgICAgIHByb2Nlc3NpbmdUaW1lOiBlbmRUaW1lIC0gcm91dGVSZXN1bHQubWV0cmljcy5odG1sLnN0cmVhbU1ldHJpY3Muc3RhcnRUaW1lLFxuICAgICAgICAgICAgICBjaHVua1JhdGU6IChldmVudC5kYXRhLmNodW5rcyB8fCAwKSAvICgoZW5kVGltZSAtIHJvdXRlUmVzdWx0Lm1ldHJpY3MuaHRtbC5zdHJlYW1NZXRyaWNzLnN0YXJ0VGltZSkgLyAxMDAwKSxcbiAgICAgICAgICAgICAgZmlsZU5hbWU6IGV2ZW50LmRhdGEuZmlsZU5hbWUsXG4gICAgICAgICAgICAgIG91dHB1dFBhdGg6IGV2ZW50LmRhdGEucGF0aCxcbiAgICAgICAgICAgICAgYmFzZURpcjogZXZlbnQuZGF0YS5iYXNlRGlyLFxuICAgICAgICAgICAgICByb3V0ZVBhdGg6IGV2ZW50LmRhdGEucm91dGVQYXRoLFxuICAgICAgICAgICAgICBzdHJlYW1NZXRyaWNzOiBjcmVhdGVTdHJlYW1NZXRyaWNzKHtcbiAgICAgICAgICAgICAgICAuLi5yb3V0ZVJlc3VsdC5tZXRyaWNzLmh0bWwuc3RyZWFtTWV0cmljcyxcbiAgICAgICAgICAgICAgICBjaHVua3M6IGV2ZW50LmRhdGEuY2h1bmtzIHx8IDAsXG4gICAgICAgICAgICAgICAgYnl0ZXM6IGV2ZW50LmRhdGEuY29udGVudC5sZW5ndGgsXG4gICAgICAgICAgICAgICAgZHVyYXRpb246IGVuZFRpbWUgLSByb3V0ZVJlc3VsdC5tZXRyaWNzLmh0bWwuc3RyZWFtTWV0cmljcy5zdGFydFRpbWUsXG4gICAgICAgICAgICAgICAgZW5kVGltZTogZW5kVGltZSxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaWYgKG9wdGlvbnMub25NZXRyaWNzKSB7XG4gICAgICAgICAgICAgIG9wdGlvbnMub25NZXRyaWNzKGh0bWxNZXRyaWNzKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQWxzbyBlbWl0IFJTQyBGdWxsIG1ldHJpY3MgaWYgYXZhaWxhYmxlXG4gICAgICAgICAgICBpZiAocm91dGVSZXN1bHQubWV0cmljcz8ucnNjRnVsbCkge1xuICAgICAgICAgICAgICBjb25zdCByc2NGdWxsRW5kVGltZSA9IHBlcmZvcm1hbmNlLm5vdygpO1xuICAgICAgICAgICAgICBjb25zdCByc2NGdWxsTWV0cmljcyA9IGNyZWF0ZVJlbmRlck1ldHJpY3Moe1xuICAgICAgICAgICAgICAgIHJvdXRlOiByb3V0ZSxcbiAgICAgICAgICAgICAgICB0eXBlOiByb3V0ZVJlc3VsdC5tZXRyaWNzLnJzY0Z1bGwudHlwZSxcbiAgICAgICAgICAgICAgICBmcm9tTWFpblRocmVhZDogcm91dGVSZXN1bHQubWV0cmljcy5yc2NGdWxsLmZyb21NYWluVGhyZWFkLFxuICAgICAgICAgICAgICAgIGZyb21Sc2NXb3JrZXI6IHJvdXRlUmVzdWx0Lm1ldHJpY3MucnNjRnVsbC5mcm9tUnNjV29ya2VyLFxuICAgICAgICAgICAgICAgIGZyb21IdG1sV29ya2VyOiByb3V0ZVJlc3VsdC5tZXRyaWNzLnJzY0Z1bGwuZnJvbUh0bWxXb3JrZXIsXG4gICAgICAgICAgICAgICAgcHJvY2Vzc2luZ1RpbWU6IHJzY0Z1bGxFbmRUaW1lIC0gcm91dGVSZXN1bHQubWV0cmljcy5yc2NGdWxsLnN0cmVhbU1ldHJpY3Muc3RhcnRUaW1lLFxuICAgICAgICAgICAgICAgIGNodW5rczogcm91dGVSZXN1bHQubWV0cmljcy5yc2NGdWxsLnN0cmVhbU1ldHJpY3MuY2h1bmtzLFxuICAgICAgICAgICAgICAgIGNodW5rUmF0ZTogcm91dGVSZXN1bHQubWV0cmljcy5yc2NGdWxsLnN0cmVhbU1ldHJpY3MuY2h1bmtzIC8gKChyc2NGdWxsRW5kVGltZSAtIHJvdXRlUmVzdWx0Lm1ldHJpY3MucnNjRnVsbC5zdHJlYW1NZXRyaWNzLnN0YXJ0VGltZSkgLyAxMDAwKSxcbiAgICAgICAgICAgICAgICBmaWxlTmFtZTogZXZlbnQuZGF0YS5maWxlTmFtZSxcbiAgICAgICAgICAgICAgICBvdXRwdXRQYXRoOiBldmVudC5kYXRhLnBhdGgsXG4gICAgICAgICAgICAgICAgYmFzZURpcjogZXZlbnQuZGF0YS5iYXNlRGlyLFxuICAgICAgICAgICAgICAgIHJvdXRlUGF0aDogZXZlbnQuZGF0YS5yb3V0ZVBhdGgsXG4gICAgICAgICAgICAgICAgc3RyZWFtTWV0cmljczogY3JlYXRlU3RyZWFtTWV0cmljcyh7XG4gICAgICAgICAgICAgICAgICAuLi5yb3V0ZVJlc3VsdC5tZXRyaWNzLnJzY0Z1bGwuc3RyZWFtTWV0cmljcyxcbiAgICAgICAgICAgICAgICAgIGR1cmF0aW9uOiByc2NGdWxsRW5kVGltZSAtIHJvdXRlUmVzdWx0Lm1ldHJpY3MucnNjRnVsbC5zdHJlYW1NZXRyaWNzLnN0YXJ0VGltZSxcbiAgICAgICAgICAgICAgICAgIGVuZFRpbWU6IHJzY0Z1bGxFbmRUaW1lLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICBpZiAob3B0aW9ucy5vbk1ldHJpY3MpIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zLm9uTWV0cmljcyhyc2NGdWxsTWV0cmljcyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LmRhdGEuZmlsZVR5cGUgPT09IFwicnNjXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IHJzY0VuZFRpbWUgPSBwZXJmb3JtYW5jZS5ub3coKTtcbiAgICAgICAgICAgIGNvbnN0IHJzY01ldHJpY3MgPSBjcmVhdGVSZW5kZXJNZXRyaWNzKHtcbiAgICAgICAgICAgICAgcm91dGU6IHJvdXRlLFxuICAgICAgICAgICAgICB0eXBlOiByb3V0ZVJlc3VsdC5tZXRyaWNzLnJzY0hlYWRsZXNzLnR5cGUsXG4gICAgICAgICAgICAgIGZyb21NYWluVGhyZWFkOiByb3V0ZVJlc3VsdC5tZXRyaWNzLnJzY0hlYWRsZXNzLmZyb21NYWluVGhyZWFkLFxuICAgICAgICAgICAgICBmcm9tUnNjV29ya2VyOiByb3V0ZVJlc3VsdC5tZXRyaWNzLnJzY0hlYWRsZXNzLmZyb21Sc2NXb3JrZXIsXG4gICAgICAgICAgICAgIGZyb21IdG1sV29ya2VyOiByb3V0ZVJlc3VsdC5tZXRyaWNzLnJzY0hlYWRsZXNzLmZyb21IdG1sV29ya2VyLFxuICAgICAgICAgICAgICBmaWxlU2l6ZTogZXZlbnQuZGF0YS5jb250ZW50Lmxlbmd0aCxcbiAgICAgICAgICAgICAgY2h1bmtzOiBldmVudC5kYXRhLmNodW5rcyB8fCAwLFxuICAgICAgICAgICAgICBwcm9jZXNzaW5nVGltZTogcnNjRW5kVGltZSAtIHJvdXRlUmVzdWx0Lm1ldHJpY3MucnNjSGVhZGxlc3Muc3RyZWFtTWV0cmljcy5zdGFydFRpbWUsXG4gICAgICAgICAgICAgIGNodW5rUmF0ZTogKGV2ZW50LmRhdGEuY2h1bmtzIHx8IDApIC8gKChyc2NFbmRUaW1lIC0gcm91dGVSZXN1bHQubWV0cmljcy5yc2NIZWFkbGVzcy5zdHJlYW1NZXRyaWNzLnN0YXJ0VGltZSkgLyAxMDAwKSxcbiAgICAgICAgICAgICAgZmlsZU5hbWU6IGV2ZW50LmRhdGEuZmlsZU5hbWUsXG4gICAgICAgICAgICAgIG91dHB1dFBhdGg6IGV2ZW50LmRhdGEucGF0aCxcbiAgICAgICAgICAgICAgYmFzZURpcjogZXZlbnQuZGF0YS5iYXNlRGlyLFxuICAgICAgICAgICAgICByb3V0ZVBhdGg6IGV2ZW50LmRhdGEucm91dGVQYXRoLFxuICAgICAgICAgICAgICBzdHJlYW1NZXRyaWNzOiBjcmVhdGVTdHJlYW1NZXRyaWNzKHtcbiAgICAgICAgICAgICAgICAuLi5yb3V0ZVJlc3VsdC5tZXRyaWNzLnJzY0hlYWRsZXNzLnN0cmVhbU1ldHJpY3MsXG4gICAgICAgICAgICAgICAgY2h1bmtzOiBldmVudC5kYXRhLmNodW5rcyB8fCAwLFxuICAgICAgICAgICAgICAgIGJ5dGVzOiBldmVudC5kYXRhLmNvbnRlbnQubGVuZ3RoLFxuICAgICAgICAgICAgICAgIGR1cmF0aW9uOiByc2NFbmRUaW1lIC0gcm91dGVSZXN1bHQubWV0cmljcy5yc2NIZWFkbGVzcy5zdHJlYW1NZXRyaWNzLnN0YXJ0VGltZSxcbiAgICAgICAgICAgICAgICBlbmRUaW1lOiByc2NFbmRUaW1lLFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpZiAob3B0aW9ucy5vbk1ldHJpY3MpIHtcbiAgICAgICAgICAgICAgb3B0aW9ucy5vbk1ldHJpY3MocnNjTWV0cmljcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIGNvbnN0IHJvdXRlSGFuZGxlck9wdGlvbnMgPSB7XG4gICAgICAuLi5vcHRpb25zLFxuICAgICAgbWFuaWZlc3QsXG4gICAgICByb3V0ZSxcbiAgICAgIHBhZ2VQYXRoOiByZXNvbHZlZFBhZ2VQYXRoIGFzIHN0cmluZyxcbiAgICAgIHByb3BzUGF0aDogcmVzb2x2ZWRQcm9wc1BhdGggYXMgc3RyaW5nLFxuICAgICAgcm9vdFBhdGg6IHJlc29sdmVkUm9vdFBhdGggYXMgc3RyaW5nLFxuICAgICAgaHRtbFBhdGg6IHJlc29sdmVkSHRtbFBhdGggYXMgc3RyaW5nLFxuICAgICAgY3NzRmlsZXM6IGNzc0ZpbGVzQnlQYWdlPy5nZXQocm91dGUpID8/IG5ldyBNYXAoKSxcbiAgICAgIGdsb2JhbENzczogb3B0aW9ucy5nbG9iYWxDc3MgPz8gbmV3IE1hcCgpLFxuICAgICAgaWQ6IGAke3JvdXRlfS0ke0RhdGUubm93KCl9LSR7TWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc3Vic3RyaW5nKDIsIDExKX1gLFxuICAgICAgb25FdmVudDogd3JhcHBlck9uRXZlbnQsXG4gICAgfTtcblxuICAgIGNvbnN0IHBhZ2VSZW5kZXJlciA9IHJlbmRlclBhZ2Uocm91dGVIYW5kbGVyT3B0aW9ucyk7XG4gICAgY29uc3QgcmVzdWx0czogUmVuZGVyUGFnZVJlc3VsdFtdID0gW107XG4gICAgbGV0IHJvdXRlRXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkO1xuXG4gICAgLy8gQ29uc3VtZSBhbGwgeWllbGRzIGZyb20gdGhlIHBhZ2UgcmVuZGVyZXIgYW5kIHdyaXRlIGZpbGVzXG4gICAgZm9yIGF3YWl0IChjb25zdCByZXN1bHQgb2YgcGFnZVJlbmRlcmVyKSB7XG4gICAgICByZXN1bHRzLnB1c2gocmVzdWx0KTtcbiAgICAgIFxuICAgICAgaWYgKHJlc3VsdC50eXBlID09PSBcImVycm9yXCIgJiYgcmVzdWx0LmVycm9yKSB7XG4gICAgICAgIHJvdXRlRXJyb3IgPSByZXN1bHQuZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IHJlc3VsdC5lcnJvciA6IG5ldyBFcnJvcihTdHJpbmcocmVzdWx0LmVycm9yKSk7XG4gICAgICB9XG4gICAgICBcbiAgICAgIGlmIChyZXN1bHQudHlwZSA9PT0gXCJzdWNjZXNzXCIgfHwgcmVzdWx0LnR5cGUgPT09IFwic2tpcFwiKSB7XG4gICAgICAgIC8vIFN0b3JlIHJlc3VsdCBmb3IgbWV0cmljcyB0cmFja2luZyAod3JhcHBlck9uRXZlbnQgbmVlZHMgdGhpcylcbiAgICAgICAgcm91dGVSZXN1bHRzLnNldChyb3V0ZSwgcmVzdWx0KTtcblxuICAgICAgICBjb25zdCByc2NXcml0ZVByb21pc2UgPSBmaWxlV3JpdGVyKFxuICAgICAgICAgIHJlc3VsdC5yc2MgYXMgYW55LFxuICAgICAgICAgIFwicnNjXCIsXG4gICAgICAgICAgeyAuLi5vcHRpb25zLCByb3V0ZSwgb25FdmVudDogd3JhcHBlck9uRXZlbnQsIGxvZ2dlcjogb3B0aW9ucy5sb2dnZXIgfSxcbiAgICAgICAgICBvcHRpb25zLnNpZ25hbFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IGh0bWxXcml0ZVByb21pc2UgPSBmaWxlV3JpdGVyKFxuICAgICAgICAgIHJlc3VsdC5odG1sIGFzIGFueSxcbiAgICAgICAgICBcImh0bWxcIixcbiAgICAgICAgICB7IC4uLm9wdGlvbnMsIHJvdXRlLCBvbkV2ZW50OiB3cmFwcGVyT25FdmVudCwgbG9nZ2VyOiBvcHRpb25zLmxvZ2dlciB9LFxuICAgICAgICAgIG9wdGlvbnMuc2lnbmFsXG4gICAgICAgICk7XG5cbiAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoW3JzY1dyaXRlUHJvbWlzZSwgaHRtbFdyaXRlUHJvbWlzZV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChyb3V0ZUVycm9yKSB7XG4gICAgICByZXR1cm4geyByb3V0ZSwgcmVzdWx0cywgZXJyb3I6IHJvdXRlRXJyb3IgfTtcbiAgICB9XG5cbiAgICByZXR1cm4geyByb3V0ZSwgcmVzdWx0cyB9O1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiB7IHJvdXRlLCByZXN1bHRzOiBbXSwgZXJyb3I6IGVycm9yIGFzIEVycm9yIH07XG4gIH1cbn1cblxuLyoqXG4gKiBTcGxpdHMgYXJyYXkgaW50byBjaHVua3Mgb2Ygc3BlY2lmaWVkIHNpemVcbiAqL1xuZnVuY3Rpb24gY2h1bms8VD4oYXJyYXk6IFRbXSwgc2l6ZTogbnVtYmVyKTogVFtdW10ge1xuICBjb25zdCBjaHVua3M6IFRbXVtdID0gW107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpICs9IHNpemUpIHtcbiAgICBjaHVua3MucHVzaChhcnJheS5zbGljZShpLCBpICsgc2l6ZSkpO1xuICB9XG4gIHJldHVybiBjaHVua3M7XG59XG5cbi8qKlxuICogQmF0Y2hlZCB2ZXJzaW9uIG9mIHJlbmRlclBhZ2VzIHRoYXQgcmVuZGVycyBwYWdlcyBpbiBwYXJhbGxlbCBiYXRjaGVzXG4gKi9cbmV4cG9ydCBjb25zdCByZW5kZXJQYWdlc0JhdGNoZWQ6IFJlbmRlclBhZ2VzRm4gPSAoXG4gIHJvdXRlcyxcbiAgaGFuZGxlck9wdGlvbnMsXG4gIHJlbmRlclBhZ2VcbikgPT4ge1xuICBjb25zdCB7XG4gICAgYXV0b0Rpc2NvdmVyZWRGaWxlcyxcbiAgICBtYW5pZmVzdCA9IHt9LFxuICAgIC4uLm9wdGlvbnNcbiAgfSA9IGhhbmRsZXJPcHRpb25zO1xuXG4gIGNvbnN0IGJhdGNoU2l6ZSA9IChvcHRpb25zIGFzIGFueSkuYmF0Y2hTaXplID8/IERFRkFVTFRfQkFUQ0hfU0laRTtcbiAgY29uc3QgY29tcGxldGVkUm91dGVzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIGNvbnN0IGZhaWxlZFJvdXRlcyA9IG5ldyBNYXA8c3RyaW5nLCB1bmtub3duPigpO1xuICBjb25zdCByZXN1bHRzID0gbmV3IE1hcDxzdHJpbmcsIFJlbmRlclBhZ2VSZXN1bHQ+KCk7XG5cbiAgaWYgKCFhdXRvRGlzY292ZXJlZEZpbGVzPy51cmxNYXApIHtcbiAgICByZXR1cm4gKGFzeW5jIGZ1bmN0aW9uKiBfcmVuZGVyUGFnZXNCYXRjaGVkKCk6IEFzeW5jR2VuZXJhdG9yPFJlbmRlclBhZ2VzUmVzdWx0LCBSZW5kZXJQYWdlc1Jlc3VsdCwgdW5rbm93bj4ge1xuICAgICAgY29uc3QgZXJyb3JSZXN1bHQ6IFJlbmRlclBhZ2VzUmVzdWx0ID0ge1xuICAgICAgICB0eXBlOiBcImVycm9yXCIsXG4gICAgICAgIGVycm9yOiBuZXcgRXJyb3IoXCJObyB1cmxNYXAgcHJvdmlkZWQgdG8gcmVuZGVyUGFnZXNcIiksXG4gICAgICAgIHJvdXRlOiBcIlwiLFxuICAgICAgICBmYWlsZWRSb3V0ZXM6IG5ldyBNYXAoKSxcbiAgICAgICAgY29tcGxldGVkUm91dGVzOiBuZXcgU2V0KCksXG4gICAgICAgIHJlc3VsdHM6IG5ldyBNYXAoKSxcbiAgICAgIH07XG4gICAgICB5aWVsZCBlcnJvclJlc3VsdDtcbiAgICAgIHJldHVybiBlcnJvclJlc3VsdDtcbiAgICB9KSgpO1xuICB9XG5cbiAgcmV0dXJuIChhc3luYyBmdW5jdGlvbiogX3JlbmRlclBhZ2VzQmF0Y2hlZCgpOiBBc3luY0dlbmVyYXRvcjxSZW5kZXJQYWdlc1Jlc3VsdCwgUmVuZGVyUGFnZXNSZXN1bHQsIHVua25vd24+IHtcbiAgICBjb25zdCByb3V0ZUFycmF5ID0gQXJyYXkuZnJvbShyb3V0ZXMpO1xuICAgIGNvbnN0IGJhdGNoZXMgPSBjaHVuayhyb3V0ZUFycmF5LCBiYXRjaFNpemUpO1xuICAgIFxuICAgIGlmIChvcHRpb25zLnZlcmJvc2UpIHtcbiAgICAgIG9wdGlvbnMubG9nZ2VyPy5pbmZvKFxuICAgICAgICBgW3JlbmRlclBhZ2VzQmF0Y2hlZF0gUmVuZGVyaW5nICR7cm91dGVBcnJheS5sZW5ndGh9IHBhZ2VzIGluICR7YmF0Y2hlcy5sZW5ndGh9IGJhdGNoZXMgb2YgJHtiYXRjaFNpemV9YFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGJhdGNoIG9mIGJhdGNoZXMpIHtcbiAgICAgIC8vIENoZWNrIGZvciBhYm9ydCBzaWduYWxcbiAgICAgIGlmIChvcHRpb25zLnNpZ25hbD8uYWJvcnRlZCkge1xuICAgICAgICBjb25zdCBhYm9ydFJlc3VsdDogUmVuZGVyUGFnZXNSZXN1bHQgPSB7XG4gICAgICAgICAgdHlwZTogXCJlcnJvclwiLFxuICAgICAgICAgIGVycm9yOiBvcHRpb25zLnNpZ25hbC5yZWFzb24gfHwgbmV3IEVycm9yKFwiQnVpbGQgYWJvcnRlZFwiKSxcbiAgICAgICAgICByb3V0ZTogYmF0Y2hbMF0gfHwgXCJcIixcbiAgICAgICAgICBmYWlsZWRSb3V0ZXMsXG4gICAgICAgICAgY29tcGxldGVkUm91dGVzLFxuICAgICAgICAgIHJlc3VsdHMsXG4gICAgICAgIH07XG4gICAgICAgIHlpZWxkIGFib3J0UmVzdWx0O1xuICAgICAgICByZXR1cm4gYWJvcnRSZXN1bHQ7XG4gICAgICB9XG5cbiAgICAgIC8vIFJlbmRlciBhbGwgcGFnZXMgaW4gdGhpcyBiYXRjaCBjb25jdXJyZW50bHlcbiAgICAgIGNvbnN0IGJhdGNoUHJvbWlzZXMgPSBiYXRjaC5tYXAocm91dGUgPT4gXG4gICAgICAgIHJlbmRlclNpbmdsZVJvdXRlKHJvdXRlLCBoYW5kbGVyT3B0aW9ucywgcmVuZGVyUGFnZSwgbWFuaWZlc3QsIGZhaWxlZFJvdXRlcylcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IGJhdGNoUmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsKGJhdGNoUHJvbWlzZXMpO1xuXG4gICAgICAvLyBQcm9jZXNzIHJlc3VsdHMgZnJvbSB0aGlzIGJhdGNoXG4gICAgICBmb3IgKGNvbnN0IHsgcm91dGUsIHJlc3VsdHM6IHBhZ2VSZXN1bHRzLCBlcnJvciB9IG9mIGJhdGNoUmVzdWx0cykge1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICBjb25zdCBwYW5pY0Vycm9yID0gaGFuZGxlRXJyb3Ioe1xuICAgICAgICAgICAgZXJyb3IsXG4gICAgICAgICAgICBsb2dnZXI6IG9wdGlvbnMubG9nZ2VyLFxuICAgICAgICAgICAgcGFuaWNUaHJlc2hvbGQ6IG9wdGlvbnMucGFuaWNUaHJlc2hvbGQsXG4gICAgICAgICAgICBjb250ZXh0OiBgcmVuZGVyUGFnZXNCYXRjaGVkKCR7cm91dGV9KWAsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpZiAocGFuaWNFcnJvciAhPSBudWxsKSB7XG4gICAgICAgICAgICBmYWlsZWRSb3V0ZXMuc2V0KHJvdXRlLCBlcnJvcik7XG4gICAgICAgICAgICBvcHRpb25zLmxvZ2dlcj8uZXJyb3IoYFtyZW5kZXJQYWdlc0JhdGNoZWRdIFBhbmljIGVycm9yIGZvciByb3V0ZSAke3JvdXRlfTogJHtlcnJvci5tZXNzYWdlfWApO1xuICAgICAgICAgICAgY29uc3QgZXJyb3JSZXN1bHQ6IFJlbmRlclBhZ2VzUmVzdWx0ID0ge1xuICAgICAgICAgICAgICB0eXBlOiBcImVycm9yXCIsXG4gICAgICAgICAgICAgIGVycm9yLFxuICAgICAgICAgICAgICByb3V0ZSxcbiAgICAgICAgICAgICAgZmFpbGVkUm91dGVzLFxuICAgICAgICAgICAgICBjb21wbGV0ZWRSb3V0ZXMsXG4gICAgICAgICAgICAgIHJlc3VsdHMsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgeWllbGQgZXJyb3JSZXN1bHQ7XG4gICAgICAgICAgICByZXR1cm4gZXJyb3JSZXN1bHQ7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG9wdGlvbnMubG9nZ2VyPy53YXJuKGBbcmVuZGVyUGFnZXNCYXRjaGVkXSBOb24tcGFuaWMgZXJyb3IgZm9yIHJvdXRlICR7cm91dGV9OiAke2Vycm9yLm1lc3NhZ2V9YCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbXBsZXRlZFJvdXRlcy5hZGQocm91dGUpO1xuICAgICAgICAgIFxuICAgICAgICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIHBhZ2VSZXN1bHRzKSB7XG4gICAgICAgICAgICBpZiAocmVzdWx0LnR5cGUgPT09IFwic3VjY2Vzc1wiIHx8IHJlc3VsdC50eXBlID09PSBcInNraXBcIikge1xuICAgICAgICAgICAgICByZXN1bHRzLnNldChyb3V0ZSwgcmVzdWx0KTtcbiAgICAgICAgICAgICAgeWllbGQge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwic3VjY2Vzc1wiLFxuICAgICAgICAgICAgICAgIHJvdXRlLFxuICAgICAgICAgICAgICAgIGZhaWxlZFJvdXRlcyxcbiAgICAgICAgICAgICAgICBjb21wbGV0ZWRSb3V0ZXMsXG4gICAgICAgICAgICAgICAgcmVzdWx0cyxcbiAgICAgICAgICAgICAgfSBzYXRpc2ZpZXMgUmVuZGVyUGFnZXNSZXN1bHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChvcHRpb25zLnZlcmJvc2UpIHtcbiAgICAgICAgb3B0aW9ucy5sb2dnZXI/LmluZm8oXG4gICAgICAgICAgYFtyZW5kZXJQYWdlc0JhdGNoZWRdIENvbXBsZXRlZCBiYXRjaDogJHtjb21wbGV0ZWRSb3V0ZXMuc2l6ZX0vJHtyb3V0ZUFycmF5Lmxlbmd0aH0gcGFnZXNgXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gRmluYWwgc3VjY2VzcyByZXN1bHRcbiAgICBjb25zdCBmaW5hbFJlc3VsdDogUmVuZGVyUGFnZXNSZXN1bHQgPSB7XG4gICAgICB0eXBlOiBcInN1Y2Nlc3NcIixcbiAgICAgIHJvdXRlOiBcIlwiLFxuICAgICAgZmFpbGVkUm91dGVzLFxuICAgICAgY29tcGxldGVkUm91dGVzLFxuICAgICAgcmVzdWx0cyxcbiAgICB9O1xuXG4gICAgcmV0dXJuIGZpbmFsUmVzdWx0O1xuICB9KSgpO1xufTtcbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBZUEsTUFBTSxrQkFBcUIsR0FBQSxDQUFBO0FBRTNCLFNBQVMsdUJBQUEsQ0FBd0Is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