vite-plugin-react-server
Version:
Vite plugin for React Server Components (RSC)
274 lines (271 loc) • 37 kB
JavaScript
/**
* vite-plugin-react-server
* Copyright (c) Nico Brinkkemper
* MIT License
*/
import { join, resolve } from 'node:path';
import { pathToFileURL } from 'node:url';
import { getModuleRef } from '../helpers/moduleRefs.js';
import { toError } from '../error/toError.js';
import { handleError } from '../error/handleError.js';
import { createSharedLoader } from '../helpers/createSharedLoader.js';
import { resolveVirtualAndNodeModules } from '../helpers/resolveVirtualAndNodeModules.js';
import { createLogger } from 'vite';
const createBuildLoader = function _createBuildLoader({ userOptions, serverManifest, staticManifest }, bundle, temporaryReferences, logger = createLogger()) {
const manifestKeys = Object.keys(serverManifest);
if (!manifestKeys.length) {
throw new Error("Server manifest is empty");
}
return async function buildLoader(id) {
if (userOptions.verbose) {
logger.info(`[buildLoader] id: ${id}`);
logger.info(`[buildLoader] Starting lookup for: ${id}`);
}
const [withoutQuery, query] = id.split("?", 2);
const [moduleId, exportName] = withoutQuery.split("#", 2);
const [normalizedKey, normalizedValue] = userOptions.normalizer(moduleId);
const virtualOrNodeModule = await resolveVirtualAndNodeModules(
moduleId,
exportName,
userOptions.verbose,
logger
);
if (virtualOrNodeModule !== null) {
return virtualOrNodeModule;
}
const moduleRef = getModuleRef(id);
if (temporaryReferences?.has(moduleRef)) {
const mod = temporaryReferences.get(moduleRef);
if (typeof mod === "object" && mod !== null && "error" in mod) ; else {
return mod;
}
}
try {
if (query === "inline") {
const manifestKey = normalizedValue;
if (userOptions.verbose) {
logger.info(
`[buildLoader] Looking for inline module: ${normalizedValue}`
);
}
let resolvedValue = normalizedValue;
if (normalizedValue.startsWith("assets/") && normalizedValue.endsWith(".css")) {
const basePath = normalizedValue.replace(
/-[a-zA-Z0-9]+\.css$/,
".css"
);
if (userOptions.verbose) {
logger.info(
`[buildLoader] CSS file detected, trying to resolve ${normalizedValue} to ${basePath}`
);
}
if (bundle[basePath]) {
resolvedValue = basePath;
if (userOptions.verbose) {
logger.info(
`[buildLoader] Resolved CSS file to: ${resolvedValue}`
);
}
}
}
if (userOptions.verbose) {
logger.info(
`[buildLoader] Trying bundle[moduleId]: bundle["${moduleId}"] = ${!!bundle[moduleId]}`
);
logger.info(
`[buildLoader] Trying bundle[normalizedValue]: bundle["${normalizedValue}"] = ${!!bundle[normalizedValue]}`
);
logger.info(
`[buildLoader] Trying bundle[resolvedValue]: bundle["${resolvedValue}"] = ${!!bundle[resolvedValue]}`
);
}
const serverChunk = bundle[moduleId] ?? bundle[normalizedValue] ?? bundle[resolvedValue] ?? bundle[serverManifest[manifestKey]?.file] ?? bundle[staticManifest[manifestKey]?.file] ?? bundle[serverManifest[normalizedKey]?.file] ?? bundle[staticManifest[normalizedKey]?.file] ?? Object.entries(bundle).find(
([, value]) => value.name === normalizedValue
)?.[1];
if (userOptions.verbose && serverChunk) {
logger.info(`[buildLoader] Found serverChunk: ${serverChunk.type}`);
}
if (serverChunk) {
if (serverChunk.type === "asset") {
if (userOptions.autoDiscover.jsonPattern.test(normalizedValue)) {
const jsonContent = serverChunk.source;
if (typeof jsonContent === "string") {
if (userOptions.verbose) {
logger.info(
`[buildLoader] Returning JSON content for: ${normalizedValue}`
);
}
return { default: JSON.parse(jsonContent) };
}
} else if (userOptions.autoDiscover.cssPattern.test(normalizedValue)) {
const cssContent = serverChunk.source;
if (typeof cssContent === "string") {
if (userOptions.verbose) {
logger.info(
`[buildLoader] Returning CSS content for: ${normalizedValue}, length: ${cssContent.length}`
);
}
return { default: cssContent };
} else {
if (userOptions.verbose) {
logger.info(
`[buildLoader] CSS source is not string: ${typeof cssContent}`
);
}
}
}
if (userOptions.verbose) {
logger.info(
`[buildLoader] Returning default asset source for: ${normalizedValue}`
);
}
return { default: serverChunk.source };
} else if ("code" in serverChunk) {
if (userOptions.verbose) {
logger.info(
`[buildLoader] Returning code for: ${normalizedValue}`
);
}
return { default: serverChunk.code };
}
}
const panicError = handleError({
error: new Error(
`Could not find inline module for: ${normalizedValue}`
),
logger,
log: true,
panicThreshold: userOptions.panicThreshold,
context: "Build Loader Error (inline)"
});
if (panicError != null) {
throw panicError;
}
return null;
}
const bundleEntry = bundle[withoutQuery];
if (bundleEntry) {
try {
const filePath = join(
userOptions.projectRoot,
userOptions.build.outDir,
userOptions.build.server,
withoutQuery
);
const fileUrl = pathToFileURL(filePath).href;
const module = await import(fileUrl);
temporaryReferences?.set(moduleRef, module);
return module;
} catch (error) {
const panicError = handleError({
error,
logger,
panicThreshold: userOptions.panicThreshold,
context: "Build Loader Error (bundle)"
});
temporaryReferences?.delete(moduleRef);
if (panicError != null) {
throw panicError;
}
}
}
const staticEntry = staticManifest[normalizedValue];
if (staticEntry) {
try {
const filePath = join(
userOptions.projectRoot,
userOptions.build.outDir,
userOptions.build.static,
staticEntry.file
);
const fileUrl = pathToFileURL(filePath).href;
const module = await import(fileUrl);
temporaryReferences?.set(moduleRef, module);
if (exportName && !(exportName in module)) {
throw new Error(
`Export ${exportName} not found in module ${normalizedValue}`
);
}
return module;
} catch (error) {
const panicError = handleError({
error,
logger,
panicThreshold: userOptions.panicThreshold,
context: "Build Loader Error (static)"
});
temporaryReferences?.delete(moduleRef);
if (panicError != null) {
throw panicError;
}
}
}
try {
const module = await createSharedLoader({
moduleId,
exportName,
verbose: userOptions.verbose,
logger,
resolveVirtual: true,
manifest: serverManifest,
normalizer: userOptions.normalizer,
moduleBase: userOptions.moduleBase,
preserveModulesRoot: userOptions.build.preserveModulesRoot,
projectRoot: userOptions.projectRoot,
buildOutDir: userOptions.build.outDir,
buildServerDir: userOptions.build.server,
isBuildMode: true,
isServeMode: false,
effectiveProjectRoot: userOptions.projectRoot,
build: {
outDir: userOptions.build.outDir,
server: userOptions.build.server,
client: userOptions.build.client,
static: userOptions.build.static
}
});
temporaryReferences?.set(moduleRef, module);
return module;
} catch (error) {
const err = toError(error);
const panicError = handleError({
error: err,
logger,
panicThreshold: userOptions.panicThreshold,
context: "Build Loader Error (shared)"
});
temporaryReferences?.delete(moduleRef);
if (panicError != null) {
throw panicError;
}
}
} catch (error) {
let enhancedError = error instanceof Error ? error : new Error(String(error));
if (enhancedError.message.includes("React Server Writer cannot be used outside a react-server environment")) {
const filePath = resolve(
userOptions.projectRoot,
userOptions.build.outDir,
userOptions.build.server,
moduleId
);
enhancedError = new Error(
`${enhancedError.message}
→ Imported from: ${moduleId}
→ Export: ${exportName}
→ File path: ${filePath}
→ NODE_OPTIONS: ${process.env.NODE_OPTIONS || "not set"}
→ execArgv: ${process.execArgv.join(" ") || "not set"}`
);
throw enhancedError;
}
const emptyExports = {
error: enhancedError,
id
};
temporaryReferences?.delete(moduleRef);
return emptyExports;
}
};
};
export { createBuildLoader };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlQnVpbGRMb2FkZXIuc2VydmVyLmpzIiwic291cmNlcyI6WyIuLi8uLi8uLi9wbHVnaW4vcmVhY3Qtc3RhdGljL2NyZWF0ZUJ1aWxkTG9hZGVyLnNlcnZlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBqb2luLCByZXNvbHZlIH0gZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHsgcGF0aFRvRmlsZVVSTCB9IGZyb20gXCJub2RlOnVybFwiO1xuaW1wb3J0IHsgZ2V0TW9kdWxlUmVmIH0gZnJvbSBcIi4uL2hlbHBlcnMvbW9kdWxlUmVmcy5qc1wiO1xuaW1wb3J0IHsgdG9FcnJvciB9IGZyb20gXCIuLi9lcnJvci90b0Vycm9yLmpzXCI7XG5pbXBvcnQgeyBoYW5kbGVFcnJvciB9IGZyb20gXCIuLi9lcnJvci9oYW5kbGVFcnJvci5qc1wiO1xuaW1wb3J0IHsgY3JlYXRlU2hhcmVkTG9hZGVyIH0gZnJvbSBcIi4uL2hlbHBlcnMvY3JlYXRlU2hhcmVkTG9hZGVyLmpzXCI7XG5pbXBvcnQgeyByZXNvbHZlVmlydHVhbEFuZE5vZGVNb2R1bGVzIH0gZnJvbSBcIi4uL2hlbHBlcnMvcmVzb2x2ZVZpcnR1YWxBbmROb2RlTW9kdWxlcy5qc1wiO1xuXG5pbXBvcnQgdHlwZSB7IENyZWF0ZUJ1aWxkTG9hZGVyRm4gfSBmcm9tIFwiLi90eXBlcy5qc1wiO1xuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyIH0gZnJvbSBcInZpdGVcIjtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbG9hZGVyIGZ1bmN0aW9uIGZvciBoYW5kbGluZyBtb2R1bGUgcmVzb2x1dGlvbiBkdXJpbmcgYnVpbGQuXG4gKlxuICogVGhlIGxvYWRlciBoYW5kbGVzIHRoZSBmb2xsb3dpbmcgc3RyYXRlZ3k6XG4gKiAgLSBGb3IgaW5saW5lIG1vZHVsZXM6IEhhbmRsZSB0aGVtIHVzaW5nIGJ1bmRsZVxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlQnVpbGRMb2FkZXI6IENyZWF0ZUJ1aWxkTG9hZGVyRm4gPVxuICBmdW5jdGlvbiBfY3JlYXRlQnVpbGRMb2FkZXIoXG4gICAgeyB1c2VyT3B0aW9ucywgc2VydmVyTWFuaWZlc3QsIHN0YXRpY01hbmlmZXN0IH0sXG4gICAgYnVuZGxlLFxuICAgIHRlbXBvcmFyeVJlZmVyZW5jZXMsXG4gICAgbG9nZ2VyID0gY3JlYXRlTG9nZ2VyKClcbiAgKSB7XG4gICAgY29uc3QgbWFuaWZlc3RLZXlzID0gT2JqZWN0LmtleXMoc2VydmVyTWFuaWZlc3QpO1xuICAgIGlmICghbWFuaWZlc3RLZXlzLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU2VydmVyIG1hbmlmZXN0IGlzIGVtcHR5XCIpO1xuICAgIH1cblxuICAgIHJldHVybiBhc3luYyBmdW5jdGlvbiBidWlsZExvYWRlcihpZCkge1xuICAgICAgaWYgKHVzZXJPcHRpb25zLnZlcmJvc2UpIHtcbiAgICAgICAgbG9nZ2VyLmluZm8oYFtidWlsZExvYWRlcl0gaWQ6ICR7aWR9YCk7XG4gICAgICAgIGxvZ2dlci5pbmZvKGBbYnVpbGRMb2FkZXJdIFN0YXJ0aW5nIGxvb2t1cCBmb3I6ICR7aWR9YCk7XG4gICAgICB9XG4gICAgICBjb25zdCBbd2l0aG91dFF1ZXJ5LCBxdWVyeV0gPSBpZC5zcGxpdChcIj9cIiwgMik7XG4gICAgICBjb25zdCBbbW9kdWxlSWQsIGV4cG9ydE5hbWVdID0gd2l0aG91dFF1ZXJ5LnNwbGl0KFwiI1wiLCAyKTtcbiAgICAgIFxuICAgICAgLy8gTm9ybWFsaXplIHRoZSBtb2R1bGVJZCBlYXJseSAodXNlZCB0aHJvdWdob3V0IHRoZSBmdW5jdGlvbilcbiAgICAgIGNvbnN0IFtub3JtYWxpemVkS2V5LCBub3JtYWxpemVkVmFsdWVdID0gdXNlck9wdGlvbnMubm9ybWFsaXplcihtb2R1bGVJZCk7XG4gICAgICBcbiAgICAgIC8vIEZvciB2aXJ0dWFsIG1vZHVsZXMgYW5kIG5vZGVfbW9kdWxlcywgdXNlIHNoYXJlZCB1dGlsaXR5IChzYW1lIGFzIFJTQyB3b3JrZXIgbG9hZGVyKVxuICAgICAgLy8gVGhpcyBoYW5kbGVzIF92aXJ0dWFsL2R5bmFtaWMtaW1wb3J0LWhlbHBlci5qcyBhbmQgcHJvdmlkZXMgc2hpbXMgaWYgbmVlZGVkXG4gICAgICAvLyBDaGVjayB0aGlzIGVhcmx5LCBiZWZvcmUgYnVpbGQtc3BlY2lmaWMgaGFuZGxpbmdcbiAgICAgIGNvbnN0IHZpcnR1YWxPck5vZGVNb2R1bGUgPSBhd2FpdCByZXNvbHZlVmlydHVhbEFuZE5vZGVNb2R1bGVzKFxuICAgICAgICBtb2R1bGVJZCxcbiAgICAgICAgZXhwb3J0TmFtZSxcbiAgICAgICAgdXNlck9wdGlvbnMudmVyYm9zZSxcbiAgICAgICAgbG9nZ2VyXG4gICAgICApO1xuICAgICAgaWYgKHZpcnR1YWxPck5vZGVNb2R1bGUgIT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIHZpcnR1YWxPck5vZGVNb2R1bGU7XG4gICAgICB9XG4gICAgICBcbiAgICAgIGNvbnN0IG1vZHVsZVJlZiA9IGdldE1vZHVsZVJlZihpZCk7XG5cbiAgICAgIC8vIENoZWNrIGlmIHdlIGhhdmUgYSB0ZW1wb3JhcnkgcmVmZXJlbmNlIChjYWNoZWQgbW9kdWxlKVxuICAgICAgaWYgKHRlbXBvcmFyeVJlZmVyZW5jZXM/Lmhhcyhtb2R1bGVSZWYpKSB7XG4gICAgICAgIGNvbnN0IG1vZCA9IHRlbXBvcmFyeVJlZmVyZW5jZXMuZ2V0KG1vZHVsZVJlZik7XG4gICAgICAgIGlmICh0eXBlb2YgbW9kID09PSBcIm9iamVjdFwiICYmIG1vZCAhPT0gbnVsbCAmJiBcImVycm9yXCIgaW4gbW9kKSB7XG4gICAgICAgICAgLy8gaWdub3JlIGl0XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIG1vZDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0cnkge1xuICAgICAgICAvLyBGb3IgaW5saW5lIG1vZHVsZXMsIGhhbmRsZSB0aGVtIGRpcmVjdGx5XG4gICAgICAgIGlmIChxdWVyeSA9PT0gXCJpbmxpbmVcIikge1xuICAgICAgICAgIGNvbnN0IG1hbmlmZXN0S2V5ID0gbm9ybWFsaXplZFZhbHVlO1xuICAgICAgICAgIGlmICh1c2VyT3B0aW9ucy52ZXJib3NlKSB7XG4gICAgICAgICAgICBsb2dnZXIuaW5mbyhcbiAgICAgICAgICAgICAgYFtidWlsZExvYWRlcl0gTG9va2luZyBmb3IgaW5saW5lIG1vZHVsZTogJHtub3JtYWxpemVkVmFsdWV9YFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBGb3IgQ1NTIGZpbGVzLCB0cnkgdG8gcmVzb2x2ZSB0aGUgaGFzaGVkIGZpbGVuYW1lIHRvIHRoZSBhY3R1YWwgYnVuZGxlIGZpbGVuYW1lXG4gICAgICAgICAgbGV0IHJlc29sdmVkVmFsdWUgPSBub3JtYWxpemVkVmFsdWU7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgbm9ybWFsaXplZFZhbHVlLnN0YXJ0c1dpdGgoXCJhc3NldHMvXCIpICYmXG4gICAgICAgICAgICBub3JtYWxpemVkVmFsdWUuZW5kc1dpdGgoXCIuY3NzXCIpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICAvLyBFeHRyYWN0IHRoZSBiYXNlIHBhdGggd2l0aG91dCBoYXNoXG4gICAgICAgICAgICBjb25zdCBiYXNlUGF0aCA9IG5vcm1hbGl6ZWRWYWx1ZS5yZXBsYWNlKFxuICAgICAgICAgICAgICAvLVthLXpBLVowLTldK1xcLmNzcyQvLFxuICAgICAgICAgICAgICBcIi5jc3NcIlxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmICh1c2VyT3B0aW9ucy52ZXJib3NlKSB7XG4gICAgICAgICAgICAgIGxvZ2dlci5pbmZvKFxuICAgICAgICAgICAgICAgIGBbYnVpbGRMb2FkZXJdIENTUyBmaWxlIGRldGVjdGVkLCB0cnlpbmcgdG8gcmVzb2x2ZSAke25vcm1hbGl6ZWRWYWx1ZX0gdG8gJHtiYXNlUGF0aH1gXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBUcnkgdGhlIGJhc2UgcGF0aCBmaXJzdFxuICAgICAgICAgICAgaWYgKGJ1bmRsZVtiYXNlUGF0aF0pIHtcbiAgICAgICAgICAgICAgcmVzb2x2ZWRWYWx1ZSA9IGJhc2VQYXRoO1xuICAgICAgICAgICAgICBpZiAodXNlck9wdGlvbnMudmVyYm9zZSkge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKFxuICAgICAgICAgICAgICAgICAgYFtidWlsZExvYWRlcl0gUmVzb2x2ZWQgQ1NTIGZpbGUgdG86ICR7cmVzb2x2ZWRWYWx1ZX1gXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIEZpcnN0IHRyeSB0byBmaW5kIHRoZSBtb2R1bGUgd2l0aG91dCB0aGUgZXhwb3J0IG5hbWVcbiAgICAgICAgICBpZiAodXNlck9wdGlvbnMudmVyYm9zZSkge1xuICAgICAgICAgICAgbG9nZ2VyLmluZm8oXG4gICAgICAgICAgICAgIGBbYnVpbGRMb2FkZXJdIFRyeWluZyBidW5kbGVbbW9kdWxlSWRdOiBidW5kbGVbXCIke21vZHVsZUlkfVwiXSA9ICR7ISFidW5kbGVbXG4gICAgICAgICAgICAgICAgbW9kdWxlSWRcbiAgICAgICAgICAgICAgXX1gXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgbG9nZ2VyLmluZm8oXG4gICAgICAgICAgICAgIGBbYnVpbGRMb2FkZXJdIFRyeWluZyBidW5kbGVbbm9ybWFsaXplZFZhbHVlXTogYnVuZGxlW1wiJHtub3JtYWxpemVkVmFsdWV9XCJdID0gJHshIWJ1bmRsZVtcbiAgICAgICAgICAgICAgICBub3JtYWxpemVkVmFsdWVcbiAgICAgICAgICAgICAgXX1gXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgbG9nZ2VyLmluZm8oXG4gICAgICAgICAgICAgIGBbYnVpbGRMb2FkZXJdIFRyeWluZyBidW5kbGVbcmVzb2x2ZWRWYWx1ZV06IGJ1bmRsZVtcIiR7cmVzb2x2ZWRWYWx1ZX1cIl0gPSAkeyEhYnVuZGxlW1xuICAgICAgICAgICAgICAgIHJlc29sdmVkVmFsdWVcbiAgICAgICAgICAgICAgXX1gXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBzZXJ2ZXJDaHVuayA9XG4gICAgICAgICAgICBidW5kbGVbbW9kdWxlSWRdID8/XG4gICAgICAgICAgICBidW5kbGVbbm9ybWFsaXplZFZhbHVlXSA/P1xuICAgICAgICAgICAgYnVuZGxlW3Jlc29sdmVkVmFsdWVdID8/XG4gICAgICAgICAgICBidW5kbGVbc2VydmVyTWFuaWZlc3RbbWFuaWZlc3RLZXldPy5maWxlXSA/P1xuICAgICAgICAgICAgYnVuZGxlW3N0YXRpY01hbmlmZXN0W21hbmlmZXN0S2V5XT8uZmlsZV0gPz9cbiAgICAgICAgICAgIGJ1bmRsZVtzZXJ2ZXJNYW5pZmVzdFtub3JtYWxpemVkS2V5XT8uZmlsZV0gPz9cbiAgICAgICAgICAgIGJ1bmRsZVtzdGF0aWNNYW5pZmVzdFtub3JtYWxpemVkS2V5XT8uZmlsZV0gPz9cbiAgICAgICAgICAgIE9iamVjdC5lbnRyaWVzKGJ1bmRsZSkuZmluZChcbiAgICAgICAgICAgICAgKFssIHZhbHVlXSkgPT4gdmFsdWUubmFtZSA9PT0gbm9ybWFsaXplZFZhbHVlXG4gICAgICAgICAgICApPy5bMV07XG5cbiAgICAgICAgICBpZiAodXNlck9wdGlvbnMudmVyYm9zZSAmJiBzZXJ2ZXJDaHVuaykge1xuICAgICAgICAgICAgbG9nZ2VyLmluZm8oYFtidWlsZExvYWRlcl0gRm91bmQgc2VydmVyQ2h1bms6ICR7c2VydmVyQ2h1bmsudHlwZX1gKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoc2VydmVyQ2h1bmspIHtcbiAgICAgICAgICAgIGlmIChzZXJ2ZXJDaHVuay50eXBlID09PSBcImFzc2V0XCIpIHtcbiAgICAgICAgICAgICAgLy8gRm9yIENTUyBmaWxlcywgZW5zdXJlIHdlJ3JlIGluIHRoZSBSZWFjdCBTZXJ2ZXIgZW52aXJvbm1lbnRcbiAgICAgICAgICAgICAgaWYgKHVzZXJPcHRpb25zLmF1dG9EaXNjb3Zlci5qc29uUGF0dGVybi50ZXN0KG5vcm1hbGl6ZWRWYWx1ZSkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBqc29uQ29udGVudCA9IHNlcnZlckNodW5rLnNvdXJjZTtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGpzb25Db250ZW50ID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICAgICAgICBpZiAodXNlck9wdGlvbnMudmVyYm9zZSkge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhcbiAgICAgICAgICAgICAgICAgICAgICBgW2J1aWxkTG9hZGVyXSBSZXR1cm5pbmcgSlNPTiBjb250ZW50IGZvcjogJHtub3JtYWxpemVkVmFsdWV9YFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgZGVmYXVsdDogSlNPTi5wYXJzZShqc29uQ29udGVudCkgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgICAgICAgdXNlck9wdGlvbnMuYXV0b0Rpc2NvdmVyLmNzc1BhdHRlcm4udGVzdChub3JtYWxpemVkVmFsdWUpXG4gICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNzc0NvbnRlbnQgPSBzZXJ2ZXJDaHVuay5zb3VyY2U7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBjc3NDb250ZW50ID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICAgICAgICBpZiAodXNlck9wdGlvbnMudmVyYm9zZSkge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhcbiAgICAgICAgICAgICAgICAgICAgICBgW2J1aWxkTG9hZGVyXSBSZXR1cm5pbmcgQ1NTIGNvbnRlbnQgZm9yOiAke25vcm1hbGl6ZWRWYWx1ZX0sIGxlbmd0aDogJHtjc3NDb250ZW50Lmxlbmd0aH1gXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICByZXR1cm4geyBkZWZhdWx0OiBjc3NDb250ZW50IH07XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIGlmICh1c2VyT3B0aW9ucy52ZXJib3NlKSB7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKFxuICAgICAgICAgICAgICAgICAgICAgIGBbYnVpbGRMb2FkZXJdIENTUyBzb3VyY2UgaXMgbm90IHN0cmluZzogJHt0eXBlb2YgY3NzQ29udGVudH1gXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmICh1c2VyT3B0aW9ucy52ZXJib3NlKSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oXG4gICAgICAgICAgICAgICAgICBgW2J1aWxkTG9hZGVyXSBSZXR1cm5pbmcgZGVmYXVsdCBhc3NldCBzb3VyY2UgZm9yOiAke25vcm1hbGl6ZWRWYWx1ZX1gXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4geyBkZWZhdWx0OiBzZXJ2ZXJDaHVuay5zb3VyY2UgfTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoXCJjb2RlXCIgaW4gc2VydmVyQ2h1bmspIHtcbiAgICAgICAgICAgICAgaWYgKHVzZXJPcHRpb25zLnZlcmJvc2UpIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhcbiAgICAgICAgICAgICAgICAgIGBbYnVpbGRMb2FkZXJdIFJldHVybmluZyBjb2RlIGZvcjogJHtub3JtYWxpemVkVmFsdWV9YFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIHsgZGVmYXVsdDogc2VydmVyQ2h1bmsuY29kZSB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBwYW5pY0Vycm9yID0gaGFuZGxlRXJyb3Ioe1xuICAgICAgICAgICAgZXJyb3I6IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgYENvdWxkIG5vdCBmaW5kIGlubGluZSBtb2R1bGUgZm9yOiAke25vcm1hbGl6ZWRWYWx1ZX1gXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgbG9nZ2VyLFxuICAgICAgICAgICAgbG9nOiB0cnVlLFxuICAgICAgICAgICAgcGFuaWNUaHJlc2hvbGQ6IHVzZXJPcHRpb25zLnBhbmljVGhyZXNob2xkLFxuICAgICAgICAgICAgY29udGV4dDogXCJCdWlsZCBMb2FkZXIgRXJyb3IgKGlubGluZSlcIixcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBpZiAocGFuaWNFcnJvciAhPSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBwYW5pY0Vycm9yO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNoZWNrIHRoZSBidW5kbGUgbWFuaWZlc3QgZm9yIGEgZGlyZWN0IG1hdGNoXG4gICAgICAgIGNvbnN0IGJ1bmRsZUVudHJ5ID0gYnVuZGxlW3dpdGhvdXRRdWVyeV07XG4gICAgICAgIGlmIChidW5kbGVFbnRyeSkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBmaWxlUGF0aCA9IGpvaW4oXG4gICAgICAgICAgICAgIHVzZXJPcHRpb25zLnByb2plY3RSb290LFxuICAgICAgICAgICAgICB1c2VyT3B0aW9ucy5idWlsZC5vdXREaXIsXG4gICAgICAgICAgICAgIHVzZXJPcHRpb25zLmJ1aWxkLnNlcnZlcixcbiAgICAgICAgICAgICAgd2l0aG91dFF1ZXJ5XG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgY29uc3QgZmlsZVVybCA9IHBhdGhUb0ZpbGVVUkwoZmlsZVBhdGgpLmhyZWY7XG4gICAgICAgICAgICBjb25zdCBtb2R1bGUgPSBhd2FpdCBpbXBvcnQoZmlsZVVybCk7XG4gICAgICAgICAgICB0ZW1wb3JhcnlSZWZlcmVuY2VzPy5zZXQobW9kdWxlUmVmLCBtb2R1bGUpO1xuICAgICAgICAgICAgcmV0dXJuIG1vZHVsZTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc3QgcGFuaWNFcnJvciA9IGhhbmRsZUVycm9yKHtcbiAgICAgICAgICAgICAgZXJyb3I6IGVycm9yLFxuICAgICAgICAgICAgICBsb2dnZXIsXG4gICAgICAgICAgICAgIHBhbmljVGhyZXNob2xkOiB1c2VyT3B0aW9ucy5wYW5pY1RocmVzaG9sZCxcbiAgICAgICAgICAgICAgY29udGV4dDogXCJCdWlsZCBMb2FkZXIgRXJyb3IgKGJ1bmRsZSlcIixcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGVtcG9yYXJ5UmVmZXJlbmNlcz8uZGVsZXRlKG1vZHVsZVJlZik7XG4gICAgICAgICAgICBpZiAocGFuaWNFcnJvciAhPSBudWxsKSB7XG4gICAgICAgICAgICAgIHRocm93IHBhbmljRXJyb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gRm9yIHN0YXRpYyBhc3NldHMsIHVzZSBzdGF0aWMgbWFuaWZlc3RcbiAgICAgICAgY29uc3Qgc3RhdGljRW50cnkgPSBzdGF0aWNNYW5pZmVzdFtub3JtYWxpemVkVmFsdWVdO1xuICAgICAgICBpZiAoc3RhdGljRW50cnkpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgZmlsZVBhdGggPSBqb2luKFxuICAgICAgICAgICAgICB1c2VyT3B0aW9ucy5wcm9qZWN0Um9vdCxcbiAgICAgICAgICAgICAgdXNlck9wdGlvbnMuYnVpbGQub3V0RGlyLFxuICAgICAgICAgICAgICB1c2VyT3B0aW9ucy5idWlsZC5zdGF0aWMsXG4gICAgICAgICAgICAgIHN0YXRpY0VudHJ5LmZpbGVcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBjb25zdCBmaWxlVXJsID0gcGF0aFRvRmlsZVVSTChmaWxlUGF0aCkuaHJlZjtcbiAgICAgICAgICAgIGNvbnN0IG1vZHVsZSA9IGF3YWl0IGltcG9ydChmaWxlVXJsKTtcbiAgICAgICAgICAgIHRlbXBvcmFyeVJlZmVyZW5jZXM/LnNldChtb2R1bGVSZWYsIG1vZHVsZSk7XG4gICAgICAgICAgICAvLyBJZiB3ZSBoYXZlIGFuIGV4cG9ydCBuYW1lLCBtYWtlIHN1cmUgaXQncyBhIGtleVxuICAgICAgICAgICAgaWYgKGV4cG9ydE5hbWUgJiYgIShleHBvcnROYW1lIGluIG1vZHVsZSkpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgIGBFeHBvcnQgJHtleHBvcnROYW1lfSBub3QgZm91bmQgaW4gbW9kdWxlICR7bm9ybWFsaXplZFZhbHVlfWBcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBtb2R1bGU7XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnN0IHBhbmljRXJyb3IgPSBoYW5kbGVFcnJvcih7XG4gICAgICAgICAgICAgIGVycm9yOiBlcnJvcixcbiAgICAgICAgICAgICAgbG9nZ2VyLFxuICAgICAgICAgICAgICBwYW5pY1RocmVzaG9sZDogdXNlck9wdGlvbnMucGFuaWNUaHJlc2hvbGQsXG4gICAgICAgICAgICAgIGNvbnRleHQ6IFwiQnVpbGQgTG9hZGVyIEVycm9yIChzdGF0aWMpXCIsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRlbXBvcmFyeVJlZmVyZW5jZXM/LmRlbGV0ZShtb2R1bGVSZWYpO1xuICAgICAgICAgICAgaWYgKHBhbmljRXJyb3IgIT0gbnVsbCkge1xuICAgICAgICAgICAgICB0aHJvdyBwYW5pY0Vycm9yO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFVzZSBzaGFyZWQgbG9hZGVyIHV0aWxpdHkgZm9yIGNvbW1vbiBjYXNlcyAodmlydHVhbCBtb2R1bGVzLCBtYW5pZmVzdCByZXNvbHV0aW9uLCBpbXBvcnRzKVxuICAgICAgICAvLyBUaGlzIGhhbmRsZXMgdGhlIHNhbWUgbG9naWMgYXMgUlNDIHdvcmtlciBsb2FkZXJcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBtb2R1bGUgPSBhd2FpdCBjcmVhdGVTaGFyZWRMb2FkZXIoe1xuICAgICAgICAgICAgbW9kdWxlSWQsXG4gICAgICAgICAgICBleHBvcnROYW1lLFxuICAgICAgICAgICAgdmVyYm9zZTogdXNlck9wdGlvbnMudmVyYm9zZSxcbiAgICAgICAgICAgIGxvZ2dlcixcbiAgICAgICAgICAgIHJlc29sdmVWaXJ0dWFsOiB0cnVlLFxuICAgICAgICAgICAgbWFuaWZlc3Q6IHNlcnZlck1hbmlmZXN0LFxuICAgICAgICAgICAgbm9ybWFsaXplcjogdXNlck9wdGlvbnMubm9ybWFsaXplcixcbiAgICAgICAgICAgIG1vZHVsZUJhc2U6IHVzZXJPcHRpb25zLm1vZHVsZUJhc2UsXG4gICAgICAgICAgICBwcmVzZXJ2ZU1vZHVsZXNSb290OiB1c2VyT3B0aW9ucy5idWlsZC5wcmVzZXJ2ZU1vZHVsZXNSb290LFxuICAgICAgICAgICAgcHJvamVjdFJvb3Q6IHVzZXJPcHRpb25zLnByb2plY3RSb290LFxuICAgICAgICAgICAgYnVpbGRPdXREaXI6IHVzZXJPcHRpb25zLmJ1aWxkLm91dERpcixcbiAgICAgICAgICAgIGJ1aWxkU2VydmVyRGlyOiB1c2VyT3B0aW9ucy5idWlsZC5zZXJ2ZXIsXG4gICAgICAgICAgICBpc0J1aWxkTW9kZTogdHJ1ZSxcbiAgICAgICAgICAgIGlzU2VydmVNb2RlOiBmYWxzZSxcbiAgICAgICAgICAgIGVmZmVjdGl2ZVByb2plY3RSb290OiB1c2VyT3B0aW9ucy5wcm9qZWN0Um9vdCxcbiAgICAgICAgICAgIGJ1aWxkOiB7XG4gICAgICAgICAgICAgIG91dERpcjogdXNlck9wdGlvbnMuYnVpbGQub3V0RGlyLFxuICAgICAgICAgICAgICBzZXJ2ZXI6IHVzZXJPcHRpb25zLmJ1aWxkLnNlcnZlcixcbiAgICAgICAgICAgICAgY2xpZW50OiB1c2VyT3B0aW9ucy5idWlsZC5jbGllbnQsXG4gICAgICAgICAgICAgIHN0YXRpYzogdXNlck9wdGlvbnMuYnVpbGQuc3RhdGljLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBcbiAgICAgICAgICAvLyBTdG9yZSBpbiB0ZW1wb3JhcnkgcmVmZXJlbmNlcyBmb3IgY2FjaGluZ1xuICAgICAgICAgIHRlbXBvcmFyeVJlZmVyZW5jZXM/LnNldChtb2R1bGVSZWYsIG1vZHVsZSk7XG4gICAgICAgICAgcmV0dXJuIG1vZHVsZTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICBjb25zdCBlcnIgPSB0b0Vycm9yKGVycm9yKTtcbiAgICAgICAgICBjb25zdCBwYW5pY0Vycm9yID0gaGFuZGxlRXJyb3Ioe1xuICAgICAgICAgICAgZXJyb3I6IGVycixcbiAgICAgICAgICAgIGxvZ2dlcixcbiAgICAgICAgICAgIHBhbmljVGhyZXNob2xkOiB1c2VyT3B0aW9ucy5wYW5pY1RocmVzaG9sZCxcbiAgICAgICAgICAgIGNvbnRleHQ6IFwiQnVpbGQgTG9hZGVyIEVycm9yIChzaGFyZWQpXCIsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdGVtcG9yYXJ5UmVmZXJlbmNlcz8uZGVsZXRlKG1vZHVsZVJlZik7XG4gICAgICAgICAgaWYgKHBhbmljRXJyb3IgIT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgcGFuaWNFcnJvcjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIC8vIEVuaGFuY2UgUmVhY3QgU2VydmVyIERPTSBlcnJvcnMgd2l0aCBpbXBvcnQgY29udGV4dFxuICAgICAgICBsZXQgZW5oYW5jZWRFcnJvciA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcihTdHJpbmcoZXJyb3IpKTtcbiAgICAgICAgaWYgKGVuaGFuY2VkRXJyb3IubWVzc2FnZS5pbmNsdWRlcygnUmVhY3QgU2VydmVyIFdyaXRlciBjYW5ub3QgYmUgdXNlZCBvdXRzaWRlIGEgcmVhY3Qtc2VydmVyIGVudmlyb25tZW50JykpIHtcbiAgICAgICAgICBjb25zdCBmaWxlUGF0aCA9IHJlc29sdmUoXG4gICAgICAgICAgICB1c2VyT3B0aW9ucy5wcm9qZWN0Um9vdCxcbiAgICAgICAgICAgIHVzZXJPcHRpb25zLmJ1aWxkLm91dERpcixcbiAgICAgICAgICAgIHVzZXJPcHRpb25zLmJ1aWxkLnNlcnZlcixcbiAgICAgICAgICAgIG1vZHVsZUlkXG4gICAgICAgICAgKTtcbiAgICAgICAgICBlbmhhbmNlZEVycm9yID0gbmV3IEVycm9yKFxuICAgICAgICAgICAgYCR7ZW5oYW5jZWRFcnJvci5tZXNzYWdlfVxcbmAgK1xuICAgICAgICAgICAgYCAg4oaSIEltcG9ydGVkIGZyb206ICR7bW9kdWxlSWR9XFxuYCArXG4gICAgICAgICAgICBgICDihpIgRXhwb3J0OiAke2V4cG9ydE5hbWV9XFxuYCArXG4gICAgICAgICAgICBgICDihpIgRmlsZSBwYXRoOiAke2ZpbGVQYXRofVxcbmAgK1xuICAgICAgICAgICAgYCAg4oaSIE5PREVfT1BUSU9OUzogJHtwcm9jZXNzLmVudi5OT0RFX09QVElPTlMgfHwgJ25vdCBzZXQnfVxcbmAgK1xuICAgICAgICAgICAgYCAg4oaSIGV4ZWNBcmd2OiAke3Byb2Nlc3MuZXhlY0FyZ3Yuam9pbignICcpIHx8ICdub3Qgc2V0J31gXG4gICAgICAgICAgKTtcbiAgICAgICAgICB0aHJvdyBlbmhhbmNlZEVycm9yO1xuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICBjb25zdCBlbXB0eUV4cG9ydHMgPSB7XG4gICAgICAgICAgZXJyb3I6IGVuaGFuY2VkRXJyb3IsXG4gICAgICAgICAgaWQ6IGlkLFxuICAgICAgICB9O1xuICAgICAgICB0ZW1wb3JhcnlSZWZlcmVuY2VzPy5kZWxldGUobW9kdWxlUmVmKTtcbiAgICAgICAgcmV0dXJuIGVtcHR5RXhwb3J0cztcbiAgICAgIH1cbiAgICB9O1xuICB9O1xuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7O0FBaUJPLE1BQU0saUJBQ1gsR0FBQSxTQUFTLGtCQUNQLENBQUEsRUFBRSxXQUFhLEVBQUEsY0FBQSxFQUFnQixjQUFlLEVBQUEsRUFDOUMsTUFDQSxFQUFBLG1CQUFBLEVBQ0EsTUFBUyxHQUFBLFlBQUEsRUFDVCxFQUFBO0FBQ0EsRUFBTSxNQUFBLFlBQUEsR0FBZSxNQUFPLENBQUEsSUFBQSxDQUFLLGNBQWMsQ0FBQTtBQUMvQyxFQUFJLElBQUEsQ0FBQyxhQUFhLE1BQVEsRUFBQTtBQUN4QixJQUFNLE1BQUEsSUFBSSxNQUFNLDBCQUEwQixDQUFBO0FBQUE7QUFHNUMsRUFBTyxPQUFBLGVBQWUsWUFBWSxFQUFJLEVBQUE7QUFDcEMsSUFBQSxJQUFJLFlBQVksT0FBUyxFQUFBO0FBQ3ZCLE1BQU8sTUFBQSxDQUFBLElBQUEsQ0FBSyxDQUFxQixrQkFBQSxFQUFBLEVBQUUsQ0FBRSxDQUFBLENBQUE7QUFDckMsTUFBTyxNQUFBLENBQUEsSUFBQSxDQUFLLENBQXNDLG1DQUFBLEVBQUEsRUFBRSxDQUFFLENBQUEsQ0FBQTtBQUFBO0FBRXhELElBQUEsTUFBTSxDQUFDLFlBQWMsRUFBQSxLQUFLLElBQUksRUFBRyxDQUFBLEtBQUEsQ0FBTSxLQUFLLENBQUMsQ0FBQTtBQUM3QyxJQUFBLE1BQU0sQ0FBQyxRQUFVLEVBQUEsVUFBVSxJQUFJLFlBQWEsQ0FBQSxLQUFBLENBQU0sS0FBSyxDQUFDLENBQUE7QUFHeEQsSUFBQSxNQUFNLENBQUMsYUFBZSxFQUFBLGVBQWUsQ0FBSSxHQUFBLFdBQUEsQ0FBWSxXQUFXLFFBQVEsQ0FBQTtBQUt4RSxJQUFBLE1BQU0sc0JBQXNCLE1BQU0sNEJBQUE7QUFBQSxNQUNoQyxRQUFBO0FBQUEsTUFDQSxVQUFBO0FBQUEsTUFDQSxXQUFZLENBQUEsT0FBQTtBQUFBLE1BQ1o7QUFBQSxLQUNGO0FBQ0EsSUFBQSxJQUFJLHdCQUF3QixJQUFNLEVBQUE7QUFDaEMsTUFBTyxPQUFBLG1CQUFBO0FBQUE7QUFHVCxJQUFNLE1BQUEsU0FBQSxHQUFZLGFBQWEsRUFBRSxDQUFBO0FBR2pDLElBQUksSUFBQSxtQkFBQSxFQUFxQixHQUFJLENBQUEsU0FBUyxDQUFHLEVBQUE7QUFDdkMsTUFBTSxNQUFBLEdBQUEsR0FBTSxtQkFBb0IsQ0FBQSxHQUFBLENBQUksU0FBUyxDQUFBO0FBQzdDLE1BQUEsSUFBSSxPQUFPLEdBQVEsS0FBQSxRQUFBLElBQVksR0FBUSxLQUFBLElBQUEsSUFBUSxXQUFXLEdBQUssRUFBQSxDQUV4RCxNQUFBO0FBQ0wsUUFBTyxPQUFBLEdBQUE7QUFBQTtBQUNUO0FBR0YsSUFBSSxJQUFBO0FBRUYsTUFBQSxJQUFJLFVBQVUsUUFBVSxFQUFBO0FBQ3RCLFFBQUEsTUFBTSxXQUFjLEdBQUEsZUFBQTtBQUNwQixRQUFBLElBQUksWUFBWSxPQUFTLEVBQUE7QUFDdkIsVUFBTyxNQUFBLENBQUEsSUFBQTtBQUFBLFlBQ0wsNENBQTRDLGVBQWUsQ0FBQTtBQUFBLFdBQzdEO0FBQUE7QUFJRixRQUFBLElBQUksYUFBZ0IsR0FBQSxlQUFBO0FBQ3BCLFFBQUEsSUFDRSxnQkFBZ0IsVUFBVyxDQUFBLFNBQVMsS0FDcEMsZUFBZ0IsQ0FBQSxRQUFBLENBQVMsTUFBTSxDQUMvQixFQUFBO0FBRUEsVUFBQSxNQUFNLFdBQVcsZUFBZ0IsQ0FBQSxPQUFBO0FBQUEsWUFDL0IscUJBQUE7QUFBQSxZQUNBO0FBQUEsV0FDRjtBQUNBLFVBQUEsSUFBSSxZQUFZLE9BQVMsRUFBQTtBQUN2QixZQUFPLE1BQUEsQ0FBQSxJQUFBO0FBQUEsY0FDTCxDQUFBLG1EQUFBLEVBQXNELGVBQWUsQ0FBQSxJQUFBLEVBQU8sUUFBUSxDQUFBO0FBQUEsYUFDdEY7QUFBQTtBQUdGLFVBQUksSUFBQSxNQUFBLENBQU8sUUFBUSxDQUFHLEVBQUE7QUFDcEIsWUFBZ0IsYUFBQSxHQUFBLFFBQUE7QUFDaEIsWUFBQSxJQUFJLFlBQVksT0FBUyxFQUFBO0FBQ3ZCLGNBQU8sTUFBQSxDQUFBLElBQUE7QUFBQSxnQkFDTCx1Q0FBdUMsYUFBYSxDQUFBO0FBQUEsZUFDdEQ7QUFBQTtBQUNGO0FBQ0Y7QUFJRixRQUFBLElBQUksWUFBWSxPQUFTLEVBQUE7QUFDdkIsVUFBTyxNQUFBLENBQUEsSUFBQTtBQUFBLFlBQ0wsa0RBQWtELFFBQVEsQ0FBQSxLQUFBLEVBQVEsQ0FBQyxDQUFDLE1BQUEsQ0FDbEUsUUFDRixDQUFDLENBQUE7QUFBQSxXQUNIO0FBQ0EsVUFBTyxNQUFBLENBQUEsSUFBQTtBQUFBLFlBQ0wseURBQXlELGVBQWUsQ0FBQSxLQUFBLEVBQVEsQ0FBQyxDQUFDLE1BQUEsQ0FDaEYsZUFDRixDQUFDLENBQUE7QUFBQSxXQUNIO0FBQ0EsVUFBTyxNQUFBLENBQUEsSUFBQTtBQUFBLFlBQ0wsdURBQXVELGFBQWEsQ0FBQSxLQUFBLEVBQVEsQ0FBQyxDQUFDLE1BQUEsQ0FDNUUsYUFDRixDQUFDLENBQUE7QUFBQSxXQUNIO0FBQUE7QUFFRixRQUFBLE1BQU0sY0FDSixNQUFPLENBQUEsUUFBUSxDQUNmLElBQUEsTUFBQSxDQUFPLGVBQWUsQ0FDdEIsSUFBQSxNQUFBLENBQU8sYUFBYSxDQUFBLElBQ3BCLE9BQU8sY0FBZSxDQUFBLFdBQVcsQ0FBRyxFQUFBLElBQUksS0FDeEMsTUFBTyxDQUFBLGNBQUEsQ0FBZSxXQUFXLENBQUEsRUFBRyxJQUFJLENBQ3hDLElBQUEsTUFBQSxDQUFPLGNBQWUsQ0FBQSxhQUFhLEdBQUcsSUFBSSxDQUFBLElBQzFDLE1BQU8sQ0FBQSxjQUFBLENBQWUsYUFBYSxDQUFHLEVBQUEsSUFBSSxLQUMxQyxNQUFPLENBQUEsT0FBQSxDQUFRLE1BQU0sQ0FBRSxDQUFBLElBQUE7QUFBQSxVQUNyQixDQUFDLEdBQUcsS0FBSyxDQUFBLEtBQU0sTUFBTSxJQUFTLEtBQUE7QUFBQSxZQUM1QixDQUFDLENBQUE7QUFFUCxRQUFJLElBQUEsV0FBQSxDQUFZLFdBQVcsV0FBYSxFQUFBO0FBQ3RDLFVBQUEsTUFBQSxDQUFPLElBQUssQ0FBQSxDQUFBLGlDQUFBLEVBQW9DLFdBQVksQ0FBQSxJQUFJLENBQUUsQ0FBQSxDQUFBO0FBQUE7QUFHcEUsUUFBQSxJQUFJLFdBQWEsRUFBQTtBQUNmLFVBQUksSUFBQSxXQUFBLENBQVksU0FBUyxPQUFTLEVBQUE7QUFFaEMsWUFBQSxJQUFJLFdBQVksQ0FBQSxZQUFBLENBQWEsV0FBWSxDQUFBLElBQUEsQ0FBSyxlQUFlLENBQUcsRUFBQTtBQUM5RCxjQUFBLE1BQU0sY0FBYyxXQUFZLENBQUEsTUFBQTtBQUNoQyxjQUFJLElBQUEsT0FBTyxnQkFBZ0IsUUFBVSxFQUFBO0FBQ25DLGdCQUFBLElBQUksWUFBWSxPQUFTLEVBQUE7QUFDdkIsa0JBQU8sTUFBQSxDQUFBLElBQUE7QUFBQSxvQkFDTCw2Q0FBNkMsZUFBZSxDQUFBO0FBQUEsbUJBQzlEO0FBQUE7QUFFRixnQkFBQSxPQUFPLEVBQUUsT0FBQSxFQUFTLElBQUssQ0FBQSxLQUFBLENBQU0sV0FBVyxDQUFFLEVBQUE7QUFBQTtBQUM1Qyx1QkFFQSxXQUFZLENBQUEsWUFBQSxDQUFhLFVBQVcsQ0FBQSxJQUFBLENBQUssZUFBZSxDQUN4RCxFQUFBO0FBQ0EsY0FBQSxNQUFNLGFBQWEsV0FBWSxDQUFBLE1BQUE7QUFDL0IsY0FBSSxJQUFBLE9BQU8sZUFBZSxRQUFVLEVBQUE7QUFDbEMsZ0JBQUEsSUFBSSxZQUFZLE9BQVMsRUFBQTtBQUN2QixrQkFBTyxNQUFBLENBQUEsSUFBQTtBQUFBLG9CQUNMLENBQTRDLHlDQUFBLEVBQUEsZUFBZSxDQUFhLFVBQUEsRUFBQSxVQUFBLENBQVcsTUFBTSxDQUFBO0FBQUEsbUJBQzNGO0FBQUE7QUFFRixnQkFBTyxPQUFBLEVBQUUsU0FBUyxVQUFXLEVBQUE7QUFBQSxlQUN4QixNQUFBO0FBQ0wsZ0JBQUEsSUFBSSxZQUFZLE9BQVMsRUFBQTtBQUN2QixrQkFBTyxNQUFBLENBQUEsSUFBQTtBQUFBLG9CQUNMLENBQUEsd0NBQUEsRUFBMkMsT0FBTyxVQUFVLENBQUE7QUFBQSxtQkFDOUQ7QUFBQTtBQUNGO0FBQ0Y7QUFFRixZQUFBLElBQUksWUFBWSxPQUFTLEVBQUE7QUFDdkIsY0FBTyxNQUFBLENBQUEsSUFBQTtBQUFBLGdCQUNMLHFEQUFxRCxlQUFlLENBQUE7QUFBQSxlQUN0RTtBQUFBO0FBRUYsWUFBTyxPQUFBLEVBQUUsT0FBUyxFQUFBLFdBQUEsQ0FBWSxNQUFPLEVBQUE7QUFBQSxXQUN2QyxNQUFBLElBQVcsVUFBVSxXQUFhLEVBQUE7QUFDaEMsWUFBQSxJQUFJLFlBQVksT0FBUyxFQUFBO0FBQ3ZCLGNBQU8sTUFBQSxDQUFBLElBQUE7QUFBQSxnQkFDTCxxQ0FBcUMsZUFBZSxDQUFBO0FBQUEsZUFDdEQ7QUFBQTtBQUVGLFlBQU8sT0FBQSxFQUFFLE9BQVMsRUFBQSxXQUFBLENBQVksSUFBSyxFQUFBO0FBQUE7QUFDckM7QUFFRixRQUFBLE1BQU0sYUFBYSxXQUFZLENBQUE7QUFBQSxVQUM3QixPQUFPLElBQUksS0FBQTtBQUFBLFlBQ1QscUNBQXFDLGVBQWUsQ0FBQTtBQUFBLFdBQ3REO0FBQUEsVUFDQSxNQUFBO0FBQUEsVUFDQSxHQUFLLEVBQUEsSUFBQTtBQUFBLFVBQ0wsZ0JBQWdCLFdBQVksQ0FBQSxjQUFBO0FBQUEsVUFDNUIsT0FBUyxFQUFBO0FBQUEsU0FDVixDQUFBO0FBQ0QsUUFBQSxJQUFJLGNBQWMsSUFBTSxFQUFBO0FBQ3RCLFVBQU0sTUFBQSxVQUFBO0FBQUE7QUFFUixRQUFPLE9BQUEsSUFBQTtBQUFBO0FBSVQsTUFBTSxNQUFBLFdBQUEsR0FBYyxPQUFPLFlBQVksQ0FBQTtBQUN2QyxNQUFBLElBQUksV0FBYSxFQUFBO0FBQ2YsUUFBSSxJQUFBO0FBQ0YsVUFBQSxNQUFNLFFBQVcsR0FBQSxJQUFBO0FBQUEsWUFDZixXQUFZLENBQUEsV0FBQTtBQUFBLFlBQ1osWUFBWSxLQUFNLENBQUEsTUFBQTtBQUFBLFlBQ2xCLFlBQVksS0FBTSxDQUFBLE1BQUE7QUFBQSxZQUNsQjtBQUFBLFdBQ0Y7QUFDQSxVQUFNLE1BQUEsT0FBQSxHQUFVLGFBQWMsQ0FBQSxRQUFRLENBQUUsQ0FBQSxJQUFBO0FBQ3hDLFVBQU0sTUFBQSxNQUFBLEdBQVMsTUFBTSxPQUFPLE9BQUEsQ0FBQTtBQUM1QixVQUFxQixtQkFBQSxFQUFBLEdBQUEsQ0FBSSxXQUFXLE1BQU0sQ0FBQTtBQUMxQyxVQUFPLE9BQUEsTUFBQTtBQUFBLGlCQUNBLEtBQU8sRUFBQTtBQUNkLFVBQUEsTUFBTSxhQUFhLFdBQVksQ0FBQTtBQUFBLFlBQzdCLEtBQUE7QUFBQSxZQUNBLE1BQUE7QUFBQSxZQUNBLGdCQUFnQixXQUFZLENBQUEsY0FBQTtBQUFBLFlBQzVCLE9BQVMsRUFBQTtBQUFBLFdBQ1YsQ0FBQTtBQUNELFVBQUEsbUJBQUEsRUFBcUIsT0FBTyxTQUFTLENBQUE7QUFDckMsVUFBQSxJQUFJLGNBQWMsSUFBTSxFQUFBO0FBQ3RCLFlBQU0sTUFBQSxVQUFBO0FBQUE7QUFDUjtBQUNGO0FBSUYsTUFBTSxNQUFBLFdBQUEsR0FBYyxlQUFlLGVBQWUsQ0FBQTtBQUNsRCxNQUFBLElBQUksV0FBYSxFQUFBO0FBQ2YsUUFBSSxJQUFBO0FBQ0YsVUFBQSxNQUFNLFFBQVcsR0FBQSxJQUFBO0FBQUEsWUFDZixXQUFZLENBQUEsV0FBQTtBQUFBLFlBQ1osWUFBWSxLQUFNLENBQUEsTUFBQTtBQUFBLFlBQ2xCLFlBQVksS0FBTSxDQUFBLE1BQUE7QUFBQSxZQUNsQixXQUFZLENBQUE7QUFBQSxXQUNkO0FBQ0EsVUFBTSxNQUFBLE9BQUEsR0FBVSxhQUFjLENBQUEsUUFBUSxDQUFFLENBQUEsSUFBQTtBQUN4QyxVQUFNLE1BQUEsTUFBQSxHQUFTLE1BQU0sT0FBTyxPQUFBLENBQUE7QUFDNUIsVUFBcUIsbUJBQUEsRUFBQSxHQUFBLENBQUksV0FBVyxNQUFNLENBQUE7QUFFMUMsVUFBSSxJQUFBLFVBQUEsSUFBYyxFQUFFLFVBQUEsSUFBYyxNQUFTLENBQUEsRUFBQTtBQUN6QyxZQUFBLE1BQU0sSUFBSSxLQUFBO0FBQUEsY0FDUixDQUFBLE9BQUEsRUFBVSxVQUFVLENBQUEscUJBQUEsRUFBd0IsZUFBZSxDQUFBO0FBQUEsYUFDN0Q7QUFBQTtBQUVGLFVBQU8sT0FBQSxNQUFBO0FBQUEsaUJBQ0EsS0FBTyxFQUFBO0FBQ2QsVUFBQSxNQUFNLGFBQWEsV0FBWSxDQUFBO0FBQUEsWUFDN0IsS0FBQTtBQUFBLFlBQ0EsTUFBQTtBQUFBLFlBQ0EsZ0JBQWdCLFdBQVksQ0FBQSxjQUFBO0FBQUEsWUFDNUIsT0FBUyxFQUFBO0FBQUEsV0FDVixDQUFBO0FBQ0QsVUFBQSxtQkFBQSxFQUFxQixPQUFPLFNBQVMsQ0FBQTtBQUNyQyxVQUFBLElBQUksY0FBYyxJQUFNLEVBQUE7QUFDdEIsWUFBTSxNQUFBLFVBQUE7QUFBQTtBQUNSO0FBQ0Y7QUFLRixNQUFJLElBQUE7QUFDRixRQUFNLE1BQUEsTUFBQSxHQUFTLE1BQU0sa0JBQW1CLENBQUE7QUFBQSxVQUN0QyxRQUFBO0FBQUEsVUFDQSxVQUFBO0FBQUEsVUFDQSxTQUFTLFdBQVksQ0FBQSxPQUFBO0FBQUEsVUFDckIsTUFBQTtBQUFBLFVBQ0EsY0FBZ0IsRUFBQSxJQUFBO0FBQUEsVUFDaEIsUUFBVSxFQUFBLGNBQUE7QUFBQSxVQUNWLFlBQVksV0FBWSxDQUFBLFVBQUE7QUFBQSxVQUN4QixZQUFZLFdBQVksQ0FBQSxVQUFBO0FBQUEsVUFDeEIsbUJBQUEsRUFBcUIsWUFBWSxLQUFNLENBQUEsbUJBQUE7QUFBQSxVQUN2QyxhQUFhLFdBQVksQ0FBQSxXQUFBO0FBQUEsVUFDekIsV0FBQSxFQUFhLFlBQVksS0FBTSxDQUFBLE1BQUE7QUFBQSxVQUMvQixjQUFBLEVBQWdCLFlBQVksS0FBTSxDQUFBLE1BQUE7QUFBQSxVQUNsQyxXQUFhLEVBQUEsSUFBQTtBQUFBLFVBQ2IsV0FBYSxFQUFBLEtBQUE7QUFBQSxVQUNiLHNCQUFzQixXQUFZLENBQUEsV0FBQTtBQUFBLFVBQ2xDLEtBQU8sRUFBQTtBQUFBLFlBQ0wsTUFBQSxFQUFRLFlBQVksS0FBTSxDQUFBLE1BQUE7QUFBQSxZQUMxQixNQUFBLEVBQVEsWUFBWSxLQUFNLENBQUEsTUFBQTtBQUFBLFlBQzFCLE1BQUEsRUFBUSxZQUFZLEtBQU0sQ0FBQSxNQUFBO0FBQUEsWUFDMUIsTUFBQSxFQUFRLFlBQVksS0FBTSxDQUFBO0FBQUE7QUFDNUIsU0FDRCxDQUFBO0FBR0QsUUFBcUIsbUJBQUEsRUFBQSxHQUFBLENBQUksV0FBVyxNQUFNLENBQUE7QUFDMUMsUUFBTyxPQUFBLE1BQUE7QUFBQSxlQUNBLEtBQU8sRUFBQTtBQUNkLFFBQU0sTUFBQSxHQUFBLEdBQU0sUUFBUSxLQUFLLENBQUE7QUFDekIsUUFBQSxNQUFNLGFBQWEsV0FBWSxDQUFBO0FBQUEsVUFDN0IsS0FBTyxFQUFBLEdBQUE7QUFBQSxVQUNQLE1BQUE7QUFBQSxVQUNBLGdCQUFnQixXQUFZLENBQUEsY0FBQTtBQUFBLFVBQzVCLE9BQVMsRUFBQTtBQUFBLFNBQ1YsQ0FBQTtBQUNELFFBQUEsbUJBQUEsRUFBcUIsT0FBTyxTQUFTLENBQUE7QUFDckMsUUFBQSxJQUFJLGNBQWMsSUFBTSxFQUFBO0FBQ3RCLFVBQU0sTUFBQSxVQUFBO0FBQUE7QUFDUjtBQUNGLGFBQ08sS0FBTyxFQUFBO0FBRWQsTUFBSSxJQUFBLGFBQUEsR0FBZ0IsaUJBQWlCLEtBQVEsR0FBQSxLQUFBLEdBQVEsSUFBSSxLQUFNLENBQUEsTUFBQSxDQUFPLEtBQUssQ0FBQyxDQUFBO0FBQzVFLE1BQUEsSUFBSSxhQUFjLENBQUEsT0FBQSxDQUFRLFFBQVMsQ0FBQSx1RUFBdUUsQ0FBRyxFQUFBO0FBQzNHLFFBQUEsTUFBTSxRQUFXLEdBQUEsT0FBQTtBQUFBLFVBQ2YsV0FBWSxDQUFBLFdBQUE7QUFBQSxVQUNaLFlBQVksS0FBTSxDQUFBLE1BQUE7QUFBQSxVQUNsQixZQUFZLEtBQU0sQ0FBQSxNQUFBO0FBQUEsVUFDbEI7QUFBQSxTQUNGO0FBQ0EsUUFBQSxhQUFBLEdBQWdCLElBQUksS0FBQTtBQUFBLFVBQ2xCLENBQUEsRUFBRyxjQUFjLE9BQU87QUFBQSxtQkFBQSxFQUNGLFFBQVE7QUFBQSxZQUFBLEVBQ2YsVUFBVTtBQUFBLGVBQUEsRUFDUCxRQUFRO0FBQUEsa0JBQ0wsRUFBQSxPQUFBLENBQVEsR0FBSSxDQUFBLFlBQUEsSUFBZ0IsU0FBUztBQUFBLGNBQUEsRUFDekMsT0FBUSxDQUFBLFFBQUEsQ0FBUyxJQUFLLENBQUEsR0FBRyxLQUFLLFNBQVMsQ0FBQTtBQUFBLFNBQzFEO0FBQ0EsUUFBTSxNQUFBLGFBQUE7QUFBQTtBQUdSLE1BQUEsTUFBTSxZQUFlLEdBQUE7QUFBQSxRQUNuQixLQUFPLEVBQUEsYUFBQTtBQUFBLFFBQ1A7QUFBQSxPQUNGO0FBQ0EsTUFBQSxtQkFBQSxFQUFxQixPQUFPLFNBQVMsQ0FBQTtBQUNyQyxNQUFPLE9BQUEsWUFBQTtBQUFBO0FBQ1QsR0FDRjtBQUNGOzs7OyJ9