UNPKG

vite-plugin-react-server

Version:
164 lines (161 loc) 30.9 kB
/** * vite-plugin-react-server * Copyright (c) Nico Brinkkemper * MIT License */ import { replaceExtension } from './extMap.js'; import { getNodeEnv } from './getNodeEnv.js'; import { DEFAULT_CONFIG } from './defaults.js'; import { detectClientModule } from 'react-server-loader/directives'; import { join, sep, resolve } from 'node:path'; import { existsSync, readFileSync } from 'node:fs'; import { createRollupLikeHash } from './createRollupLikeHash.js'; const createDefaultModuleID = (options, configEnv, mode = getNodeEnv()) => { const { moduleBase, moduleBasePath, build, moduleBaseURL, projectRoot, autoDiscover } = options; const assetsDir = build.assetsDir || DEFAULT_CONFIG.BUILD.assetsDir; const isBuild = configEnv?.command === "build"; const shouldHash = isBuild; const isProd = mode === "production" || isBuild; const removeModuleBase = (isProd || isBuild) && !options.build.preserveModulesRoot; const hashOption = build?.hash ?? DEFAULT_CONFIG.BUILD.hash; const virtualPattern = autoDiscover?.virtualPattern ?? DEFAULT_CONFIG.AUTO_DISCOVER.virtualPattern; const isClientComponentId = (id, sourceContent, isClientByDirective) => isClientByDirective === true || detectClientModule({ source: sourceContent, moduleId: id }); const hash = (input, _ssr, sourceContent, isClientByDirective) => { if (!input) return ""; if (new RegExp(/\.(node|d\.ts)$/).test(input)) { return input; } if (input.includes("node_modules")) { return input; } if (input.includes("_virtual") || virtualPattern && virtualPattern.test(input)) { return input; } if (hashOption === "false") { return input; } const isClientComponent = isClientComponentId( input, sourceContent, isClientByDirective ); if (!isClientComponent) { return input; } let contentToHash; if (sourceContent) { contentToHash = sourceContent; } else { try { const sourcePath = resolve(projectRoot, input); if (existsSync(sourcePath)) { contentToHash = readFileSync(sourcePath, "utf-8"); } else { contentToHash = input; } } catch (error) { contentToHash = input; } } const hashCharacters = typeof hashOption === "object" && hashOption?.format === "hex" ? "hex" : "base36"; const contentHash = createRollupLikeHash(contentToHash, hashCharacters); const extensionIndex = input.lastIndexOf("."); if (extensionIndex !== -1) { const extension = input.slice(extensionIndex); const filename = input.slice(0, extensionIndex); return filename + "-" + contentHash + extension; } else { return input + "-" + contentHash; } }; const staticClientDist = isBuild ? join(build?.outDir || "dist", build?.static || "static") : ""; const ssrClientDist = isBuild ? join(build?.outDir || "dist", build?.client || "client") : ""; const serverDist = isBuild ? join(build?.outDir || "dist", build?.server || "server") : ""; const buildDirs = isBuild ? [serverDist, ssrClientDist, staticClientDist] : []; return (id, sourceContent, isClientByDirective) => { if (shouldHash) { for (const buildDir of buildDirs) { if (id.startsWith(buildDir)) { const result = id.slice(buildDir.length); return result; } } if (id.includes("//")) { const lastDistIndex = id.lastIndexOf("dist/"); if (lastDistIndex !== -1) { const result = id.slice(lastDistIndex); return result; } } const isClientComponent2 = isClientComponentId( id, sourceContent, isClientByDirective ); if (isClientComponent2) { let transformedId = id; if (removeModuleBase && transformedId.startsWith(moduleBase + sep)) { transformedId = transformedId.slice(moduleBase.length + sep.length); } if (isClientByDirective) { const noExt = transformedId.replace(/\.[cm]?[jt]sx?$/, ""); if (!noExt.endsWith(".client") && !noExt.endsWith(".server")) { const lastDot = noExt.lastIndexOf("."); if (lastDot > noExt.lastIndexOf("/")) { transformedId = noExt.slice(0, lastDot) + transformedId.slice(noExt.length); } } } transformedId = replaceExtension(transformedId, { build: { extensionMap: build.extensionMap } }); transformedId = hash(transformedId, false, sourceContent, isClientByDirective); if (moduleBasePath && !transformedId.startsWith(moduleBasePath)) { transformedId = moduleBasePath + transformedId; } return transformedId; } return id; } if (id.startsWith(assetsDir + sep + moduleBase + sep)) { id = assetsDir + sep + id.slice((assetsDir + sep + moduleBase + sep).length); } if (moduleBaseURL && moduleBaseURL !== "/" && id.startsWith(moduleBaseURL)) { id = id.slice(moduleBaseURL.length); } if (moduleBasePath && moduleBasePath !== "/" && id.startsWith(moduleBasePath + moduleBase)) { id = moduleBasePath + id.slice((moduleBasePath + moduleBase).length); } if (removeModuleBase && id.startsWith(moduleBase + sep)) { id = id.slice(moduleBase.length + sep.length); } if (moduleBasePath && !id.startsWith(moduleBasePath)) { id = moduleBasePath + id; } const isClientComponent = isClientComponentId( id, sourceContent, isClientByDirective ); if (isBuild) { id = replaceExtension(id, { build: { extensionMap: build.extensionMap } }); } if (isBuild && id.endsWith(".css") && !id.startsWith(assetsDir + sep)) { id = assetsDir + sep + id; } if (shouldHash) { id = hash(id, false, sourceContent, isClientByDirective); } if (isClientComponent && moduleBasePath === "") { return id; } if (moduleBasePath === "") { return id; } return id; }; }; export { createDefaultModuleID }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlTW9kdWxlSUQuanMiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3BsdWdpbi9jb25maWcvY3JlYXRlTW9kdWxlSUQudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBSZXNvbHZlZFVzZXJPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzLmpzXCI7XG5pbXBvcnQgeyByZXBsYWNlRXh0ZW5zaW9uIH0gZnJvbSBcIi4vZXh0TWFwLmpzXCI7XG5pbXBvcnQgeyBnZXROb2RlRW52IH0gZnJvbSBcIi4vZ2V0Tm9kZUVudi5qc1wiO1xuaW1wb3J0IHsgREVGQVVMVF9DT05GSUcgfSBmcm9tIFwiLi9kZWZhdWx0cy5qc1wiO1xuaW1wb3J0IHsgZGV0ZWN0Q2xpZW50TW9kdWxlIH0gZnJvbSBcInJlYWN0LXNlcnZlci1sb2FkZXIvZGlyZWN0aXZlc1wiO1xuaW1wb3J0IHR5cGUgeyBDb25maWdFbnYgfSBmcm9tIFwidml0ZVwiO1xuaW1wb3J0IHsgc2VwLCByZXNvbHZlLCBqb2luIH0gZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHsgcmVhZEZpbGVTeW5jLCBleGlzdHNTeW5jIH0gZnJvbSBcIm5vZGU6ZnNcIjtcbmltcG9ydCB7IGNyZWF0ZVJvbGx1cExpa2VIYXNoIH0gZnJvbSBcIi4vY3JlYXRlUm9sbHVwTGlrZUhhc2guanNcIjtcblxuZXhwb3J0IHR5cGUgTW9kdWxlSURLZXkgPVxuICB8IFwibW9kdWxlUGF0dGVyblwiXG4gIHwgXCJjc3NQYXR0ZXJuXCJcbiAgfCBcImpzb25QYXR0ZXJuXCJcbiAgfCBcImh0bWxQYXR0ZXJuXCJcbiAgfCBcInJzY1BhdHRlcm5cIlxuICB8IFwibm9kZU9ubHlcIlxuICB8IFwiY3NzTW9kdWxlUGF0dGVyblwiXG4gIHwgXCJ2ZW5kb3JQYXR0ZXJuXCJcbiAgfCBcInZpcnR1YWxQYXR0ZXJuXCJcbiAgfCBcImRvdEZpbGVzXCI7XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVEZWZhdWx0TW9kdWxlSUQgPSAoXG4gIG9wdGlvbnM6IFBpY2s8XG4gICAgUmVzb2x2ZWRVc2VyT3B0aW9ucyxcbiAgICBcIm1vZHVsZUJhc2VcIiB8IFwibW9kdWxlQmFzZVBhdGhcIiB8IFwiYXV0b0Rpc2NvdmVyXCIgfCBcImJ1aWxkXCIgfCBcImRldlwiIHwgXCJtb2R1bGVCYXNlVVJMXCIgfCBcInByb2plY3RSb290XCJcbiAgPixcbiAgY29uZmlnRW52PzogQ29uZmlnRW52LFxuICBtb2RlID0gZ2V0Tm9kZUVudigpXG4pID0+IHtcbiAgY29uc3QgeyBtb2R1bGVCYXNlLCBtb2R1bGVCYXNlUGF0aCwgYnVpbGQsIG1vZHVsZUJhc2VVUkwsIHByb2plY3RSb290LCBhdXRvRGlzY292ZXIgfSA9IG9wdGlvbnM7XG4gIGNvbnN0IGFzc2V0c0RpciA9IGJ1aWxkLmFzc2V0c0RpciB8fCBERUZBVUxUX0NPTkZJRy5CVUlMRC5hc3NldHNEaXI7XG4gIGNvbnN0IGlzQnVpbGQgPSBjb25maWdFbnY/LmNvbW1hbmQgPT09IFwiYnVpbGRcIjtcbiAgLy8gSGFzaGluZyArIG1vZHVsZUJhc2Utc3RyaXBwaW5nIG11c3QgdHJhY2sgYGlzQnVpbGRgLCBOT1QgYG1vZGVgLiBUaGUgY2h1bmtcbiAgLy8gRU1JU1NJT04gc2lkZSAocmVzb2x2ZU9wdGlvbnMnIGVudHJ5RmlsZS9jaHVua0ZpbGUgaGFzaCgpICsgUm9sbHVwJ3NcbiAgLy8gcHJlc2VydmVNb2R1bGVzUm9vdCkgaGFzaGVzIGFuZCBzdHJpcHMgYHNyYy9gIG9uIEVWRVJZIGJ1aWxkIHJlZ2FyZGxlc3Mgb2ZcbiAgLy8gbW9kZSwgc28gdGhlIGNsaWVudC1SRUZFUkVOQ0Ugc2lkZSAodGhpcyBmbiwgdXNlZCBieSB0aGUgdHJhbnNmb3JtZXIpIG11c3RcbiAgLy8gZG8gdGhlIHNhbWUg4oCUIG90aGVyd2lzZSBhIGB2aXRlIGJ1aWxkIC0tbW9kZSBkZXZlbG9wbWVudGAgKE5PREVfRU5WPVxuICAvLyBkZXZlbG9wbWVudCkgZW1pdHMgaGFzaGVkL3NyYy1zdHJpcHBlZCBjaHVua3MgYnV0IGJha2VzIHVuaGFzaGVkL3NyYy1rZXB0XG4gIC8vIHJlZnMgaW50byB0aGUgUlNDIHN0cmVhbSwgYW5kIFNTRyBmYWlscyB3aXRoIEVSUl9NT0RVTEVfTk9UX0ZPVU5ELlxuICAvLyBUaGUgZGVwZW5kZW5jeSBvcHRpbWl6ZXIgaXMgTk9UIGEgY29uY2VybiBoZXJlOiBpdCBydW5zIHVuZGVyXG4gIC8vIGNvbW1hbmQgPT09IFwic2VydmVcIiAoc28gaXNCdWlsZCA9PT0gZmFsc2UpIGFuZCBvbmx5IHByZS1idW5kbGVzXG4gIC8vIG5vZGVfbW9kdWxlcyDigJQgaXQgbmV2ZXIgbmFtZXMgYSBmaXJzdC1wYXJ0eSBgc3JjLyouY2xpZW50LipgIGNodW5rLlxuICBjb25zdCBzaG91bGRIYXNoID0gaXNCdWlsZDtcbiAgY29uc3QgaXNQcm9kID0gbW9kZSA9PT0gXCJwcm9kdWN0aW9uXCIgfHwgaXNCdWlsZDtcbiAgY29uc3QgcmVtb3ZlTW9kdWxlQmFzZSA9XG4gICAgKGlzUHJvZCB8fCBpc0J1aWxkKSAmJiAhb3B0aW9ucy5idWlsZC5wcmVzZXJ2ZU1vZHVsZXNSb290O1xuICBcblxuICAvLyBIYXNoIGNvbmZpZ3VyYXRpb25cbiAgY29uc3QgaGFzaE9wdGlvbiA9IGJ1aWxkPy5oYXNoID8/IERFRkFVTFRfQ09ORklHLkJVSUxELmhhc2g7XG4gIFxuICAvLyBWaXJ0dWFsIHBhdHRlcm4gZm9yIGV4Y2x1ZGluZyB2aXJ0dWFsIG1vZHVsZXMgZnJvbSBoYXNoaW5nXG4gIGNvbnN0IHZpcnR1YWxQYXR0ZXJuID0gYXV0b0Rpc2NvdmVyPy52aXJ0dWFsUGF0dGVybiA/PyBERUZBVUxUX0NPTkZJRy5BVVRPX0RJU0NPVkVSLnZpcnR1YWxQYXR0ZXJuO1xuICBcbiAgLy8gQSBtb2R1bGUgaXMgYSBjbGllbnQgY29tcG9uZW50IChhbmQgdGhlcmVmb3JlIG11c3QgZ2V0IGEgaG9zdGVkLFxuICAvLyBgbW9kdWxlQmFzZVBhdGhgLXByZWZpeGVkIG1vZHVsZUlEKSB3aGVuIHRoZSB1bmlmaWVkIGBkZXRlY3RDbGllbnRNb2R1bGVgXG4gIC8vIGhlbHBlciBzYXlzIHNvIOKAlCBmaWxlbmFtZSBgLmNsaWVudC5bY21dP1tqdF1zeD8kYCBPUiBhIHRvcC1vZi1maWxlXG4gIC8vIGBcInVzZSBjbGllbnRcImAgZGlyZWN0aXZlLiBUaGUgYGlzQ2xpZW50QnlEaXJlY3RpdmVgIG92ZXJyaWRlIGZhc3QtcGF0aHNcbiAgLy8gdGhlIGJ1aWxkJ3MgdHJhbnNmb3JtZXIgYW5zd2VyIChjb21wdXRlZCB3aXRoIFJvbGx1cCdzIEpTWC1hd2FyZVxuICAvLyBgdGhpcy5wYXJzZWApLCBzbyB3ZSBkb24ndCByZS1wYXJzZSBoZXJlLlxuICAvL1xuICAvLyBUaGlzIGlzIHdoYXQgbGV0cyBkaXJlY3RpdmUtb25seSBjbGllbnQgbW9kdWxlcyAobm8gYC5jbGllbnQuYCBzdWZmaXgsXG4gIC8vIGUuZy4gbm9kZV9tb2R1bGVzIGxpYnMgdGhhdCBzaGlwIGBcInVzZSBjbGllbnRcImApIGJlIGhvc3RlZCBpbiB0aGUgc3RhdGljXG4gIC8vIGJ1aWxkIGluc3RlYWQgb2YgdGhyb3dpbmcgXCJBdHRlbXB0ZWQgdG8gbG9hZCBhIENsaWVudCBNb2R1bGUgb3V0c2lkZSB0aGVcbiAgLy8gaG9zdGVkIHJvb3RcIi5cbiAgY29uc3QgaXNDbGllbnRDb21wb25lbnRJZCA9IChcbiAgICBpZDogc3RyaW5nLFxuICAgIHNvdXJjZUNvbnRlbnQ/OiBzdHJpbmcsXG4gICAgaXNDbGllbnRCeURpcmVjdGl2ZT86IGJvb2xlYW5cbiAgKSA9PlxuICAgIGlzQ2xpZW50QnlEaXJlY3RpdmUgPT09IHRydWUgfHxcbiAgICBkZXRlY3RDbGllbnRNb2R1bGUoeyBzb3VyY2U6IHNvdXJjZUNvbnRlbnQsIG1vZHVsZUlkOiBpZCB9KTtcblxuICAvLyBIYXNoIGZ1bmN0aW9uIGZvciBjbGllbnQgY29tcG9uZW50cyAtIHNhbWUgbG9naWMgYXMgcmVzb2x2ZU9wdGlvbnMudHNcbiAgY29uc3QgaGFzaCA9IChcbiAgICBpbnB1dDogc3RyaW5nIHwgbnVsbCxcbiAgICBfc3NyOiBib29sZWFuLFxuICAgIHNvdXJjZUNvbnRlbnQ/OiBzdHJpbmcsXG4gICAgaXNDbGllbnRCeURpcmVjdGl2ZT86IGJvb2xlYW5cbiAgKSA9PiB7XG4gICAgaWYgKCFpbnB1dCkgcmV0dXJuIFwiXCI7XG4gICAgaWYgKG5ldyBSZWdFeHAoL1xcLihub2RlfGRcXC50cykkLykudGVzdChpbnB1dCkpIHtcbiAgICAgIHJldHVybiBpbnB1dDtcbiAgICB9XG4gICAgXG4gICAgLy8gQ1JJVElDQUw6IE5ldmVyIGhhc2ggbm9kZV9tb2R1bGVzIGZpbGVzIC0gVml0ZS9Sb2xsdXAgaGFuZGxlcyB0aG9zZVxuICAgIGlmIChpbnB1dC5pbmNsdWRlcyhcIm5vZGVfbW9kdWxlc1wiKSkge1xuICAgICAgcmV0dXJuIGlucHV0O1xuICAgIH1cbiAgICBcbiAgICAvLyBDUklUSUNBTDogTmV2ZXIgaGFzaCB2aXJ0dWFsIG1vZHVsZXMgKF92aXJ0dWFsIG9yIG1hdGNoaW5nIHZpcnR1YWxQYXR0ZXJuKSAtIFZpdGUgaGFuZGxlcyB0aG9zZVxuICAgIGlmIChpbnB1dC5pbmNsdWRlcyhcIl92aXJ0dWFsXCIpIHx8ICh2aXJ0dWFsUGF0dGVybiAmJiB2aXJ0dWFsUGF0dGVybi50ZXN0KGlucHV0KSkpIHtcbiAgICAgIHJldHVybiBpbnB1dDtcbiAgICB9XG4gICAgXG4gICAgLy8gQ2hlY2sgaWYgaGFzaGluZyBpcyBkaXNhYmxlZFxuICAgIGlmIChoYXNoT3B0aW9uID09PSBcImZhbHNlXCIpIHtcbiAgICAgIHJldHVybiBpbnB1dDtcbiAgICB9XG4gICAgXG4gICAgLy8gT25seSBoYXNoIGNsaWVudCBjb21wb25lbnRzIC0gc2VydmVyIGZpbGVzIHNob3VsZCBub3QgYmUgaGFzaGVkLlxuICAgIC8vIFJlY29nbml6ZSB0aGUgYC5jbGllbnQuYCBmaWxlbmFtZSBjb252ZW50aW9uLCBhIHRvcC1vZi1maWxlXG4gICAgLy8gYFwidXNlIGNsaWVudFwiYCBkaXJlY3RpdmUgKHdoZW4gc291cmNlIGNvbnRlbnQgaXMgYXZhaWxhYmxlKSwgb3IgYW5cbiAgICAvLyBleHBsaWNpdCBkaXJlY3RpdmUgb3ZlcnJpZGUgdGhyZWFkZWQgZnJvbSB0aGUgdHJhbnNmb3JtZXIuXG4gICAgY29uc3QgaXNDbGllbnRDb21wb25lbnQgPSBpc0NsaWVudENvbXBvbmVudElkKFxuICAgICAgaW5wdXQsXG4gICAgICBzb3VyY2VDb250ZW50LFxuICAgICAgaXNDbGllbnRCeURpcmVjdGl2ZVxuICAgICk7XG5cbiAgICBpZiAoIWlzQ2xpZW50Q29tcG9uZW50KSB7XG4gICAgICByZXR1cm4gaW5wdXQ7XG4gICAgfVxuICAgIFxuICAgIC8vIEFsd2F5cyBoYXNoIHRoZSBzb3VyY2UgY29udGVudCBmb3IgY29uc2lzdGVuY3kgYWNyb3NzIGJ1aWxkc1xuICAgIC8vIFRoaXMgZW5zdXJlcyB0aGUgc2FtZSBoYXNoIGlzIGdlbmVyYXRlZCBpbiB0cmFuc2Zvcm1lciBhbmQgYnVpbGQgcHJvY2Vzc1xuICAgIGxldCBjb250ZW50VG9IYXNoOiBzdHJpbmc7XG4gICAgXG4gICAgaWYgKHNvdXJjZUNvbnRlbnQpIHtcbiAgICAgIC8vIFVzZSBwcm92aWRlZCBzb3VyY2UgY29udGVudCAocHJlZmVycmVkKVxuICAgICAgY29udGVudFRvSGFzaCA9IHNvdXJjZUNvbnRlbnQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFRyeSB0byByZWFkIHNvdXJjZSBmaWxlIGNvbnRlbnRcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHNvdXJjZVBhdGggPSByZXNvbHZlKHByb2plY3RSb290LCBpbnB1dCk7XG4gICAgICAgIGlmIChleGlzdHNTeW5jKHNvdXJjZVBhdGgpKSB7XG4gICAgICAgICAgY29udGVudFRvSGFzaCA9IHJlYWRGaWxlU3luYyhzb3VyY2VQYXRoLCAndXRmLTgnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBGYWxsYmFjayB0byBmaWxlbmFtZVxuICAgICAgICAgIGNvbnRlbnRUb0hhc2ggPSBpbnB1dDtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgLy8gRmFsbGJhY2sgdG8gZmlsZW5hbWVcbiAgICAgICAgY29udGVudFRvSGFzaCA9IGlucHV0O1xuICAgICAgfVxuICAgIH1cbiAgICBcbiAgICAvLyBHZW5lcmF0ZSBoYXNoIHVzaW5nIFJvbGx1cC1saWtlIGFsZ29yaXRobVxuICAgIGNvbnN0IGhhc2hDaGFyYWN0ZXJzID0gdHlwZW9mIGhhc2hPcHRpb24gPT09ICdvYmplY3QnICYmIGhhc2hPcHRpb24/LmZvcm1hdCA9PT0gJ2hleCcgPyAnaGV4JyA6ICdiYXNlMzYnO1xuICAgIGNvbnN0IGNvbnRlbnRIYXNoID0gY3JlYXRlUm9sbHVwTGlrZUhhc2goY29udGVudFRvSGFzaCwgaGFzaENoYXJhY3RlcnMpO1xuICAgIFxuICAgIC8vIEFwcGx5IG5hbWluZyBsb2dpY1xuICAgIGNvbnN0IGV4dGVuc2lvbkluZGV4ID0gaW5wdXQubGFzdEluZGV4T2YoXCIuXCIpO1xuICAgIGlmIChleHRlbnNpb25JbmRleCAhPT0gLTEpIHtcbiAgICAgIGNvbnN0IGV4dGVuc2lvbiA9IGlucHV0LnNsaWNlKGV4dGVuc2lvbkluZGV4KTtcbiAgICAgIGNvbnN0IGZpbGVuYW1lID0gaW5wdXQuc2xpY2UoMCwgZXh0ZW5zaW9uSW5kZXgpO1xuICAgICAgcmV0dXJuIGZpbGVuYW1lICsgXCItXCIgKyBjb250ZW50SGFzaCArIGV4dGVuc2lvbjtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGlucHV0ICsgXCItXCIgKyBjb250ZW50SGFzaDtcbiAgICB9XG4gIH07XG4gIGNvbnN0IHN0YXRpY0NsaWVudERpc3QgPSBpc0J1aWxkID8gam9pbihidWlsZD8ub3V0RGlyIHx8IFwiZGlzdFwiLCBidWlsZD8uc3RhdGljIHx8IFwic3RhdGljXCIpIDogXCJcIjtcbiAgY29uc3Qgc3NyQ2xpZW50RGlzdCA9IGlzQnVpbGQgPyBqb2luKGJ1aWxkPy5vdXREaXIgfHwgXCJkaXN0XCIsIGJ1aWxkPy5jbGllbnQgfHwgXCJjbGllbnRcIikgOiBcIlwiO1xuICBjb25zdCBzZXJ2ZXJEaXN0ID0gaXNCdWlsZCA/IGpvaW4oYnVpbGQ/Lm91dERpciB8fCBcImRpc3RcIiwgYnVpbGQ/LnNlcnZlciB8fCBcInNlcnZlclwiKSA6IFwiXCI7XG4gIGNvbnN0IGJ1aWxkRGlycyA9IGlzQnVpbGQgPyBbc2VydmVyRGlzdCwgc3NyQ2xpZW50RGlzdCwgc3RhdGljQ2xpZW50RGlzdF0gOiBbXTtcblxuICByZXR1cm4gKFxuICAgIGlkOiBzdHJpbmcsXG4gICAgc291cmNlQ29udGVudD86IHN0cmluZyxcbiAgICBpc0NsaWVudEJ5RGlyZWN0aXZlPzogYm9vbGVhblxuICApID0+IHtcbiAgICAvLyBGb3IgdHJhbnNmb3JtZXIgdXNhZ2UgKHdoZW4gd2UncmUgaW4gYnVpbGQgbW9kZSBhbmQgcHJvY2Vzc2luZyBzZXJ2ZXIgY29tcG9uZW50cyksXG4gICAgLy8gd2Ugd2FudCB0byBzdHJpcCBidWlsZCBkaXJlY3RvcnkgcHJlZml4ZXMgdG8gZ2V0IHJlbGF0aXZlIHBhdGhzXG4gICAgLy8gVGhpcyBlbnN1cmVzIHRoZSBSU0Mgc3RyZWFtIGNvbnRhaW5zIHBhdGhzIHRoYXQgY2FuIGJlIHJlc29sdmVkIGJ5IHRoZSBIVE1MIHRyYW5zZm9ybVxuICAgIGlmIChzaG91bGRIYXNoKSB7XG4gICAgICAvLyBTdHJpcCBidWlsZCBkaXJlY3RvcnkgcHJlZml4ZXMgdG8gZ2V0IHJlbGF0aXZlIHBhdGhzXG4gICAgICBmb3IgKGNvbnN0IGJ1aWxkRGlyIG9mIGJ1aWxkRGlycykge1xuICAgICAgICBpZiAoaWQuc3RhcnRzV2l0aChidWlsZERpcikpIHtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBpZC5zbGljZShidWlsZERpci5sZW5ndGgpO1xuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIENoZWNrIGZvciBkb3VibGUgcGF0aCBpc3N1ZXMgKGxpa2UgZGlzdC9jbGllbnQvL2Rpc3Qvc2VydmVyLylcbiAgICAgIGlmIChpZC5pbmNsdWRlcygnLy8nKSkge1xuICAgICAgICAvLyBUcnkgdG8gZml4IGRvdWJsZSBwYXRoIGlzc3VlcyBieSBmaW5kaW5nIHRoZSBsYXN0IG9jY3VycmVuY2Ugb2YgZGlzdC9cbiAgICAgICAgY29uc3QgbGFzdERpc3RJbmRleCA9IGlkLmxhc3RJbmRleE9mKCdkaXN0LycpO1xuICAgICAgICBpZiAobGFzdERpc3RJbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBpZC5zbGljZShsYXN0RGlzdEluZGV4KTtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBcbiAgICAgIC8vIEZvciBjbGllbnQgY29tcG9uZW50cyBpbiBidWlsZCBtb2RlLCB0cmFuc2Zvcm0gc291cmNlIHBhdGhzIHRvIGJ1aWx0IHBhdGhzLlxuICAgICAgLy8gRGlyZWN0aXZlLWRldGVjdGVkIGNsaWVudCBtb2R1bGVzIChubyBgLmNsaWVudC5gIHN1ZmZpeCkgYXJlIGhvc3RlZCB0b28uXG4gICAgICBjb25zdCBpc0NsaWVudENvbXBvbmVudCA9IGlzQ2xpZW50Q29tcG9uZW50SWQoXG4gICAgICAgIGlkLFxuICAgICAgICBzb3VyY2VDb250ZW50LFxuICAgICAgICBpc0NsaWVudEJ5RGlyZWN0aXZlXG4gICAgICApO1xuICAgICAgaWYgKGlzQ2xpZW50Q29tcG9uZW50KSB7XG4gICAgICAgIC8vIFRyYW5zZm9ybSBzb3VyY2UgcGF0aCB0byBidWlsdCBjbGllbnQgcGF0aFxuICAgICAgICBsZXQgdHJhbnNmb3JtZWRJZCA9IGlkO1xuICAgICAgICBcbiAgICAgICAgLy8gU3RlcCAxOiBSZW1vdmUgbW9kdWxlQmFzZSAodHlwaWNhbGx5IFwic3JjL1wiKSBmcm9tIHRoZSBiZWdpbm5pbmdcbiAgICAgICAgaWYgKHJlbW92ZU1vZHVsZUJhc2UgJiYgdHJhbnNmb3JtZWRJZC5zdGFydHNXaXRoKG1vZHVsZUJhc2UgKyBzZXApKSB7XG4gICAgICAgICAgdHJhbnNmb3JtZWRJZCA9IHRyYW5zZm9ybWVkSWQuc2xpY2UobW9kdWxlQmFzZS5sZW5ndGggKyBzZXAubGVuZ3RoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFN0ZXAgMWI6IE1hdGNoIHRoZSBidWlsZCdzIGVudHJ5RmlsZSBuYW1lIG5vcm1hbGl6YXRpb24gZm9yXG4gICAgICAgIC8vIERJUkVDVElWRS1kZXRlY3RlZCBjbGllbnQgbW9kdWxlcy4gVGhlIGVtaXR0ZWQgY2h1bmsgbmFtZSBjb21lcyBmcm9tXG4gICAgICAgIC8vIGBlbnRyeUZpbGVgIOKGkiBgbm9ybWFsaXplcihuLm5hbWUpYCwgd2hpY2ggc3RyaXBzIG9uZSB0cmFpbGluZ1xuICAgICAgICAvLyBcIi5zZWdtZW50XCIgdW5sZXNzIGl0J3MgYC5jbGllbnRgL2Auc2VydmVyYC4gRm9yIGEgY29tcG91bmQgZmlsZW5hbWVcbiAgICAgICAgLy8gbGlrZSBgdmlldy9WaWV3LmdlbmVyYXRlZC50c3hgIHRoYXQgY29sbGFwc2VzIHRvIGB2aWV3L1ZpZXdgLCBidXRcbiAgICAgICAgLy8gdGhpcyBtb2R1bGVJRCBvdGhlcndpc2Uga2VlcHMgYC5nZW5lcmF0ZWRgIOKAlCBzbyB0aGUgcmVnaXN0ZXJlZCBjbGllbnRcbiAgICAgICAgLy8gcmVmZXJlbmNlIChgdmlldy9WaWV3LmdlbmVyYXRlZC08aGFzaD4uanNgKSB3b3VsZG4ndCBtYXRjaCB0aGUgZW1pdHRlZFxuICAgICAgICAvLyBjaHVuayAoYHZpZXcvVmlldy08aGFzaD4uanNgKSDihpIgRVJSX01PRFVMRV9OT1RfRk9VTkQgYXQgU1NHIHJlbmRlci5cbiAgICAgICAgLy8gYC5jbGllbnQuYC1uYW1lZCBtb2R1bGVzIGFyZSB1bmFmZmVjdGVkICh0aGUgbm9ybWFsaXplciBwcmVzZXJ2ZXNcbiAgICAgICAgLy8gdGhhdCBzdWZmaXgsIGFuZCBzbyBkbyB3ZSkuIFNpbmdsZS1zZWdtZW50IG5hbWVzIGhhdmUgbm90aGluZyB0byBzdHJpcC5cbiAgICAgICAgaWYgKGlzQ2xpZW50QnlEaXJlY3RpdmUpIHtcbiAgICAgICAgICBjb25zdCBub0V4dCA9IHRyYW5zZm9ybWVkSWQucmVwbGFjZSgvXFwuW2NtXT9banRdc3g/JC8sIFwiXCIpO1xuICAgICAgICAgIGlmICghbm9FeHQuZW5kc1dpdGgoXCIuY2xpZW50XCIpICYmICFub0V4dC5lbmRzV2l0aChcIi5zZXJ2ZXJcIikpIHtcbiAgICAgICAgICAgIGNvbnN0IGxhc3REb3QgPSBub0V4dC5sYXN0SW5kZXhPZihcIi5cIik7XG4gICAgICAgICAgICBpZiAobGFzdERvdCA+IG5vRXh0Lmxhc3RJbmRleE9mKFwiL1wiKSkge1xuICAgICAgICAgICAgICB0cmFuc2Zvcm1lZElkID1cbiAgICAgICAgICAgICAgICBub0V4dC5zbGljZSgwLCBsYXN0RG90KSArIHRyYW5zZm9ybWVkSWQuc2xpY2Uobm9FeHQubGVuZ3RoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTdGVwIDI6IEFwcGx5IGV4dGVuc2lvbiBtYXBwaW5nIGZvciBidWlsZFxuICAgICAgICB0cmFuc2Zvcm1lZElkID0gcmVwbGFjZUV4dGVuc2lvbih0cmFuc2Zvcm1lZElkLCB7XG4gICAgICAgICAgYnVpbGQ6IHsgZXh0ZW5zaW9uTWFwOiBidWlsZC5leHRlbnNpb25NYXAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIFxuICAgICAgICBcbiAgICAgICAgLy8gU3RlcCAzOiBBcHBseSBoYXNoaW5nIGZvciBjbGllbnQgY29tcG9uZW50c1xuICAgICAgICB0cmFuc2Zvcm1lZElkID0gaGFzaCh0cmFuc2Zvcm1lZElkLCBmYWxzZSwgc291cmNlQ29udGVudCwgaXNDbGllbnRCeURpcmVjdGl2ZSk7XG4gICAgICAgIFxuICAgICAgICAvLyBTdGVwIDQ6IEVuc3VyZSBwYXRocyBzdGFydCB3aXRoIG1vZHVsZUJhc2VQYXRoXG4gICAgICAgIGlmIChtb2R1bGVCYXNlUGF0aCAmJiAhdHJhbnNmb3JtZWRJZC5zdGFydHNXaXRoKG1vZHVsZUJhc2VQYXRoKSkge1xuICAgICAgICAgIHRyYW5zZm9ybWVkSWQgPSBtb2R1bGVCYXNlUGF0aCArIHRyYW5zZm9ybWVkSWQ7XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIHJldHVybiB0cmFuc2Zvcm1lZElkO1xuICAgICAgfVxuICAgICAgXG4gICAgICByZXR1cm4gaWQ7XG4gICAgfVxuICAgIFxuICAgIC8vIE5vcm1hbCBidWlsZCBwYXRoIHRyYW5zZm9ybWF0aW9uIChleGlzdGluZyBsb2dpYylcblxuICAgIC8vIFN0ZXAgMTogSGFuZGxlIGFzc2V0cyBkaXJlY3RvcnkgcGF0aHMgLSByZW1vdmUgc3JjIGZyb20gd2l0aGluIGFzc2V0cyBwYXRoXG4gICAgLy8gVHJhbnNmb3JtOiBhc3NldHMvc3JjL3BhZ2UvZmlsZS5jc3MgLT4gYXNzZXRzL3BhZ2UvZmlsZS5jc3NcbiAgICBpZiAoaWQuc3RhcnRzV2l0aChhc3NldHNEaXIgKyBzZXAgKyBtb2R1bGVCYXNlICsgc2VwKSkge1xuICAgICAgaWQgPSBhc3NldHNEaXIgKyBzZXAgKyBpZC5zbGljZSgoYXNzZXRzRGlyICsgc2VwICsgbW9kdWxlQmFzZSArIHNlcCkubGVuZ3RoKTtcbiAgICB9XG4gICAgXG4gICAgLy8gU3RlcCAyOiBSZW1vdmUgbW9kdWxlQmFzZVVSTCBpZiBwcmVzZW50IChmb3IgaW5jb21pbmcgSURzIHRoYXQgYWxyZWFkeSBoYXZlIGJhc2UgVVJMKVxuICAgIGlmIChtb2R1bGVCYXNlVVJMICYmIG1vZHVsZUJhc2VVUkwgIT09IFwiL1wiICYmIGlkLnN0YXJ0c1dpdGgobW9kdWxlQmFzZVVSTCkpIHtcbiAgICAgIGlkID0gaWQuc2xpY2UobW9kdWxlQmFzZVVSTC5sZW5ndGgpO1xuICAgIH1cbiAgICBcbiAgICAvLyBTdGVwIDM6IFJlbW92ZSBzcmMgYWZ0ZXIgdGhlIG1vZHVsZUJhc2VQYXRoIGlmIHByZXNlbnRcbiAgICBpZiAobW9kdWxlQmFzZVBhdGggJiYgbW9kdWxlQmFzZVBhdGggIT09IFwiL1wiICYmIGlkLnN0YXJ0c1dpdGgobW9kdWxlQmFzZVBhdGggKyBtb2R1bGVCYXNlKSkge1xuICAgICAgLy8gc2xpY2UgaW5iZXR3ZWVuIHRoZSBtb2R1bGVCYXNlUGF0aCBhbmQgbW9kdWxlQmFzZVxuICAgICAgaWQgPSBtb2R1bGVCYXNlUGF0aCArIGlkLnNsaWNlKChtb2R1bGVCYXNlUGF0aCArIG1vZHVsZUJhc2UpLmxlbmd0aCk7XG4gICAgfVxuICAgIFxuICAgIC8vIFN0ZXAgNDogUmVtb3ZlIG1vZHVsZUJhc2UgKHR5cGljYWxseSBcInNyYy9cIikgZnJvbSB0aGUgYmVnaW5uaW5nXG4gICAgaWYgKHJlbW92ZU1vZHVsZUJhc2UgJiYgaWQuc3RhcnRzV2l0aChtb2R1bGVCYXNlICsgc2VwKSkge1xuICAgICAgaWQgPSBpZC5zbGljZShtb2R1bGVCYXNlLmxlbmd0aCArIHNlcC5sZW5ndGgpO1xuICAgIH1cblxuICAgIC8vIFN0ZXAgNTogRW5zdXJlIHBhdGhzIHN0YXJ0IHdpdGggbW9kdWxlQmFzZVBhdGggKGF2b2lkIGRvdWJsZS1wcmVmaXgpXG4gICAgaWYgKG1vZHVsZUJhc2VQYXRoICYmICFpZC5zdGFydHNXaXRoKG1vZHVsZUJhc2VQYXRoKSkge1xuICAgICAgaWQgPSBtb2R1bGVCYXNlUGF0aCArIGlkO1xuICAgIH1cbiAgICBcbiAgICAvLyBTdGVwIDY6IEFwcGx5IGV4dGVuc2lvbiBtYXBwaW5nIOKAlCBCVUlMRCBPTkxZLlxuICAgIC8vIEluIGEgYnVpbGQgdGhlIGJyb3dzZXIgY2FuJ3QgaW1wb3J0IC50c3gsIHNvIGNsaWVudCBjb21wb25lbnRzIGFyZSBtYXBwZWRcbiAgICAvLyB0byAuanMuIEluIERFViwgVml0ZSB0cmFuc3BpbGVzIC50c3ggb24gdGhlIGZseSwgc28gbWFwcGluZyB0aGVyZSBnaXZlc1xuICAgIC8vIHRoZSBjbGllbnQtcmVmZXJlbmNlIGlkIGEgcGhhbnRvbSAuanMgdGhlIGRldiBtb2R1bGUgZ3JhcGggbmV2ZXIgaGFzIOKAlFxuICAgIC8vIHRoZSBpbXBvcnQgcmVzb2x2ZXMgdG8gXCI8bmFtZT4uY2xpZW50LmpzLnRzeFwiLCB3aGljaCA0MDRzIG9uIHRoZSBzZWNvbmRcbiAgICAvLyBITVIgZmV0Y2ggYW5kIGtpbGxzIEZhc3QgUmVmcmVzaCBhZnRlciB0aGUgZmlyc3QgZWRpdCAoYmQtNTcyKS4gS2VlcCB0aGVcbiAgICAvLyByZWFsIC50c3ggaWQgaW4gZGV2LlxuICAgIGNvbnN0IGlzQ2xpZW50Q29tcG9uZW50ID0gaXNDbGllbnRDb21wb25lbnRJZChcbiAgICAgIGlkLFxuICAgICAgc291cmNlQ29udGVudCxcbiAgICAgIGlzQ2xpZW50QnlEaXJlY3RpdmVcbiAgICApO1xuICAgIGlmIChpc0J1aWxkKSB7XG4gICAgICBpZCA9IHJlcGxhY2VFeHRlbnNpb24oaWQsIHtcbiAgICAgICAgYnVpbGQ6IHsgZXh0ZW5zaW9uTWFwOiBidWlsZC5leHRlbnNpb25NYXAgfSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICBcbiAgICAvLyBTdGVwIDc6IEVuc3VyZSBDU1MgZmlsZXMgYXJlIHBsYWNlZCBpbiB0aGUgYXNzZXRzIGRpcmVjdG9yeVxuICAgIGlmIChpc0J1aWxkICYmIGlkLmVuZHNXaXRoKCcuY3NzJykgJiYgIWlkLnN0YXJ0c1dpdGgoYXNzZXRzRGlyICsgc2VwKSkge1xuICAgICAgaWQgPSBhc3NldHNEaXIgKyBzZXAgKyBpZDtcbiAgICB9XG4gICAgXG4gICAgLy8gU3RlcCA4OiBBcHBseSBoYXNoaW5nIGZvciBjbGllbnQgY29tcG9uZW50cyAob25seSBpbiBwcm9kdWN0aW9uIGJ1aWxkcywgbm90IGRldilcbiAgICBpZiAoc2hvdWxkSGFzaCkge1xuICAgICAgaWQgPSBoYXNoKGlkLCBmYWxzZSwgc291cmNlQ29udGVudCwgaXNDbGllbnRCeURpcmVjdGl2ZSk7XG4gICAgfVxuICAgIFxuICAgIC8vIEZvciBjbGllbnQgY29tcG9uZW50cywgZW5zdXJlIG5vIGxlYWRpbmcgc2xhc2ggdG8gYWxsb3cgcHJvcGVyIHJlbGF0aXZlIHJlc29sdXRpb25cbiAgICAvLyAoaXNDbGllbnRDb21wb25lbnQgYWxyZWFkeSBkZWZpbmVkIGluIFN0ZXAgNilcbiAgICBpZiAoaXNDbGllbnRDb21wb25lbnQgJiYgbW9kdWxlQmFzZVBhdGggPT09ICcnKSB7XG4gICAgICByZXR1cm4gaWQ7IC8vIE5vIGxlYWRpbmcgc2xhc2ggZm9yIGNsaWVudCBjb21wb25lbnRzXG4gICAgfVxuICAgIFxuICAgIC8vIERvbid0IGFkZCBsZWFkaW5nIHNsYXNoIGZvciByZWxhdGl2ZSBwYXRocyAtIHRoaXMgY2F1c2VzIG1vZHVsZSByZXNvbHV0aW9uIGlzc3Vlc1xuICAgIGlmIChtb2R1bGVCYXNlUGF0aCA9PT0gJycpIHtcbiAgICAgIHJldHVybiBpZDsgLy8gUmV0dXJuIGFzLWlzIHdpdGhvdXQgbGVhZGluZyBzbGFzaFxuICAgIH1cbiAgICBcbiAgICAvLyBpZCBhbHJlYWR5IGhhcyBtb2R1bGVCYXNlUGF0aCBmcm9tIFN0ZXAgNSDigJQgcmV0dXJuIGFzLWlzXG4gICAgcmV0dXJuIGlkO1xuICB9O1xufTtcblxuIl0sIm5hbWVzIjpbImlzQ2xpZW50Q29tcG9uZW50Il0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7O0FBc0JPLE1BQU0sd0JBQXdCLENBQ25DLE9BQUEsRUFJQSxTQUNBLEVBQUEsSUFBQSxHQUFPLFlBQ0osS0FBQTtBQUNILEVBQUEsTUFBTSxFQUFFLFVBQVksRUFBQSxjQUFBLEVBQWdCLE9BQU8sYUFBZSxFQUFBLFdBQUEsRUFBYSxjQUFpQixHQUFBLE9BQUE7QUFDeEYsRUFBQSxNQUFNLFNBQVksR0FBQSxLQUFBLENBQU0sU0FBYSxJQUFBLGNBQUEsQ0FBZSxLQUFNLENBQUEsU0FBQTtBQUMxRCxFQUFNLE1BQUEsT0FBQSxHQUFVLFdBQVcsT0FBWSxLQUFBLE9BQUE7QUFXdkMsRUFBQSxNQUFNLFVBQWEsR0FBQSxPQUFBO0FBQ25CLEVBQU0sTUFBQSxNQUFBLEdBQVMsU0FBUyxZQUFnQixJQUFBLE9BQUE7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