vite-plugin-react-server
Version:
Vite plugin for React Server Components (RSC)
133 lines (130 loc) • 20.1 kB
JavaScript
/**
* vite-plugin-react-server
* Copyright (c) Nico Brinkkemper
* MIT License
*/
import { configureReactServer } from './configureReactServer.server.js';
import { resolveOptions } from '../config/resolveOptions.js';
import { CSS_EXT } from './collectRunnerCss.js';
import { detectClientModule } from 'react-server-loader/directives';
import { readFileSync } from 'node:fs';
const vitePluginReactDevServer = function _vitePluginReactServerDevServer(options) {
if (options == null) {
throw new Error("options is required");
}
const resolvedOptions = resolveOptions(options);
if (resolvedOptions.type === "error") {
if (resolvedOptions.error != null) {
throw resolvedOptions.error;
}
throw new Error("Failed to resolve options");
}
const userOptions = resolvedOptions.userOptions;
const hmrPlugin = {
name: "vite-plugin-react-server:server-hmr",
apply: "serve",
// Server-level handleHotUpdate — sends custom WS event to client
// Vite 6 Environment API: hotUpdate runs per-environment.
// Prevent server/ssr environments from triggering page reload for client components.
hotUpdate(ctx) {
const { file, server } = ctx;
const envName = ctx.environment?.name ?? "unknown";
const moduleBase = userOptions.moduleBase || "src";
const projectRoot = userOptions.projectRoot || server?.config?.root || "";
const normalizedFile = file.replace(projectRoot, "").replace(/^\/+/, "");
const isSourceFile = normalizedFile.startsWith(moduleBase + "/");
if (!isSourceFile) return;
if (envName === "client") {
const isClient = (file.endsWith(".tsx") || file.endsWith(".ts") || file.endsWith(".jsx") || file.endsWith(".js")) && (() => {
try {
const source = readFileSync(file, "utf-8");
return detectClientModule({ source, moduleId: file });
} catch {
return false;
}
})();
if (isClient) return;
const isCssFile = CSS_EXT.test(file);
if (isCssFile && (ctx.modules?.length ?? 0) > 0) {
return;
}
const kind = isCssFile ? "css" : "component";
if (userOptions.verbose) {
server.config.logger.info(`[vite-plugin-react-server] File changed (RSC refetch): ${normalizedFile}`);
}
server.ws.send({
type: "custom",
event: "vite-plugin-react-server:server-component-update",
data: { file: normalizedFile, path: file, kind }
});
return [];
}
if (envName === "server") {
const mod = ctx.environment?.moduleGraph?.getModulesByFile(file);
if (mod) {
for (const m of mod) {
ctx.environment.moduleGraph.invalidateModule(m);
}
}
}
return [];
}
};
const serverPlugin = {
name: "vite-plugin-react-server:dev-server-server",
apply: "serve",
applyToEnvironment(partialEnvironment) {
return partialEnvironment?.consumer === "server";
},
configureServer(server) {
server.config.logger.info(`[vite-plugin-react-server] Dev server plugin configured for server environment (react-server condition)`);
configureReactServer({
server,
autoDiscoveredFiles: {
propsMap: /* @__PURE__ */ new Map(),
pageMap: /* @__PURE__ */ new Map(),
rootMap: /* @__PURE__ */ new Map(),
htmlMap: /* @__PURE__ */ new Map(),
routeMap: /* @__PURE__ */ new Map(),
urlMap: /* @__PURE__ */ new Map(),
errors: [],
workerPaths: {},
serverEntry: null,
clientEntry: {},
clientInputs: {},
staticInputs: {},
serverInputs: {},
// staticManifest removed from AutoDiscoveredFiles
serverActions: {}
},
userOptions,
serverManifest: {},
resolvedConfig: server.config
});
}
};
const cjsFixPlugin = {
name: "vite-plugin-react-server:server-cjs-fix",
apply: "serve",
enforce: "post",
applyToEnvironment(env) {
return env?.name === "server";
},
transform(code, id) {
if (id.includes("node_modules")) return;
if (!id.match(/\.[jt]sx?$/)) return;
const namedImportRe = /import\s*\{([^}]+)\}\s*from\s*["']react["']\s*;?/g;
if (!namedImportRe.test(code)) return;
namedImportRe.lastIndex = 0;
let counter = 0;
const result = code.replace(namedImportRe, (_match, imports) => {
const alias = `__react_cjs_${counter++}`;
return `import ${alias} from "react"; const {${imports}} = ${alias};`;
});
return { code: result, map: null };
}
};
return [hmrPlugin, cjsFixPlugin, serverPlugin];
};
export { vitePluginReactDevServer };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLnNlcnZlci5qcyIsInNvdXJjZXMiOlsiLi4vLi4vLi4vcGx1Z2luL2Rldi1zZXJ2ZXIvcGx1Z2luLnNlcnZlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IFN0cmVhbVBsdWdpbk9wdGlvbnMgfSBmcm9tIFwiLi4vLi4vdHlwZXMuanNcIjtcbmltcG9ydCB7IGNvbmZpZ3VyZVJlYWN0U2VydmVyIH0gZnJvbSBcIi4vY29uZmlndXJlUmVhY3RTZXJ2ZXIuc2VydmVyLmpzXCI7XG5pbXBvcnQgeyByZXNvbHZlT3B0aW9ucyB9IGZyb20gXCIuLi9jb25maWcvcmVzb2x2ZU9wdGlvbnMuanNcIjtcbmltcG9ydCB7IENTU19FWFQgfSBmcm9tIFwiLi9jb2xsZWN0UnVubmVyQ3NzLmpzXCI7XG5pbXBvcnQgeyBkZXRlY3RDbGllbnRNb2R1bGUgfSBmcm9tIFwicmVhY3Qtc2VydmVyLWxvYWRlci9kaXJlY3RpdmVzXCI7XG5pbXBvcnQgdHlwZSB7IFBsdWdpbiwgVml0ZURldlNlcnZlciB9IGZyb20gXCJ2aXRlXCI7XG5pbXBvcnQgeyByZWFkRmlsZVN5bmMgfSBmcm9tIFwibm9kZTpmc1wiO1xuXG4vKipcbiAqIERldiBzZXJ2ZXIgcGx1Z2luIGZvciBzZXJ2ZXIgZW52aXJvbm1lbnQuXG4gKiBSZXR1cm5zIHR3byBwbHVnaW5zOiBvbmUgZm9yIEhNUiBoYW5kbGluZyAoYWxsIGVudmlyb25tZW50cykgYW5kIG9uZSBmb3Igc2VydmVyIGNvbmZpZy5cbiAqL1xuZXhwb3J0IGNvbnN0IHZpdGVQbHVnaW5SZWFjdERldlNlcnZlciA9IGZ1bmN0aW9uIF92aXRlUGx1Z2luUmVhY3RTZXJ2ZXJEZXZTZXJ2ZXIob3B0aW9uczogU3RyZWFtUGx1Z2luT3B0aW9ucyk6IFBsdWdpbltdIHtcbiAgaWYgKG9wdGlvbnMgPT0gbnVsbCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIm9wdGlvbnMgaXMgcmVxdWlyZWRcIik7XG4gIH1cblxuICBjb25zdCByZXNvbHZlZE9wdGlvbnMgPSByZXNvbHZlT3B0aW9ucyhvcHRpb25zKTtcbiAgaWYgKHJlc29sdmVkT3B0aW9ucy50eXBlID09PSBcImVycm9yXCIpIHtcbiAgICBpZiAocmVzb2x2ZWRPcHRpb25zLmVycm9yICE9IG51bGwpIHtcbiAgICAgIHRocm93IHJlc29sdmVkT3B0aW9ucy5lcnJvcjtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiRmFpbGVkIHRvIHJlc29sdmUgb3B0aW9uc1wiKTtcbiAgfVxuICBjb25zdCB1c2VyT3B0aW9ucyA9IHJlc29sdmVkT3B0aW9ucy51c2VyT3B0aW9ucztcblxuICAvLyBTZXBhcmF0ZSBwbHVnaW4gZm9yIEhNUiBoYW5kbGluZyAobXVzdCBhcHBseSB0byBhbGwgZW52aXJvbm1lbnRzKVxuICBjb25zdCBobXJQbHVnaW4gPSB7XG4gICAgbmFtZTogXCJ2aXRlLXBsdWdpbi1yZWFjdC1zZXJ2ZXI6c2VydmVyLWhtclwiLFxuICAgIGFwcGx5OiBcInNlcnZlXCIgYXMgY29uc3QsXG4gICAgLy8gU2VydmVyLWxldmVsIGhhbmRsZUhvdFVwZGF0ZSDigJQgc2VuZHMgY3VzdG9tIFdTIGV2ZW50IHRvIGNsaWVudFxuICAgIC8vIFZpdGUgNiBFbnZpcm9ubWVudCBBUEk6IGhvdFVwZGF0ZSBydW5zIHBlci1lbnZpcm9ubWVudC5cbiAgICAvLyBQcmV2ZW50IHNlcnZlci9zc3IgZW52aXJvbm1lbnRzIGZyb20gdHJpZ2dlcmluZyBwYWdlIHJlbG9hZCBmb3IgY2xpZW50IGNvbXBvbmVudHMuXG4gICAgaG90VXBkYXRlKGN0eDogYW55KSB7XG4gICAgICBjb25zdCB7IGZpbGUsIHNlcnZlciB9ID0gY3R4O1xuICAgICAgY29uc3QgZW52TmFtZSA9IGN0eC5lbnZpcm9ubWVudD8ubmFtZSA/PyAndW5rbm93bic7XG5cbiAgICAgIGNvbnN0IG1vZHVsZUJhc2UgPSB1c2VyT3B0aW9ucy5tb2R1bGVCYXNlIHx8IFwic3JjXCI7XG4gICAgICBjb25zdCBwcm9qZWN0Um9vdCA9IHVzZXJPcHRpb25zLnByb2plY3RSb290IHx8IHNlcnZlcj8uY29uZmlnPy5yb290IHx8ICcnO1xuICAgICAgY29uc3Qgbm9ybWFsaXplZEZpbGUgPSBmaWxlLnJlcGxhY2UocHJvamVjdFJvb3QsICcnKS5yZXBsYWNlKC9eXFwvKy8sICcnKTtcbiAgICAgIGNvbnN0IGlzU291cmNlRmlsZSA9IG5vcm1hbGl6ZWRGaWxlLnN0YXJ0c1dpdGgobW9kdWxlQmFzZSArICcvJyk7XG4gICAgICBcbiAgICAgIGlmICghaXNTb3VyY2VGaWxlKSByZXR1cm47XG4gICAgICBcbiAgICAgIC8vIENsaWVudCBlbnZpcm9ubWVudDogVml0ZSBvd25zIGNsaWVudC1zaWRlIEhNUiAoRmFzdCBSZWZyZXNoIGlmXG4gICAgICAvLyBgQHZpdGVqcy9wbHVnaW4tcmVhY3RgIGlzIGluc3RhbGxlZDsgcGxhaW4gcmVsb2FkIG90aGVyd2lzZSkuXG4gICAgICBpZiAoZW52TmFtZSA9PT0gJ2NsaWVudCcpIHtcbiAgICAgICAgY29uc3QgaXNDbGllbnQgPSAoZmlsZS5lbmRzV2l0aCgnLnRzeCcpIHx8IGZpbGUuZW5kc1dpdGgoJy50cycpIHx8IGZpbGUuZW5kc1dpdGgoJy5qc3gnKSB8fCBmaWxlLmVuZHNXaXRoKCcuanMnKSkgJiYgKCgpID0+IHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3Qgc291cmNlID0gcmVhZEZpbGVTeW5jKGZpbGUsIFwidXRmLThcIik7XG4gICAgICAgICAgICByZXR1cm4gZGV0ZWN0Q2xpZW50TW9kdWxlKHsgc291cmNlLCBtb2R1bGVJZDogZmlsZSB9KTtcbiAgICAgICAgICB9IGNhdGNoIHsgcmV0dXJuIGZhbHNlOyB9XG4gICAgICAgIH0pKCk7XG5cbiAgICAgICAgaWYgKGlzQ2xpZW50KSByZXR1cm47IC8vIFZpdGUncyBjbGllbnQtc2lkZSBITVIgb3ducyB0aGlzIHVwZGF0ZVxuXG4gICAgICAgIGNvbnN0IGlzQ3NzRmlsZSA9IENTU19FWFQudGVzdChmaWxlKTtcblxuICAgICAgICAvLyBBIENTUyBtb2R1bGUgaW1wb3J0ZWQgdHJhbnNpdGl2ZWx5IGJ5IGEgXCJ1c2UgY2xpZW50XCIgY29tcG9uZW50IGxpdmVzXG4gICAgICAgIC8vIGluIHRoZSBDTElFTlQgbW9kdWxlIGdyYXBoICh0aGUgYnJvd3NlciBmZXRjaGVzIGl0IGRpcmVjdGx5IGFuZCBWaXRlXG4gICAgICAgIC8vIGluamVjdHMgaXQgYXMgYSA8c3R5bGU+KSwgc28gVml0ZSdzIG5hdGl2ZSBDU1MgSE1SIGFscmVhZHkgdXBkYXRlcyBpdFxuICAgICAgICAvLyBpbiBwbGFjZSDigJQgbm8gcmVsb2FkLCBubyA8bGluaz4gY2FjaGUtYnVzdC4gRGV0ZWN0IHRoYXQgY2FzZSBieSB0aGVcbiAgICAgICAgLy8gcHJlc2VuY2Ugb2YgY2xpZW50LWVudmlyb25tZW50IG1vZHVsZXMgZm9yIHRoaXMgZmlsZSBhbmQgaGFuZCB0aGVcbiAgICAgICAgLy8gdXBkYXRlIGJhY2sgdG8gVml0ZS4gU3VwcHJlc3NpbmcgaXQgaGVyZSAodGhlIGByZXR1cm4gW11gIGJlbG93KSBpc1xuICAgICAgICAvLyB3aGF0IHByZXZpb3VzbHkgbGVmdCBjbGllbnQtZ3JhcGggQ1NTIGVkaXRzIHN0dWNrIHVudGlsIGEgbWFudWFsXG4gICAgICAgIC8vIHJlZnJlc2g6IHRoZSBSU0MgPGxpbms+IGNhY2hlLWJ1c3QgbmV2ZXIgbWF0Y2hlcyBhIFZpdGUgPHN0eWxlPi5cbiAgICAgICAgaWYgKGlzQ3NzRmlsZSAmJiAoY3R4Lm1vZHVsZXM/Lmxlbmd0aCA/PyAwKSA+IDApIHtcbiAgICAgICAgICByZXR1cm47IC8vIGxldCBWaXRlJ3MgbmF0aXZlIGNsaWVudCBDU1MgSE1SIGFwcGx5IHRoZSB1cGRhdGVcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENTUyBmaWxlcyB0aGF0IGFyZW4ndCBpbXBvcnRlZCB2aWEgdGhlIGNsaWVudCBtb2R1bGUgZ3JhcGggKHZwcnMnc1xuICAgICAgICAvLyA8Q3NzIGNzc0ZpbGVzPXsuLi59Lz4gcGF0dGVybiBjb2xsZWN0cyB0aGVtIHNlcnZlci1zaWRlKSBhcmVuJ3RcbiAgICAgICAgLy8gdHJhY2tlZCBieSBWaXRlJ3MgQ1NTIEhNUiwgc28gYSBjb250ZW50IGVkaXQgbGVhdmVzIHRoZSA8bGluaz5cbiAgICAgICAgLy8gdGFnJ3MgaHJlZiB1bmNoYW5nZWQuIFRhZyB0aGUgZXZlbnQgc28gdXNlUnNjSG1yIGtub3dzIHRvIHJlZnJlc2hcbiAgICAgICAgLy8gbWF0Y2hpbmcgbGluayB0YWdzIGJ5IGNhY2hlLWJ1c3RpbmcgdGhlaXIgaHJlZi5cbiAgICAgICAgY29uc3Qga2luZDogJ2NzcycgfCAnY29tcG9uZW50JyA9IGlzQ3NzRmlsZSA/ICdjc3MnIDogJ2NvbXBvbmVudCc7XG5cbiAgICAgICAgLy8gU2VydmVyIGNvbXBvbmVudCBjaGFuZ2VkIOKAlCBzZW5kIFJTQyByZWZldGNoIGV2ZW50IHRvIGNsaWVudFxuICAgICAgICAvLyBPbmx5IGRvIHRoaXMgb25jZSAoZnJvbSBjbGllbnQgZW52KSB0byBhdm9pZCBkdXBsaWNhdGUgZXZlbnRzXG4gICAgICAgIGlmICh1c2VyT3B0aW9ucy52ZXJib3NlKSB7XG4gICAgICAgICAgc2VydmVyLmNvbmZpZy5sb2dnZXIuaW5mbyhgW3ZpdGUtcGx1Z2luLXJlYWN0LXNlcnZlcl0gRmlsZSBjaGFuZ2VkIChSU0MgcmVmZXRjaCk6ICR7bm9ybWFsaXplZEZpbGV9YCk7XG4gICAgICAgIH1cbiAgICAgICAgc2VydmVyLndzLnNlbmQoe1xuICAgICAgICAgIHR5cGU6ICdjdXN0b20nLFxuICAgICAgICAgIGV2ZW50OiAndml0ZS1wbHVnaW4tcmVhY3Qtc2VydmVyOnNlcnZlci1jb21wb25lbnQtdXBkYXRlJyxcbiAgICAgICAgICBkYXRhOiB7IGZpbGU6IG5vcm1hbGl6ZWRGaWxlLCBwYXRoOiBmaWxlLCBraW5kIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBbXTsgLy8gRG9uJ3QgdHJpZ2dlciBjbGllbnQtc2lkZSBwYWdlIHJlbG9hZFxuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBTZXJ2ZXIvU1NSIGVudmlyb25tZW50czogc3VwcHJlc3MgcGFnZSByZWxvYWQgZm9yIGFsbCBzb3VyY2UgZmlsZXNcbiAgICAgIC8vIFNlcnZlciBjb21wb25lbnRzIGFyZSBoYW5kbGVkIGJ5IHRoZSBSU0MgcmVmZXRjaCBldmVudCBzZW50IGFib3ZlXG4gICAgICAvLyBJbnZhbGlkYXRlIHRoZSBzZXJ2ZXIgbW9kdWxlIHNvIG5leHQgUlNDIHJlcXVlc3QgZ2V0cyBmcmVzaCBjb250ZW50XG4gICAgICBpZiAoZW52TmFtZSA9PT0gJ3NlcnZlcicpIHtcbiAgICAgICAgY29uc3QgbW9kID0gY3R4LmVudmlyb25tZW50Py5tb2R1bGVHcmFwaD8uZ2V0TW9kdWxlc0J5RmlsZShmaWxlKTtcbiAgICAgICAgaWYgKG1vZCkge1xuICAgICAgICAgIGZvciAoY29uc3QgbSBvZiBtb2QpIHtcbiAgICAgICAgICAgIGN0eC5lbnZpcm9ubWVudC5tb2R1bGVHcmFwaC5pbnZhbGlkYXRlTW9kdWxlKG0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIFtdO1xuICAgIH0sXG4gIH07XG5cbiAgY29uc3Qgc2VydmVyUGx1Z2luID0ge1xuICAgIG5hbWU6IFwidml0ZS1wbHVnaW4tcmVhY3Qtc2VydmVyOmRldi1zZXJ2ZXItc2VydmVyXCIsXG4gICAgYXBwbHk6IFwic2VydmVcIiBhcyBjb25zdCxcbmFwcGx5VG9FbnZpcm9ubWVudChwYXJ0aWFsRW52aXJvbm1lbnQ6IGFueSkge1xuICAgICAgcmV0dXJuIHBhcnRpYWxFbnZpcm9ubWVudD8uY29uc3VtZXIgPT09ICdzZXJ2ZXInO1xuICAgIH0sXG4gICAgY29uZmlndXJlU2VydmVyKHNlcnZlcjogVml0ZURldlNlcnZlcikge1xuICAgICAgLy8gTG9nIHRoYXQgcGx1Z2luIGlzIGJlaW5nIGNvbmZpZ3VyZWRcbiAgICAgIHNlcnZlci5jb25maWcubG9nZ2VyLmluZm8oYFt2aXRlLXBsdWdpbi1yZWFjdC1zZXJ2ZXJdIERldiBzZXJ2ZXIgcGx1Z2luIGNvbmZpZ3VyZWQgZm9yIHNlcnZlciBlbnZpcm9ubWVudCAocmVhY3Qtc2VydmVyIGNvbmRpdGlvbilgKTtcbiAgICAgIFxuICAgICAgLy8gQ29uZmlndXJlIHRoZSBSZWFjdCBzZXJ2ZXIgZm9yIHNlcnZlciBlbnZpcm9ubWVudCAoZGlyZWN0IFJTQyBwcm9jZXNzaW5nKVxuICAgICAgLy8gVGhpcyB1c2VzIHRoZSBleGlzdGluZyBjb25maWd1cmVSZWFjdFNlcnZlci5zZXJ2ZXIuanMgaW1wbGVtZW50YXRpb25cbiAgICAgIGNvbmZpZ3VyZVJlYWN0U2VydmVyKHtcbiAgICAgICAgc2VydmVyLFxuICAgICAgICBhdXRvRGlzY292ZXJlZEZpbGVzOiB7XG4gICAgICAgICAgcHJvcHNNYXA6IG5ldyBNYXAoKSxcbiAgICAgICAgICBwYWdlTWFwOiBuZXcgTWFwKCksXG4gICAgICAgICAgcm9vdE1hcDogbmV3IE1hcCgpLFxuICAgICAgICAgIGh0bWxNYXA6IG5ldyBNYXAoKSxcbiAgICAgICAgICByb3V0ZU1hcDogbmV3IE1hcCgpLFxuICAgICAgICAgIHVybE1hcDogbmV3IE1hcCgpLFxuICAgICAgICAgIGVycm9yczogW10sXG4gICAgICAgICAgd29ya2VyUGF0aHM6IHt9LFxuICAgICAgICAgIHNlcnZlckVudHJ5OiBudWxsLFxuICAgICAgICAgIGNsaWVudEVudHJ5OiB7fSxcbiAgICAgICAgICBjbGllbnRJbnB1dHM6IHt9LFxuICAgICAgICAgIHN0YXRpY0lucHV0czoge30sXG4gICAgICAgICAgc2VydmVySW5wdXRzOiB7fSxcbiAgICAgICAgICAvLyBzdGF0aWNNYW5pZmVzdCByZW1vdmVkIGZyb20gQXV0b0Rpc2NvdmVyZWRGaWxlc1xuICAgICAgICAgIHNlcnZlckFjdGlvbnM6IHt9LFxuICAgICAgICB9LFxuICAgICAgICB1c2VyT3B0aW9ucyxcbiAgICAgICAgc2VydmVyTWFuaWZlc3Q6IHt9LFxuICAgICAgICByZXNvbHZlZENvbmZpZzogc2VydmVyLmNvbmZpZyxcbiAgICAgIH0pO1xuICAgIH0sXG4gIH07XG5cbiAgLy8gRml4IENKUyBuYW1lZCBpbXBvcnRzIGluIHNlcnZlciBlbnZpcm9ubWVudC5cbiAgLy8gVml0ZSdzIGVzYnVpbGQgSlNYIHRyYW5zZm9ybSAoYW5kIEB2aXRlanMvcGx1Z2luLXJlYWN0IGlmIHByZXNlbnQpIGdlbmVyYXRlc1xuICAvLyBuYW1lZCBpbXBvcnRzIGxpa2UgYGltcG9ydCB7IHVzZUVmZmVjdCB9IGZyb20gXCJyZWFjdFwiYC4gSW4gdGhlIHNlcnZlciBlbnZpcm9ubWVudCxcbiAgLy8gcmVhY3QncyByZWFjdC1zZXJ2ZXIgZXhwb3J0IGlzIENKUy1vbmx5LCBhbmQgTm9kZSdzIEVTTSBpbnRlcm9wIGRvZXNuJ3Qgc3VwcG9ydFxuICAvLyBuYW1lZCBleHBvcnRzIGZyb20gQ0pTLiBUaGlzIHBvc3QtdHJhbnNmb3JtIHJld3JpdGVzIHRoZW0uXG4gIGNvbnN0IGNqc0ZpeFBsdWdpbjogUGx1Z2luID0ge1xuICAgIG5hbWU6IFwidml0ZS1wbHVnaW4tcmVhY3Qtc2VydmVyOnNlcnZlci1janMtZml4XCIsXG4gICAgYXBwbHk6IFwic2VydmVcIiBhcyBjb25zdCxcbiAgICBlbmZvcmNlOiBcInBvc3RcIiBhcyBjb25zdCxcbiAgICBhcHBseVRvRW52aXJvbm1lbnQoZW52OiBhbnkpIHtcbiAgICAgIHJldHVybiBlbnY/Lm5hbWUgPT09ICdzZXJ2ZXInO1xuICAgIH0sXG4gICAgdHJhbnNmb3JtKGNvZGU6IHN0cmluZywgaWQ6IHN0cmluZykge1xuICAgICAgaWYgKGlkLmluY2x1ZGVzKCdub2RlX21vZHVsZXMnKSkgcmV0dXJuO1xuICAgICAgaWYgKCFpZC5tYXRjaCgvXFwuW2p0XXN4PyQvKSkgcmV0dXJuO1xuICAgICAgXG4gICAgICBjb25zdCBuYW1lZEltcG9ydFJlID0gL2ltcG9ydFxccypcXHsoW159XSspXFx9XFxzKmZyb21cXHMqW1wiJ11yZWFjdFtcIiddXFxzKjs/L2c7XG4gICAgICBpZiAoIW5hbWVkSW1wb3J0UmUudGVzdChjb2RlKSkgcmV0dXJuO1xuICAgICAgXG4gICAgICBuYW1lZEltcG9ydFJlLmxhc3RJbmRleCA9IDA7XG4gICAgICBsZXQgY291bnRlciA9IDA7XG4gICAgICBjb25zdCByZXN1bHQgPSBjb2RlLnJlcGxhY2UobmFtZWRJbXBvcnRSZSwgKF9tYXRjaCwgaW1wb3J0cykgPT4ge1xuICAgICAgICBjb25zdCBhbGlhcyA9IGBfX3JlYWN0X2Nqc18ke2NvdW50ZXIrK31gO1xuICAgICAgICByZXR1cm4gYGltcG9ydCAke2FsaWFzfSBmcm9tIFwicmVhY3RcIjsgY29uc3QgeyR7aW1wb3J0c319ID0gJHthbGlhc307YDtcbiAgICAgIH0pO1xuICAgICAgXG4gICAgICByZXR1cm4geyBjb2RlOiByZXN1bHQsIG1hcDogbnVsbCB9O1xuICAgIH0sXG4gIH07XG5cbiAgcmV0dXJuIFtobXJQbHVnaW4sIGNqc0ZpeFBsdWdpbiwgc2VydmVyUGx1Z2luXTtcbn07XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFZYSxNQUFBLHdCQUFBLEdBQTJCLFNBQVMsK0JBQUEsQ0FBZ0MsT0FBd0MsRUFBQTtBQUN2SCxFQUFBLElBQUksV0FBVyxJQUFNLEVBQUE7QUFDbkIsSUFBTSxNQUFBLElBQUksTUFBTSxxQkFBcUIsQ0FBQTtBQUFBO0FBR3ZDLEVBQU0sTUFBQSxlQUFBLEdBQWtCLGVBQWUsT0FBTyxDQUFBO0FBQzlDLEVBQUksSUFBQSxlQUFBLENBQWdCLFNBQVMsT0FBUyxFQUFBO0FBQ3BDLElBQUksSUFBQSxlQUFBLENBQWdCLFNBQVMsSUFBTSxFQUFBO0FBQ2pDLE1BQUEsTUFBTSxlQUFnQixDQUFBLEtBQUE7QUFBQTtBQUV4QixJQUFNLE1BQUEsSUFBSSxNQUFNLDJCQUEyQixDQUFBO0FBQUE7QUFFN0MsRUFBQSxNQUFNLGNBQWMsZUFBZ0IsQ0FBQSxXQUFBO0FBR3BDLEVBQUEsTUFBTSxTQUFZLEdBQUE7QUFBQSxJ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