@analogjs/vite-plugin-nitro 3.0.0-alpha.22 → 3.0.0-alpha.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@analogjs/vite-plugin-nitro",
3
- "version": "3.0.0-alpha.22",
3
+ "version": "3.0.0-alpha.23",
4
4
  "description": "A Vite plugin for adding a nitro API server",
5
5
  "type": "module",
6
6
  "author": "Brandon Roberts <robertsbt@gmail.com>",
@@ -43,6 +43,7 @@
43
43
  "dependencies": {
44
44
  "defu": "^6.1.4",
45
45
  "nitro": "3.0.260311-beta",
46
+ "obug": "^2.1.1",
46
47
  "ofetch": "2.0.0-alpha.3",
47
48
  "oxc-parser": "^0.121.0",
48
49
  "radix3": "^1.1.2",
@@ -0,0 +1,3 @@
1
+ export declare const debugNitro: unknown;
2
+ export declare const debugSsr: unknown;
3
+ export declare const debugPrerender: unknown;
@@ -0,0 +1,9 @@
1
+ import { createDebug } from "obug";
2
+ //#region packages/vite-plugin-nitro/src/lib/utils/debug.ts
3
+ var debugNitro = createDebug("analog:nitro");
4
+ var debugSsr = createDebug("analog:nitro:ssr");
5
+ createDebug("analog:nitro:prerender");
6
+ //#endregion
7
+ export { debugNitro, debugSsr };
8
+
9
+ //# sourceMappingURL=debug.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug.js","names":[],"sources":["../../../../src/lib/utils/debug.ts"],"sourcesContent":["import { createDebug } from 'obug';\n\nexport const debugNitro = createDebug('analog:nitro');\nexport const debugSsr = createDebug('analog:nitro:ssr');\nexport const debugPrerender = createDebug('analog:nitro:prerender');\n"],"mappings":";;AAEA,IAAa,aAAa,YAAY,eAAe;AACrD,IAAa,WAAW,YAAY,mBAAmB;AACzB,YAAY,yBAAyB"}
@@ -8,6 +8,7 @@ import { buildSitemap } from "./build-sitemap.js";
8
8
  import { toWebRequest, writeWebResponseToNode } from "./utils/node-web-bridge.js";
9
9
  import { devServerPlugin } from "./plugins/dev-server-plugin.js";
10
10
  import { getMatchingContentFilesWithFrontMatter } from "./utils/get-content-files.js";
11
+ import { debugNitro, debugSsr } from "./utils/debug.js";
11
12
  import { build, createDevServer, createNitro } from "nitro/builder";
12
13
  import { mergeConfig, normalizePath } from "vite";
13
14
  import { relative, resolve } from "node:path";
@@ -89,31 +90,31 @@ function sanitizeNitroBundlerConfig(_nitro, bundlerConfig) {
89
90
  }
90
91
  function resolveClientOutputPath(cachedPath, workspaceRoot, rootDir, configuredOutDir) {
91
92
  if (cachedPath) {
92
- debugLog("resolveClientOutputPath using cached path", () => ({
93
+ debugNitro("resolveClientOutputPath using cached path", {
93
94
  cachedPath,
94
95
  workspaceRoot,
95
96
  rootDir,
96
97
  configuredOutDir
97
- }));
98
+ });
98
99
  return cachedPath;
99
100
  }
100
101
  if (configuredOutDir) {
101
102
  const resolvedPath = normalizePath(resolve(workspaceRoot, rootDir, configuredOutDir));
102
- debugLog("resolveClientOutputPath using configured build.outDir", () => ({
103
+ debugNitro("resolveClientOutputPath using configured build.outDir", {
103
104
  workspaceRoot,
104
105
  rootDir,
105
106
  configuredOutDir,
106
107
  resolvedPath
107
- }));
108
+ });
108
109
  return resolvedPath;
109
110
  }
110
111
  const resolvedPath = normalizePath(resolve(workspaceRoot, "dist", rootDir, "client"));
111
- debugLog("resolveClientOutputPath using default dist client path", () => ({
112
+ debugNitro("resolveClientOutputPath using default dist client path", {
112
113
  workspaceRoot,
113
114
  rootDir,
114
115
  configuredOutDir,
115
116
  resolvedPath
116
- }));
117
+ });
117
118
  return resolvedPath;
118
119
  }
119
120
  function getEnvironmentBuildOutDir(environment) {
@@ -125,23 +126,23 @@ function resolveBuiltClientOutputPath(cachedPath, workspaceRoot, rootDir, config
125
126
  const environmentOutDir = getEnvironmentBuildOutDir(environment);
126
127
  if (environmentOutDir) {
127
128
  const resolvedPath = normalizePath(resolve(workspaceRoot, rootDir, environmentOutDir));
128
- debugLog("resolveBuiltClientOutputPath using environment outDir", () => ({
129
+ debugNitro("resolveBuiltClientOutputPath using environment outDir", {
129
130
  cachedPath,
130
131
  workspaceRoot,
131
132
  rootDir,
132
133
  configuredOutDir,
133
134
  environmentOutDir,
134
135
  resolvedPath
135
- }));
136
+ });
136
137
  return resolvedPath;
137
138
  }
138
- debugLog("resolveBuiltClientOutputPath falling back to shared resolver", () => ({
139
+ debugNitro("resolveBuiltClientOutputPath falling back to shared resolver", {
139
140
  cachedPath,
140
141
  workspaceRoot,
141
142
  rootDir,
142
143
  configuredOutDir,
143
144
  environmentOutDir
144
- }));
145
+ });
145
146
  return resolveClientOutputPath(cachedPath, workspaceRoot, rootDir, configuredOutDir);
146
147
  }
147
148
  function getNitroPublicOutputDir(nitroConfig) {
@@ -149,26 +150,6 @@ function getNitroPublicOutputDir(nitroConfig) {
149
150
  if (!publicDir) throw new Error("Nitro public output directory is required to build the sitemap.");
150
151
  return publicDir;
151
152
  }
152
- var DEBUG_NAMESPACE = "analog:vite-plugin-nitro";
153
- function escapeRegExp(value) {
154
- return value.replace(/[|\\{}()[\]^$+?.*]/g, "\\$&");
155
- }
156
- function isDebugEnabled(namespace) {
157
- const debugValue = process.env["DEBUG"];
158
- if (!debugValue) return false;
159
- return debugValue.split(/[\s,]+/).filter(Boolean).some((pattern) => {
160
- return new RegExp(`^${escapeRegExp(pattern).replace(/\\\*/g, ".*")}$`).test(namespace);
161
- });
162
- }
163
- function debugLog(label, details) {
164
- if (!isDebugEnabled(DEBUG_NAMESPACE)) return;
165
- const resolvedDetails = typeof details === "function" ? details() : details;
166
- if (resolvedDetails && Object.keys(resolvedDetails).length > 0) {
167
- console.log(`DEBUG: ${label}`, resolvedDetails);
168
- return;
169
- }
170
- console.log(`DEBUG: ${label}`);
171
- }
172
153
  function readDirectoryEntries(path) {
173
154
  try {
174
155
  return readdirSync(path).sort();
@@ -190,24 +171,24 @@ function assetSourceToString(source) {
190
171
  function captureClientIndexHtmlFromBundle(bundle, hook) {
191
172
  const indexHtmlAsset = Object.values(bundle).find((chunk) => chunk.type === "asset" && chunk.fileName === "index.html" && typeof chunk.source !== "undefined");
192
173
  if (!indexHtmlAsset?.source) {
193
- debugLog(`client bundle did not expose index.html during ${hook}`, () => ({
174
+ debugNitro(`client bundle did not expose index.html during ${hook}`, {
194
175
  hook,
195
176
  bundleKeys: Object.keys(bundle).sort(),
196
177
  assetFileNames: Object.values(bundle).filter((chunk) => chunk.type === "asset").map((chunk) => chunk.fileName).filter(Boolean)
197
- }));
178
+ });
198
179
  return;
199
180
  }
200
181
  const indexHtml = assetSourceToString(indexHtmlAsset.source);
201
- debugLog(`captured client bundle index.html asset during ${hook}`, () => ({
182
+ debugNitro(`captured client bundle index.html asset during ${hook}`, {
202
183
  hook,
203
184
  fileName: indexHtmlAsset.fileName,
204
185
  htmlLength: indexHtml.length
205
- }));
186
+ });
206
187
  return indexHtml;
207
188
  }
208
189
  function registerIndexHtmlVirtual(nitroConfig, clientOutputPath, inlineIndexHtml) {
209
190
  const indexHtmlPath = resolve(clientOutputPath, "index.html");
210
- debugLog("registerIndexHtmlVirtual inspecting client output", () => ({
191
+ debugNitro("registerIndexHtmlVirtual inspecting client output", {
211
192
  platform: process.platform,
212
193
  cwd: process.cwd(),
213
194
  clientOutputPath,
@@ -215,9 +196,9 @@ function registerIndexHtmlVirtual(nitroConfig, clientOutputPath, inlineIndexHtml
215
196
  indexHtmlPath,
216
197
  indexHtmlExists: existsSync(indexHtmlPath),
217
198
  hasInlineIndexHtml: typeof inlineIndexHtml === "string"
218
- }));
199
+ });
219
200
  if (!existsSync(indexHtmlPath) && typeof inlineIndexHtml !== "string") {
220
- debugLog("registerIndexHtmlVirtual missing index.html", () => ({
201
+ debugNitro("registerIndexHtmlVirtual missing index.html", {
221
202
  platform: process.platform,
222
203
  cwd: process.cwd(),
223
204
  clientOutputPath,
@@ -226,14 +207,14 @@ function registerIndexHtmlVirtual(nitroConfig, clientOutputPath, inlineIndexHtml
226
207
  hasInlineIndexHtml: typeof inlineIndexHtml === "string",
227
208
  nitroOutput: nitroConfig.output,
228
209
  nitroPublicAssets: nitroConfig.publicAssets
229
- }));
210
+ });
230
211
  throw new Error(`[analog] Client build output not found at ${indexHtmlPath}.\nEnsure the client environment build completed successfully before the server build.`);
231
212
  }
232
213
  const indexHtml = typeof inlineIndexHtml === "string" ? inlineIndexHtml : readFileSync(indexHtmlPath, "utf8");
233
- debugLog("registerIndexHtmlVirtual using HTML template source", () => ({
214
+ debugNitro("registerIndexHtmlVirtual using HTML template source", {
234
215
  source: typeof inlineIndexHtml === "string" ? "captured client bundle asset" : "client output index.html file",
235
216
  indexHtmlPath
236
- }));
217
+ });
237
218
  nitroConfig.virtual = {
238
219
  ...nitroConfig.virtual,
239
220
  "#analog/index": `export default ${JSON.stringify(indexHtml)};`
@@ -344,7 +325,7 @@ function nitro(options, nitroOptions) {
344
325
  hasAPIDir
345
326
  });
346
327
  const resolvedClientOutputPath = resolveClientOutputPath(clientOutputPath, workspaceRoot, rootDir, config.build?.outDir);
347
- debugLog("nitro config resolved client output path", () => ({
328
+ debugNitro("nitro config resolved client output path", {
348
329
  platform: process.platform,
349
330
  workspaceRoot,
350
331
  configRoot: config.root,
@@ -355,7 +336,7 @@ function nitro(options, nitroOptions) {
355
336
  resolvedClientOutputPath,
356
337
  hasEnvironmentConfig: !!config.environments,
357
338
  clientEnvironmentOutDir: config.environments?.["client"] && typeof config.environments["client"] === "object" && "build" in config.environments["client"] ? config.environments["client"].build?.outDir : void 0
358
- }));
339
+ });
359
340
  nitroConfig = {
360
341
  rootDir: normalizePath(rootDir),
361
342
  preset: buildPreset,
@@ -396,11 +377,11 @@ function nitro(options, nitroOptions) {
396
377
  if (isFirebaseAppHosting()) nitroConfig = withAppHostingOutput(nitroConfig);
397
378
  if (!ssrBuild && !isTest) {
398
379
  clientOutputPath = resolvedClientOutputPath;
399
- debugLog("nitro config cached client output path for later SSR/Nitro build", () => ({
380
+ debugNitro("nitro config cached client output path for later SSR/Nitro build", {
400
381
  ssrBuild,
401
382
  isTest,
402
383
  clientOutputPath
403
- }));
384
+ });
404
385
  }
405
386
  nitroConfig.alias = {};
406
387
  if (isBuild) {
@@ -502,7 +483,7 @@ function nitro(options, nitroOptions) {
502
483
  sharedPlugins: true,
503
484
  buildApp: async (builder) => {
504
485
  environmentBuild = true;
505
- debugLog("builder.buildApp starting", () => ({
486
+ debugNitro("builder.buildApp starting", {
506
487
  platform: process.platform,
507
488
  workspaceRoot,
508
489
  rootDir,
@@ -510,23 +491,23 @@ function nitro(options, nitroOptions) {
510
491
  configuredBuildOutDir: config.build?.outDir,
511
492
  clientEnvironmentOutDir: getEnvironmentBuildOutDir(builder.environments["client"]),
512
493
  ssrEnvironmentOutDir: getEnvironmentBuildOutDir(builder.environments["ssr"])
513
- }));
494
+ });
514
495
  await builder.build(builder.environments["client"]);
515
496
  const postClientBuildOutputPath = resolveBuiltClientOutputPath(clientOutputPath, workspaceRoot, rootDir, config.build?.outDir, builder.environments["client"]);
516
497
  registerIndexHtmlVirtual(nitroConfig, postClientBuildOutputPath, clientIndexHtml);
517
- debugLog("builder.buildApp completed client build", () => ({
498
+ debugNitro("builder.buildApp completed client build", {
518
499
  postClientBuildOutputPath,
519
500
  postClientBuildOutputInfo: getPathDebugInfo(postClientBuildOutputPath),
520
501
  postClientBuildIndexHtmlPath: resolve(postClientBuildOutputPath, "index.html"),
521
502
  postClientBuildIndexHtmlExists: existsSync(resolve(postClientBuildOutputPath, "index.html"))
522
- }));
503
+ });
523
504
  if (options?.ssr || nitroConfig.prerender?.routes?.length) {
524
- debugLog("builder.buildApp starting SSR build", () => ({
505
+ debugSsr("builder.buildApp starting SSR build", {
525
506
  ssrEnabled: options?.ssr,
526
507
  prerenderRoutes: nitroConfig.prerender?.routes
527
- }));
508
+ });
528
509
  await builder.build(builder.environments["ssr"]);
529
- debugLog("builder.buildApp completed SSR build", () => ({ ssrOutputPath: options?.ssrBuildDir || resolve(workspaceRoot, "dist", rootDir, "ssr") }));
510
+ debugSsr("builder.buildApp completed SSR build", { ssrOutputPath: options?.ssrBuildDir || resolve(workspaceRoot, "dist", rootDir, "ssr") });
530
511
  }
531
512
  applySsrEntryAlias(nitroConfig, options, workspaceRoot, rootDir);
532
513
  const resolvedClientOutputPath = resolveBuiltClientOutputPath(clientOutputPath, workspaceRoot, rootDir, config.build?.outDir, builder.environments["client"]);
@@ -534,11 +515,11 @@ function nitro(options, nitroOptions) {
534
515
  dir: normalizePath(resolvedClientOutputPath),
535
516
  maxAge: 0
536
517
  }];
537
- debugLog("builder.buildApp resolved final client output path before Nitro build", () => ({
518
+ debugNitro("builder.buildApp resolved final client output path before Nitro build", {
538
519
  resolvedClientOutputPath,
539
520
  resolvedClientOutputInfo: getPathDebugInfo(resolvedClientOutputPath),
540
521
  nitroPublicAssets: nitroConfig.publicAssets
541
- }));
522
+ });
542
523
  await buildServer(options, nitroConfig, routeSourceFiles);
543
524
  if (nitroConfig.prerender?.routes?.length && options?.prerender?.sitemap) {
544
525
  console.log("Building Sitemap...");
@@ -615,7 +596,10 @@ function nitro(options, nitroOptions) {
615
596
  process.env["ANALOG_HOST"] = !viteServer.config.server.host ? "localhost" : viteServer.config.server.host;
616
597
  process.env["ANALOG_PORT"] = `${viteServer.config.server.port}`;
617
598
  });
618
- if (nitroOptions?.experimental?.websocket) viteServer.httpServer?.on("upgrade", server.upgrade);
599
+ if (nitroOptions?.experimental?.websocket) {
600
+ debugNitro("experimental websocket upgrade handler enabled");
601
+ viteServer.httpServer?.on("upgrade", server.upgrade);
602
+ }
619
603
  console.log(`\n\nThe server endpoints are accessible under the "${prefix}${apiPrefix}" path.`);
620
604
  }
621
605
  },
@@ -625,7 +609,7 @@ function nitro(options, nitroOptions) {
625
609
  if (ssrBuild) return;
626
610
  if (isBuild) {
627
611
  const resolvedClientOutputPath = resolveClientOutputPath(clientOutputPath, workspaceRoot, rootDir, config.build?.outDir);
628
- debugLog("closeBundle resolved client output path before legacy SSR build", () => ({
612
+ debugNitro("closeBundle resolved client output path before legacy SSR build", {
629
613
  platform: process.platform,
630
614
  workspaceRoot,
631
615
  rootDir,
@@ -633,17 +617,17 @@ function nitro(options, nitroOptions) {
633
617
  configuredBuildOutDir: config.build?.outDir,
634
618
  resolvedClientOutputPath,
635
619
  resolvedClientOutputInfo: getPathDebugInfo(resolvedClientOutputPath)
636
- }));
620
+ });
637
621
  const indexHtmlPath = resolve(resolvedClientOutputPath, "index.html");
638
622
  if (!existsSync(indexHtmlPath) && typeof clientIndexHtml !== "string") {
639
- debugLog("closeBundle rebuilding missing client output before SSR/Nitro", () => ({
623
+ debugNitro("closeBundle rebuilding missing client output before SSR/Nitro", {
640
624
  platform: process.platform,
641
625
  workspaceRoot,
642
626
  rootDir,
643
627
  configuredBuildOutDir: config.build?.outDir,
644
628
  resolvedClientOutputPath,
645
629
  indexHtmlPath
646
- }));
630
+ });
647
631
  legacyClientSubBuild = true;
648
632
  try {
649
633
  await buildClientApp(config, options);
@@ -655,13 +639,13 @@ function nitro(options, nitroOptions) {
655
639
  if (options?.ssr) {
656
640
  console.log("Building SSR application...");
657
641
  await buildSSRApp(config, options);
658
- debugLog("closeBundle completed standalone SSR build", () => ({
642
+ debugSsr("closeBundle completed standalone SSR build", {
659
643
  ssrBuildDir: options?.ssrBuildDir || resolve(workspaceRoot, "dist", rootDir, "ssr"),
660
644
  clientOutputPathInfo: clientOutputPath ? getPathDebugInfo(clientOutputPath) : null
661
- }));
645
+ });
662
646
  }
663
647
  applySsrEntryAlias(nitroConfig, options, workspaceRoot, rootDir);
664
- debugLog("closeBundle resolved client output path before Nitro build", () => ({
648
+ debugNitro("closeBundle resolved client output path before Nitro build", {
665
649
  platform: process.platform,
666
650
  workspaceRoot,
667
651
  rootDir,
@@ -669,7 +653,7 @@ function nitro(options, nitroOptions) {
669
653
  configuredBuildOutDir: config.build?.outDir,
670
654
  resolvedClientOutputPath,
671
655
  resolvedClientOutputInfo: getPathDebugInfo(resolvedClientOutputPath)
672
- }));
656
+ });
673
657
  registerIndexHtmlVirtual(nitroConfig, resolvedClientOutputPath, clientIndexHtml);
674
658
  await buildServer(options, nitroConfig, routeSourceFiles);
675
659
  if (nitroConfig.prerender?.routes?.length && options?.prerender?.sitemap) {
@@ -1 +1 @@
1
- {"version":3,"file":"vite-plugin-nitro.js","names":[],"sources":["../../../src/lib/vite-plugin-nitro.ts"],"sourcesContent":["import type { NitroConfig, NitroEventHandler, RollupConfig } from 'nitro/types';\nimport { build, createDevServer, createNitro } from 'nitro/builder';\nimport * as vite from 'vite';\nimport type { Plugin, UserConfig, ViteDevServer } from 'vite';\nimport { mergeConfig, normalizePath } from 'vite';\nimport { relative, resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { existsSync, readFileSync, readdirSync } from 'node:fs';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\n\nimport { buildServer, isVercelPreset } from './build-server.js';\nimport { buildClientApp, buildSSRApp } from './build-ssr.js';\nimport {\n Options,\n PrerenderContentDir,\n PrerenderContentFile,\n PrerenderRouteConfig,\n PrerenderSitemapConfig,\n} from './options.js';\nimport { pageEndpointsPlugin } from './plugins/page-endpoints.js';\nimport { getPageHandlers } from './utils/get-page-handlers.js';\nimport { buildSitemap } from './build-sitemap.js';\nimport { devServerPlugin } from './plugins/dev-server-plugin.js';\nimport {\n toWebRequest,\n writeWebResponseToNode,\n} from './utils/node-web-bridge.js';\nimport { getMatchingContentFilesWithFrontMatter } from './utils/get-content-files.js';\nimport {\n ssrRenderer,\n clientRenderer,\n apiMiddleware,\n} from './utils/renderers.js';\nimport { getBundleOptionsKey, isRolldown } from './utils/rolldown.js';\n\nfunction createNitroMiddlewareHandler(handler: string): NitroEventHandler {\n return {\n route: '/**',\n handler,\n middleware: true,\n };\n}\n\n/**\n * Creates a `rollup:before` hook that marks specified packages as external\n * in Nitro's bundler config (applied to both the server build and the\n * prerender build).\n *\n * ## Subpath matching (Rolldown compatibility)\n *\n * When `bundlerConfig.external` is an **array**, Rollup automatically\n * prefix-matches entries — `'rxjs'` in the array will also externalise\n * `'rxjs/operators'`, `'rxjs/internal/Observable'`, etc.\n *\n * Rolldown (the default bundler in Nitro v3) does **not** do this. It\n * treats array entries as exact strings. To keep behaviour consistent\n * across both bundlers, the **function** branch already needed explicit\n * subpath matching. We now use the same `isExternal` helper for all\n * branches so that `'rxjs'` reliably matches `'rxjs/operators'`\n * regardless of whether the existing `external` value is a function,\n * array, or absent.\n *\n * Without this, the Nitro prerender build fails on Windows CI with:\n *\n * [RESOLVE_ERROR] Could not resolve 'rxjs/operators'\n */\nfunction createRollupBeforeHook(externalEntries: string[]) {\n const isExternal = (source: string) =>\n externalEntries.some(\n (entry) => source === entry || source.startsWith(entry + '/'),\n );\n\n return (_nitro: unknown, bundlerConfig: RollupConfig) => {\n sanitizeNitroBundlerConfig(_nitro, bundlerConfig);\n\n if (externalEntries.length === 0) {\n return;\n }\n\n const existing = bundlerConfig.external;\n if (!existing) {\n bundlerConfig.external = externalEntries;\n } else if (typeof existing === 'function') {\n bundlerConfig.external = (\n source: string,\n importer: string | undefined,\n isResolved: boolean,\n ) => existing(source, importer, isResolved) || isExternal(source);\n } else if (Array.isArray(existing)) {\n bundlerConfig.external = [...existing, ...externalEntries];\n } else {\n bundlerConfig.external = [existing as string, ...externalEntries];\n }\n };\n}\n\nfunction appendNoExternals(\n noExternals: NitroConfig['noExternals'],\n ...entries: string[]\n): NitroConfig['noExternals'] {\n if (!noExternals) {\n return entries;\n }\n\n return Array.isArray(noExternals)\n ? [...noExternals, ...entries]\n : noExternals;\n}\n\n/**\n * Patches Nitro's internal Rollup/Rolldown bundler config to work around\n * incompatibilities in the Nitro v3 alpha series.\n *\n * Called from the `rollup:before` hook, this function runs against the *final*\n * bundler config that Nitro assembles for its server/prerender builds — it\n * does NOT touch the normal Vite client or SSR environment configs.\n *\n * Each workaround is narrowly scoped and safe to remove once the corresponding\n * upstream Nitro issue is resolved.\n */\nfunction sanitizeNitroBundlerConfig(\n _nitro: unknown,\n bundlerConfig: RollupConfig,\n) {\n const output = bundlerConfig['output'];\n if (!output || Array.isArray(output) || typeof output !== 'object') {\n return;\n }\n\n // ── 1. Remove invalid `output.codeSplitting` ────────────────────────\n //\n // Nitro 3.0.1-alpha.2 adds `output.codeSplitting` to its internal bundler\n // config, but Rolldown rejects it as an unknown key:\n //\n // Warning: Invalid output options (1 issue found)\n // - For the \"codeSplitting\". Invalid key: Expected never but received \"codeSplitting\".\n //\n // Analog never sets this option. Removing it restores default bundler\n // behavior without changing any Analog semantics.\n if ('codeSplitting' in output) {\n delete (output as Record<string, unknown>)['codeSplitting'];\n }\n\n // ── 2. Remove invalid `output.manualChunks` ─────────────────────────\n //\n // Nitro's default config enables manual chunking for node_modules. Under\n // Nitro v3 alpha + Rollup 4.59 this crashes during the prerender rebundle:\n //\n // Cannot read properties of undefined (reading 'included')\n //\n // A single server bundle is acceptable for Analog's use case, so we strip\n // `manualChunks` until the upstream bug is fixed.\n if ('manualChunks' in output) {\n delete (output as Record<string, unknown>)['manualChunks'];\n }\n\n // ── 3. Escape route params in `output.chunkFileNames` ───────────────\n //\n // Nitro's `getChunkName()` derives chunk filenames from route patterns,\n // using its internal `routeToFsPath()` helper to convert route params\n // (`:productId` → `[productId]`) and catch-alls (`**` → `[...]`).\n //\n // Rollup/Rolldown interprets *any* `[token]` in the string returned by a\n // `chunkFileNames` function as a placeholder. Only a handful are valid —\n // `[name]`, `[hash]`, `[format]`, `[ext]` — so route-derived tokens like\n // `[productId]` or `[...]` trigger a build error:\n //\n // \"[productId]\" is not a valid placeholder in the \"output.chunkFileNames\" pattern.\n //\n // We wrap the original function to replace non-standard `[token]` patterns\n // with `_token_`, preserving the intended filename while avoiding the\n // placeholder validation error.\n //\n // Example: `_routes/products/[productId].mjs` → `_routes/products/_productId_.mjs`\n const VALID_ROLLUP_PLACEHOLDER = /^\\[(?:name|hash|format|ext)\\]$/;\n const chunkFileNames = (output as Record<string, unknown>)['chunkFileNames'];\n if (typeof chunkFileNames === 'function') {\n const originalFn = chunkFileNames as (...args: unknown[]) => unknown;\n (output as Record<string, unknown>)['chunkFileNames'] = (\n ...args: unknown[]\n ) => {\n const result = originalFn(...args);\n if (typeof result !== 'string') return result;\n return result.replace(/\\[[^\\]]+\\]/g, (match: string) =>\n VALID_ROLLUP_PLACEHOLDER.test(match)\n ? match\n : `_${match.slice(1, -1)}_`,\n );\n };\n }\n}\n\nfunction resolveClientOutputPath(\n cachedPath: string,\n workspaceRoot: string,\n rootDir: string,\n configuredOutDir: string | undefined,\n) {\n if (cachedPath) {\n debugLog('resolveClientOutputPath using cached path', () => ({\n cachedPath,\n workspaceRoot,\n rootDir,\n configuredOutDir,\n }));\n return cachedPath;\n }\n\n if (configuredOutDir) {\n const resolvedPath = normalizePath(\n resolve(workspaceRoot, rootDir, configuredOutDir),\n );\n debugLog('resolveClientOutputPath using configured build.outDir', () => ({\n workspaceRoot,\n rootDir,\n configuredOutDir,\n resolvedPath,\n }));\n return resolvedPath;\n }\n\n // When no explicit build.outDir is set, the environment build config defaults\n // to `<workspace>/dist/<root>/client` for the client build. The non-SSR\n // (client) and SSR paths must agree on this so that registerIndexHtmlVirtual()\n // and publicAssets read from the directory the client build actually wrote to.\n const resolvedPath = normalizePath(\n resolve(workspaceRoot, 'dist', rootDir, 'client'),\n );\n debugLog('resolveClientOutputPath using default dist client path', () => ({\n workspaceRoot,\n rootDir,\n configuredOutDir,\n resolvedPath,\n }));\n return resolvedPath;\n}\n\nfunction getEnvironmentBuildOutDir(environment: unknown): string | undefined {\n if (!environment || typeof environment !== 'object') {\n return undefined;\n }\n\n const environmentConfig = environment as {\n config?: {\n build?: {\n outDir?: string;\n };\n };\n build?: {\n outDir?: string;\n };\n };\n\n return (\n environmentConfig.config?.build?.outDir ?? environmentConfig.build?.outDir\n );\n}\n\nfunction resolveBuiltClientOutputPath(\n cachedPath: string,\n workspaceRoot: string,\n rootDir: string,\n configuredOutDir: string | undefined,\n environment?: unknown,\n) {\n const environmentOutDir = getEnvironmentBuildOutDir(environment);\n if (environmentOutDir) {\n const resolvedPath = normalizePath(\n resolve(workspaceRoot, rootDir, environmentOutDir),\n );\n debugLog('resolveBuiltClientOutputPath using environment outDir', () => ({\n cachedPath,\n workspaceRoot,\n rootDir,\n configuredOutDir,\n environmentOutDir,\n resolvedPath,\n }));\n return resolvedPath;\n }\n\n debugLog(\n 'resolveBuiltClientOutputPath falling back to shared resolver',\n () => ({\n cachedPath,\n workspaceRoot,\n rootDir,\n configuredOutDir,\n environmentOutDir,\n }),\n );\n return resolveClientOutputPath(\n cachedPath,\n workspaceRoot,\n rootDir,\n configuredOutDir,\n );\n}\n\nfunction getNitroPublicOutputDir(nitroConfig: NitroConfig): string {\n const publicDir = nitroConfig.output?.publicDir;\n if (!publicDir) {\n throw new Error(\n 'Nitro public output directory is required to build the sitemap.',\n );\n }\n\n return publicDir;\n}\n\nconst DEBUG_NAMESPACE = 'analog:vite-plugin-nitro';\n\nfunction escapeRegExp(value: string) {\n return value.replace(/[|\\\\{}()[\\]^$+?.*]/g, '\\\\$&');\n}\n\n// Keep DEBUG matching local to this package so CI can opt into verbose traces\n// with familiar patterns like `analog:*` without adding a runtime dependency.\nfunction isDebugEnabled(namespace: string) {\n const debugValue = process.env['DEBUG'];\n if (!debugValue) {\n return false;\n }\n\n return debugValue\n .split(/[\\s,]+/)\n .filter(Boolean)\n .some((pattern) => {\n const matcher = new RegExp(\n `^${escapeRegExp(pattern).replace(/\\\\\\*/g, '.*')}$`,\n );\n return matcher.test(namespace);\n });\n}\n\nfunction debugLog(\n label: string,\n details?: Record<string, unknown> | (() => Record<string, unknown>),\n) {\n if (!isDebugEnabled(DEBUG_NAMESPACE)) {\n return;\n }\n\n const resolvedDetails = typeof details === 'function' ? details() : details;\n if (resolvedDetails && Object.keys(resolvedDetails).length > 0) {\n console.log(`DEBUG: ${label}`, resolvedDetails);\n return;\n }\n\n console.log(`DEBUG: ${label}`);\n}\n\nfunction readDirectoryEntries(path: string): string[] {\n try {\n return readdirSync(path).sort();\n } catch (error) {\n return [\n `<<unable to read directory: ${error instanceof Error ? error.message : String(error)}>>`,\n ];\n }\n}\n\nfunction getPathDebugInfo(path: string) {\n return {\n rawPath: path,\n normalizedPath: normalizePath(path),\n exists: existsSync(path),\n entries: existsSync(path) ? readDirectoryEntries(path) : [],\n };\n}\n\nfunction assetSourceToString(source: string | Uint8Array) {\n return typeof source === 'string'\n ? source\n : Buffer.from(source).toString('utf8');\n}\n\nfunction captureClientIndexHtmlFromBundle(\n bundle: Record<\n string,\n {\n type?: string;\n fileName?: string;\n source?: string | Uint8Array;\n }\n >,\n hook: 'generateBundle' | 'writeBundle',\n) {\n const indexHtmlAsset = Object.values(bundle).find(\n (chunk) =>\n chunk.type === 'asset' &&\n chunk.fileName === 'index.html' &&\n typeof chunk.source !== 'undefined',\n );\n\n if (!indexHtmlAsset?.source) {\n debugLog(`client bundle did not expose index.html during ${hook}`, () => ({\n hook,\n bundleKeys: Object.keys(bundle).sort(),\n assetFileNames: Object.values(bundle)\n .filter((chunk) => chunk.type === 'asset')\n .map((chunk) => chunk.fileName)\n .filter(Boolean),\n }));\n return undefined;\n }\n\n const indexHtml = assetSourceToString(indexHtmlAsset.source);\n debugLog(`captured client bundle index.html asset during ${hook}`, () => ({\n hook,\n fileName: indexHtmlAsset.fileName,\n htmlLength: indexHtml.length,\n }));\n return indexHtml;\n}\n\n// Nitro only needs the HTML template string. Prefer the on-disk file when it\n// exists, but allow the captured client asset to cover build flows where the\n// client output directory disappears before Nitro assembles its virtual modules.\nfunction registerIndexHtmlVirtual(\n nitroConfig: NitroConfig,\n clientOutputPath: string,\n inlineIndexHtml?: string,\n) {\n const indexHtmlPath = resolve(clientOutputPath, 'index.html');\n debugLog('registerIndexHtmlVirtual inspecting client output', () => ({\n platform: process.platform,\n cwd: process.cwd(),\n clientOutputPath,\n clientOutputPathInfo: getPathDebugInfo(clientOutputPath),\n indexHtmlPath,\n indexHtmlExists: existsSync(indexHtmlPath),\n hasInlineIndexHtml: typeof inlineIndexHtml === 'string',\n }));\n if (!existsSync(indexHtmlPath) && typeof inlineIndexHtml !== 'string') {\n debugLog('registerIndexHtmlVirtual missing index.html', () => ({\n platform: process.platform,\n cwd: process.cwd(),\n clientOutputPath,\n clientOutputPathInfo: getPathDebugInfo(clientOutputPath),\n indexHtmlPath,\n hasInlineIndexHtml: typeof inlineIndexHtml === 'string',\n nitroOutput: nitroConfig.output,\n nitroPublicAssets: nitroConfig.publicAssets,\n }));\n throw new Error(\n `[analog] Client build output not found at ${indexHtmlPath}.\\n` +\n `Ensure the client environment build completed successfully before the server build.`,\n );\n }\n const indexHtml =\n typeof inlineIndexHtml === 'string'\n ? inlineIndexHtml\n : readFileSync(indexHtmlPath, 'utf8');\n debugLog('registerIndexHtmlVirtual using HTML template source', () => ({\n source:\n typeof inlineIndexHtml === 'string'\n ? 'captured client bundle asset'\n : 'client output index.html file',\n indexHtmlPath,\n }));\n nitroConfig.virtual = {\n ...nitroConfig.virtual,\n '#analog/index': `export default ${JSON.stringify(indexHtml)};`,\n };\n}\n\n/**\n * Converts the built SSR entry path into a specifier that Nitro's bundler\n * can resolve, including all relative `./assets/*` chunk imports inside\n * the entry.\n *\n * The returned path **must** be an absolute filesystem path with forward\n * slashes (e.g. `D:/a/analog/dist/apps/blog-app/ssr/main.server.js`).\n * This lets Rollup/Rolldown determine the entry's directory and resolve\n * sibling chunk imports like `./assets/core-DTazUigR.js` correctly.\n *\n * ## Why not pathToFileURL() on Windows?\n *\n * Earlier versions converted the path to a `file:///D:/a/...` URL on\n * Windows, which worked with Nitro v2 + Rollup. Nitro v3 switched its\n * default bundler to Rolldown, and Rolldown does **not** extract the\n * importer directory from `file://` URLs. This caused every relative\n * import inside the SSR entry to fail during the prerender build:\n *\n * [RESOLVE_ERROR] Could not resolve './assets/core-DTazUigR.js'\n * in ../../dist/apps/blog-app/ssr/main.server.js\n *\n * `normalizePath()` (from Vite) simply converts backslashes to forward\n * slashes, which both Rollup and Rolldown handle correctly on all\n * platforms.\n */\nfunction toNitroSsrEntrypointSpecifier(ssrEntryPath: string) {\n return normalizePath(ssrEntryPath);\n}\n\nfunction applySsrEntryAlias(\n nitroConfig: NitroConfig,\n options: Options | undefined,\n workspaceRoot: string,\n rootDir: string,\n): void {\n const ssrOutDir =\n options?.ssrBuildDir || resolve(workspaceRoot, 'dist', rootDir, 'ssr');\n if (options?.ssr || nitroConfig.prerender?.routes?.length) {\n const ssrEntryPath = resolveBuiltSsrEntryPath(ssrOutDir);\n const ssrEntry = toNitroSsrEntrypointSpecifier(ssrEntryPath);\n nitroConfig.alias = {\n ...nitroConfig.alias,\n '#analog/ssr': ssrEntry,\n };\n }\n}\n\nfunction resolveBuiltSsrEntryPath(ssrOutDir: string) {\n const candidatePaths = [\n resolve(ssrOutDir, 'main.server.mjs'),\n resolve(ssrOutDir, 'main.server.js'),\n resolve(ssrOutDir, 'main.server'),\n ];\n\n const ssrEntryPath = candidatePaths.find((candidatePath) =>\n existsSync(candidatePath),\n );\n\n if (!ssrEntryPath) {\n throw new Error(\n `Unable to locate the built SSR entry in \"${ssrOutDir}\". Expected one of: ${candidatePaths.join(\n ', ',\n )}`,\n );\n }\n\n return ssrEntryPath;\n}\n\nexport function nitro(options?: Options, nitroOptions?: NitroConfig): Plugin[] {\n const workspaceRoot = options?.workspaceRoot ?? process.cwd();\n const sourceRoot = options?.sourceRoot ?? 'src';\n let isTest = process.env['NODE_ENV'] === 'test' || !!process.env['VITEST'];\n const baseURL = process.env['NITRO_APP_BASE_URL'] || '';\n const prefix = baseURL ? baseURL.substring(0, baseURL.length - 1) : '';\n const apiPrefix = `/${options?.apiPrefix || 'api'}`;\n const useAPIMiddleware =\n typeof options?.useAPIMiddleware !== 'undefined'\n ? options?.useAPIMiddleware\n : true;\n const viteRolldownOutput = options?.vite?.build?.rolldownOptions?.output;\n // Vite's native build typing allows `output` to be either a single object or\n // an array. Analog only forwards `codeSplitting` into the client environment\n // when there is a single output object to merge into.\n const viteRolldownOutputConfig =\n viteRolldownOutput && !Array.isArray(viteRolldownOutput)\n ? viteRolldownOutput\n : undefined;\n const codeSplitting = viteRolldownOutputConfig?.codeSplitting;\n\n let isBuild = false;\n let isServe = false;\n let ssrBuild = false;\n let config: UserConfig;\n let nitroConfig: NitroConfig;\n let environmentBuild = false;\n let hasAPIDir = false;\n let clientOutputPath = '';\n let clientIndexHtml: string | undefined;\n let legacyClientSubBuild = false;\n const rollupExternalEntries: string[] = [];\n const sitemapRoutes: string[] = [];\n const routeSitemaps: Record<\n string,\n PrerenderSitemapConfig | (() => PrerenderSitemapConfig)\n > = {};\n const routeSourceFiles: Record<string, string> = {};\n let rootDir = workspaceRoot;\n\n return [\n (options?.ssr\n ? devServerPlugin({\n entryServer: options?.entryServer,\n index: options?.index,\n routeRules: nitroOptions?.routeRules,\n })\n : false) as Plugin,\n {\n name: '@analogjs/vite-plugin-nitro',\n async config(userConfig, { mode, command }) {\n isServe = command === 'serve';\n isBuild = command === 'build';\n ssrBuild = userConfig.build?.ssr === true;\n config = userConfig;\n isTest = isTest ? isTest : mode === 'test';\n rollupExternalEntries.length = 0;\n clientIndexHtml = undefined;\n sitemapRoutes.length = 0;\n for (const key of Object.keys(routeSitemaps)) {\n delete routeSitemaps[key];\n }\n for (const key of Object.keys(routeSourceFiles)) {\n delete routeSourceFiles[key];\n }\n\n const resolvedConfigRoot = config.root\n ? resolve(workspaceRoot, config.root)\n : workspaceRoot;\n rootDir = relative(workspaceRoot, resolvedConfigRoot) || '.';\n hasAPIDir = existsSync(\n resolve(\n workspaceRoot,\n rootDir,\n `${sourceRoot}/server/routes/${options?.apiPrefix || 'api'}`,\n ),\n );\n const buildPreset =\n process.env['BUILD_PRESET'] ??\n (nitroOptions?.preset as string | undefined) ??\n (process.env['VERCEL'] ? 'vercel' : undefined);\n\n const pageHandlers = getPageHandlers({\n workspaceRoot,\n sourceRoot,\n rootDir,\n additionalPagesDirs: options?.additionalPagesDirs,\n hasAPIDir,\n });\n const resolvedClientOutputPath = resolveClientOutputPath(\n clientOutputPath,\n workspaceRoot,\n rootDir,\n config.build?.outDir,\n );\n debugLog('nitro config resolved client output path', () => ({\n platform: process.platform,\n workspaceRoot,\n configRoot: config.root,\n resolvedConfigRoot,\n rootDir,\n buildOutDir: config.build?.outDir,\n clientOutputPath,\n resolvedClientOutputPath,\n hasEnvironmentConfig: !!config.environments,\n clientEnvironmentOutDir:\n config.environments?.['client'] &&\n typeof config.environments['client'] === 'object' &&\n 'build' in config.environments['client']\n ? (\n config.environments['client'] as {\n build?: { outDir?: string };\n }\n ).build?.outDir\n : undefined,\n }));\n\n nitroConfig = {\n rootDir: normalizePath(rootDir),\n preset: buildPreset,\n compatibilityDate: '2025-11-19',\n logLevel: nitroOptions?.logLevel || 0,\n serverDir: normalizePath(`${sourceRoot}/server`),\n scanDirs: [\n normalizePath(`${rootDir}/${sourceRoot}/server`),\n ...(options?.additionalAPIDirs || []).map((dir) =>\n normalizePath(`${workspaceRoot}${dir}`),\n ),\n ],\n output: {\n dir: normalizePath(\n resolve(workspaceRoot, 'dist', rootDir, 'analog'),\n ),\n publicDir: normalizePath(\n resolve(workspaceRoot, 'dist', rootDir, 'analog/public'),\n ),\n },\n buildDir: normalizePath(\n resolve(workspaceRoot, 'dist', rootDir, '.nitro'),\n ),\n typescript: {\n generateTsConfig: false,\n },\n runtimeConfig: {\n apiPrefix: apiPrefix.substring(1),\n prefix,\n },\n // Analog provides its own renderer handler; prevent Nitro v3 from\n // auto-detecting index.html in rootDir and adding a conflicting one.\n renderer: false,\n imports: {\n autoImport: false,\n },\n hooks: {\n 'rollup:before': createRollupBeforeHook(rollupExternalEntries),\n },\n rollupConfig: {\n onwarn(warning) {\n if (\n warning.message.includes('empty chunk') &&\n warning.message.endsWith('.server')\n ) {\n return;\n }\n },\n plugins: [pageEndpointsPlugin()],\n },\n handlers: [\n ...(hasAPIDir\n ? []\n : useAPIMiddleware\n ? [createNitroMiddlewareHandler('#ANALOG_API_MIDDLEWARE')]\n : []),\n ...pageHandlers,\n ],\n routeRules: hasAPIDir\n ? undefined\n : useAPIMiddleware\n ? undefined\n : {\n [`${prefix}${apiPrefix}/**`]: {\n proxy: { to: '/**' },\n },\n },\n virtual: {\n '#ANALOG_SSR_RENDERER': ssrRenderer(),\n '#ANALOG_CLIENT_RENDERER': clientRenderer(),\n ...(hasAPIDir ? {} : { '#ANALOG_API_MIDDLEWARE': apiMiddleware }),\n },\n };\n\n if (isVercelPreset(buildPreset)) {\n nitroConfig = withVercelOutputAPI(nitroConfig, workspaceRoot);\n }\n\n if (isCloudflarePreset(buildPreset)) {\n nitroConfig = withCloudflareOutput(nitroConfig);\n }\n\n if (\n isNetlifyPreset(buildPreset) &&\n rootDir === '.' &&\n !existsSync(resolve(workspaceRoot, 'netlify.toml'))\n ) {\n nitroConfig = withNetlifyOutputAPI(nitroConfig, workspaceRoot);\n }\n\n if (isFirebaseAppHosting()) {\n nitroConfig = withAppHostingOutput(nitroConfig);\n }\n\n if (!ssrBuild && !isTest) {\n // store the client output path for the SSR build config\n clientOutputPath = resolvedClientOutputPath;\n debugLog(\n 'nitro config cached client output path for later SSR/Nitro build',\n () => ({\n ssrBuild,\n isTest,\n clientOutputPath,\n }),\n );\n }\n\n // Start with a clean alias map. #analog/index is registered as a Nitro\n // virtual module after the client build, inlining the HTML template so\n // the server bundle imports it instead of using readFileSync with an\n // absolute path.\n nitroConfig.alias = {};\n\n if (isBuild) {\n nitroConfig.publicAssets = [\n { dir: normalizePath(resolvedClientOutputPath), maxAge: 0 },\n ];\n\n // In Nitro v3, renderer.entry is resolved via resolveModulePath()\n // during options normalization, which requires a real filesystem path.\n // Virtual modules (prefixed with #) can't survive this resolution.\n // Instead, we add the renderer as a catch-all handler directly —\n // this is functionally equivalent to what Nitro does internally\n // (it converts renderer.entry into a { route: '/**', lazy: true }\n // handler), but avoids the filesystem resolution step.\n const rendererHandler = options?.ssr\n ? '#ANALOG_SSR_RENDERER'\n : '#ANALOG_CLIENT_RENDERER';\n nitroConfig.handlers = [\n ...(nitroConfig.handlers || []),\n {\n handler: rendererHandler,\n route: '/**',\n lazy: true,\n },\n ];\n\n if (isEmptyPrerenderRoutes(options)) {\n nitroConfig.prerender = {};\n nitroConfig.prerender.routes = ['/'];\n }\n\n if (options?.prerender) {\n nitroConfig.prerender = nitroConfig.prerender ?? {};\n nitroConfig.prerender.crawlLinks = options?.prerender?.discover;\n\n let routes: (\n | string\n | PrerenderContentDir\n | PrerenderRouteConfig\n | undefined\n )[] = [];\n\n const prerenderRoutes = options?.prerender?.routes;\n const hasExplicitPrerenderRoutes =\n typeof prerenderRoutes === 'function' ||\n Array.isArray(prerenderRoutes);\n if (\n isArrayWithElements<string | PrerenderContentDir>(prerenderRoutes)\n ) {\n routes = prerenderRoutes;\n } else if (typeof prerenderRoutes === 'function') {\n routes = await prerenderRoutes();\n }\n\n const resolvedPrerenderRoutes = routes.reduce<string[]>(\n (prev, current) => {\n if (!current) {\n return prev;\n }\n if (typeof current === 'string') {\n prev.push(current);\n sitemapRoutes.push(current);\n return prev;\n }\n\n if ('route' in current) {\n if (current.sitemap) {\n routeSitemaps[current.route] = current.sitemap;\n }\n\n if (current.outputSourceFile) {\n const sourcePath = resolve(\n workspaceRoot,\n rootDir,\n current.outputSourceFile,\n );\n routeSourceFiles[current.route] = readFileSync(\n sourcePath,\n 'utf8',\n );\n }\n\n prev.push(current.route);\n sitemapRoutes.push(current.route);\n\n // Add the server-side data fetching endpoint URL\n if ('staticData' in current) {\n prev.push(`${apiPrefix}/_analog/pages/${current.route}`);\n }\n\n return prev;\n }\n\n const affectedFiles: PrerenderContentFile[] =\n getMatchingContentFilesWithFrontMatter(\n workspaceRoot,\n rootDir,\n current.contentDir,\n );\n\n affectedFiles.forEach((f) => {\n const result = current.transform(f);\n\n if (result) {\n if (current.sitemap) {\n routeSitemaps[result] =\n current.sitemap && typeof current.sitemap === 'function'\n ? current.sitemap?.(f)\n : current.sitemap;\n }\n\n if (current.outputSourceFile) {\n const sourceContent = current.outputSourceFile(f);\n if (sourceContent) {\n routeSourceFiles[result] = sourceContent;\n }\n }\n\n prev.push(result);\n sitemapRoutes.push(result);\n\n // Add the server-side data fetching endpoint URL\n if ('staticData' in current) {\n prev.push(`${apiPrefix}/_analog/pages/${result}`);\n }\n }\n });\n\n return prev;\n },\n [],\n );\n\n nitroConfig.prerender.routes =\n hasExplicitPrerenderRoutes || resolvedPrerenderRoutes.length\n ? resolvedPrerenderRoutes\n : (nitroConfig.prerender.routes ?? []);\n }\n\n // ── SSR / prerender Nitro config ─────────────────────────────\n //\n // This block configures Nitro for builds that rebundle the SSR\n // entry (main.server.{js,mjs}). That happens in two cases:\n //\n // 1. Full SSR apps — `options.ssr === true`\n // 2. Prerender-only — no runtime SSR, but the prerender build\n // still imports the SSR entry to render static pages.\n //\n // The original gate was `if (ssrBuild)`, which checks the Vite\n // top-level `build.ssr` flag. That works for SSR-only builds but\n // misses two Vite 6+ paths:\n //\n // a. **Vite Environment API (Vite 6+)** — SSR config lives in\n // `environments.ssr.build.ssr`, not `build.ssr`, so\n // `ssrBuild` is always `false`.\n // b. **Prerender-only apps** (e.g. blog-app) — `options.ssr`\n // is `false`, but prerender routes exist and the prerender\n // build still processes the SSR entry.\n //\n // Without this block:\n // - `rxjs` is never externalised → RESOLVE_ERROR in the\n // Nitro prerender build (especially on Windows CI).\n // - `moduleSideEffects` for zone.js is never set → zone.js\n // side-effects may be tree-shaken.\n // - The handlers list is not reassembled with page endpoints\n // + the renderer catch-all.\n //\n // The widened condition covers all supported build paths:\n // - `ssrBuild` → SSR-only build\n // - `options?.ssr` → Environment API SSR\n // - `nitroConfig.prerender?.routes?.length` → prerender-only\n if (\n ssrBuild ||\n options?.ssr ||\n nitroConfig.prerender?.routes?.length\n ) {\n if (process.platform === 'win32') {\n nitroConfig.noExternals = appendNoExternals(\n nitroConfig.noExternals,\n 'std-env',\n );\n }\n\n rollupExternalEntries.push(\n 'rxjs',\n 'node-fetch-native/dist/polyfill',\n // sharp is a native module with platform-specific binaries\n // (e.g. @img/sharp-darwin-arm64). pnpm creates symlinks for\n // ALL optional platform deps but only installs the matching\n // one — leaving broken symlinks that crash Nitro's bundler\n // with ENOENT during realpath(). Externalizing sharp avoids\n // bundling it entirely; it resolves from node_modules at\n // runtime instead.\n 'sharp',\n );\n\n nitroConfig = {\n ...nitroConfig,\n moduleSideEffects: ['zone.js/node', 'zone.js/fesm2015/zone-node'],\n handlers: [\n ...(hasAPIDir\n ? []\n : useAPIMiddleware\n ? [createNitroMiddlewareHandler('#ANALOG_API_MIDDLEWARE')]\n : []),\n ...pageHandlers,\n // Preserve the renderer catch-all handler added above\n {\n handler: rendererHandler,\n route: '/**',\n lazy: true,\n },\n ],\n };\n }\n }\n\n nitroConfig = mergeConfig(\n nitroConfig,\n nitroOptions as Record<string, any>,\n );\n\n // Only configure Vite 8 environments + builder on the top-level\n // build invocation. When buildApp's builder.build() calls re-enter\n // the config hook, returning environments/builder again would create\n // recursive buildApp invocations — each nesting another client build\n // that re-triggers config, producing an infinite loop of\n // \"building client environment... ✓ 1 modules transformed\".\n //\n // environmentBuild — already inside a buildApp call (recursion guard)\n // ssrBuild — legacy SSR-only sub-build\n // isServe — dev server / Vitest test runner (command: 'serve')\n if (environmentBuild || ssrBuild || isServe) {\n return {};\n }\n\n return {\n environments: {\n client: {\n build: {\n outDir:\n config?.build?.outDir ||\n resolve(workspaceRoot, 'dist', rootDir, 'client'),\n emptyOutDir: true,\n // Forward code-splitting config to Rolldown when running\n // under Vite 8+. `false` disables splitting (inlines all\n // dynamic imports); an object configures chunk groups.\n // The `!== undefined` check ensures `codeSplitting: false`\n // is forwarded correctly (a truthy check would swallow it).\n ...(isRolldown() && codeSplitting !== undefined\n ? {\n rolldownOptions: {\n output: {\n // Preserve any sibling Rolldown output options while\n // overriding just `codeSplitting` for the client build.\n ...viteRolldownOutputConfig,\n codeSplitting,\n },\n },\n }\n : {}),\n },\n },\n ssr: {\n build: {\n ssr: true,\n [getBundleOptionsKey()]: {\n input:\n options?.entryServer ||\n resolve(\n workspaceRoot,\n rootDir,\n `${sourceRoot}/main.server.ts`,\n ),\n },\n outDir:\n options?.ssrBuildDir ||\n resolve(workspaceRoot, 'dist', rootDir, 'ssr'),\n // Preserve the client build output. The client environment is\n // built first and Nitro reads its index.html after SSR finishes.\n emptyOutDir: false,\n },\n },\n },\n builder: {\n sharedPlugins: true,\n buildApp: async (builder) => {\n environmentBuild = true;\n debugLog('builder.buildApp starting', () => ({\n platform: process.platform,\n workspaceRoot,\n rootDir,\n cachedClientOutputPath: clientOutputPath,\n configuredBuildOutDir: config.build?.outDir,\n clientEnvironmentOutDir: getEnvironmentBuildOutDir(\n builder.environments['client'],\n ),\n ssrEnvironmentOutDir: getEnvironmentBuildOutDir(\n builder.environments['ssr'],\n ),\n }));\n\n // Client must complete before SSR — the server build reads the\n // client's index.html via registerIndexHtmlVirtual(). Running\n // them in parallel caused a race on Windows where emptyOutDir\n // could delete client output before the server read it.\n await builder.build(builder.environments['client']);\n const postClientBuildOutputPath = resolveBuiltClientOutputPath(\n clientOutputPath,\n workspaceRoot,\n rootDir,\n config.build?.outDir,\n builder.environments['client'],\n );\n // Capture the client template before any SSR/prerender work runs.\n // On Windows, later phases can leave the client output directory\n // unavailable even though the client build itself succeeded.\n registerIndexHtmlVirtual(\n nitroConfig,\n postClientBuildOutputPath,\n clientIndexHtml,\n );\n debugLog('builder.buildApp completed client build', () => ({\n postClientBuildOutputPath,\n postClientBuildOutputInfo: getPathDebugInfo(\n postClientBuildOutputPath,\n ),\n postClientBuildIndexHtmlPath: resolve(\n postClientBuildOutputPath,\n 'index.html',\n ),\n postClientBuildIndexHtmlExists: existsSync(\n resolve(postClientBuildOutputPath, 'index.html'),\n ),\n }));\n\n if (options?.ssr || nitroConfig.prerender?.routes?.length) {\n debugLog('builder.buildApp starting SSR build', () => ({\n ssrEnabled: options?.ssr,\n prerenderRoutes: nitroConfig.prerender?.routes,\n }));\n await builder.build(builder.environments['ssr']);\n debugLog('builder.buildApp completed SSR build', () => ({\n ssrOutputPath:\n options?.ssrBuildDir ||\n resolve(workspaceRoot, 'dist', rootDir, 'ssr'),\n }));\n }\n\n applySsrEntryAlias(nitroConfig, options, workspaceRoot, rootDir);\n\n const resolvedClientOutputPath = resolveBuiltClientOutputPath(\n clientOutputPath,\n workspaceRoot,\n rootDir,\n config.build?.outDir,\n builder.environments['client'],\n );\n\n nitroConfig.publicAssets = [\n { dir: normalizePath(resolvedClientOutputPath), maxAge: 0 },\n ];\n debugLog(\n 'builder.buildApp resolved final client output path before Nitro build',\n () => ({\n resolvedClientOutputPath,\n resolvedClientOutputInfo: getPathDebugInfo(\n resolvedClientOutputPath,\n ),\n nitroPublicAssets: nitroConfig.publicAssets,\n }),\n );\n\n await buildServer(options, nitroConfig, routeSourceFiles);\n\n if (\n nitroConfig.prerender?.routes?.length &&\n options?.prerender?.sitemap\n ) {\n console.log('Building Sitemap...');\n // sitemap needs to be built after all directories are built\n await buildSitemap(\n config,\n options.prerender.sitemap,\n sitemapRoutes.length\n ? sitemapRoutes\n : nitroConfig.prerender.routes,\n getNitroPublicOutputDir(nitroConfig),\n routeSitemaps,\n { apiPrefix: options?.apiPrefix || 'api' },\n );\n }\n\n console.log(\n `\\n\\nThe '@analogjs/platform' server has been successfully built.`,\n );\n },\n },\n };\n },\n generateBundle(\n _options,\n bundle: Record<\n string,\n {\n type?: string;\n fileName?: string;\n source?: string | Uint8Array;\n }\n >,\n ) {\n if (!isBuild || ssrBuild) {\n return;\n }\n\n clientIndexHtml =\n captureClientIndexHtmlFromBundle(bundle, 'generateBundle') ??\n clientIndexHtml;\n },\n writeBundle(\n _options,\n bundle: Record<\n string,\n {\n type?: string;\n fileName?: string;\n source?: string | Uint8Array;\n }\n >,\n ) {\n if (!isBuild || ssrBuild) {\n return;\n }\n\n clientIndexHtml =\n captureClientIndexHtmlFromBundle(bundle, 'writeBundle') ??\n clientIndexHtml;\n },\n async configureServer(viteServer: ViteDevServer) {\n if (isServe && !isTest) {\n const nitro = await createNitro({\n dev: true,\n // Nitro's Vite builder now rejects `build()` in dev mode, but Analog's\n // dev integration still relies on the builder-driven reload hooks.\n // Force the server worker onto Rollup for this dev-only path.\n builder: 'rollup',\n ...nitroConfig,\n });\n const server = createDevServer(nitro);\n await build(nitro);\n const nitroSourceRoots = [\n normalizePath(\n resolve(workspaceRoot, rootDir, `${sourceRoot}/server`),\n ),\n ...(options?.additionalAPIDirs || []).map((dir) =>\n normalizePath(`${workspaceRoot}${dir}`),\n ),\n ];\n const isNitroSourceFile = (path: string) => {\n const normalizedPath = normalizePath(path);\n return nitroSourceRoots.some(\n (root) =>\n normalizedPath === root ||\n normalizedPath.startsWith(`${root}/`),\n );\n };\n let nitroRebuildPromise: Promise<void> | undefined;\n let nitroRebuildPending = false;\n const rebuildNitroServer = () => {\n if (nitroRebuildPromise) {\n // Coalesce rapid file events so a save that touches multiple server\n // route files results in one follow-up rebuild instead of many.\n nitroRebuildPending = true;\n return nitroRebuildPromise;\n }\n\n nitroRebuildPromise = (async () => {\n do {\n nitroRebuildPending = false;\n // Nitro API routes are not part of Vite's normal client HMR graph,\n // so rebuild the Nitro dev server to pick up handler edits.\n await build(nitro);\n } while (nitroRebuildPending);\n\n // Reload the page after the server rebuild completes so the next\n // request observes the updated API route implementation.\n viteServer.ws.send({ type: 'full-reload' });\n })()\n .catch((error: unknown) => {\n viteServer.config.logger.error(\n `[analog] Failed to rebuild Nitro dev server.\\n${error instanceof Error ? error.stack || error.message : String(error)}`,\n );\n })\n .finally(() => {\n nitroRebuildPromise = undefined;\n });\n\n return nitroRebuildPromise;\n };\n const onNitroSourceChange = (path: string) => {\n if (!isNitroSourceFile(path)) {\n return;\n }\n\n void rebuildNitroServer();\n };\n\n // Watch the full Nitro source roots instead of only the API route\n // directory. API handlers often read helper modules, shared data, or\n // middleware from elsewhere under `src/server`, and those edits should\n // still rebuild the Nitro dev server and refresh connected browsers.\n viteServer.watcher.on('add', onNitroSourceChange);\n viteServer.watcher.on('change', onNitroSourceChange);\n viteServer.watcher.on('unlink', onNitroSourceChange);\n\n const apiHandler = async (\n req: IncomingMessage,\n res: ServerResponse,\n ) => {\n // Nitro v3's dev server is fetch-first, so adapt Vite's Node\n // request once and let Nitro respond with a standard Web Response.\n const response = await server.fetch(toWebRequest(req));\n await writeWebResponseToNode(res, response);\n };\n\n if (hasAPIDir) {\n viteServer.middlewares.use(\n (\n req: IncomingMessage,\n res: ServerResponse,\n next: (error?: unknown) => void,\n ) => {\n if (req.url?.startsWith(`${prefix}${apiPrefix}`)) {\n void apiHandler(req, res).catch((error) => next(error));\n return;\n }\n\n next();\n },\n );\n } else {\n viteServer.middlewares.use(\n apiPrefix,\n (\n req: IncomingMessage,\n res: ServerResponse,\n next: (error?: unknown) => void,\n ) => {\n void apiHandler(req, res).catch((error) => next(error));\n },\n );\n }\n\n viteServer.httpServer?.once('listening', () => {\n process.env['ANALOG_HOST'] = !viteServer.config.server.host\n ? 'localhost'\n : (viteServer.config.server.host as string);\n process.env['ANALOG_PORT'] = `${viteServer.config.server.port}`;\n });\n\n // handle upgrades if websockets are enabled\n if (nitroOptions?.experimental?.websocket) {\n viteServer.httpServer?.on('upgrade', server.upgrade);\n }\n\n console.log(\n `\\n\\nThe server endpoints are accessible under the \"${prefix}${apiPrefix}\" path.`,\n );\n }\n },\n\n async closeBundle() {\n if (legacyClientSubBuild) {\n return;\n }\n\n // When builder.buildApp ran, it already handled the full\n // client → SSR → Nitro pipeline. Skip to avoid double work.\n if (environmentBuild) {\n return;\n }\n\n // SSR sub-build — Vite re-enters the plugin with build.ssr;\n // Nitro server assembly happens only after the client pass.\n if (ssrBuild) {\n return;\n }\n\n // Nx executors (and any caller that runs `vite build` without\n // the Environment API) never trigger builder.buildApp, so\n // closeBundle is the only place to drive the SSR + Nitro build.\n if (isBuild) {\n const resolvedClientOutputPath = resolveClientOutputPath(\n clientOutputPath,\n workspaceRoot,\n rootDir,\n config.build?.outDir,\n );\n debugLog(\n 'closeBundle resolved client output path before legacy SSR build',\n () => ({\n platform: process.platform,\n workspaceRoot,\n rootDir,\n cachedClientOutputPath: clientOutputPath,\n configuredBuildOutDir: config.build?.outDir,\n resolvedClientOutputPath,\n resolvedClientOutputInfo: getPathDebugInfo(\n resolvedClientOutputPath,\n ),\n }),\n );\n const indexHtmlPath = resolve(resolvedClientOutputPath, 'index.html');\n if (\n !existsSync(indexHtmlPath) &&\n typeof clientIndexHtml !== 'string'\n ) {\n debugLog(\n 'closeBundle rebuilding missing client output before SSR/Nitro',\n () => ({\n platform: process.platform,\n workspaceRoot,\n rootDir,\n configuredBuildOutDir: config.build?.outDir,\n resolvedClientOutputPath,\n indexHtmlPath,\n }),\n );\n legacyClientSubBuild = true;\n try {\n await buildClientApp(config, options);\n } finally {\n legacyClientSubBuild = false;\n }\n }\n // Capture the client HTML before kicking off the standalone SSR build.\n // This mirrors the successful sequencing from before the closeBundle\n // refactor and avoids depending on the client directory surviving the\n // nested SSR build on Windows.\n registerIndexHtmlVirtual(\n nitroConfig,\n resolvedClientOutputPath,\n clientIndexHtml,\n );\n\n if (options?.ssr) {\n console.log('Building SSR application...');\n await buildSSRApp(config, options);\n debugLog('closeBundle completed standalone SSR build', () => ({\n ssrBuildDir:\n options?.ssrBuildDir ||\n resolve(workspaceRoot, 'dist', rootDir, 'ssr'),\n clientOutputPathInfo: clientOutputPath\n ? getPathDebugInfo(clientOutputPath)\n : null,\n }));\n }\n\n applySsrEntryAlias(nitroConfig, options, workspaceRoot, rootDir);\n debugLog(\n 'closeBundle resolved client output path before Nitro build',\n () => ({\n platform: process.platform,\n workspaceRoot,\n rootDir,\n cachedClientOutputPath: clientOutputPath,\n configuredBuildOutDir: config.build?.outDir,\n resolvedClientOutputPath,\n resolvedClientOutputInfo: getPathDebugInfo(\n resolvedClientOutputPath,\n ),\n }),\n );\n registerIndexHtmlVirtual(\n nitroConfig,\n resolvedClientOutputPath,\n clientIndexHtml,\n );\n\n await buildServer(options, nitroConfig, routeSourceFiles);\n\n if (\n nitroConfig.prerender?.routes?.length &&\n options?.prerender?.sitemap\n ) {\n console.log('Building Sitemap...');\n await buildSitemap(\n config,\n options.prerender.sitemap,\n sitemapRoutes.length\n ? sitemapRoutes\n : nitroConfig.prerender.routes,\n getNitroPublicOutputDir(nitroConfig),\n routeSitemaps,\n { apiPrefix: options?.apiPrefix || 'api' },\n );\n }\n\n console.log(\n `\\n\\nThe '@analogjs/platform' server has been successfully built.`,\n );\n }\n },\n },\n {\n name: '@analogjs/vite-plugin-nitro-api-prefix',\n config() {\n return {\n define: {\n ANALOG_API_PREFIX: `\"${baseURL.substring(1)}${apiPrefix.substring(1)}\"`,\n },\n };\n },\n },\n ];\n}\n\nfunction isEmptyPrerenderRoutes(options?: Options): boolean {\n if (!options || isArrayWithElements(options?.prerender?.routes)) {\n return false;\n }\n return !options.prerender?.routes;\n}\n\nfunction isArrayWithElements<T>(arr: unknown): arr is [T, ...T[]] {\n return !!(Array.isArray(arr) && arr.length);\n}\n\nconst VERCEL_PRESET = 'vercel';\n// Nitro v3 consolidates the old `vercel-edge` preset into `vercel` with\n// fluid compute enabled by default, so a single preset covers both\n// serverless and edge deployments.\nconst withVercelOutputAPI = (\n nitroConfig: NitroConfig | undefined,\n workspaceRoot: string,\n) => ({\n ...nitroConfig,\n preset: nitroConfig?.preset ?? 'vercel',\n vercel: {\n ...nitroConfig?.vercel,\n entryFormat: nitroConfig?.vercel?.entryFormat ?? 'node',\n functions: {\n runtime: nitroConfig?.vercel?.functions?.runtime ?? 'nodejs24.x',\n ...nitroConfig?.vercel?.functions,\n },\n },\n output: {\n ...nitroConfig?.output,\n dir: normalizePath(resolve(workspaceRoot, '.vercel', 'output')),\n publicDir: normalizePath(\n resolve(workspaceRoot, '.vercel', 'output/static'),\n ),\n },\n});\n\n// Nitro v3 uses underscore-separated preset names (e.g. `cloudflare_pages`),\n// but we accept both hyphen and underscore forms for backwards compatibility.\nconst isCloudflarePreset = (buildPreset: string | undefined) =>\n process.env['CF_PAGES'] ||\n (buildPreset &&\n (buildPreset.toLowerCase().includes('cloudflare-pages') ||\n buildPreset.toLowerCase().includes('cloudflare_pages')));\n\nconst withCloudflareOutput = (nitroConfig: NitroConfig | undefined) => ({\n ...nitroConfig,\n output: {\n ...nitroConfig?.output,\n serverDir: '{{ output.publicDir }}/_worker.js',\n },\n});\n\nconst isFirebaseAppHosting = () => !!process.env['NG_BUILD_LOGS_JSON'];\nconst withAppHostingOutput = (nitroConfig: NitroConfig) => {\n let hasOutput = false;\n\n return <NitroConfig>{\n ...nitroConfig,\n serveStatic: true,\n rollupConfig: {\n ...nitroConfig.rollupConfig,\n output: {\n ...nitroConfig.rollupConfig?.output,\n entryFileNames: 'server.mjs',\n },\n },\n hooks: {\n ...nitroConfig.hooks,\n compiled: () => {\n if (!hasOutput) {\n const buildOutput = {\n errors: [],\n warnings: [],\n outputPaths: {\n root: pathToFileURL(`${nitroConfig.output?.dir}`),\n browser: pathToFileURL(`${nitroConfig.output?.publicDir}`),\n server: pathToFileURL(`${nitroConfig.output?.dir}/server`),\n },\n };\n\n // Log the build output for Firebase App Hosting to pick up\n console.log(JSON.stringify(buildOutput, null, 2));\n hasOutput = true;\n }\n },\n },\n };\n};\n\nconst isNetlifyPreset = (buildPreset: string | undefined) =>\n process.env['NETLIFY'] ||\n (buildPreset && buildPreset.toLowerCase().includes('netlify'));\n\nconst withNetlifyOutputAPI = (\n nitroConfig: NitroConfig | undefined,\n workspaceRoot: string,\n) => ({\n ...nitroConfig,\n output: {\n ...nitroConfig?.output,\n dir: normalizePath(resolve(workspaceRoot, 'netlify/functions')),\n },\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"vite-plugin-nitro.js","names":[],"sources":["../../../src/lib/vite-plugin-nitro.ts"],"sourcesContent":["import type { NitroConfig, NitroEventHandler, RollupConfig } from 'nitro/types';\nimport { build, createDevServer, createNitro } from 'nitro/builder';\nimport * as vite from 'vite';\nimport type { Plugin, UserConfig, ViteDevServer } from 'vite';\nimport { mergeConfig, normalizePath } from 'vite';\nimport { relative, resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { existsSync, readFileSync, readdirSync } from 'node:fs';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\n\nimport { buildServer, isVercelPreset } from './build-server.js';\nimport { buildClientApp, buildSSRApp } from './build-ssr.js';\nimport {\n Options,\n PrerenderContentDir,\n PrerenderContentFile,\n PrerenderRouteConfig,\n PrerenderSitemapConfig,\n} from './options.js';\nimport { pageEndpointsPlugin } from './plugins/page-endpoints.js';\nimport { getPageHandlers } from './utils/get-page-handlers.js';\nimport { buildSitemap } from './build-sitemap.js';\nimport { devServerPlugin } from './plugins/dev-server-plugin.js';\nimport {\n toWebRequest,\n writeWebResponseToNode,\n} from './utils/node-web-bridge.js';\nimport { getMatchingContentFilesWithFrontMatter } from './utils/get-content-files.js';\nimport {\n ssrRenderer,\n clientRenderer,\n apiMiddleware,\n} from './utils/renderers.js';\nimport { getBundleOptionsKey, isRolldown } from './utils/rolldown.js';\nimport { debugNitro, debugSsr } from './utils/debug.js';\n\nfunction createNitroMiddlewareHandler(handler: string): NitroEventHandler {\n return {\n route: '/**',\n handler,\n middleware: true,\n };\n}\n\n/**\n * Creates a `rollup:before` hook that marks specified packages as external\n * in Nitro's bundler config (applied to both the server build and the\n * prerender build).\n *\n * ## Subpath matching (Rolldown compatibility)\n *\n * When `bundlerConfig.external` is an **array**, Rollup automatically\n * prefix-matches entries — `'rxjs'` in the array will also externalise\n * `'rxjs/operators'`, `'rxjs/internal/Observable'`, etc.\n *\n * Rolldown (the default bundler in Nitro v3) does **not** do this. It\n * treats array entries as exact strings. To keep behaviour consistent\n * across both bundlers, the **function** branch already needed explicit\n * subpath matching. We now use the same `isExternal` helper for all\n * branches so that `'rxjs'` reliably matches `'rxjs/operators'`\n * regardless of whether the existing `external` value is a function,\n * array, or absent.\n *\n * Without this, the Nitro prerender build fails on Windows CI with:\n *\n * [RESOLVE_ERROR] Could not resolve 'rxjs/operators'\n */\nfunction createRollupBeforeHook(externalEntries: string[]) {\n const isExternal = (source: string) =>\n externalEntries.some(\n (entry) => source === entry || source.startsWith(entry + '/'),\n );\n\n return (_nitro: unknown, bundlerConfig: RollupConfig) => {\n sanitizeNitroBundlerConfig(_nitro, bundlerConfig);\n\n if (externalEntries.length === 0) {\n return;\n }\n\n const existing = bundlerConfig.external;\n if (!existing) {\n bundlerConfig.external = externalEntries;\n } else if (typeof existing === 'function') {\n bundlerConfig.external = (\n source: string,\n importer: string | undefined,\n isResolved: boolean,\n ) => existing(source, importer, isResolved) || isExternal(source);\n } else if (Array.isArray(existing)) {\n bundlerConfig.external = [...existing, ...externalEntries];\n } else {\n bundlerConfig.external = [existing as string, ...externalEntries];\n }\n };\n}\n\nfunction appendNoExternals(\n noExternals: NitroConfig['noExternals'],\n ...entries: string[]\n): NitroConfig['noExternals'] {\n if (!noExternals) {\n return entries;\n }\n\n return Array.isArray(noExternals)\n ? [...noExternals, ...entries]\n : noExternals;\n}\n\n/**\n * Patches Nitro's internal Rollup/Rolldown bundler config to work around\n * incompatibilities in the Nitro v3 alpha series.\n *\n * Called from the `rollup:before` hook, this function runs against the *final*\n * bundler config that Nitro assembles for its server/prerender builds — it\n * does NOT touch the normal Vite client or SSR environment configs.\n *\n * Each workaround is narrowly scoped and safe to remove once the corresponding\n * upstream Nitro issue is resolved.\n */\nfunction sanitizeNitroBundlerConfig(\n _nitro: unknown,\n bundlerConfig: RollupConfig,\n) {\n const output = bundlerConfig['output'];\n if (!output || Array.isArray(output) || typeof output !== 'object') {\n return;\n }\n\n // ── 1. Remove invalid `output.codeSplitting` ────────────────────────\n //\n // Nitro 3.0.1-alpha.2 adds `output.codeSplitting` to its internal bundler\n // config, but Rolldown rejects it as an unknown key:\n //\n // Warning: Invalid output options (1 issue found)\n // - For the \"codeSplitting\". Invalid key: Expected never but received \"codeSplitting\".\n //\n // Analog never sets this option. Removing it restores default bundler\n // behavior without changing any Analog semantics.\n if ('codeSplitting' in output) {\n delete (output as Record<string, unknown>)['codeSplitting'];\n }\n\n // ── 2. Remove invalid `output.manualChunks` ─────────────────────────\n //\n // Nitro's default config enables manual chunking for node_modules. Under\n // Nitro v3 alpha + Rollup 4.59 this crashes during the prerender rebundle:\n //\n // Cannot read properties of undefined (reading 'included')\n //\n // A single server bundle is acceptable for Analog's use case, so we strip\n // `manualChunks` until the upstream bug is fixed.\n if ('manualChunks' in output) {\n delete (output as Record<string, unknown>)['manualChunks'];\n }\n\n // ── 3. Escape route params in `output.chunkFileNames` ───────────────\n //\n // Nitro's `getChunkName()` derives chunk filenames from route patterns,\n // using its internal `routeToFsPath()` helper to convert route params\n // (`:productId` → `[productId]`) and catch-alls (`**` → `[...]`).\n //\n // Rollup/Rolldown interprets *any* `[token]` in the string returned by a\n // `chunkFileNames` function as a placeholder. Only a handful are valid —\n // `[name]`, `[hash]`, `[format]`, `[ext]` — so route-derived tokens like\n // `[productId]` or `[...]` trigger a build error:\n //\n // \"[productId]\" is not a valid placeholder in the \"output.chunkFileNames\" pattern.\n //\n // We wrap the original function to replace non-standard `[token]` patterns\n // with `_token_`, preserving the intended filename while avoiding the\n // placeholder validation error.\n //\n // Example: `_routes/products/[productId].mjs` → `_routes/products/_productId_.mjs`\n const VALID_ROLLUP_PLACEHOLDER = /^\\[(?:name|hash|format|ext)\\]$/;\n const chunkFileNames = (output as Record<string, unknown>)['chunkFileNames'];\n if (typeof chunkFileNames === 'function') {\n const originalFn = chunkFileNames as (...args: unknown[]) => unknown;\n (output as Record<string, unknown>)['chunkFileNames'] = (\n ...args: unknown[]\n ) => {\n const result = originalFn(...args);\n if (typeof result !== 'string') return result;\n return result.replace(/\\[[^\\]]+\\]/g, (match: string) =>\n VALID_ROLLUP_PLACEHOLDER.test(match)\n ? match\n : `_${match.slice(1, -1)}_`,\n );\n };\n }\n}\n\nfunction resolveClientOutputPath(\n cachedPath: string,\n workspaceRoot: string,\n rootDir: string,\n configuredOutDir: string | undefined,\n) {\n if (cachedPath) {\n debugNitro('resolveClientOutputPath using cached path', {\n cachedPath,\n workspaceRoot,\n rootDir,\n configuredOutDir,\n });\n return cachedPath;\n }\n\n if (configuredOutDir) {\n const resolvedPath = normalizePath(\n resolve(workspaceRoot, rootDir, configuredOutDir),\n );\n debugNitro('resolveClientOutputPath using configured build.outDir', {\n workspaceRoot,\n rootDir,\n configuredOutDir,\n resolvedPath,\n });\n return resolvedPath;\n }\n\n // When no explicit build.outDir is set, the environment build config defaults\n // to `<workspace>/dist/<root>/client` for the client build. The non-SSR\n // (client) and SSR paths must agree on this so that registerIndexHtmlVirtual()\n // and publicAssets read from the directory the client build actually wrote to.\n const resolvedPath = normalizePath(\n resolve(workspaceRoot, 'dist', rootDir, 'client'),\n );\n debugNitro('resolveClientOutputPath using default dist client path', {\n workspaceRoot,\n rootDir,\n configuredOutDir,\n resolvedPath,\n });\n return resolvedPath;\n}\n\nfunction getEnvironmentBuildOutDir(environment: unknown): string | undefined {\n if (!environment || typeof environment !== 'object') {\n return undefined;\n }\n\n const environmentConfig = environment as {\n config?: {\n build?: {\n outDir?: string;\n };\n };\n build?: {\n outDir?: string;\n };\n };\n\n return (\n environmentConfig.config?.build?.outDir ?? environmentConfig.build?.outDir\n );\n}\n\nfunction resolveBuiltClientOutputPath(\n cachedPath: string,\n workspaceRoot: string,\n rootDir: string,\n configuredOutDir: string | undefined,\n environment?: unknown,\n) {\n const environmentOutDir = getEnvironmentBuildOutDir(environment);\n if (environmentOutDir) {\n const resolvedPath = normalizePath(\n resolve(workspaceRoot, rootDir, environmentOutDir),\n );\n debugNitro('resolveBuiltClientOutputPath using environment outDir', {\n cachedPath,\n workspaceRoot,\n rootDir,\n configuredOutDir,\n environmentOutDir,\n resolvedPath,\n });\n return resolvedPath;\n }\n\n debugNitro('resolveBuiltClientOutputPath falling back to shared resolver', {\n cachedPath,\n workspaceRoot,\n rootDir,\n configuredOutDir,\n environmentOutDir,\n });\n return resolveClientOutputPath(\n cachedPath,\n workspaceRoot,\n rootDir,\n configuredOutDir,\n );\n}\n\nfunction getNitroPublicOutputDir(nitroConfig: NitroConfig): string {\n const publicDir = nitroConfig.output?.publicDir;\n if (!publicDir) {\n throw new Error(\n 'Nitro public output directory is required to build the sitemap.',\n );\n }\n\n return publicDir;\n}\n\nfunction readDirectoryEntries(path: string): string[] {\n try {\n return readdirSync(path).sort();\n } catch (error) {\n return [\n `<<unable to read directory: ${error instanceof Error ? error.message : String(error)}>>`,\n ];\n }\n}\n\nfunction getPathDebugInfo(path: string) {\n return {\n rawPath: path,\n normalizedPath: normalizePath(path),\n exists: existsSync(path),\n entries: existsSync(path) ? readDirectoryEntries(path) : [],\n };\n}\n\nfunction assetSourceToString(source: string | Uint8Array) {\n return typeof source === 'string'\n ? source\n : Buffer.from(source).toString('utf8');\n}\n\nfunction captureClientIndexHtmlFromBundle(\n bundle: Record<\n string,\n {\n type?: string;\n fileName?: string;\n source?: string | Uint8Array;\n }\n >,\n hook: 'generateBundle' | 'writeBundle',\n) {\n const indexHtmlAsset = Object.values(bundle).find(\n (chunk) =>\n chunk.type === 'asset' &&\n chunk.fileName === 'index.html' &&\n typeof chunk.source !== 'undefined',\n );\n\n if (!indexHtmlAsset?.source) {\n debugNitro(`client bundle did not expose index.html during ${hook}`, {\n hook,\n bundleKeys: Object.keys(bundle).sort(),\n assetFileNames: Object.values(bundle)\n .filter((chunk) => chunk.type === 'asset')\n .map((chunk) => chunk.fileName)\n .filter(Boolean),\n });\n return undefined;\n }\n\n const indexHtml = assetSourceToString(indexHtmlAsset.source);\n debugNitro(`captured client bundle index.html asset during ${hook}`, {\n hook,\n fileName: indexHtmlAsset.fileName,\n htmlLength: indexHtml.length,\n });\n return indexHtml;\n}\n\n// Nitro only needs the HTML template string. Prefer the on-disk file when it\n// exists, but allow the captured client asset to cover build flows where the\n// client output directory disappears before Nitro assembles its virtual modules.\nfunction registerIndexHtmlVirtual(\n nitroConfig: NitroConfig,\n clientOutputPath: string,\n inlineIndexHtml?: string,\n) {\n const indexHtmlPath = resolve(clientOutputPath, 'index.html');\n debugNitro('registerIndexHtmlVirtual inspecting client output', {\n platform: process.platform,\n cwd: process.cwd(),\n clientOutputPath,\n clientOutputPathInfo: getPathDebugInfo(clientOutputPath),\n indexHtmlPath,\n indexHtmlExists: existsSync(indexHtmlPath),\n hasInlineIndexHtml: typeof inlineIndexHtml === 'string',\n });\n if (!existsSync(indexHtmlPath) && typeof inlineIndexHtml !== 'string') {\n debugNitro('registerIndexHtmlVirtual missing index.html', {\n platform: process.platform,\n cwd: process.cwd(),\n clientOutputPath,\n clientOutputPathInfo: getPathDebugInfo(clientOutputPath),\n indexHtmlPath,\n hasInlineIndexHtml: typeof inlineIndexHtml === 'string',\n nitroOutput: nitroConfig.output,\n nitroPublicAssets: nitroConfig.publicAssets,\n });\n throw new Error(\n `[analog] Client build output not found at ${indexHtmlPath}.\\n` +\n `Ensure the client environment build completed successfully before the server build.`,\n );\n }\n const indexHtml =\n typeof inlineIndexHtml === 'string'\n ? inlineIndexHtml\n : readFileSync(indexHtmlPath, 'utf8');\n debugNitro('registerIndexHtmlVirtual using HTML template source', {\n source:\n typeof inlineIndexHtml === 'string'\n ? 'captured client bundle asset'\n : 'client output index.html file',\n indexHtmlPath,\n });\n nitroConfig.virtual = {\n ...nitroConfig.virtual,\n '#analog/index': `export default ${JSON.stringify(indexHtml)};`,\n };\n}\n\n/**\n * Converts the built SSR entry path into a specifier that Nitro's bundler\n * can resolve, including all relative `./assets/*` chunk imports inside\n * the entry.\n *\n * The returned path **must** be an absolute filesystem path with forward\n * slashes (e.g. `D:/a/analog/dist/apps/blog-app/ssr/main.server.js`).\n * This lets Rollup/Rolldown determine the entry's directory and resolve\n * sibling chunk imports like `./assets/core-DTazUigR.js` correctly.\n *\n * ## Why not pathToFileURL() on Windows?\n *\n * Earlier versions converted the path to a `file:///D:/a/...` URL on\n * Windows, which worked with Nitro v2 + Rollup. Nitro v3 switched its\n * default bundler to Rolldown, and Rolldown does **not** extract the\n * importer directory from `file://` URLs. This caused every relative\n * import inside the SSR entry to fail during the prerender build:\n *\n * [RESOLVE_ERROR] Could not resolve './assets/core-DTazUigR.js'\n * in ../../dist/apps/blog-app/ssr/main.server.js\n *\n * `normalizePath()` (from Vite) simply converts backslashes to forward\n * slashes, which both Rollup and Rolldown handle correctly on all\n * platforms.\n */\nfunction toNitroSsrEntrypointSpecifier(ssrEntryPath: string) {\n return normalizePath(ssrEntryPath);\n}\n\nfunction applySsrEntryAlias(\n nitroConfig: NitroConfig,\n options: Options | undefined,\n workspaceRoot: string,\n rootDir: string,\n): void {\n const ssrOutDir =\n options?.ssrBuildDir || resolve(workspaceRoot, 'dist', rootDir, 'ssr');\n if (options?.ssr || nitroConfig.prerender?.routes?.length) {\n const ssrEntryPath = resolveBuiltSsrEntryPath(ssrOutDir);\n const ssrEntry = toNitroSsrEntrypointSpecifier(ssrEntryPath);\n nitroConfig.alias = {\n ...nitroConfig.alias,\n '#analog/ssr': ssrEntry,\n };\n }\n}\n\nfunction resolveBuiltSsrEntryPath(ssrOutDir: string) {\n const candidatePaths = [\n resolve(ssrOutDir, 'main.server.mjs'),\n resolve(ssrOutDir, 'main.server.js'),\n resolve(ssrOutDir, 'main.server'),\n ];\n\n const ssrEntryPath = candidatePaths.find((candidatePath) =>\n existsSync(candidatePath),\n );\n\n if (!ssrEntryPath) {\n throw new Error(\n `Unable to locate the built SSR entry in \"${ssrOutDir}\". Expected one of: ${candidatePaths.join(\n ', ',\n )}`,\n );\n }\n\n return ssrEntryPath;\n}\n\nexport function nitro(options?: Options, nitroOptions?: NitroConfig): Plugin[] {\n const workspaceRoot = options?.workspaceRoot ?? process.cwd();\n const sourceRoot = options?.sourceRoot ?? 'src';\n let isTest = process.env['NODE_ENV'] === 'test' || !!process.env['VITEST'];\n const baseURL = process.env['NITRO_APP_BASE_URL'] || '';\n const prefix = baseURL ? baseURL.substring(0, baseURL.length - 1) : '';\n const apiPrefix = `/${options?.apiPrefix || 'api'}`;\n const useAPIMiddleware =\n typeof options?.useAPIMiddleware !== 'undefined'\n ? options?.useAPIMiddleware\n : true;\n const viteRolldownOutput = options?.vite?.build?.rolldownOptions?.output;\n // Vite's native build typing allows `output` to be either a single object or\n // an array. Analog only forwards `codeSplitting` into the client environment\n // when there is a single output object to merge into.\n const viteRolldownOutputConfig =\n viteRolldownOutput && !Array.isArray(viteRolldownOutput)\n ? viteRolldownOutput\n : undefined;\n const codeSplitting = viteRolldownOutputConfig?.codeSplitting;\n\n let isBuild = false;\n let isServe = false;\n let ssrBuild = false;\n let config: UserConfig;\n let nitroConfig: NitroConfig;\n let environmentBuild = false;\n let hasAPIDir = false;\n let clientOutputPath = '';\n let clientIndexHtml: string | undefined;\n let legacyClientSubBuild = false;\n const rollupExternalEntries: string[] = [];\n const sitemapRoutes: string[] = [];\n const routeSitemaps: Record<\n string,\n PrerenderSitemapConfig | (() => PrerenderSitemapConfig)\n > = {};\n const routeSourceFiles: Record<string, string> = {};\n let rootDir = workspaceRoot;\n\n return [\n (options?.ssr\n ? devServerPlugin({\n entryServer: options?.entryServer,\n index: options?.index,\n routeRules: nitroOptions?.routeRules,\n })\n : false) as Plugin,\n {\n name: '@analogjs/vite-plugin-nitro',\n async config(userConfig, { mode, command }) {\n isServe = command === 'serve';\n isBuild = command === 'build';\n ssrBuild = userConfig.build?.ssr === true;\n config = userConfig;\n isTest = isTest ? isTest : mode === 'test';\n rollupExternalEntries.length = 0;\n clientIndexHtml = undefined;\n sitemapRoutes.length = 0;\n for (const key of Object.keys(routeSitemaps)) {\n delete routeSitemaps[key];\n }\n for (const key of Object.keys(routeSourceFiles)) {\n delete routeSourceFiles[key];\n }\n\n const resolvedConfigRoot = config.root\n ? resolve(workspaceRoot, config.root)\n : workspaceRoot;\n rootDir = relative(workspaceRoot, resolvedConfigRoot) || '.';\n hasAPIDir = existsSync(\n resolve(\n workspaceRoot,\n rootDir,\n `${sourceRoot}/server/routes/${options?.apiPrefix || 'api'}`,\n ),\n );\n const buildPreset =\n process.env['BUILD_PRESET'] ??\n (nitroOptions?.preset as string | undefined) ??\n (process.env['VERCEL'] ? 'vercel' : undefined);\n\n const pageHandlers = getPageHandlers({\n workspaceRoot,\n sourceRoot,\n rootDir,\n additionalPagesDirs: options?.additionalPagesDirs,\n hasAPIDir,\n });\n const resolvedClientOutputPath = resolveClientOutputPath(\n clientOutputPath,\n workspaceRoot,\n rootDir,\n config.build?.outDir,\n );\n debugNitro('nitro config resolved client output path', {\n platform: process.platform,\n workspaceRoot,\n configRoot: config.root,\n resolvedConfigRoot,\n rootDir,\n buildOutDir: config.build?.outDir,\n clientOutputPath,\n resolvedClientOutputPath,\n hasEnvironmentConfig: !!config.environments,\n clientEnvironmentOutDir:\n config.environments?.['client'] &&\n typeof config.environments['client'] === 'object' &&\n 'build' in config.environments['client']\n ? (\n config.environments['client'] as {\n build?: { outDir?: string };\n }\n ).build?.outDir\n : undefined,\n });\n\n nitroConfig = {\n rootDir: normalizePath(rootDir),\n preset: buildPreset,\n compatibilityDate: '2025-11-19',\n logLevel: nitroOptions?.logLevel || 0,\n serverDir: normalizePath(`${sourceRoot}/server`),\n scanDirs: [\n normalizePath(`${rootDir}/${sourceRoot}/server`),\n ...(options?.additionalAPIDirs || []).map((dir) =>\n normalizePath(`${workspaceRoot}${dir}`),\n ),\n ],\n output: {\n dir: normalizePath(\n resolve(workspaceRoot, 'dist', rootDir, 'analog'),\n ),\n publicDir: normalizePath(\n resolve(workspaceRoot, 'dist', rootDir, 'analog/public'),\n ),\n },\n buildDir: normalizePath(\n resolve(workspaceRoot, 'dist', rootDir, '.nitro'),\n ),\n typescript: {\n generateTsConfig: false,\n },\n runtimeConfig: {\n apiPrefix: apiPrefix.substring(1),\n prefix,\n },\n // Analog provides its own renderer handler; prevent Nitro v3 from\n // auto-detecting index.html in rootDir and adding a conflicting one.\n renderer: false,\n imports: {\n autoImport: false,\n },\n hooks: {\n 'rollup:before': createRollupBeforeHook(rollupExternalEntries),\n },\n rollupConfig: {\n onwarn(warning) {\n if (\n warning.message.includes('empty chunk') &&\n warning.message.endsWith('.server')\n ) {\n return;\n }\n },\n plugins: [pageEndpointsPlugin()],\n },\n handlers: [\n ...(hasAPIDir\n ? []\n : useAPIMiddleware\n ? [createNitroMiddlewareHandler('#ANALOG_API_MIDDLEWARE')]\n : []),\n ...pageHandlers,\n ],\n routeRules: hasAPIDir\n ? undefined\n : useAPIMiddleware\n ? undefined\n : {\n [`${prefix}${apiPrefix}/**`]: {\n proxy: { to: '/**' },\n },\n },\n virtual: {\n '#ANALOG_SSR_RENDERER': ssrRenderer(),\n '#ANALOG_CLIENT_RENDERER': clientRenderer(),\n ...(hasAPIDir ? {} : { '#ANALOG_API_MIDDLEWARE': apiMiddleware }),\n },\n };\n\n if (isVercelPreset(buildPreset)) {\n nitroConfig = withVercelOutputAPI(nitroConfig, workspaceRoot);\n }\n\n if (isCloudflarePreset(buildPreset)) {\n nitroConfig = withCloudflareOutput(nitroConfig);\n }\n\n if (\n isNetlifyPreset(buildPreset) &&\n rootDir === '.' &&\n !existsSync(resolve(workspaceRoot, 'netlify.toml'))\n ) {\n nitroConfig = withNetlifyOutputAPI(nitroConfig, workspaceRoot);\n }\n\n if (isFirebaseAppHosting()) {\n nitroConfig = withAppHostingOutput(nitroConfig);\n }\n\n if (!ssrBuild && !isTest) {\n // store the client output path for the SSR build config\n clientOutputPath = resolvedClientOutputPath;\n debugNitro(\n 'nitro config cached client output path for later SSR/Nitro build',\n {\n ssrBuild,\n isTest,\n clientOutputPath,\n },\n );\n }\n\n // Start with a clean alias map. #analog/index is registered as a Nitro\n // virtual module after the client build, inlining the HTML template so\n // the server bundle imports it instead of using readFileSync with an\n // absolute path.\n nitroConfig.alias = {};\n\n if (isBuild) {\n nitroConfig.publicAssets = [\n { dir: normalizePath(resolvedClientOutputPath), maxAge: 0 },\n ];\n\n // In Nitro v3, renderer.entry is resolved via resolveModulePath()\n // during options normalization, which requires a real filesystem path.\n // Virtual modules (prefixed with #) can't survive this resolution.\n // Instead, we add the renderer as a catch-all handler directly —\n // this is functionally equivalent to what Nitro does internally\n // (it converts renderer.entry into a { route: '/**', lazy: true }\n // handler), but avoids the filesystem resolution step.\n const rendererHandler = options?.ssr\n ? '#ANALOG_SSR_RENDERER'\n : '#ANALOG_CLIENT_RENDERER';\n nitroConfig.handlers = [\n ...(nitroConfig.handlers || []),\n {\n handler: rendererHandler,\n route: '/**',\n lazy: true,\n },\n ];\n\n if (isEmptyPrerenderRoutes(options)) {\n nitroConfig.prerender = {};\n nitroConfig.prerender.routes = ['/'];\n }\n\n if (options?.prerender) {\n nitroConfig.prerender = nitroConfig.prerender ?? {};\n nitroConfig.prerender.crawlLinks = options?.prerender?.discover;\n\n let routes: (\n | string\n | PrerenderContentDir\n | PrerenderRouteConfig\n | undefined\n )[] = [];\n\n const prerenderRoutes = options?.prerender?.routes;\n const hasExplicitPrerenderRoutes =\n typeof prerenderRoutes === 'function' ||\n Array.isArray(prerenderRoutes);\n if (\n isArrayWithElements<string | PrerenderContentDir>(prerenderRoutes)\n ) {\n routes = prerenderRoutes;\n } else if (typeof prerenderRoutes === 'function') {\n routes = await prerenderRoutes();\n }\n\n const resolvedPrerenderRoutes = routes.reduce<string[]>(\n (prev, current) => {\n if (!current) {\n return prev;\n }\n if (typeof current === 'string') {\n prev.push(current);\n sitemapRoutes.push(current);\n return prev;\n }\n\n if ('route' in current) {\n if (current.sitemap) {\n routeSitemaps[current.route] = current.sitemap;\n }\n\n if (current.outputSourceFile) {\n const sourcePath = resolve(\n workspaceRoot,\n rootDir,\n current.outputSourceFile,\n );\n routeSourceFiles[current.route] = readFileSync(\n sourcePath,\n 'utf8',\n );\n }\n\n prev.push(current.route);\n sitemapRoutes.push(current.route);\n\n // Add the server-side data fetching endpoint URL\n if ('staticData' in current) {\n prev.push(`${apiPrefix}/_analog/pages/${current.route}`);\n }\n\n return prev;\n }\n\n const affectedFiles: PrerenderContentFile[] =\n getMatchingContentFilesWithFrontMatter(\n workspaceRoot,\n rootDir,\n current.contentDir,\n );\n\n affectedFiles.forEach((f) => {\n const result = current.transform(f);\n\n if (result) {\n if (current.sitemap) {\n routeSitemaps[result] =\n current.sitemap && typeof current.sitemap === 'function'\n ? current.sitemap?.(f)\n : current.sitemap;\n }\n\n if (current.outputSourceFile) {\n const sourceContent = current.outputSourceFile(f);\n if (sourceContent) {\n routeSourceFiles[result] = sourceContent;\n }\n }\n\n prev.push(result);\n sitemapRoutes.push(result);\n\n // Add the server-side data fetching endpoint URL\n if ('staticData' in current) {\n prev.push(`${apiPrefix}/_analog/pages/${result}`);\n }\n }\n });\n\n return prev;\n },\n [],\n );\n\n nitroConfig.prerender.routes =\n hasExplicitPrerenderRoutes || resolvedPrerenderRoutes.length\n ? resolvedPrerenderRoutes\n : (nitroConfig.prerender.routes ?? []);\n }\n\n // ── SSR / prerender Nitro config ─────────────────────────────\n //\n // This block configures Nitro for builds that rebundle the SSR\n // entry (main.server.{js,mjs}). That happens in two cases:\n //\n // 1. Full SSR apps — `options.ssr === true`\n // 2. Prerender-only — no runtime SSR, but the prerender build\n // still imports the SSR entry to render static pages.\n //\n // The original gate was `if (ssrBuild)`, which checks the Vite\n // top-level `build.ssr` flag. That works for SSR-only builds but\n // misses two Vite 6+ paths:\n //\n // a. **Vite Environment API (Vite 6+)** — SSR config lives in\n // `environments.ssr.build.ssr`, not `build.ssr`, so\n // `ssrBuild` is always `false`.\n // b. **Prerender-only apps** (e.g. blog-app) — `options.ssr`\n // is `false`, but prerender routes exist and the prerender\n // build still processes the SSR entry.\n //\n // Without this block:\n // - `rxjs` is never externalised → RESOLVE_ERROR in the\n // Nitro prerender build (especially on Windows CI).\n // - `moduleSideEffects` for zone.js is never set → zone.js\n // side-effects may be tree-shaken.\n // - The handlers list is not reassembled with page endpoints\n // + the renderer catch-all.\n //\n // The widened condition covers all supported build paths:\n // - `ssrBuild` → SSR-only build\n // - `options?.ssr` → Environment API SSR\n // - `nitroConfig.prerender?.routes?.length` → prerender-only\n if (\n ssrBuild ||\n options?.ssr ||\n nitroConfig.prerender?.routes?.length\n ) {\n if (process.platform === 'win32') {\n nitroConfig.noExternals = appendNoExternals(\n nitroConfig.noExternals,\n 'std-env',\n );\n }\n\n rollupExternalEntries.push(\n 'rxjs',\n 'node-fetch-native/dist/polyfill',\n // sharp is a native module with platform-specific binaries\n // (e.g. @img/sharp-darwin-arm64). pnpm creates symlinks for\n // ALL optional platform deps but only installs the matching\n // one — leaving broken symlinks that crash Nitro's bundler\n // with ENOENT during realpath(). Externalizing sharp avoids\n // bundling it entirely; it resolves from node_modules at\n // runtime instead.\n 'sharp',\n );\n\n nitroConfig = {\n ...nitroConfig,\n moduleSideEffects: ['zone.js/node', 'zone.js/fesm2015/zone-node'],\n handlers: [\n ...(hasAPIDir\n ? []\n : useAPIMiddleware\n ? [createNitroMiddlewareHandler('#ANALOG_API_MIDDLEWARE')]\n : []),\n ...pageHandlers,\n // Preserve the renderer catch-all handler added above\n {\n handler: rendererHandler,\n route: '/**',\n lazy: true,\n },\n ],\n };\n }\n }\n\n nitroConfig = mergeConfig(\n nitroConfig,\n nitroOptions as Record<string, any>,\n );\n\n // Only configure Vite 8 environments + builder on the top-level\n // build invocation. When buildApp's builder.build() calls re-enter\n // the config hook, returning environments/builder again would create\n // recursive buildApp invocations — each nesting another client build\n // that re-triggers config, producing an infinite loop of\n // \"building client environment... ✓ 1 modules transformed\".\n //\n // environmentBuild — already inside a buildApp call (recursion guard)\n // ssrBuild — legacy SSR-only sub-build\n // isServe — dev server / Vitest test runner (command: 'serve')\n if (environmentBuild || ssrBuild || isServe) {\n return {};\n }\n\n return {\n environments: {\n client: {\n build: {\n outDir:\n config?.build?.outDir ||\n resolve(workspaceRoot, 'dist', rootDir, 'client'),\n emptyOutDir: true,\n // Forward code-splitting config to Rolldown when running\n // under Vite 8+. `false` disables splitting (inlines all\n // dynamic imports); an object configures chunk groups.\n // The `!== undefined` check ensures `codeSplitting: false`\n // is forwarded correctly (a truthy check would swallow it).\n ...(isRolldown() && codeSplitting !== undefined\n ? {\n rolldownOptions: {\n output: {\n // Preserve any sibling Rolldown output options while\n // overriding just `codeSplitting` for the client build.\n ...viteRolldownOutputConfig,\n codeSplitting,\n },\n },\n }\n : {}),\n },\n },\n ssr: {\n build: {\n ssr: true,\n [getBundleOptionsKey()]: {\n input:\n options?.entryServer ||\n resolve(\n workspaceRoot,\n rootDir,\n `${sourceRoot}/main.server.ts`,\n ),\n },\n outDir:\n options?.ssrBuildDir ||\n resolve(workspaceRoot, 'dist', rootDir, 'ssr'),\n // Preserve the client build output. The client environment is\n // built first and Nitro reads its index.html after SSR finishes.\n emptyOutDir: false,\n },\n },\n },\n builder: {\n sharedPlugins: true,\n buildApp: async (builder) => {\n environmentBuild = true;\n debugNitro('builder.buildApp starting', {\n platform: process.platform,\n workspaceRoot,\n rootDir,\n cachedClientOutputPath: clientOutputPath,\n configuredBuildOutDir: config.build?.outDir,\n clientEnvironmentOutDir: getEnvironmentBuildOutDir(\n builder.environments['client'],\n ),\n ssrEnvironmentOutDir: getEnvironmentBuildOutDir(\n builder.environments['ssr'],\n ),\n });\n\n // Client must complete before SSR — the server build reads the\n // client's index.html via registerIndexHtmlVirtual(). Running\n // them in parallel caused a race on Windows where emptyOutDir\n // could delete client output before the server read it.\n await builder.build(builder.environments['client']);\n const postClientBuildOutputPath = resolveBuiltClientOutputPath(\n clientOutputPath,\n workspaceRoot,\n rootDir,\n config.build?.outDir,\n builder.environments['client'],\n );\n // Capture the client template before any SSR/prerender work runs.\n // On Windows, later phases can leave the client output directory\n // unavailable even though the client build itself succeeded.\n registerIndexHtmlVirtual(\n nitroConfig,\n postClientBuildOutputPath,\n clientIndexHtml,\n );\n debugNitro('builder.buildApp completed client build', {\n postClientBuildOutputPath,\n postClientBuildOutputInfo: getPathDebugInfo(\n postClientBuildOutputPath,\n ),\n postClientBuildIndexHtmlPath: resolve(\n postClientBuildOutputPath,\n 'index.html',\n ),\n postClientBuildIndexHtmlExists: existsSync(\n resolve(postClientBuildOutputPath, 'index.html'),\n ),\n });\n\n if (options?.ssr || nitroConfig.prerender?.routes?.length) {\n debugSsr('builder.buildApp starting SSR build', {\n ssrEnabled: options?.ssr,\n prerenderRoutes: nitroConfig.prerender?.routes,\n });\n await builder.build(builder.environments['ssr']);\n debugSsr('builder.buildApp completed SSR build', {\n ssrOutputPath:\n options?.ssrBuildDir ||\n resolve(workspaceRoot, 'dist', rootDir, 'ssr'),\n });\n }\n\n applySsrEntryAlias(nitroConfig, options, workspaceRoot, rootDir);\n\n const resolvedClientOutputPath = resolveBuiltClientOutputPath(\n clientOutputPath,\n workspaceRoot,\n rootDir,\n config.build?.outDir,\n builder.environments['client'],\n );\n\n nitroConfig.publicAssets = [\n { dir: normalizePath(resolvedClientOutputPath), maxAge: 0 },\n ];\n debugNitro(\n 'builder.buildApp resolved final client output path before Nitro build',\n {\n resolvedClientOutputPath,\n resolvedClientOutputInfo: getPathDebugInfo(\n resolvedClientOutputPath,\n ),\n nitroPublicAssets: nitroConfig.publicAssets,\n },\n );\n\n await buildServer(options, nitroConfig, routeSourceFiles);\n\n if (\n nitroConfig.prerender?.routes?.length &&\n options?.prerender?.sitemap\n ) {\n console.log('Building Sitemap...');\n // sitemap needs to be built after all directories are built\n await buildSitemap(\n config,\n options.prerender.sitemap,\n sitemapRoutes.length\n ? sitemapRoutes\n : nitroConfig.prerender.routes,\n getNitroPublicOutputDir(nitroConfig),\n routeSitemaps,\n { apiPrefix: options?.apiPrefix || 'api' },\n );\n }\n\n console.log(\n `\\n\\nThe '@analogjs/platform' server has been successfully built.`,\n );\n },\n },\n };\n },\n generateBundle(\n _options,\n bundle: Record<\n string,\n {\n type?: string;\n fileName?: string;\n source?: string | Uint8Array;\n }\n >,\n ) {\n if (!isBuild || ssrBuild) {\n return;\n }\n\n clientIndexHtml =\n captureClientIndexHtmlFromBundle(bundle, 'generateBundle') ??\n clientIndexHtml;\n },\n writeBundle(\n _options,\n bundle: Record<\n string,\n {\n type?: string;\n fileName?: string;\n source?: string | Uint8Array;\n }\n >,\n ) {\n if (!isBuild || ssrBuild) {\n return;\n }\n\n clientIndexHtml =\n captureClientIndexHtmlFromBundle(bundle, 'writeBundle') ??\n clientIndexHtml;\n },\n async configureServer(viteServer: ViteDevServer) {\n if (isServe && !isTest) {\n const nitro = await createNitro({\n dev: true,\n // Nitro's Vite builder now rejects `build()` in dev mode, but Analog's\n // dev integration still relies on the builder-driven reload hooks.\n // Force the server worker onto Rollup for this dev-only path.\n builder: 'rollup',\n ...nitroConfig,\n });\n const server = createDevServer(nitro);\n await build(nitro);\n const nitroSourceRoots = [\n normalizePath(\n resolve(workspaceRoot, rootDir, `${sourceRoot}/server`),\n ),\n ...(options?.additionalAPIDirs || []).map((dir) =>\n normalizePath(`${workspaceRoot}${dir}`),\n ),\n ];\n const isNitroSourceFile = (path: string) => {\n const normalizedPath = normalizePath(path);\n return nitroSourceRoots.some(\n (root) =>\n normalizedPath === root ||\n normalizedPath.startsWith(`${root}/`),\n );\n };\n let nitroRebuildPromise: Promise<void> | undefined;\n let nitroRebuildPending = false;\n const rebuildNitroServer = () => {\n if (nitroRebuildPromise) {\n // Coalesce rapid file events so a save that touches multiple server\n // route files results in one follow-up rebuild instead of many.\n nitroRebuildPending = true;\n return nitroRebuildPromise;\n }\n\n nitroRebuildPromise = (async () => {\n do {\n nitroRebuildPending = false;\n // Nitro API routes are not part of Vite's normal client HMR graph,\n // so rebuild the Nitro dev server to pick up handler edits.\n await build(nitro);\n } while (nitroRebuildPending);\n\n // Reload the page after the server rebuild completes so the next\n // request observes the updated API route implementation.\n viteServer.ws.send({ type: 'full-reload' });\n })()\n .catch((error: unknown) => {\n viteServer.config.logger.error(\n `[analog] Failed to rebuild Nitro dev server.\\n${error instanceof Error ? error.stack || error.message : String(error)}`,\n );\n })\n .finally(() => {\n nitroRebuildPromise = undefined;\n });\n\n return nitroRebuildPromise;\n };\n const onNitroSourceChange = (path: string) => {\n if (!isNitroSourceFile(path)) {\n return;\n }\n\n void rebuildNitroServer();\n };\n\n // Watch the full Nitro source roots instead of only the API route\n // directory. API handlers often read helper modules, shared data, or\n // middleware from elsewhere under `src/server`, and those edits should\n // still rebuild the Nitro dev server and refresh connected browsers.\n viteServer.watcher.on('add', onNitroSourceChange);\n viteServer.watcher.on('change', onNitroSourceChange);\n viteServer.watcher.on('unlink', onNitroSourceChange);\n\n const apiHandler = async (\n req: IncomingMessage,\n res: ServerResponse,\n ) => {\n // Nitro v3's dev server is fetch-first, so adapt Vite's Node\n // request once and let Nitro respond with a standard Web Response.\n const response = await server.fetch(toWebRequest(req));\n await writeWebResponseToNode(res, response);\n };\n\n if (hasAPIDir) {\n viteServer.middlewares.use(\n (\n req: IncomingMessage,\n res: ServerResponse,\n next: (error?: unknown) => void,\n ) => {\n if (req.url?.startsWith(`${prefix}${apiPrefix}`)) {\n void apiHandler(req, res).catch((error) => next(error));\n return;\n }\n\n next();\n },\n );\n } else {\n viteServer.middlewares.use(\n apiPrefix,\n (\n req: IncomingMessage,\n res: ServerResponse,\n next: (error?: unknown) => void,\n ) => {\n void apiHandler(req, res).catch((error) => next(error));\n },\n );\n }\n\n viteServer.httpServer?.once('listening', () => {\n process.env['ANALOG_HOST'] = !viteServer.config.server.host\n ? 'localhost'\n : (viteServer.config.server.host as string);\n process.env['ANALOG_PORT'] = `${viteServer.config.server.port}`;\n });\n\n // handle upgrades if websockets are enabled\n if (nitroOptions?.experimental?.websocket) {\n debugNitro('experimental websocket upgrade handler enabled');\n viteServer.httpServer?.on('upgrade', server.upgrade);\n }\n\n console.log(\n `\\n\\nThe server endpoints are accessible under the \"${prefix}${apiPrefix}\" path.`,\n );\n }\n },\n\n async closeBundle() {\n if (legacyClientSubBuild) {\n return;\n }\n\n // When builder.buildApp ran, it already handled the full\n // client → SSR → Nitro pipeline. Skip to avoid double work.\n if (environmentBuild) {\n return;\n }\n\n // SSR sub-build — Vite re-enters the plugin with build.ssr;\n // Nitro server assembly happens only after the client pass.\n if (ssrBuild) {\n return;\n }\n\n // Nx executors (and any caller that runs `vite build` without\n // the Environment API) never trigger builder.buildApp, so\n // closeBundle is the only place to drive the SSR + Nitro build.\n if (isBuild) {\n const resolvedClientOutputPath = resolveClientOutputPath(\n clientOutputPath,\n workspaceRoot,\n rootDir,\n config.build?.outDir,\n );\n debugNitro(\n 'closeBundle resolved client output path before legacy SSR build',\n {\n platform: process.platform,\n workspaceRoot,\n rootDir,\n cachedClientOutputPath: clientOutputPath,\n configuredBuildOutDir: config.build?.outDir,\n resolvedClientOutputPath,\n resolvedClientOutputInfo: getPathDebugInfo(\n resolvedClientOutputPath,\n ),\n },\n );\n const indexHtmlPath = resolve(resolvedClientOutputPath, 'index.html');\n if (\n !existsSync(indexHtmlPath) &&\n typeof clientIndexHtml !== 'string'\n ) {\n debugNitro(\n 'closeBundle rebuilding missing client output before SSR/Nitro',\n {\n platform: process.platform,\n workspaceRoot,\n rootDir,\n configuredBuildOutDir: config.build?.outDir,\n resolvedClientOutputPath,\n indexHtmlPath,\n },\n );\n legacyClientSubBuild = true;\n try {\n await buildClientApp(config, options);\n } finally {\n legacyClientSubBuild = false;\n }\n }\n // Capture the client HTML before kicking off the standalone SSR build.\n // This mirrors the successful sequencing from before the closeBundle\n // refactor and avoids depending on the client directory surviving the\n // nested SSR build on Windows.\n registerIndexHtmlVirtual(\n nitroConfig,\n resolvedClientOutputPath,\n clientIndexHtml,\n );\n\n if (options?.ssr) {\n console.log('Building SSR application...');\n await buildSSRApp(config, options);\n debugSsr('closeBundle completed standalone SSR build', {\n ssrBuildDir:\n options?.ssrBuildDir ||\n resolve(workspaceRoot, 'dist', rootDir, 'ssr'),\n clientOutputPathInfo: clientOutputPath\n ? getPathDebugInfo(clientOutputPath)\n : null,\n });\n }\n\n applySsrEntryAlias(nitroConfig, options, workspaceRoot, rootDir);\n debugNitro(\n 'closeBundle resolved client output path before Nitro build',\n {\n platform: process.platform,\n workspaceRoot,\n rootDir,\n cachedClientOutputPath: clientOutputPath,\n configuredBuildOutDir: config.build?.outDir,\n resolvedClientOutputPath,\n resolvedClientOutputInfo: getPathDebugInfo(\n resolvedClientOutputPath,\n ),\n },\n );\n registerIndexHtmlVirtual(\n nitroConfig,\n resolvedClientOutputPath,\n clientIndexHtml,\n );\n\n await buildServer(options, nitroConfig, routeSourceFiles);\n\n if (\n nitroConfig.prerender?.routes?.length &&\n options?.prerender?.sitemap\n ) {\n console.log('Building Sitemap...');\n await buildSitemap(\n config,\n options.prerender.sitemap,\n sitemapRoutes.length\n ? sitemapRoutes\n : nitroConfig.prerender.routes,\n getNitroPublicOutputDir(nitroConfig),\n routeSitemaps,\n { apiPrefix: options?.apiPrefix || 'api' },\n );\n }\n\n console.log(\n `\\n\\nThe '@analogjs/platform' server has been successfully built.`,\n );\n }\n },\n },\n {\n name: '@analogjs/vite-plugin-nitro-api-prefix',\n config() {\n return {\n define: {\n ANALOG_API_PREFIX: `\"${baseURL.substring(1)}${apiPrefix.substring(1)}\"`,\n },\n };\n },\n },\n ];\n}\n\nfunction isEmptyPrerenderRoutes(options?: Options): boolean {\n if (!options || isArrayWithElements(options?.prerender?.routes)) {\n return false;\n }\n return !options.prerender?.routes;\n}\n\nfunction isArrayWithElements<T>(arr: unknown): arr is [T, ...T[]] {\n return !!(Array.isArray(arr) && arr.length);\n}\n\nconst VERCEL_PRESET = 'vercel';\n// Nitro v3 consolidates the old `vercel-edge` preset into `vercel` with\n// fluid compute enabled by default, so a single preset covers both\n// serverless and edge deployments.\nconst withVercelOutputAPI = (\n nitroConfig: NitroConfig | undefined,\n workspaceRoot: string,\n) => ({\n ...nitroConfig,\n preset: nitroConfig?.preset ?? 'vercel',\n vercel: {\n ...nitroConfig?.vercel,\n entryFormat: nitroConfig?.vercel?.entryFormat ?? 'node',\n functions: {\n runtime: nitroConfig?.vercel?.functions?.runtime ?? 'nodejs24.x',\n ...nitroConfig?.vercel?.functions,\n },\n },\n output: {\n ...nitroConfig?.output,\n dir: normalizePath(resolve(workspaceRoot, '.vercel', 'output')),\n publicDir: normalizePath(\n resolve(workspaceRoot, '.vercel', 'output/static'),\n ),\n },\n});\n\n// Nitro v3 uses underscore-separated preset names (e.g. `cloudflare_pages`),\n// but we accept both hyphen and underscore forms for backwards compatibility.\nconst isCloudflarePreset = (buildPreset: string | undefined) =>\n process.env['CF_PAGES'] ||\n (buildPreset &&\n (buildPreset.toLowerCase().includes('cloudflare-pages') ||\n buildPreset.toLowerCase().includes('cloudflare_pages')));\n\nconst withCloudflareOutput = (nitroConfig: NitroConfig | undefined) => ({\n ...nitroConfig,\n output: {\n ...nitroConfig?.output,\n serverDir: '{{ output.publicDir }}/_worker.js',\n },\n});\n\nconst isFirebaseAppHosting = () => !!process.env['NG_BUILD_LOGS_JSON'];\nconst withAppHostingOutput = (nitroConfig: NitroConfig) => {\n let hasOutput = false;\n\n return <NitroConfig>{\n ...nitroConfig,\n serveStatic: true,\n rollupConfig: {\n ...nitroConfig.rollupConfig,\n output: {\n ...nitroConfig.rollupConfig?.output,\n entryFileNames: 'server.mjs',\n },\n },\n hooks: {\n ...nitroConfig.hooks,\n compiled: () => {\n if (!hasOutput) {\n const buildOutput = {\n errors: [],\n warnings: [],\n outputPaths: {\n root: pathToFileURL(`${nitroConfig.output?.dir}`),\n browser: pathToFileURL(`${nitroConfig.output?.publicDir}`),\n server: pathToFileURL(`${nitroConfig.output?.dir}/server`),\n },\n };\n\n // Log the build output for Firebase App Hosting to pick up\n console.log(JSON.stringify(buildOutput, null, 2));\n hasOutput = true;\n }\n },\n },\n };\n};\n\nconst isNetlifyPreset = (buildPreset: string | undefined) =>\n process.env['NETLIFY'] ||\n (buildPreset && buildPreset.toLowerCase().includes('netlify'));\n\nconst withNetlifyOutputAPI = (\n nitroConfig: NitroConfig | undefined,\n workspaceRoot: string,\n) => ({\n ...nitroConfig,\n output: {\n ...nitroConfig?.output,\n dir: normalizePath(resolve(workspaceRoot, 'netlify/functions')),\n },\n});\n"],"mappings":";;;;;;;;;;;;;;;;;AAoCA,SAAS,6BAA6B,SAAoC;AACxE,QAAO;EACL,OAAO;EACP;EACA,YAAY;EACb;;;;;;;;;;;;;;;;;;;;;;;;;AA0BH,SAAS,uBAAuB,iBAA2B;CACzD,MAAM,cAAc,WAClB,gBAAgB,MACb,UAAU,WAAW,SAAS,OAAO,WAAW,QAAQ,IAAI,CAC9D;AAEH,SAAQ,QAAiB,kBAAgC;AACvD,6BAA2B,QAAQ,cAAc;AAEjD,MAAI,gBAAgB,WAAW,EAC7B;EAGF,MAAM,WAAW,cAAc;AAC/B,MAAI,CAAC,SACH,eAAc,WAAW;WAChB,OAAO,aAAa,WAC7B,eAAc,YACZ,QACA,UACA,eACG,SAAS,QAAQ,UAAU,WAAW,IAAI,WAAW,OAAO;WACxD,MAAM,QAAQ,SAAS,CAChC,eAAc,WAAW,CAAC,GAAG,UAAU,GAAG,gBAAgB;MAE1D,eAAc,WAAW,CAAC,UAAoB,GAAG,gBAAgB;;;AAKvE,SAAS,kBACP,aACA,GAAG,SACyB;AAC5B,KAAI,CAAC,YACH,QAAO;AAGT,QAAO,MAAM,QAAQ,YAAY,GAC7B,CAAC,GAAG,aAAa,GAAG,QAAQ,GAC5B;;;;;;;;;;;;;AAcN,SAAS,2BACP,QACA,eACA;CACA,MAAM,SAAS,cAAc;AAC7B,KAAI,CAAC,UAAU,MAAM,QAAQ,OAAO,IAAI,OAAO,WAAW,SACxD;AAaF,KAAI,mBAAmB,OACrB,QAAQ,OAAmC;AAY7C,KAAI,kBAAkB,OACpB,QAAQ,OAAmC;CAqB7C,MAAM,2BAA2B;CACjC,MAAM,iBAAkB,OAAmC;AAC3D,KAAI,OAAO,mBAAmB,YAAY;EACxC,MAAM,aAAa;AAClB,SAAmC,qBAClC,GAAG,SACA;GACH,MAAM,SAAS,WAAW,GAAG,KAAK;AAClC,OAAI,OAAO,WAAW,SAAU,QAAO;AACvC,UAAO,OAAO,QAAQ,gBAAgB,UACpC,yBAAyB,KAAK,MAAM,GAChC,QACA,IAAI,MAAM,MAAM,GAAG,GAAG,CAAC,GAC5B;;;;AAKP,SAAS,wBACP,YACA,eACA,SACA,kBACA;AACA,KAAI,YAAY;AACd,aAAW,6CAA6C;GACtD;GACA;GACA;GACA;GACD,CAAC;AACF,SAAO;;AAGT,KAAI,kBAAkB;EACpB,MAAM,eAAe,cACnB,QAAQ,eAAe,SAAS,iBAAiB,CAClD;AACD,aAAW,yDAAyD;GAClE;GACA;GACA;GACA;GACD,CAAC;AACF,SAAO;;CAOT,MAAM,eAAe,cACnB,QAAQ,eAAe,QAAQ,SAAS,SAAS,CAClD;AACD,YAAW,0DAA0D;EACnE;EACA;EACA;EACA;EACD,CAAC;AACF,QAAO;;AAGT,SAAS,0BAA0B,aAA0C;AAC3E,KAAI,CAAC,eAAe,OAAO,gBAAgB,SACzC;CAGF,MAAM,oBAAoB;AAW1B,QACE,kBAAkB,QAAQ,OAAO,UAAU,kBAAkB,OAAO;;AAIxE,SAAS,6BACP,YACA,eACA,SACA,kBACA,aACA;CACA,MAAM,oBAAoB,0BAA0B,YAAY;AAChE,KAAI,mBAAmB;EACrB,MAAM,eAAe,cACnB,QAAQ,eAAe,SAAS,kBAAkB,CACnD;AACD,aAAW,yDAAyD;GAClE;GACA;GACA;GACA;GACA;GACA;GACD,CAAC;AACF,SAAO;;AAGT,YAAW,gEAAgE;EACzE;EACA;EACA;EACA;EACA;EACD,CAAC;AACF,QAAO,wBACL,YACA,eACA,SACA,iBACD;;AAGH,SAAS,wBAAwB,aAAkC;CACjE,MAAM,YAAY,YAAY,QAAQ;AACtC,KAAI,CAAC,UACH,OAAM,IAAI,MACR,kEACD;AAGH,QAAO;;AAGT,SAAS,qBAAqB,MAAwB;AACpD,KAAI;AACF,SAAO,YAAY,KAAK,CAAC,MAAM;UACxB,OAAO;AACd,SAAO,CACL,+BAA+B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,CAAC,IACvF;;;AAIL,SAAS,iBAAiB,MAAc;AACtC,QAAO;EACL,SAAS;EACT,gBAAgB,cAAc,KAAK;EACnC,QAAQ,WAAW,KAAK;EACxB,SAAS,WAAW,KAAK,GAAG,qBAAqB,KAAK,GAAG,EAAE;EAC5D;;AAGH,SAAS,oBAAoB,QAA6B;AACxD,QAAO,OAAO,WAAW,WACrB,SACA,OAAO,KAAK,OAAO,CAAC,SAAS,OAAO;;AAG1C,SAAS,iCACP,QAQA,MACA;CACA,MAAM,iBAAiB,OAAO,OAAO,OAAO,CAAC,MAC1C,UACC,MAAM,SAAS,WACf,MAAM,aAAa,gBACnB,OAAO,MAAM,WAAW,YAC3B;AAED,KAAI,CAAC,gBAAgB,QAAQ;AAC3B,aAAW,kDAAkD,QAAQ;GACnE;GACA,YAAY,OAAO,KAAK,OAAO,CAAC,MAAM;GACtC,gBAAgB,OAAO,OAAO,OAAO,CAClC,QAAQ,UAAU,MAAM,SAAS,QAAQ,CACzC,KAAK,UAAU,MAAM,SAAS,CAC9B,OAAO,QAAQ;GACnB,CAAC;AACF;;CAGF,MAAM,YAAY,oBAAoB,eAAe,OAAO;AAC5D,YAAW,kDAAkD,QAAQ;EACnE;EACA,UAAU,eAAe;EACzB,YAAY,UAAU;EACvB,CAAC;AACF,QAAO;;AAMT,SAAS,yBACP,aACA,kBACA,iBACA;CACA,MAAM,gBAAgB,QAAQ,kBAAkB,aAAa;AAC7D,YAAW,qDAAqD;EAC9D,UAAU,QAAQ;EAClB,KAAK,QAAQ,KAAK;EAClB;EACA,sBAAsB,iBAAiB,iBAAiB;EACxD;EACA,iBAAiB,WAAW,cAAc;EAC1C,oBAAoB,OAAO,oBAAoB;EAChD,CAAC;AACF,KAAI,CAAC,WAAW,cAAc,IAAI,OAAO,oBAAoB,UAAU;AACrE,aAAW,+CAA+C;GACxD,UAAU,QAAQ;GAClB,KAAK,QAAQ,KAAK;GAClB;GACA,sBAAsB,iBAAiB,iBAAiB;GACxD;GACA,oBAAoB,OAAO,oBAAoB;GAC/C,aAAa,YAAY;GACzB,mBAAmB,YAAY;GAChC,CAAC;AACF,QAAM,IAAI,MACR,6CAA6C,cAAc,wFAE5D;;CAEH,MAAM,YACJ,OAAO,oBAAoB,WACvB,kBACA,aAAa,eAAe,OAAO;AACzC,YAAW,uDAAuD;EAChE,QACE,OAAO,oBAAoB,WACvB,iCACA;EACN;EACD,CAAC;AACF,aAAY,UAAU;EACpB,GAAG,YAAY;EACf,iBAAiB,kBAAkB,KAAK,UAAU,UAAU,CAAC;EAC9D;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BH,SAAS,8BAA8B,cAAsB;AAC3D,QAAO,cAAc,aAAa;;AAGpC,SAAS,mBACP,aACA,SACA,eACA,SACM;CACN,MAAM,YACJ,SAAS,eAAe,QAAQ,eAAe,QAAQ,SAAS,MAAM;AACxE,KAAI,SAAS,OAAO,YAAY,WAAW,QAAQ,QAAQ;EAEzD,MAAM,WAAW,8BADI,yBAAyB,UAAU,CACI;AAC5D,cAAY,QAAQ;GAClB,GAAG,YAAY;GACf,eAAe;GAChB;;;AAIL,SAAS,yBAAyB,WAAmB;CACnD,MAAM,iBAAiB;EACrB,QAAQ,WAAW,kBAAkB;EACrC,QAAQ,WAAW,iBAAiB;EACpC,QAAQ,WAAW,cAAc;EAClC;CAED,MAAM,eAAe,eAAe,MAAM,kBACxC,WAAW,cAAc,CAC1B;AAED,KAAI,CAAC,aACH,OAAM,IAAI,MACR,4CAA4C,UAAU,sBAAsB,eAAe,KACzF,KACD,GACF;AAGH,QAAO;;AAGT,SAAgB,MAAM,SAAmB,cAAsC;CAC7E,MAAM,gBAAgB,SAAS,iBAAiB,QAAQ,KAAK;CAC7D,MAAM,aAAa,SAAS,cAAc;CAC1C,IAAI,SAAA,QAAA,IAAA,aAAqC,UAAU,CAAC,CAAC,QAAQ,IAAI;CACjE,MAAM,UAAU,QAAQ,IAAI,yBAAyB;CACrD,MAAM,SAAS,UAAU,QAAQ,UAAU,GAAG,QAAQ,SAAS,EAAE,GAAG;CACpE,MAAM,YAAY,IAAI,SAAS,aAAa;CAC5C,MAAM,mBACJ,OAAO,SAAS,qBAAqB,cACjC,SAAS,mBACT;CACN,MAAM,qBAAqB,SAAS,MAAM,OAAO,iBAAiB;CAIlE,MAAM,2BACJ,sBAAsB,CAAC,MAAM,QAAQ,mBAAmB,GACpD,qBACA,KAAA;CACN,MAAM,gBAAgB,0BAA0B;CAEhD,IAAI,UAAU;CACd,IAAI,UAAU;CACd,IAAI,WAAW;CACf,IAAI;CACJ,IAAI;CACJ,IAAI,mBAAmB;CACvB,IAAI,YAAY;CAChB,IAAI,mBAAmB;CACvB,IAAI;CACJ,IAAI,uBAAuB;CAC3B,MAAM,wBAAkC,EAAE;CAC1C,MAAM,gBAA0B,EAAE;CAClC,MAAM,gBAGF,EAAE;CACN,MAAM,mBAA2C,EAAE;CACnD,IAAI,UAAU;AAEd,QAAO;EACJ,SAAS,MACN,gBAAgB;GACd,aAAa,SAAS;GACtB,OAAO,SAAS;GAChB,YAAY,cAAc;GAC3B,CAAC,GACF;EACJ;GACE,MAAM;GACN,MAAM,OAAO,YAAY,EAAE,MAAM,WAAW;AAC1C,cAAU,YAAY;AACtB,cAAU,YAAY;AACtB,eAAW,WAAW,OAAO,QAAQ;AACrC,aAAS;AACT,aAAS,SAAS,SAAS,SAAS;AACpC,0BAAsB,SAAS;AAC/B,sBAAkB,KAAA;AAClB,kBAAc,SAAS;AACvB,SAAK,MAAM,OAAO,OAAO,KAAK,cAAc,CAC1C,QAAO,cAAc;AAEvB,SAAK,MAAM,OAAO,OAAO,KAAK,iBAAiB,CAC7C,QAAO,iBAAiB;IAG1B,MAAM,qBAAqB,OAAO,OAC9B,QAAQ,eAAe,OAAO,KAAK,GACnC;AACJ,cAAU,SAAS,eAAe,mBAAmB,IAAI;AACzD,gBAAY,WACV,QACE,eACA,SACA,GAAG,WAAW,iBAAiB,SAAS,aAAa,QACtD,CACF;IACD,MAAM,cACJ,QAAQ,IAAI,mBACX,cAAc,WACd,QAAQ,IAAI,YAAY,WAAW,KAAA;IAEtC,MAAM,eAAe,gBAAgB;KACnC;KACA;KACA;KACA,qBAAqB,SAAS;KAC9B;KACD,CAAC;IACF,MAAM,2BAA2B,wBAC/B,kBACA,eACA,SACA,OAAO,OAAO,OACf;AACD,eAAW,4CAA4C;KACrD,UAAU,QAAQ;KAClB;KACA,YAAY,OAAO;KACnB;KACA;KACA,aAAa,OAAO,OAAO;KAC3B;KACA;KACA,sBAAsB,CAAC,CAAC,OAAO;KAC/B,yBACE,OAAO,eAAe,aACtB,OAAO,OAAO,aAAa,cAAc,YACzC,WAAW,OAAO,aAAa,YAEzB,OAAO,aAAa,UAGpB,OAAO,SACT,KAAA;KACP,CAAC;AAEF,kBAAc;KACZ,SAAS,cAAc,QAAQ;KAC/B,QAAQ;KACR,mBAAmB;KACnB,UAAU,cAAc,YAAY;KACpC,WAAW,cAAc,GAAG,WAAW,SAAS;KAChD,UAAU,CACR,cAAc,GAAG,QAAQ,GAAG,WAAW,SAAS,EAChD,IAAI,SAAS,qBAAqB,EAAE,EAAE,KAAK,QACzC,cAAc,GAAG,gBAAgB,MAAM,CACxC,CACF;KACD,QAAQ;MACN,KAAK,cACH,QAAQ,eAAe,QAAQ,SAAS,SAAS,CAClD;MACD,WAAW,cACT,QAAQ,eAAe,QAAQ,SAAS,gBAAgB,CACzD;MACF;KACD,UAAU,cACR,QAAQ,eAAe,QAAQ,SAAS,SAAS,CAClD;KACD,YAAY,EACV,kBAAkB,OACnB;KACD,eAAe;MACb,WAAW,UAAU,UAAU,EAAE;MACjC;MACD;KAGD,UAAU;KACV,SAAS,EACP,YAAY,OACb;KACD,OAAO,EACL,iBAAiB,uBAAuB,sBAAsB,EAC/D;KACD,cAAc;MACZ,OAAO,SAAS;AACd,WACE,QAAQ,QAAQ,SAAS,cAAc,IACvC,QAAQ,QAAQ,SAAS,UAAU,CAEnC;;MAGJ,SAAS,CAAC,qBAAqB,CAAC;MACjC;KACD,UAAU,CACR,GAAI,YACA,EAAE,GACF,mBACE,CAAC,6BAA6B,yBAAyB,CAAC,GACxD,EAAE,EACR,GAAG,aACJ;KACD,YAAY,YACR,KAAA,IACA,mBACE,KAAA,IACA,GACG,GAAG,SAAS,UAAU,OAAO,EAC5B,OAAO,EAAE,IAAI,OAAO,EACrB,EACF;KACP,SAAS;MACP,wBAAwB,aAAa;MACrC,2BAA2B,gBAAgB;MAC3C,GAAI,YAAY,EAAE,GAAG,EAAE,0BAA0B,eAAe;MACjE;KACF;AAED,QAAI,eAAe,YAAY,CAC7B,eAAc,oBAAoB,aAAa,cAAc;AAG/D,QAAI,mBAAmB,YAAY,CACjC,eAAc,qBAAqB,YAAY;AAGjD,QACE,gBAAgB,YAAY,IAC5B,YAAY,OACZ,CAAC,WAAW,QAAQ,eAAe,eAAe,CAAC,CAEnD,eAAc,qBAAqB,aAAa,cAAc;AAGhE,QAAI,sBAAsB,CACxB,eAAc,qBAAqB,YAAY;AAGjD,QAAI,CAAC,YAAY,CAAC,QAAQ;AAExB,wBAAmB;AACnB,gBACE,oEACA;MACE;MACA;MACA;MACD,CACF;;AAOH,gBAAY,QAAQ,EAAE;AAEtB,QAAI,SAAS;AACX,iBAAY,eAAe,CACzB;MAAE,KAAK,cAAc,yBAAyB;MAAE,QAAQ;MAAG,CAC5D;KASD,MAAM,kBAAkB,SAAS,MAC7B,yBACA;AACJ,iBAAY,WAAW,CACrB,GAAI,YAAY,YAAY,EAAE,EAC9B;MACE,SAAS;MACT,OAAO;MACP,MAAM;MACP,CACF;AAED,SAAI,uBAAuB,QAAQ,EAAE;AACnC,kBAAY,YAAY,EAAE;AAC1B,kBAAY,UAAU,SAAS,CAAC,IAAI;;AAGtC,SAAI,SAAS,WAAW;AACtB,kBAAY,YAAY,YAAY,aAAa,EAAE;AACnD,kBAAY,UAAU,aAAa,SAAS,WAAW;MAEvD,IAAI,SAKE,EAAE;MAER,MAAM,kBAAkB,SAAS,WAAW;MAC5C,MAAM,6BACJ,OAAO,oBAAoB,cAC3B,MAAM,QAAQ,gBAAgB;AAChC,UACE,oBAAkD,gBAAgB,CAElE,UAAS;eACA,OAAO,oBAAoB,WACpC,UAAS,MAAM,iBAAiB;MAGlC,MAAM,0BAA0B,OAAO,QACpC,MAAM,YAAY;AACjB,WAAI,CAAC,QACH,QAAO;AAET,WAAI,OAAO,YAAY,UAAU;AAC/B,aAAK,KAAK,QAAQ;AAClB,sBAAc,KAAK,QAAQ;AAC3B,eAAO;;AAGT,WAAI,WAAW,SAAS;AACtB,YAAI,QAAQ,QACV,eAAc,QAAQ,SAAS,QAAQ;AAGzC,YAAI,QAAQ,kBAAkB;SAC5B,MAAM,aAAa,QACjB,eACA,SACA,QAAQ,iBACT;AACD,0BAAiB,QAAQ,SAAS,aAChC,YACA,OACD;;AAGH,aAAK,KAAK,QAAQ,MAAM;AACxB,sBAAc,KAAK,QAAQ,MAAM;AAGjC,YAAI,gBAAgB,QAClB,MAAK,KAAK,GAAG,UAAU,iBAAiB,QAAQ,QAAQ;AAG1D,eAAO;;AAIP,8CACE,eACA,SACA,QAAQ,WACT,CAEW,SAAS,MAAM;QAC3B,MAAM,SAAS,QAAQ,UAAU,EAAE;AAEnC,YAAI,QAAQ;AACV,aAAI,QAAQ,QACV,eAAc,UACZ,QAAQ,WAAW,OAAO,QAAQ,YAAY,aAC1C,QAAQ,UAAU,EAAE,GACpB,QAAQ;AAGhB,aAAI,QAAQ,kBAAkB;UAC5B,MAAM,gBAAgB,QAAQ,iBAAiB,EAAE;AACjD,cAAI,cACF,kBAAiB,UAAU;;AAI/B,cAAK,KAAK,OAAO;AACjB,uBAAc,KAAK,OAAO;AAG1B,aAAI,gBAAgB,QAClB,MAAK,KAAK,GAAG,UAAU,iBAAiB,SAAS;;SAGrD;AAEF,cAAO;SAET,EAAE,CACH;AAED,kBAAY,UAAU,SACpB,8BAA8B,wBAAwB,SAClD,0BACC,YAAY,UAAU,UAAU,EAAE;;AAmC3C,SACE,YACA,SAAS,OACT,YAAY,WAAW,QAAQ,QAC/B;AACA,UAAI,QAAQ,aAAa,QACvB,aAAY,cAAc,kBACxB,YAAY,aACZ,UACD;AAGH,4BAAsB,KACpB,QACA,mCAQA,QACD;AAED,oBAAc;OACZ,GAAG;OACH,mBAAmB,CAAC,gBAAgB,6BAA6B;OACjE,UAAU;QACR,GAAI,YACA,EAAE,GACF,mBACE,CAAC,6BAA6B,yBAAyB,CAAC,GACxD,EAAE;QACR,GAAG;QAEH;SACE,SAAS;SACT,OAAO;SACP,MAAM;SACP;QACF;OACF;;;AAIL,kBAAc,YACZ,aACA,aACD;AAYD,QAAI,oBAAoB,YAAY,QAClC,QAAO,EAAE;AAGX,WAAO;KACL,cAAc;MACZ,QAAQ,EACN,OAAO;OACL,QACE,QAAQ,OAAO,UACf,QAAQ,eAAe,QAAQ,SAAS,SAAS;OACnD,aAAa;OAMb,GAAI,YAAY,IAAI,kBAAkB,KAAA,IAClC,EACE,iBAAiB,EACf,QAAQ;QAGN,GAAG;QACH;QACD,EACF,EACF,GACD,EAAE;OACP,EACF;MACD,KAAK,EACH,OAAO;OACL,KAAK;QACJ,qBAAqB,GAAG,EACvB,OACE,SAAS,eACT,QACE,eACA,SACA,GAAG,WAAW,iBACf,EACJ;OACD,QACE,SAAS,eACT,QAAQ,eAAe,QAAQ,SAAS,MAAM;OAGhD,aAAa;OACd,EACF;MACF;KACD,SAAS;MACP,eAAe;MACf,UAAU,OAAO,YAAY;AAC3B,0BAAmB;AACnB,kBAAW,6BAA6B;QACtC,UAAU,QAAQ;QAClB;QACA;QACA,wBAAwB;QACxB,uBAAuB,OAAO,OAAO;QACrC,yBAAyB,0BACvB,QAAQ,aAAa,UACtB;QACD,sBAAsB,0BACpB,QAAQ,aAAa,OACtB;QACF,CAAC;AAMF,aAAM,QAAQ,MAAM,QAAQ,aAAa,UAAU;OACnD,MAAM,4BAA4B,6BAChC,kBACA,eACA,SACA,OAAO,OAAO,QACd,QAAQ,aAAa,UACtB;AAID,gCACE,aACA,2BACA,gBACD;AACD,kBAAW,2CAA2C;QACpD;QACA,2BAA2B,iBACzB,0BACD;QACD,8BAA8B,QAC5B,2BACA,aACD;QACD,gCAAgC,WAC9B,QAAQ,2BAA2B,aAAa,CACjD;QACF,CAAC;AAEF,WAAI,SAAS,OAAO,YAAY,WAAW,QAAQ,QAAQ;AACzD,iBAAS,uCAAuC;SAC9C,YAAY,SAAS;SACrB,iBAAiB,YAAY,WAAW;SACzC,CAAC;AACF,cAAM,QAAQ,MAAM,QAAQ,aAAa,OAAO;AAChD,iBAAS,wCAAwC,EAC/C,eACE,SAAS,eACT,QAAQ,eAAe,QAAQ,SAAS,MAAM,EACjD,CAAC;;AAGJ,0BAAmB,aAAa,SAAS,eAAe,QAAQ;OAEhE,MAAM,2BAA2B,6BAC/B,kBACA,eACA,SACA,OAAO,OAAO,QACd,QAAQ,aAAa,UACtB;AAED,mBAAY,eAAe,CACzB;QAAE,KAAK,cAAc,yBAAyB;QAAE,QAAQ;QAAG,CAC5D;AACD,kBACE,yEACA;QACE;QACA,0BAA0B,iBACxB,yBACD;QACD,mBAAmB,YAAY;QAChC,CACF;AAED,aAAM,YAAY,SAAS,aAAa,iBAAiB;AAEzD,WACE,YAAY,WAAW,QAAQ,UAC/B,SAAS,WAAW,SACpB;AACA,gBAAQ,IAAI,sBAAsB;AAElC,cAAM,aACJ,QACA,QAAQ,UAAU,SAClB,cAAc,SACV,gBACA,YAAY,UAAU,QAC1B,wBAAwB,YAAY,EACpC,eACA,EAAE,WAAW,SAAS,aAAa,OAAO,CAC3C;;AAGH,eAAQ,IACN,mEACD;;MAEJ;KACF;;GAEH,eACE,UACA,QAQA;AACA,QAAI,CAAC,WAAW,SACd;AAGF,sBACE,iCAAiC,QAAQ,iBAAiB,IAC1D;;GAEJ,YACE,UACA,QAQA;AACA,QAAI,CAAC,WAAW,SACd;AAGF,sBACE,iCAAiC,QAAQ,cAAc,IACvD;;GAEJ,MAAM,gBAAgB,YAA2B;AAC/C,QAAI,WAAW,CAAC,QAAQ;KACtB,MAAM,QAAQ,MAAM,YAAY;MAC9B,KAAK;MAIL,SAAS;MACT,GAAG;MACJ,CAAC;KACF,MAAM,SAAS,gBAAgB,MAAM;AACrC,WAAM,MAAM,MAAM;KAClB,MAAM,mBAAmB,CACvB,cACE,QAAQ,eAAe,SAAS,GAAG,WAAW,SAAS,CACxD,EACD,IAAI,SAAS,qBAAqB,EAAE,EAAE,KAAK,QACzC,cAAc,GAAG,gBAAgB,MAAM,CACxC,CACF;KACD,MAAM,qBAAqB,SAAiB;MAC1C,MAAM,iBAAiB,cAAc,KAAK;AAC1C,aAAO,iBAAiB,MACrB,SACC,mBAAmB,QACnB,eAAe,WAAW,GAAG,KAAK,GAAG,CACxC;;KAEH,IAAI;KACJ,IAAI,sBAAsB;KAC1B,MAAM,2BAA2B;AAC/B,UAAI,qBAAqB;AAGvB,6BAAsB;AACtB,cAAO;;AAGT,6BAAuB,YAAY;AACjC,UAAG;AACD,8BAAsB;AAGtB,cAAM,MAAM,MAAM;gBACX;AAIT,kBAAW,GAAG,KAAK,EAAE,MAAM,eAAe,CAAC;UACzC,CACD,OAAO,UAAmB;AACzB,kBAAW,OAAO,OAAO,MACvB,iDAAiD,iBAAiB,QAAQ,MAAM,SAAS,MAAM,UAAU,OAAO,MAAM,GACvH;QACD,CACD,cAAc;AACb,6BAAsB,KAAA;QACtB;AAEJ,aAAO;;KAET,MAAM,uBAAuB,SAAiB;AAC5C,UAAI,CAAC,kBAAkB,KAAK,CAC1B;AAGG,0BAAoB;;AAO3B,gBAAW,QAAQ,GAAG,OAAO,oBAAoB;AACjD,gBAAW,QAAQ,GAAG,UAAU,oBAAoB;AACpD,gBAAW,QAAQ,GAAG,UAAU,oBAAoB;KAEpD,MAAM,aAAa,OACjB,KACA,QACG;AAIH,YAAM,uBAAuB,KADZ,MAAM,OAAO,MAAM,aAAa,IAAI,CAAC,CACX;;AAG7C,SAAI,UACF,YAAW,YAAY,KAEnB,KACA,KACA,SACG;AACH,UAAI,IAAI,KAAK,WAAW,GAAG,SAAS,YAAY,EAAE;AAC3C,kBAAW,KAAK,IAAI,CAAC,OAAO,UAAU,KAAK,MAAM,CAAC;AACvD;;AAGF,YAAM;OAET;SAED,YAAW,YAAY,IACrB,YAEE,KACA,KACA,SACG;AACE,iBAAW,KAAK,IAAI,CAAC,OAAO,UAAU,KAAK,MAAM,CAAC;OAE1D;AAGH,gBAAW,YAAY,KAAK,mBAAmB;AAC7C,cAAQ,IAAI,iBAAiB,CAAC,WAAW,OAAO,OAAO,OACnD,cACC,WAAW,OAAO,OAAO;AAC9B,cAAQ,IAAI,iBAAiB,GAAG,WAAW,OAAO,OAAO;OACzD;AAGF,SAAI,cAAc,cAAc,WAAW;AACzC,iBAAW,iDAAiD;AAC5D,iBAAW,YAAY,GAAG,WAAW,OAAO,QAAQ;;AAGtD,aAAQ,IACN,sDAAsD,SAAS,UAAU,SAC1E;;;GAIL,MAAM,cAAc;AAClB,QAAI,qBACF;AAKF,QAAI,iBACF;AAKF,QAAI,SACF;AAMF,QAAI,SAAS;KACX,MAAM,2BAA2B,wBAC/B,kBACA,eACA,SACA,OAAO,OAAO,OACf;AACD,gBACE,mEACA;MACE,UAAU,QAAQ;MAClB;MACA;MACA,wBAAwB;MACxB,uBAAuB,OAAO,OAAO;MACrC;MACA,0BAA0B,iBACxB,yBACD;MACF,CACF;KACD,MAAM,gBAAgB,QAAQ,0BAA0B,aAAa;AACrE,SACE,CAAC,WAAW,cAAc,IAC1B,OAAO,oBAAoB,UAC3B;AACA,iBACE,iEACA;OACE,UAAU,QAAQ;OAClB;OACA;OACA,uBAAuB,OAAO,OAAO;OACrC;OACA;OACD,CACF;AACD,6BAAuB;AACvB,UAAI;AACF,aAAM,eAAe,QAAQ,QAAQ;gBAC7B;AACR,8BAAuB;;;AAO3B,8BACE,aACA,0BACA,gBACD;AAED,SAAI,SAAS,KAAK;AAChB,cAAQ,IAAI,8BAA8B;AAC1C,YAAM,YAAY,QAAQ,QAAQ;AAClC,eAAS,8CAA8C;OACrD,aACE,SAAS,eACT,QAAQ,eAAe,QAAQ,SAAS,MAAM;OAChD,sBAAsB,mBAClB,iBAAiB,iBAAiB,GAClC;OACL,CAAC;;AAGJ,wBAAmB,aAAa,SAAS,eAAe,QAAQ;AAChE,gBACE,8DACA;MACE,UAAU,QAAQ;MAClB;MACA;MACA,wBAAwB;MACxB,uBAAuB,OAAO,OAAO;MACrC;MACA,0BAA0B,iBACxB,yBACD;MACF,CACF;AACD,8BACE,aACA,0BACA,gBACD;AAED,WAAM,YAAY,SAAS,aAAa,iBAAiB;AAEzD,SACE,YAAY,WAAW,QAAQ,UAC/B,SAAS,WAAW,SACpB;AACA,cAAQ,IAAI,sBAAsB;AAClC,YAAM,aACJ,QACA,QAAQ,UAAU,SAClB,cAAc,SACV,gBACA,YAAY,UAAU,QAC1B,wBAAwB,YAAY,EACpC,eACA,EAAE,WAAW,SAAS,aAAa,OAAO,CAC3C;;AAGH,aAAQ,IACN,mEACD;;;GAGN;EACD;GACE,MAAM;GACN,SAAS;AACP,WAAO,EACL,QAAQ,EACN,mBAAmB,IAAI,QAAQ,UAAU,EAAE,GAAG,UAAU,UAAU,EAAE,CAAC,IACtE,EACF;;GAEJ;EACF;;AAGH,SAAS,uBAAuB,SAA4B;AAC1D,KAAI,CAAC,WAAW,oBAAoB,SAAS,WAAW,OAAO,CAC7D,QAAO;AAET,QAAO,CAAC,QAAQ,WAAW;;AAG7B,SAAS,oBAAuB,KAAkC;AAChE,QAAO,CAAC,EAAE,MAAM,QAAQ,IAAI,IAAI,IAAI;;AAOtC,IAAM,uBACJ,aACA,mBACI;CACJ,GAAG;CACH,QAAQ,aAAa,UAAU;CAC/B,QAAQ;EACN,GAAG,aAAa;EAChB,aAAa,aAAa,QAAQ,eAAe;EACjD,WAAW;GACT,SAAS,aAAa,QAAQ,WAAW,WAAW;GACpD,GAAG,aAAa,QAAQ;GACzB;EACF;CACD,QAAQ;EACN,GAAG,aAAa;EAChB,KAAK,cAAc,QAAQ,eAAe,WAAW,SAAS,CAAC;EAC/D,WAAW,cACT,QAAQ,eAAe,WAAW,gBAAgB,CACnD;EACF;CACF;AAID,IAAM,sBAAsB,gBAC1B,QAAQ,IAAI,eACX,gBACE,YAAY,aAAa,CAAC,SAAS,mBAAmB,IACrD,YAAY,aAAa,CAAC,SAAS,mBAAmB;AAE5D,IAAM,wBAAwB,iBAA0C;CACtE,GAAG;CACH,QAAQ;EACN,GAAG,aAAa;EAChB,WAAW;EACZ;CACF;AAED,IAAM,6BAA6B,CAAC,CAAC,QAAQ,IAAI;AACjD,IAAM,wBAAwB,gBAA6B;CACzD,IAAI,YAAY;AAEhB,QAAoB;EAClB,GAAG;EACH,aAAa;EACb,cAAc;GACZ,GAAG,YAAY;GACf,QAAQ;IACN,GAAG,YAAY,cAAc;IAC7B,gBAAgB;IACjB;GACF;EACD,OAAO;GACL,GAAG,YAAY;GACf,gBAAgB;AACd,QAAI,CAAC,WAAW;KACd,MAAM,cAAc;MAClB,QAAQ,EAAE;MACV,UAAU,EAAE;MACZ,aAAa;OACX,MAAM,cAAc,GAAG,YAAY,QAAQ,MAAM;OACjD,SAAS,cAAc,GAAG,YAAY,QAAQ,YAAY;OAC1D,QAAQ,cAAc,GAAG,YAAY,QAAQ,IAAI,SAAS;OAC3D;MACF;AAGD,aAAQ,IAAI,KAAK,UAAU,aAAa,MAAM,EAAE,CAAC;AACjD,iBAAY;;;GAGjB;EACF;;AAGH,IAAM,mBAAmB,gBACvB,QAAQ,IAAI,cACX,eAAe,YAAY,aAAa,CAAC,SAAS,UAAU;AAE/D,IAAM,wBACJ,aACA,mBACI;CACJ,GAAG;CACH,QAAQ;EACN,GAAG,aAAa;EAChB,KAAK,cAAc,QAAQ,eAAe,oBAAoB,CAAC;EAChE;CACF"}