@slidev/cli 52.15.1 → 52.16.0

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.
@@ -1,15 +1,17 @@
1
- import { a as resolveImportPath, c as toAtFS, i as resolveEntry, n as getRoots, o as resolveImportUrl, r as isInstalledGlobally, s as resolveSourceFiles, t as createResolver } from "./resolver-XedCEhxI.mjs";
1
+ import { a as resolveImportPath, c as toAtFS, i as resolveEntry, n as getRoots, o as resolveImportUrl, r as isInstalledGlobally, s as resolveSourceFiles, t as createResolver } from "./resolver-CZx9LFrt.mjs";
2
2
  import { builtinModules } from "node:module";
3
3
  import path, { basename, dirname, join, relative, resolve, win32 } from "node:path";
4
- import { loadConfigFromFile, mergeConfig } from "vite";
4
+ import process from "node:process";
5
+ import { createServer, loadConfigFromFile, mergeConfig, parseSync } from "vite";
5
6
  import MarkdownExit from "markdown-exit";
6
- import fs, { existsSync } from "node:fs";
7
+ import fs, { existsSync, mkdirSync, realpathSync, writeFileSync } from "node:fs";
7
8
  import fs$1, { readFile } from "node:fs/promises";
8
9
  import { fileURLToPath, pathToFileURL } from "node:url";
9
10
  import { ensureSuffix, isString, isTruthy, notNullish, objectEntries, objectMap, range, slash, uniq } from "@antfu/utils";
10
11
  import { bold, gray, red, white, yellow } from "ansis";
11
12
  import { createResolve } from "mlly";
12
13
  import { findDepPkgJsonPath } from "vitefu";
14
+ import { createHash } from "node:crypto";
13
15
  import { createJiti } from "jiti";
14
16
  import YAML from "yaml";
15
17
  import IconsResolver from "unplugin-icons/resolver";
@@ -32,9 +34,9 @@ import Markdown from "unplugin-vue-markdown/vite";
32
34
  import MarkdownItComark from "@comark/markdown-it";
33
35
  import MarkdownItFootnote from "markdown-it-footnote";
34
36
  import MarkdownItGitHubAlerts from "markdown-it-github-alerts";
37
+ import { toKeyedTokens } from "@shikijs/magic-move/core";
35
38
  import { defineCodeblockTransformer } from "@slidev/types";
36
39
  import lz from "lz-string";
37
- import { toKeyedTokens } from "shiki-magic-move/core";
38
40
  import { encode } from "plantuml-encoder";
39
41
  import { SourceMapConsumer } from "source-map-js";
40
42
  import { fromAsyncCodeToHtml } from "@shikijs/markdown-it/async";
@@ -43,7 +45,6 @@ import UnoCSS from "unocss/vite";
43
45
  import { mergeConfigs, presetIcons } from "unocss";
44
46
  import Vue from "@vitejs/plugin-vue";
45
47
  import VueJsx from "@vitejs/plugin-vue-jsx";
46
-
47
48
  //#region node/syntax/link.ts
48
49
  const RE_DIGITS_ONLY = /^\d+$/;
49
50
  function MarkdownItLink(md) {
@@ -64,7 +65,6 @@ function MarkdownItLink(md) {
64
65
  return defaultRender(tokens, idx, options, env, self);
65
66
  };
66
67
  }
67
-
68
68
  //#endregion
69
69
  //#region node/utils.ts
70
70
  const RE_WHITESPACE_ONLY = /^\s*$/;
@@ -104,8 +104,8 @@ function updateFrontmatterPatch(source, frontmatter) {
104
104
  else {
105
105
  const valueNode = doc.createNode(value);
106
106
  let found = false;
107
- YAML.visit(doc.contents, { Pair(_key, node, path$1) {
108
- if (path$1.length === 1 && YAML.isScalar(node.key) && node.key.value === key) {
107
+ YAML.visit(doc.contents, { Pair(_key, node, path) {
108
+ if (path.length === 1 && YAML.isScalar(node.key) && node.key.value === key) {
109
109
  node.value = valueNode;
110
110
  found = true;
111
111
  return YAML.visit.BREAK;
@@ -119,13 +119,13 @@ function updateFrontmatterPatch(source, frontmatter) {
119
119
  }
120
120
  }
121
121
  function getBodyJson(req) {
122
- return new Promise((resolve$2, reject) => {
122
+ return new Promise((resolve, reject) => {
123
123
  let body = "";
124
124
  req.on("data", (chunk) => body += chunk);
125
125
  req.on("error", reject);
126
126
  req.on("end", () => {
127
127
  try {
128
- resolve$2(JSON.parse(body) || {});
128
+ resolve(JSON.parse(body) || {});
129
129
  } catch (e) {
130
130
  reject(e);
131
131
  }
@@ -137,39 +137,51 @@ function getImportGlobRelativePath(from, to) {
137
137
  const normalizedTo = slash(to);
138
138
  return slash(RE_WINDOWS_DRIVE.test(normalizedFrom) || RE_WINDOWS_DRIVE.test(normalizedTo) ? win32.relative(normalizedFrom, normalizedTo) : relative(normalizedFrom, normalizedTo));
139
139
  }
140
- function makeAbsoluteImportGlob(self, globs, options = {}, baseRoot) {
141
- const root = baseRoot && globs.some((glob) => RE_WINDOWS_DRIVE.test(slash(glob))) ? baseRoot : void 0;
140
+ function resolveImportGlobProxyModule(proxyBase, content) {
141
+ return `${proxyBase}.${createHash("sha256").update(content).digest("hex").slice(0, 10)}.ts`;
142
+ }
143
+ function createMakeAbsoluteImportGlob(baseRoot) {
144
+ const proxyModules = /* @__PURE__ */ new Map();
145
+ const proxyBase = slash(join(baseRoot, "node_modules/.slidev/virtual/import-glob"));
146
+ return function makeAbsoluteImportGlob(globs, options = {}) {
147
+ const content = `export default ${makeAbsoluteImportGlobExpression(dirname(proxyBase), globs, options)}\n`;
148
+ const proxyModule = resolveImportGlobProxyModule(proxyBase, content);
149
+ if (proxyModules.get(proxyModule) !== content) {
150
+ mkdirSync(dirname(proxyModule), { recursive: true });
151
+ writeFileSync(proxyModule, content, "utf-8");
152
+ proxyModules.set(proxyModule, content);
153
+ }
154
+ return toAtFS(proxyModule);
155
+ };
156
+ }
157
+ function makeAbsoluteImportGlobExpression(self, globs, options = {}) {
142
158
  const relativeGlobs = globs.map((glob) => {
143
- const relativeGlob = getImportGlobRelativePath(root ?? self, glob);
144
- return root && !relativeGlob.startsWith(".") && !RE_WINDOWS_DRIVE.test(relativeGlob) ? `./${relativeGlob}` : relativeGlob;
159
+ const relativeGlob = getImportGlobRelativePath(self, glob);
160
+ return !relativeGlob.startsWith(".") && !RE_WINDOWS_DRIVE.test(relativeGlob) ? `./${relativeGlob}` : relativeGlob;
145
161
  });
146
162
  const opts = {
147
163
  eager: true,
148
164
  exhaustive: true,
149
- ...root ? { base: "/" } : {},
150
165
  ...options
151
166
  };
152
167
  return `import.meta.glob(${JSON.stringify(relativeGlobs)}, ${JSON.stringify(opts)})`;
153
168
  }
154
-
155
169
  //#endregion
156
170
  //#region node/setups/load.ts
157
171
  async function loadSetups(roots, filename, args, extraLoader) {
158
172
  return await Promise.all(roots.flatMap((root) => {
159
173
  const tasks = [];
160
- const path$1 = resolve(root, "setup", filename);
161
- if (existsSync(path$1)) tasks.push(loadModule(path$1).then((mod) => mod.default(...args)));
174
+ const path = resolve(root, "setup", filename);
175
+ if (existsSync(path)) tasks.push(loadModule(path).then((mod) => mod.default(...args)));
162
176
  if (extraLoader) tasks.push(...extraLoader(root));
163
177
  return tasks;
164
178
  }));
165
179
  }
166
-
167
180
  //#endregion
168
181
  //#region node/setups/vite-plugins.ts
169
182
  async function setupVitePlugins(options) {
170
183
  return await loadSetups(options.roots, "vite-plugins.ts", [options]);
171
184
  }
172
-
173
185
  //#endregion
174
186
  //#region node/vite/compilerFlagsVue.ts
175
187
  const RE_VUE_FILE = /\.vue(?:$|\?)/;
@@ -181,8 +193,8 @@ function createVueCompilerFlagsPlugin(options) {
181
193
  return {
182
194
  name: "slidev:flags",
183
195
  enforce: "pre",
184
- transform: { handler(code, id$2) {
185
- if (!RE_VUE_FILE.test(id$2) && !id$2.includes("?vue&")) return;
196
+ transform: { handler(code, id) {
197
+ if (!RE_VUE_FILE.test(id) && !id.includes("?vue&")) return;
186
198
  const original = code;
187
199
  define.forEach(([from, to]) => {
188
200
  code = code.replaceAll(from, to);
@@ -191,7 +203,6 @@ function createVueCompilerFlagsPlugin(options) {
191
203
  } }
192
204
  };
193
205
  }
194
-
195
206
  //#endregion
196
207
  //#region node/vite/components.ts
197
208
  const RE_VUE_EXT$1 = /\.vue$/;
@@ -227,7 +238,6 @@ function createComponentsPlugin({ clientRoot, roots }, pluginOptions) {
227
238
  ...pluginOptions.components
228
239
  });
229
240
  }
230
-
231
241
  //#endregion
232
242
  //#region node/vite/common.ts
233
243
  const regexSlideReqPath = /^\/__slidev\/slides\/(\d+)\.json$/;
@@ -236,7 +246,6 @@ const regexSlideSourceId = /__slidev_(\d+)\.(md|frontmatter)$/;
236
246
  const templateInjectionMarker = "/* @slidev-injection */";
237
247
  const templateImportContextUtils = `import { useSlideContext as _useSlideContext, frontmatterToProps as _frontmatterToProps } from "@slidev/client/context.ts"`;
238
248
  const templateInitContext = `const { $slidev, $nav, $clicksContext, $clicks, $page, $renderContext, $frontmatter } = _useSlideContext()`;
239
-
240
249
  //#endregion
241
250
  //#region node/vite/contextInjection.ts
242
251
  const RE_EXPORT_DEFAULT_OBJECT = /export\s+default\s+\{/;
@@ -247,9 +256,9 @@ const RE_INJECT_OPTION = /.*inject\s*:\s*([[{])/;
247
256
  function createContextInjectionPlugin() {
248
257
  return {
249
258
  name: "slidev:context-injection",
250
- transform: { async handler(code, id$2) {
251
- if (!id$2.endsWith(".vue") || id$2.includes("/@slidev/client/") || id$2.includes("/packages/client/")) return;
252
- if (code.includes(templateInjectionMarker) || code.includes("useSlideContext()")) return code;
259
+ transform: { async handler(code, id) {
260
+ if (!id.endsWith(".vue") || id.includes("/@slidev/client/") || id.includes("/packages/client/")) return;
261
+ if (code.includes("/* @slidev-injection */") || code.includes("useSlideContext()")) return code;
253
262
  const imports = [
254
263
  templateImportContextUtils,
255
264
  templateInitContext,
@@ -291,7 +300,6 @@ ${code.slice(scriptIndex)}`;
291
300
  } }
292
301
  };
293
302
  }
294
-
295
303
  //#endregion
296
304
  //#region node/vite/extendConfig.ts
297
305
  const RE_SLIDEV_CLIENT = /^@slidev\/client$/;
@@ -311,6 +319,7 @@ const INCLUDE_GLOBAL = [
311
319
  const INCLUDE_LOCAL = INCLUDE_GLOBAL.map((i) => `@slidev/cli > @slidev/client > ${i}`);
312
320
  const EXCLUDE_GLOBAL = [
313
321
  "@antfu/utils",
322
+ "@shikijs/magic-move/vue",
314
323
  "@shikijs/monaco",
315
324
  "@shikijs/vitepress-twoslash/client",
316
325
  "@slidev/client",
@@ -332,7 +341,6 @@ const EXCLUDE_GLOBAL = [
332
341
  "fuse.js",
333
342
  "mermaid",
334
343
  "monaco-editor",
335
- "shiki-magic-move/vue",
336
344
  "shiki",
337
345
  "shiki/core",
338
346
  "vue-demi",
@@ -412,18 +420,18 @@ function createConfigPlugin(options) {
412
420
  if (chunkInfo.moduleIds.filter((i) => i.match(RE_MONACO_EDITOR)).length > chunkInfo.moduleIds.length * .6) return "assets/monaco/[name]-[hash].js";
413
421
  return DEFAULT;
414
422
  },
415
- manualChunks(id$2) {
416
- if (id$2.startsWith("/@slidev-monaco-types/") || id$2.includes("/@slidev/monaco-types") || id$2.endsWith("?monaco-types&raw")) return "monaco/bundled-types";
417
- if (id$2.includes("/shiki/") || id$2.includes("/@shikijs/")) return `modules/shiki`;
418
- if (id$2.startsWith("~icons/")) return "modules/unplugin-icons";
419
- const matchedAsyncModule = ASYNC_MODULES.find((i) => id$2.includes(`/node_modules/${i}`));
423
+ manualChunks(id) {
424
+ if (id.startsWith("/@slidev-monaco-types/") || id.includes("/@slidev/monaco-types") || id.endsWith("?monaco-types&raw")) return "monaco/bundled-types";
425
+ if (id.includes("/shiki/") || id.includes("/@shikijs/")) return `modules/shiki`;
426
+ if (id.startsWith("~icons/")) return "modules/unplugin-icons";
427
+ const matchedAsyncModule = ASYNC_MODULES.find((i) => id.includes(`/node_modules/${i}`));
420
428
  if (matchedAsyncModule) return `modules/${matchedAsyncModule.replace("@", "").replace("/", "-")}`;
421
429
  }
422
430
  } } },
423
431
  cacheDir: isInstalledGlobally.value ? join(options.cliRoot, "node_modules/.vite") : void 0
424
432
  };
425
- function isSlidevClient(id$2) {
426
- return id$2.includes("/@slidev/") || id$2.includes("/slidev/packages/client/") || id$2.includes("/@vueuse/");
433
+ function isSlidevClient(id) {
434
+ return id.includes("/@slidev/") || id.includes("/slidev/packages/client/") || id.includes("/@vueuse/");
427
435
  }
428
436
  return mergeConfig(injection, config);
429
437
  },
@@ -444,7 +452,6 @@ function createConfigPlugin(options) {
444
452
  }
445
453
  };
446
454
  }
447
-
448
455
  //#endregion
449
456
  //#region node/vite/hmrPatch.ts
450
457
  /**
@@ -455,14 +462,13 @@ function createHmrPatchPlugin() {
455
462
  name: "slidev:hmr-patch",
456
463
  transform: {
457
464
  filter: { id: { include: regexSlideSourceId } },
458
- handler(code, id$2) {
459
- if (!id$2.match(regexSlideSourceId)) return;
465
+ handler(code, id) {
466
+ if (!id.match(regexSlideSourceId)) return;
460
467
  return code.replace("if (_rerender_only)", "if (false)");
461
468
  }
462
469
  }
463
470
  };
464
471
  }
465
-
466
472
  //#endregion
467
473
  //#region node/vite/icons.ts
468
474
  function createIconsPlugin(options, pluginOptions) {
@@ -472,7 +478,155 @@ function createIconsPlugin(options, pluginOptions) {
472
478
  ...pluginOptions.icons
473
479
  });
474
480
  }
481
+ //#endregion
482
+ //#region node/virtual/deprecated.ts
483
+ /**
484
+ * Kept for backward compatibility, use #slidev/slides instead
485
+ *
486
+ * @deprecated
487
+ */
488
+ const templateLegacyRoutes = {
489
+ id: "/@slidev/routes",
490
+ getContent() {
491
+ return [`export { slides } from '#slidev/slides'`, `console.warn('[slidev] #slidev/routes is deprecated, use #slidev/slides instead')`].join("\n");
492
+ }
493
+ };
494
+ /**
495
+ * Kept for backward compatibility, use #slidev/title-renderer instead
496
+ *
497
+ * @deprecated
498
+ */
499
+ const templateLegacyTitles = {
500
+ id: "/@slidev/titles.md",
501
+ getContent() {
502
+ return `
503
+ <script setup lang="ts">
504
+ import TitleRenderer from '#slidev/title-renderer'
505
+ defineProps<{ no: number | string }>()
506
+ console.warn('/@slidev/titles.md is deprecated, import from #slidev/title-renderer instead')
507
+ <\/script>
475
508
 
509
+ <TitleRenderer :no="no" />
510
+ `;
511
+ }
512
+ };
513
+ //#endregion
514
+ //#region node/virtual/titles.ts
515
+ const templateTitleRendererMd = {
516
+ id: "/@slidev/title-renderer.md",
517
+ getContent({ data }) {
518
+ const lines = data.slides.map(({ title }, i) => `<template ${i === 0 ? "v-if" : "v-else-if"}="no === ${i + 1}">\n\n${title}\n\n</template>`);
519
+ lines.push(`<script setup lang="ts">`, `import { useSlideContext } from '@slidev/client/context.ts'`, `import { computed } from 'vue'`, `const props = defineProps<{ no?: number | string }>()`, `const { $page } = useSlideContext()`, `const no = computed(() => +(props.no ?? $page.value))`, `<\/script>`);
520
+ return lines.join("\n");
521
+ }
522
+ };
523
+ const templateTitleRenderer = {
524
+ id: "/@slidev/title-renderer",
525
+ async getContent() {
526
+ return "export { default } from \"/@slidev/title-renderer.md\"";
527
+ }
528
+ };
529
+ //#endregion
530
+ //#region node/vite/importGuard.ts
531
+ const virtualSlideMarkdownIds = new Set([templateTitleRendererMd.id, templateLegacyTitles.id]);
532
+ function createSlideImportGuardPlugin() {
533
+ let config;
534
+ let allowRoots = [];
535
+ return {
536
+ name: "slidev:slide-import-guard",
537
+ configResolved(resolved) {
538
+ config = resolved;
539
+ allowRoots = config.server.fs.allow.map(normalizeFsPath);
540
+ },
541
+ async transform(code, id) {
542
+ if (!isSlideMarkdownId(id) || !config?.server.fs.strict) return null;
543
+ const importer = filePathFromId(id) ?? id;
544
+ await Promise.all(extractImportSources(code, id).map(async ({ value, start }) => {
545
+ const resolved = await this.resolve(value, importer, { skipSelf: true });
546
+ if (!resolved || resolved.external) return;
547
+ const filePath = filePathFromId(resolved.id);
548
+ if (!filePath) return;
549
+ const normalized = normalizeFsPath(filePath);
550
+ if (isAllowedFile(normalized, allowRoots)) return;
551
+ if (isBareImport(value) && isDependencyFile(normalized)) return;
552
+ this.error(`[slidev] Import "${value}" from slide Markdown resolves outside of Vite server.fs.allow: ${normalized}`, start);
553
+ }));
554
+ return null;
555
+ }
556
+ };
557
+ }
558
+ function isSlideMarkdownId(id) {
559
+ const clean = cleanUrl$1(id);
560
+ return regexSlideSourceId.test(clean) || virtualSlideMarkdownIds.has(clean);
561
+ }
562
+ function filePathFromId(id) {
563
+ const clean = cleanUrl$1(id);
564
+ if (clean.startsWith("file://")) return fileURLToPath(clean);
565
+ if (clean.startsWith("/@fs/")) return clean.slice(4);
566
+ if (clean.startsWith("/@")) return null;
567
+ if (path.isAbsolute(clean)) return clean;
568
+ return null;
569
+ }
570
+ function isAllowedFile(filePath, allowRoots) {
571
+ return allowRoots.some((root) => isFileInRoot(root, filePath));
572
+ }
573
+ function extractImportSources(code, id) {
574
+ const result = parseSync(id, code);
575
+ const sources = [];
576
+ for (const item of result.module.staticImports) sources.push({
577
+ value: item.moduleRequest.value,
578
+ start: item.moduleRequest.start
579
+ });
580
+ for (const item of result.module.staticExports) for (const entry of item.entries) if (entry.moduleRequest) sources.push({
581
+ value: entry.moduleRequest.value,
582
+ start: entry.moduleRequest.start
583
+ });
584
+ for (const item of result.module.dynamicImports) {
585
+ const source = parseStringLiteral(code.slice(item.moduleRequest.start, item.moduleRequest.end));
586
+ if (source) sources.push({
587
+ value: source,
588
+ start: item.moduleRequest.start
589
+ });
590
+ }
591
+ return sources;
592
+ }
593
+ function cleanUrl$1(id) {
594
+ return id.replace(/[?#].*$/, "");
595
+ }
596
+ function normalizeFsPath(filePath) {
597
+ const absolute = path.resolve(filePath);
598
+ if (!existsSync(absolute)) return normalizeMissingFsPath(absolute);
599
+ return realpathSync.native(absolute);
600
+ }
601
+ function normalizeMissingFsPath(filePath) {
602
+ const dir = path.dirname(filePath);
603
+ if (dir === filePath) return filePath;
604
+ if (existsSync(dir)) return path.join(realpathSync.native(dir), path.basename(filePath));
605
+ return path.join(normalizeMissingFsPath(dir), path.basename(filePath));
606
+ }
607
+ function isFileInRoot(root, filePath) {
608
+ const relative = path.relative(root, filePath);
609
+ return relative === "" || !!relative && !relative.startsWith("..") && !path.isAbsolute(relative);
610
+ }
611
+ function isDependencyFile(filePath) {
612
+ return filePath.split(/[\\/]/).includes("node_modules");
613
+ }
614
+ function isBareImport(source) {
615
+ return /^(?![a-z]:)[\w@](?!.*:\/\/)/i.test(source);
616
+ }
617
+ function parseStringLiteral(raw) {
618
+ const trimmed = raw.trim();
619
+ const quote = trimmed[0];
620
+ if (quote !== "\"" && quote !== "'" && quote !== "`") return null;
621
+ if (trimmed.at(-1) !== quote) return null;
622
+ if (quote === "`" && trimmed.includes("${")) return null;
623
+ try {
624
+ if (quote === "\"") return JSON.parse(trimmed);
625
+ return JSON.parse(`"${trimmed.slice(1, -1).replace(/"/g, "\\\"")}"`);
626
+ } catch {
627
+ return trimmed.slice(1, -1);
628
+ }
629
+ }
476
630
  //#endregion
477
631
  //#region node/vite/inspect.ts
478
632
  async function createInspectPlugin(options, pluginOptions) {
@@ -484,7 +638,6 @@ async function createInspectPlugin(options, pluginOptions) {
484
638
  ...pluginOptions.inspect
485
639
  });
486
640
  }
487
-
488
641
  //#endregion
489
642
  //#region node/vite/layoutWrapper.ts
490
643
  const RE_SCRIPT_SETUP_TAG = /^<script setup.*>/m;
@@ -493,8 +646,8 @@ function createLayoutWrapperPlugin({ data, utils }) {
493
646
  name: "slidev:layout-wrapper",
494
647
  transform: {
495
648
  filter: { id: { include: regexSlideSourceId } },
496
- async handler(code, id$2) {
497
- const match = id$2.match(regexSlideSourceId);
649
+ async handler(code, id) {
650
+ const match = id.match(regexSlideSourceId);
498
651
  if (!match) return;
499
652
  const [, no, type] = match;
500
653
  if (type !== "md") return;
@@ -530,11 +683,9 @@ function createLayoutWrapperPlugin({ data, utils }) {
530
683
  }
531
684
  };
532
685
  }
533
-
534
686
  //#endregion
535
687
  //#region package.json
536
- var version = "52.15.1";
537
-
688
+ var version = "52.16.0";
538
689
  //#endregion
539
690
  //#region node/integrations/addons.ts
540
691
  async function resolveAddons(addonsInConfig) {
@@ -553,26 +704,21 @@ async function resolveAddons(addonsInConfig) {
553
704
  if (Array.isArray(userPkgJson.slidev?.addons)) await Promise.all(userPkgJson.slidev.addons.map((addon) => resolveAddon(addon, userRoot)));
554
705
  return resolved;
555
706
  }
556
-
557
- //#endregion
558
- //#region node/integrations/themes.ts
559
- const officialThemes = {
707
+ const resolveTheme = createResolver("theme", {
560
708
  "none": "",
561
709
  "default": "@slidev/theme-default",
562
710
  "seriph": "@slidev/theme-seriph",
563
711
  "apple-basic": "@slidev/theme-apple-basic",
564
712
  "shibainu": "@slidev/theme-shibainu",
565
713
  "bricks": "@slidev/theme-bricks"
566
- };
567
- const resolveTheme = createResolver("theme", officialThemes);
714
+ });
568
715
  async function getThemeMeta(name, root) {
569
- const path$1 = join(root, "package.json");
570
- if (!existsSync(path$1)) return {};
571
- const { slidev = {}, engines = {} } = JSON.parse(await fs$1.readFile(path$1, "utf-8"));
716
+ const path = join(root, "package.json");
717
+ if (!existsSync(path)) return {};
718
+ const { slidev = {}, engines = {} } = JSON.parse(await fs$1.readFile(path, "utf-8"));
572
719
  if (engines.slidev && !satisfies(version, engines.slidev, { includePrerelease: true })) throw new Error(`[slidev] theme "${name}" requires Slidev version range "${engines.slidev}" but found "${version}"`);
573
720
  return slidev;
574
721
  }
575
-
576
722
  //#endregion
577
723
  //#region node/setups/indexHtml.ts
578
724
  const RE_TRAILING_SLASH = /\/$/;
@@ -609,11 +755,11 @@ async function setupIndexHtml({ mode, entry, clientRoot, userRoot, roots, data,
609
755
  let body = "";
610
756
  const inputs = [];
611
757
  for (const root of roots) {
612
- const path$1 = join(root, "index.html");
613
- if (!existsSync(path$1)) continue;
614
- const html = await readFile(path$1, "utf-8");
758
+ const path = join(root, "index.html");
759
+ if (!existsSync(path)) continue;
760
+ const html = await readFile(path, "utf-8");
615
761
  if (root === userRoot && html.includes("<!DOCTYPE")) {
616
- console.error(yellow(`[Slidev] Ignored provided index.html with doctype declaration. (${white(path$1)})`));
762
+ console.error(yellow(`[Slidev] Ignored provided index.html with doctype declaration. (${white(path)})`));
617
763
  console.error(yellow("This file may be generated by Slidev, please remove it from your project."));
618
764
  continue;
619
765
  }
@@ -663,7 +809,7 @@ async function setupIndexHtml({ mode, entry, clientRoot, userRoot, roots, data,
663
809
  },
664
810
  {
665
811
  property: "slidev:entry",
666
- content: mode === "dev" && slash(entry)
812
+ content: mode === "dev" ? slash(entry) : null
667
813
  },
668
814
  {
669
815
  name: "description",
@@ -726,16 +872,14 @@ async function setupIndexHtml({ mode, entry, clientRoot, userRoot, roots, data,
726
872
  main = main.replace("__ENTRY__", encodeURI(basePrefix + mainUrl));
727
873
  }
728
874
  main = main.replace("<!-- body -->", body);
729
- return await transformHtmlTemplate(unhead, main);
875
+ return transformHtmlTemplate(unhead, main);
730
876
  }
731
-
732
877
  //#endregion
733
878
  //#region node/setups/katex.ts
734
879
  async function setupKatex(roots) {
735
880
  const options = await loadSetups(roots, "katex.ts", []);
736
881
  return Object.assign({ strict: false }, ...options);
737
882
  }
738
-
739
883
  //#endregion
740
884
  //#region ../client/setup/shiki-options.ts
741
885
  function resolveShikiOptions(options) {
@@ -807,16 +951,17 @@ function extractThemeNames(themes) {
807
951
  return [key, name];
808
952
  });
809
953
  }
810
-
811
954
  //#endregion
812
955
  //#region node/setups/shiki.ts
813
956
  let cachedRoots;
814
957
  let cachedShiki;
815
958
  async function setupShiki(roots) {
816
959
  if (cachedRoots === roots) return cachedShiki;
817
- const { options, languageInput, themeInput } = resolveShikiOptions(await loadSetups(roots, "shiki.ts", [{ async loadTheme(path$1) {
960
+ const { options, languageInput, themeInput } = resolveShikiOptions(await loadSetups(roots, "shiki.ts", [{
961
+ /** @deprecated */
962
+ async loadTheme(path) {
818
963
  console.warn("[slidev] `loadTheme` in `setup/shiki.ts` is deprecated. Pass directly the theme name it's supported by Shiki. For custom themes, load it manually via `JSON.parse(fs.readFileSync(path, 'utf-8'))` and pass the raw JSON object instead.");
819
- return JSON.parse(await fs$1.readFile(path$1, "utf-8"));
964
+ return JSON.parse(await fs$1.readFile(path, "utf-8"));
820
965
  } }]));
821
966
  const createHighlighter = createBundledHighlighter({
822
967
  engine: createJavaScriptRegexEngine,
@@ -829,7 +974,6 @@ async function setupShiki(roots) {
829
974
  shikiOptions: options
830
975
  };
831
976
  }
832
-
833
977
  //#endregion
834
978
  //#region node/options.ts
835
979
  const RE_FILE_EXTENSION = /\.\w+$/;
@@ -837,7 +981,10 @@ const debug = createDebug("slidev:options");
837
981
  async function resolveOptions(entryOptions, mode) {
838
982
  const entry = await resolveEntry(entryOptions.entry);
839
983
  const rootsInfo = await getRoots(entry);
840
- const loaded = await parser.load(rootsInfo.userRoot, entry, void 0, mode);
984
+ const loaded = await parser.load({
985
+ userRoot: rootsInfo.userRoot,
986
+ roots: [rootsInfo.userRoot]
987
+ }, entry, void 0, mode);
841
988
  let themeRaw = entryOptions.theme || loaded.headmatter.theme;
842
989
  themeRaw = themeRaw === null ? "none" : themeRaw || "default";
843
990
  const [theme, themeRoot] = await resolveTheme(themeRaw, entry);
@@ -939,7 +1086,6 @@ function getDefine(options) {
939
1086
  __SLIDEV_HAS_SERVER__: options.mode !== "build"
940
1087
  }, (v, k) => [v, JSON.stringify(k)]);
941
1088
  }
942
-
943
1089
  //#endregion
944
1090
  //#region node/syntax/utils.ts
945
1091
  function normalizeRangeStr(rangeStr = "") {
@@ -951,7 +1097,6 @@ function normalizeRangeStr(rangeStr = "") {
951
1097
  function escapeVueInCode(md) {
952
1098
  return md.replace(/\{\{/g, "&lbrace;&lbrace;");
953
1099
  }
954
-
955
1100
  //#endregion
956
1101
  //#region node/syntax/katex.ts
957
1102
  const RE_KATEX_BLOCK_INFO = /^\{([\w*,|-]+)\}\s*(\{[^}]*\})?/;
@@ -1076,9 +1221,9 @@ function MarkdownItKatex(md, options) {
1076
1221
  };
1077
1222
  const blockRenderer = function(tokens, idx) {
1078
1223
  const token = tokens[idx];
1079
- const [, rangeStr, options$1] = RE_KATEX_BLOCK_INFO.exec(token.info) || [];
1224
+ const [, rangeStr, options] = RE_KATEX_BLOCK_INFO.exec(token.info) || [];
1080
1225
  const ranges = normalizeRangeStr(rangeStr);
1081
- return `<KaTexBlockWrapper ${options$1 ? `v-bind="${options$1}"` : ""} :ranges='${JSON.stringify(ranges)}'>${katexBlock(tokens[idx].content)}</KaTexBlockWrapper>\n`;
1226
+ return `<KaTexBlockWrapper ${options ? `v-bind="${options}"` : ""} :ranges='${JSON.stringify(ranges)}'>${katexBlock(tokens[idx].content)}</KaTexBlockWrapper>\n`;
1082
1227
  };
1083
1228
  md.inline.ruler.after("escape", "math_inline", math_inline);
1084
1229
  md.block.ruler.after("blockquote", "math_block", math_block, { alt: [
@@ -1090,24 +1235,22 @@ function MarkdownItKatex(md, options) {
1090
1235
  md.renderer.rules.math_inline = inlineRenderer;
1091
1236
  md.renderer.rules.math_block = blockRenderer;
1092
1237
  }
1093
-
1094
- //#endregion
1095
- //#region node/virtual/conditional-styles.ts
1096
- const id$1 = "/@slidev/conditional-styles";
1097
1238
  const templateConditionalStyles = {
1098
- id: id$1,
1099
- async getContent({ data, roots, userRoot }) {
1239
+ id: "/@slidev/conditional-styles",
1240
+ async getContent({ data, roots }) {
1100
1241
  const imports = [];
1101
- for (const root of roots) imports.push(makeAbsoluteImportGlob(id$1, [
1102
- join(root, "styles/index.{ts,js,css}"),
1103
- join(root, "styles.{ts,js,css}"),
1104
- join(root, "style.{ts,js,css}")
1105
- ], {}, userRoot));
1242
+ for (const root of roots) {
1243
+ const importPath = this.makeAbsoluteImportGlob([
1244
+ join(root, "styles/index.{ts,js,css}"),
1245
+ join(root, "styles.{ts,js,css}"),
1246
+ join(root, "style.{ts,js,css}")
1247
+ ]);
1248
+ imports.push(`import ${JSON.stringify(importPath)}`);
1249
+ }
1106
1250
  if (data.features.katex) imports.push(`import "${await resolveImportUrl("katex/dist/katex.min.css")}"`);
1107
1251
  return imports.join("\n");
1108
1252
  }
1109
1253
  };
1110
-
1111
1254
  //#endregion
1112
1255
  //#region node/virtual/configs.ts
1113
1256
  const templateConfigs = {
@@ -1122,59 +1265,24 @@ const templateConfigs = {
1122
1265
  return `export default ${JSON.stringify(config)}`;
1123
1266
  }
1124
1267
  };
1125
-
1126
- //#endregion
1127
- //#region node/virtual/deprecated.ts
1128
- /**
1129
- * Kept for backward compatibility, use #slidev/slides instead
1130
- *
1131
- * @deprecated
1132
- */
1133
- const templateLegacyRoutes = {
1134
- id: "/@slidev/routes",
1135
- getContent() {
1136
- return [`export { slides } from '#slidev/slides'`, `console.warn('[slidev] #slidev/routes is deprecated, use #slidev/slides instead')`].join("\n");
1137
- }
1138
- };
1139
- /**
1140
- * Kept for backward compatibility, use #slidev/title-renderer instead
1141
- *
1142
- * @deprecated
1143
- */
1144
- const templateLegacyTitles = {
1145
- id: "/@slidev/titles.md",
1146
- getContent() {
1147
- return `
1148
- <script setup lang="ts">
1149
- import TitleRenderer from '#slidev/title-renderer'
1150
- defineProps<{ no: number | string }>()
1151
- console.warn('/@slidev/titles.md is deprecated, import from #slidev/title-renderer instead')
1152
- <\/script>
1153
-
1154
- <TitleRenderer :no="no" />
1155
- `;
1156
- }
1157
- };
1158
-
1159
- //#endregion
1160
- //#region node/virtual/global-layers.ts
1161
- const id = `/@slidev/global-layers`;
1162
1268
  const templateGlobalLayers = {
1163
- id,
1164
- getContent({ roots, userRoot }) {
1269
+ id: `/@slidev/global-layers`,
1270
+ getContent({ roots }) {
1271
+ const { makeAbsoluteImportGlob } = this;
1272
+ const imports = [`import { h } from 'vue'`];
1273
+ let importIndex = 0;
1165
1274
  function* getComponent(name, names) {
1166
1275
  yield `const ${name}Components = [\n`;
1167
1276
  for (const root of roots) {
1168
- const globs = names.map((name$1) => join(root, `${name$1}.{ts,js,vue}`));
1169
- yield " Object.values(";
1170
- yield makeAbsoluteImportGlob(id, globs, { import: "default" }, userRoot);
1171
- yield ")[0],\n";
1277
+ const globs = names.map((name) => join(root, `${name}.{ts,js,vue}`));
1278
+ const importName = `__slidev_global_layer_${importIndex++}`;
1279
+ imports.push(`import ${importName} from ${JSON.stringify(makeAbsoluteImportGlob(globs, { import: "default" }))}`);
1280
+ yield ` Object.values(${importName})[0],\n`;
1172
1281
  }
1173
1282
  yield `].filter(Boolean)\n`;
1174
1283
  yield `export const ${name} = { render: () => ${name}Components.map(comp => h(comp)) }\n\n`;
1175
1284
  }
1176
- return [
1177
- `import { h } from 'vue'\n\n`,
1285
+ const body = [
1178
1286
  ...getComponent("GlobalTop", [
1179
1287
  "global",
1180
1288
  "global-top",
@@ -1184,9 +1292,9 @@ const templateGlobalLayers = {
1184
1292
  ...getComponent("SlideTop", ["slide-top", "SlideTop"]),
1185
1293
  ...getComponent("SlideBottom", ["slide-bottom", "SlideBottom"])
1186
1294
  ].join("");
1295
+ return `${imports.join("\n")}\n\n${body}`;
1187
1296
  }
1188
1297
  };
1189
-
1190
1298
  //#endregion
1191
1299
  //#region node/virtual/layouts.ts
1192
1300
  const templateLayouts = {
@@ -1200,7 +1308,6 @@ const templateLayouts = {
1200
1308
  return [imports.join("\n"), `export default {\n${Object.entries(layouts).map(([k, v]) => `"${k}": ${v}`).join(",\n")}\n}`].join("\n\n");
1201
1309
  }
1202
1310
  };
1203
-
1204
1311
  //#endregion
1205
1312
  //#region node/virtual/monaco-deps.ts
1206
1313
  const templateMonacoRunDeps = {
@@ -1226,7 +1333,6 @@ const templateMonacoRunDeps = {
1226
1333
  return result;
1227
1334
  }
1228
1335
  };
1229
-
1230
1336
  //#endregion
1231
1337
  //#region node/virtual/monaco-types.ts
1232
1338
  const templateMonacoTypes = {
@@ -1263,7 +1369,6 @@ const templateMonacoTypes = {
1263
1369
  return result;
1264
1370
  }
1265
1371
  };
1266
-
1267
1372
  //#endregion
1268
1373
  //#region node/virtual/nav-controls.ts
1269
1374
  const templateNavControls = {
@@ -1279,21 +1384,24 @@ export default {
1279
1384
  }`;
1280
1385
  }
1281
1386
  };
1282
-
1283
1387
  //#endregion
1284
1388
  //#region node/virtual/setups.ts
1285
1389
  function createSetupTemplate(name) {
1286
- const id$2 = `/@slidev/setups/${name}`;
1287
1390
  return {
1288
- id: id$2,
1289
- getContent({ roots, userRoot }) {
1290
- return `export default [${roots.map((root) => {
1291
- return `Object.values(${makeAbsoluteImportGlob(id$2, [join(root, `setup/${name}.{ts,js,mts,mjs}`)], { import: "default" }, userRoot)})[0]`;
1292
- }).join(", ")}].filter(Boolean)`;
1391
+ id: `/@slidev/setups/${name}`,
1392
+ getContent({ roots }) {
1393
+ const imports = [];
1394
+ const globs = roots.map((root) => {
1395
+ const glob = join(root, `setup/${name}.{ts,js,mts,mjs}`);
1396
+ const importName = `__slidev_setup_${imports.length}`;
1397
+ imports.push(`import ${importName} from ${JSON.stringify(this.makeAbsoluteImportGlob([glob], { import: "default" }))}`);
1398
+ return `Object.values(${importName})[0]`;
1399
+ });
1400
+ return `${imports.join("\n")}\n\nexport default [${globs.join(", ")}].filter(Boolean)`;
1293
1401
  }
1294
1402
  };
1295
1403
  }
1296
- const setupModules = [
1404
+ const templateSetups = [
1297
1405
  "shiki",
1298
1406
  "code-runners",
1299
1407
  "monaco",
@@ -1304,9 +1412,7 @@ const setupModules = [
1304
1412
  "routes",
1305
1413
  "shortcuts",
1306
1414
  "context-menu"
1307
- ];
1308
- const templateSetups = setupModules.map(createSetupTemplate);
1309
-
1415
+ ].map(createSetupTemplate);
1310
1416
  //#endregion
1311
1417
  //#region node/virtual/slides.ts
1312
1418
  const VIRTUAL_SLIDE_PREFIX = "/@slidev/slides/";
@@ -1344,24 +1450,6 @@ const templateSlides = {
1344
1450
  ].join("\n");
1345
1451
  }
1346
1452
  };
1347
-
1348
- //#endregion
1349
- //#region node/virtual/titles.ts
1350
- const templateTitleRendererMd = {
1351
- id: "/@slidev/title-renderer.md",
1352
- getContent({ data }) {
1353
- const lines = data.slides.map(({ title }, i) => `<template ${i === 0 ? "v-if" : "v-else-if"}="no === ${i + 1}">\n\n${title}\n\n</template>`);
1354
- lines.push(`<script setup lang="ts">`, `import { useSlideContext } from '@slidev/client/context.ts'`, `import { computed } from 'vue'`, `const props = defineProps<{ no?: number | string }>()`, `const { $page } = useSlideContext()`, `const no = computed(() => +(props.no ?? $page.value))`, `<\/script>`);
1355
- return lines.join("\n");
1356
- }
1357
- };
1358
- const templateTitleRenderer = {
1359
- id: "/@slidev/title-renderer",
1360
- async getContent() {
1361
- return "export { default } from \"/@slidev/title-renderer.md\"";
1362
- }
1363
- };
1364
-
1365
1453
  //#endregion
1366
1454
  //#region node/virtual/index.ts
1367
1455
  const templates = [
@@ -1379,7 +1467,6 @@ const templates = [
1379
1467
  templateLegacyRoutes,
1380
1468
  templateLegacyTitles
1381
1469
  ];
1382
-
1383
1470
  //#endregion
1384
1471
  //#region node/vite/loaders.ts
1385
1472
  const RE_WORD_CHARS_ONLY = /^[\w-]+$/;
@@ -1391,13 +1478,14 @@ function createSlidesLoader(options, serverOptions) {
1391
1478
  const hmrSlidesIndexes = /* @__PURE__ */ new Set();
1392
1479
  let server;
1393
1480
  let skipHmr = null;
1481
+ const makeAbsoluteImportGlob = createMakeAbsoluteImportGlob(options.userRoot);
1394
1482
  let sourceIds = resolveSourceIds(data);
1395
- function resolveSourceIds(data$1) {
1483
+ function resolveSourceIds(data) {
1396
1484
  const ids = {
1397
1485
  md: [],
1398
1486
  frontmatter: []
1399
1487
  };
1400
- for (const type of ["md", "frontmatter"]) for (let i = 0; i < data$1.slides.length; i++) ids[type].push(`${data$1.slides[i].source.filepath}__slidev_${i + 1}.${type}`);
1488
+ for (const type of ["md", "frontmatter"]) for (let i = 0; i < data.slides.length; i++) ids[type].push(`${data.slides[i].source.filepath}__slidev_${i + 1}.${type}`);
1401
1489
  return ids;
1402
1490
  }
1403
1491
  function updateServerWatcher() {
@@ -1435,7 +1523,7 @@ function createSlidesLoader(options, serverOptions) {
1435
1523
  if (parsed.errors.length) console.error("ERROR when saving frontmatter", parsed.errors);
1436
1524
  else slide.source.frontmatterDoc = parsed;
1437
1525
  }
1438
- if (body.note) slide.note = slide.source.note = body.note;
1526
+ if (body.note != null) slide.note = slide.source.note = body.note;
1439
1527
  if (body.frontmatter) {
1440
1528
  updateFrontmatterPatch(slide.source, body.frontmatter);
1441
1529
  Object.assign(slide.frontmatter, body.frontmatter);
@@ -1523,32 +1611,38 @@ function createSlidesLoader(options, serverOptions) {
1523
1611
  const moduleEntries = [
1524
1612
  ...ctx.modules.filter((i) => i.id === templateMonacoRunDeps.id || i.id === templateMonacoTypes.id),
1525
1613
  ...vueModules,
1526
- ...Array.from(moduleIds).map((id$2) => ctx.server.moduleGraph.getModuleById(id$2))
1614
+ ...Array.from(moduleIds).map((id) => ctx.server.moduleGraph.getModuleById(id))
1527
1615
  ].filter(notNullish).filter((i) => !i.id?.startsWith("/@id/@vite-icons"));
1528
1616
  updateServerWatcher();
1529
1617
  return moduleEntries;
1530
1618
  },
1531
1619
  resolveId: {
1532
1620
  order: "pre",
1533
- handler(id$2) {
1534
- if (id$2.startsWith("/@slidev/") || id$2.includes("__slidev_")) return id$2;
1621
+ handler(id) {
1622
+ if (id.startsWith("/@slidev/") || id.includes("__slidev_")) return id;
1535
1623
  return null;
1536
1624
  }
1537
1625
  },
1538
- async load(id$2) {
1539
- const template = templates.find((i) => i.id === id$2);
1540
- if (template) return {
1541
- code: await template.getContent.call(this, options),
1542
- map: { mappings: "" }
1543
- };
1544
- const matchFacade = id$2.match(regexSlideFacadeId);
1626
+ async load(id) {
1627
+ const template = templates.find((i) => i.id === id);
1628
+ if (template) {
1629
+ const templateContext = {
1630
+ resolve: this.resolve.bind(this),
1631
+ makeAbsoluteImportGlob
1632
+ };
1633
+ return {
1634
+ code: await template.getContent.call(templateContext, options),
1635
+ map: { mappings: "" }
1636
+ };
1637
+ }
1638
+ const matchFacade = id.match(regexSlideFacadeId);
1545
1639
  if (matchFacade) {
1546
1640
  const [, no, type] = matchFacade;
1547
1641
  const idx = +no - 1;
1548
1642
  const sourceId = JSON.stringify(sourceIds[type][idx]);
1549
1643
  return [`export * from ${sourceId}`, `export { default } from ${sourceId}`].join("\n");
1550
1644
  }
1551
- const matchSource = id$2.match(regexSlideSourceId);
1645
+ const matchSource = id.match(regexSlideSourceId);
1552
1646
  if (matchSource) {
1553
1647
  const [, no, type] = matchSource;
1554
1648
  const idx = +no - 1;
@@ -1600,6 +1694,7 @@ function createSlidesLoader(options, serverOptions) {
1600
1694
  ` frontmatter,`,
1601
1695
  ` filepath: ${JSON.stringify(mode === "dev" ? slide.source.filepath : "")},`,
1602
1696
  ` start: ${JSON.stringify(slide.source.start)},`,
1697
+ ` sourceIndex: ${JSON.stringify(slide.source.index)},`,
1603
1698
  ` id: ${idx},`,
1604
1699
  ` no: ${no},`,
1605
1700
  " },",
@@ -1611,7 +1706,7 @@ function createSlidesLoader(options, serverOptions) {
1611
1706
  };
1612
1707
  }
1613
1708
  }
1614
- if (data.markdownFiles[id$2]) return "";
1709
+ if (data.markdownFiles[id]) return "";
1615
1710
  }
1616
1711
  };
1617
1712
  function renderNote(text = "") {
@@ -1632,15 +1727,14 @@ function createSlidesLoader(options, serverOptions) {
1632
1727
  }
1633
1728
  return notesMd.render(md);
1634
1729
  }
1635
- function withRenderedNote(data$1) {
1730
+ function withRenderedNote(data) {
1636
1731
  return {
1637
- ...data$1,
1732
+ ...data,
1638
1733
  ...withoutNotes && { note: "" },
1639
- noteHTML: renderNote(data$1?.note)
1734
+ noteHTML: renderNote(data?.note)
1640
1735
  };
1641
1736
  }
1642
1737
  }
1643
-
1644
1738
  //#endregion
1645
1739
  //#region node/setups/transformers.ts
1646
1740
  async function setupTransformers(roots) {
@@ -1663,26 +1757,24 @@ async function setupTransformers(roots) {
1663
1757
  }
1664
1758
  return result;
1665
1759
  }
1666
-
1667
1760
  //#endregion
1668
- //#region ../../node_modules/.pnpm/@hedgedoc+markdown-it-plugins@2.1.4_patch_hash=49e14003b6caa0b7d164cbe71da573809d375bab_0dce998d26f79c06311f476731d22630/node_modules/@hedgedoc/markdown-it-plugins/dist/esm/image-size/specialCharacters.js
1761
+ //#region ../../node_modules/.pnpm/@hedgedoc+markdown-it-plugins@2.1.4_patch_hash=49e14003b6caa0b7d164cbe71da573809d375bab_20f9b6719589445333fe4d166d07e531/node_modules/@hedgedoc/markdown-it-plugins/dist/esm/image-size/specialCharacters.js
1669
1762
  var SpecialCharacters;
1670
- (function(SpecialCharacters$1) {
1671
- SpecialCharacters$1[SpecialCharacters$1["EXCLAMATION_MARK"] = 33] = "EXCLAMATION_MARK";
1672
- SpecialCharacters$1[SpecialCharacters$1["OPENING_BRACKET"] = 91] = "OPENING_BRACKET";
1673
- SpecialCharacters$1[SpecialCharacters$1["OPENING_PARENTHESIS"] = 40] = "OPENING_PARENTHESIS";
1674
- SpecialCharacters$1[SpecialCharacters$1["WHITESPACE"] = 32] = "WHITESPACE";
1675
- SpecialCharacters$1[SpecialCharacters$1["NEW_LINE"] = 10] = "NEW_LINE";
1676
- SpecialCharacters$1[SpecialCharacters$1["EQUALS"] = 61] = "EQUALS";
1677
- SpecialCharacters$1[SpecialCharacters$1["LOWER_CASE_X"] = 120] = "LOWER_CASE_X";
1678
- SpecialCharacters$1[SpecialCharacters$1["NUMBER_ZERO"] = 48] = "NUMBER_ZERO";
1679
- SpecialCharacters$1[SpecialCharacters$1["NUMBER_NINE"] = 57] = "NUMBER_NINE";
1680
- SpecialCharacters$1[SpecialCharacters$1["PERCENTAGE"] = 37] = "PERCENTAGE";
1681
- SpecialCharacters$1[SpecialCharacters$1["CLOSING_PARENTHESIS"] = 41] = "CLOSING_PARENTHESIS";
1763
+ (function(SpecialCharacters) {
1764
+ SpecialCharacters[SpecialCharacters["EXCLAMATION_MARK"] = 33] = "EXCLAMATION_MARK";
1765
+ SpecialCharacters[SpecialCharacters["OPENING_BRACKET"] = 91] = "OPENING_BRACKET";
1766
+ SpecialCharacters[SpecialCharacters["OPENING_PARENTHESIS"] = 40] = "OPENING_PARENTHESIS";
1767
+ SpecialCharacters[SpecialCharacters["WHITESPACE"] = 32] = "WHITESPACE";
1768
+ SpecialCharacters[SpecialCharacters["NEW_LINE"] = 10] = "NEW_LINE";
1769
+ SpecialCharacters[SpecialCharacters["EQUALS"] = 61] = "EQUALS";
1770
+ SpecialCharacters[SpecialCharacters["LOWER_CASE_X"] = 120] = "LOWER_CASE_X";
1771
+ SpecialCharacters[SpecialCharacters["NUMBER_ZERO"] = 48] = "NUMBER_ZERO";
1772
+ SpecialCharacters[SpecialCharacters["NUMBER_NINE"] = 57] = "NUMBER_NINE";
1773
+ SpecialCharacters[SpecialCharacters["PERCENTAGE"] = 37] = "PERCENTAGE";
1774
+ SpecialCharacters[SpecialCharacters["CLOSING_PARENTHESIS"] = 41] = "CLOSING_PARENTHESIS";
1682
1775
  })(SpecialCharacters || (SpecialCharacters = {}));
1683
-
1684
1776
  //#endregion
1685
- //#region ../../node_modules/.pnpm/markdown-it@14.1.1/node_modules/markdown-it/lib/token.mjs
1777
+ //#region ../../node_modules/.pnpm/markdown-it@14.2.0/node_modules/markdown-it/lib/token.mjs
1686
1778
  /**
1687
1779
  * class Token
1688
1780
  **/
@@ -1835,10 +1927,8 @@ Token.prototype.attrJoin = function attrJoin(name, value) {
1835
1927
  if (idx < 0) this.attrPush([name, value]);
1836
1928
  else this.attrs[idx][1] = this.attrs[idx][1] + " " + value;
1837
1929
  };
1838
- var token_default = Token;
1839
-
1840
1930
  //#endregion
1841
- //#region ../../node_modules/.pnpm/@hedgedoc+markdown-it-plugins@2.1.4_patch_hash=49e14003b6caa0b7d164cbe71da573809d375bab_0dce998d26f79c06311f476731d22630/node_modules/@hedgedoc/markdown-it-plugins/dist/esm/task-lists/index.js
1931
+ //#region ../../node_modules/.pnpm/@hedgedoc+markdown-it-plugins@2.1.4_patch_hash=49e14003b6caa0b7d164cbe71da573809d375bab_20f9b6719589445333fe4d166d07e531/node_modules/@hedgedoc/markdown-it-plugins/dist/esm/task-lists/index.js
1842
1932
  const checkboxRegex = /^ *\[([\sx])] /i;
1843
1933
  function taskLists(md, options = {
1844
1934
  enabled: false,
@@ -1883,11 +1973,11 @@ function isTodoItem(tokens, index) {
1883
1973
  }
1884
1974
  function todoify(token, options) {
1885
1975
  if (token.children == null) return;
1886
- const id$2 = generateIdForToken(token);
1887
- token.children.splice(0, 0, createCheckboxToken(token, options.enabled, id$2));
1976
+ const id = generateIdForToken(token);
1977
+ token.children.splice(0, 0, createCheckboxToken(token, options.enabled, id));
1888
1978
  token.children[1].content = token.children[1].content.replace(checkboxRegex, "");
1889
1979
  if (options.label) {
1890
- token.children.splice(1, 0, createLabelBeginToken(id$2));
1980
+ token.children.splice(1, 0, createLabelBeginToken(id));
1891
1981
  token.children.push(createLabelEndToken());
1892
1982
  }
1893
1983
  }
@@ -1895,21 +1985,21 @@ function generateIdForToken(token) {
1895
1985
  if (token.map) return `task-item-${token.map[0]}`;
1896
1986
  else return `task-item-${Math.ceil(Math.random() * (1e4 * 1e3) - 1e3)}`;
1897
1987
  }
1898
- function createCheckboxToken(token, enabled, id$2) {
1899
- const checkbox = new token_default("taskListItemCheckbox", "", 0);
1988
+ function createCheckboxToken(token, enabled, id) {
1989
+ const checkbox = new Token("taskListItemCheckbox", "", 0);
1900
1990
  if (!enabled) checkbox.attrSet("disabled", "true");
1901
1991
  if (token.map) checkbox.attrSet("line", token.map[0].toString());
1902
- checkbox.attrSet("id", id$2);
1992
+ checkbox.attrSet("id", id);
1903
1993
  if (checkboxRegex.exec(token.content)?.[1].toLowerCase() === "x") checkbox.attrSet("checked", "true");
1904
1994
  return checkbox;
1905
1995
  }
1906
- function createLabelBeginToken(id$2) {
1907
- const labelBeginToken = new token_default("taskListItemLabel_open", "", 1);
1908
- labelBeginToken.attrSet("id", id$2);
1996
+ function createLabelBeginToken(id) {
1997
+ const labelBeginToken = new Token("taskListItemLabel_open", "", 1);
1998
+ labelBeginToken.attrSet("id", id);
1909
1999
  return labelBeginToken;
1910
2000
  }
1911
2001
  function createLabelEndToken() {
1912
- return new token_default("taskListItemLabel_close", "", -1);
2002
+ return new Token("taskListItemLabel_close", "", -1);
1913
2003
  }
1914
2004
  function isInline(token) {
1915
2005
  return token.type === "inline";
@@ -1923,38 +2013,227 @@ function isListItem(token) {
1923
2013
  function startsWithTodoMarkdown(token) {
1924
2014
  return checkboxRegex.test(token.content);
1925
2015
  }
1926
-
2016
+ //#endregion
2017
+ //#region node/vite/monacoWrite.ts
2018
+ const monacoWriterWhitelist = /* @__PURE__ */ new Set();
2019
+ function createMonacoWriterPlugin({ userRoot }) {
2020
+ return {
2021
+ name: "slidev:monaco-write",
2022
+ apply: "serve",
2023
+ configureServer(server) {
2024
+ server.ws.on("connection", (socket) => {
2025
+ socket.on("message", async (data) => {
2026
+ let json;
2027
+ try {
2028
+ json = JSON.parse(data.toString());
2029
+ } catch {
2030
+ return;
2031
+ }
2032
+ if (json.type === "custom" && json.event === "slidev:monaco-write") {
2033
+ const { file, content } = json.data;
2034
+ if (!monacoWriterWhitelist.has(file)) {
2035
+ console.error(`[Slidev] Unauthorized file write: ${file}`);
2036
+ return;
2037
+ }
2038
+ const filepath = path.join(userRoot, file);
2039
+ console.log("[Slidev] Writing file:", filepath);
2040
+ await fs$1.writeFile(filepath, content, "utf-8");
2041
+ }
2042
+ });
2043
+ });
2044
+ }
2045
+ };
2046
+ }
2047
+ //#endregion
2048
+ //#region node/syntax/snippet.ts
2049
+ const RE_NEWLINE = /\r?\n/;
2050
+ function dedent(text) {
2051
+ const lines = text.split("\n");
2052
+ const minIndentLength = lines.reduce((acc, line) => {
2053
+ for (let i = 0; i < line.length; i++) if (line[i] !== " " && line[i] !== " ") return Math.min(i, acc);
2054
+ return acc;
2055
+ }, Number.POSITIVE_INFINITY);
2056
+ if (minIndentLength < Number.POSITIVE_INFINITY) return lines.map((x) => x.slice(minIndentLength)).join("\n");
2057
+ return text;
2058
+ }
2059
+ const markers = [
2060
+ {
2061
+ start: /^\s*\/\/\s*#?region\b\s*(.*?)\s*$/,
2062
+ end: /^\s*\/\/\s*#?endregion\b\s*(.*?)\s*$/
2063
+ },
2064
+ {
2065
+ start: /^\s*<!--\s*#?region\b\s*(.*?)\s*-->/,
2066
+ end: /^\s*<!--\s*#?endregion\b\s*(.*?)\s*-->/
2067
+ },
2068
+ {
2069
+ start: /^\s*\/\*\s*#region\b\s*(.*?)\s*\*\//,
2070
+ end: /^\s*\/\*\s*#endregion\b\s*(.*?)\s*\*\//
2071
+ },
2072
+ {
2073
+ start: /^\s*#[rR]egion\b\s*(.*?)\s*$/,
2074
+ end: /^\s*#[eE]nd ?[rR]egion\b\s*(.*?)\s*$/
2075
+ },
2076
+ {
2077
+ start: /^\s*#\s*#?region\b\s*(.*?)\s*$/,
2078
+ end: /^\s*#\s*#?endregion\b\s*(.*?)\s*$/
2079
+ },
2080
+ {
2081
+ start: /^\s*(?:--|::|@?REM)\s*#region\b\s*(.*?)\s*$/,
2082
+ end: /^\s*(?:--|::|@?REM)\s*#endregion\b\s*(.*?)\s*$/
2083
+ },
2084
+ {
2085
+ start: /^\s*#pragma\s+region\b\s*(.*?)\s*$/,
2086
+ end: /^\s*#pragma\s+endregion\b\s*(.*?)\s*$/
2087
+ },
2088
+ {
2089
+ start: /^\s*\(\*\s*#region\b\s*(.*?)\s*\*\)/,
2090
+ end: /^\s*\(\*\s*#endregion\b\s*(.*?)\s*\*\)/
2091
+ }
2092
+ ];
2093
+ function findRegion(lines, regionName) {
2094
+ let chosen = null;
2095
+ for (let i = 0; i < lines.length; i++) {
2096
+ for (const re of markers) if (re.start.exec(lines[i])?.[1] === regionName) {
2097
+ chosen = {
2098
+ re,
2099
+ start: i + 1
2100
+ };
2101
+ break;
2102
+ }
2103
+ if (chosen) break;
2104
+ }
2105
+ if (!chosen) return null;
2106
+ let counter = 1;
2107
+ for (let i = chosen.start; i < lines.length; i++) {
2108
+ if (chosen.re.start.exec(lines[i])?.[1] === regionName) {
2109
+ counter++;
2110
+ continue;
2111
+ }
2112
+ const endRegion = chosen.re.end.exec(lines[i])?.[1];
2113
+ if (endRegion === regionName || endRegion === "") {
2114
+ if (--counter === 0) return {
2115
+ ...chosen,
2116
+ end: i
2117
+ };
2118
+ }
2119
+ }
2120
+ return null;
2121
+ }
2122
+ const RE_SNIPPET_IMPORT = /^<<<[ \t]*(\S.*?)(#[\w-]+)?[ \t]*(?:[ \t](\S+?))?[ \t]*(\{.*)?$/;
2123
+ function resolveSnippetImport(lineText, userRoot, slide) {
2124
+ const match = lineText.trimStart().match(RE_SNIPPET_IMPORT);
2125
+ if (!match) return null;
2126
+ let [, filepath = "", regionName = "", lang = "", meta = ""] = match;
2127
+ const dir = path.dirname(slide.source.filepath);
2128
+ const src = slash(filepath.startsWith("@/") ? path.resolve(userRoot, filepath.slice(2)) : path.resolve(dir, filepath));
2129
+ lang = lang.trim() || path.extname(filepath).slice(1);
2130
+ meta = meta.trim();
2131
+ if (!(fs.existsSync(src) && fs.statSync(src).isFile())) throw new Error(`Code snippet path not found: ${src}`);
2132
+ let content = fs.readFileSync(src, "utf8");
2133
+ if (regionName) {
2134
+ const lines = content.split(RE_NEWLINE);
2135
+ const region = findRegion(lines, regionName.slice(1));
2136
+ if (region) content = dedent(lines.slice(region.start, region.end).filter((l) => !(region.re.start.test(l) || region.re.end.test(l))).join("\n"));
2137
+ }
2138
+ return {
2139
+ content,
2140
+ filepath,
2141
+ lang,
2142
+ meta,
2143
+ src
2144
+ };
2145
+ }
2146
+ function MarkdownItSnippet(md, { userRoot, data: { watchFiles, slides } }) {
2147
+ md.block.ruler.before("fence", "snippet_import", (state, startLine, _endLine, silent) => {
2148
+ const pos = state.bMarks[startLine] + state.tShift[startLine];
2149
+ const max = state.eMarks[startLine];
2150
+ const lineText = state.src.slice(pos, max);
2151
+ if (!lineText.match(RE_SNIPPET_IMPORT)) return false;
2152
+ if (silent) return true;
2153
+ const slideNo = state.env.id?.match(regexSlideSourceId);
2154
+ const slide = slideNo ? slides[slideNo[1] - 1] : null;
2155
+ if (!slide) {
2156
+ console.warn(yellow(`[markdown-it-snippet] Snippet syntax is not supported in ${state.env.id || "unknown source"}. Skipped.`));
2157
+ return false;
2158
+ }
2159
+ const snippet = resolveSnippetImport(lineText, userRoot, slide);
2160
+ if (!snippet) return false;
2161
+ const { content, filepath, src } = snippet;
2162
+ let { lang, meta } = snippet;
2163
+ if (meta.includes("{monaco-write}")) {
2164
+ monacoWriterWhitelist.add(filepath);
2165
+ lang = lang.trim();
2166
+ meta = meta.replace("{monaco-write}", "").trim() || "{}";
2167
+ const safeFilepath = JSON.stringify(filepath).slice(1, -1);
2168
+ const encoded = lz.compressToBase64(content);
2169
+ const token = state.push("html_block", "", 0);
2170
+ token.content = `<Monaco writable="${safeFilepath}" code-lz="${encoded}" lang="${lang}" v-bind="${meta}" />\n`;
2171
+ token.map = [startLine, startLine + 1];
2172
+ } else {
2173
+ watchFiles[src] ??= /* @__PURE__ */ new Set();
2174
+ watchFiles[src].add(slide.index);
2175
+ const token = state.push("fence", "code", 0);
2176
+ token.info = `${lang} ${meta}`.trim();
2177
+ token.content = content.endsWith("\n") ? content : `${content}\n`;
2178
+ token.map = [startLine, startLine + 1];
2179
+ }
2180
+ state.line = startLine + 1;
2181
+ return true;
2182
+ }, { alt: [
2183
+ "paragraph",
2184
+ "reference",
2185
+ "blockquote",
2186
+ "list"
2187
+ ] });
2188
+ }
1927
2189
  //#endregion
1928
2190
  //#region node/syntax/codeblock/magic-move.ts
1929
2191
  const RE_MAGIC_MOVE_INFO = /^(?:md|markdown) magic-move\s*(?:\[([^\]]*)\])?\s*(\{[^}]*\})?/;
1930
2192
  const RE_CODE_BLOCK = /^```([\w'-]+)?(?:[ \t]*|[ \t][ \w\t'-]*)(?:\[([^\]]*)\])?[ \t]*(?:\{([\w*,|-]+)\}[ \t]*(\{[^}]*\})?([^\r\n]*))?\r?\n((?:(?!^```)[\s\S])*?)^```$/gm;
2193
+ const RE_INNER_CODE_FENCE = /^```/;
1931
2194
  const RE_LINES_TRUE = /\blines: *true\b/;
1932
2195
  const RE_LINES_FALSE = /\blines: *false\b/;
1933
2196
  function parseLineNumbersOption(options) {
1934
2197
  return RE_LINES_TRUE.test(options) ? true : RE_LINES_FALSE.test(options) ? false : void 0;
1935
2198
  }
1936
- var magic_move_default = defineCodeblockTransformer(async ({ info, fence, code, options: { data: { config }, utils: { shikiOptions, shiki } } }) => {
2199
+ function resolveMagicMoveSnippetImports(code, userRoot, slide, watchFiles) {
2200
+ let inCodeBlock = false;
2201
+ return code.split(/\r?\n/).map((line) => {
2202
+ if (RE_INNER_CODE_FENCE.test(line)) {
2203
+ inCodeBlock = !inCodeBlock;
2204
+ return line;
2205
+ }
2206
+ if (inCodeBlock) return line;
2207
+ const snippet = resolveSnippetImport(line, userRoot, slide);
2208
+ if (!snippet) return line;
2209
+ watchFiles[snippet.src] ??= /* @__PURE__ */ new Set();
2210
+ watchFiles[snippet.src].add(slide.index);
2211
+ return `\`\`\`${`${snippet.lang} ${snippet.meta}`.trim()}\n${snippet.content.endsWith("\n") ? snippet.content : `${snippet.content}\n`}\`\`\``;
2212
+ }).join("\n");
2213
+ }
2214
+ var magic_move_default = defineCodeblockTransformer(async ({ info, fence, code, slide, options: { userRoot, data: { config, watchFiles }, utils: { shikiOptions, shiki } } }) => {
1937
2215
  if (fence !== 4) return;
1938
2216
  const match = info.match(RE_MAGIC_MOVE_INFO);
1939
2217
  if (!match) return;
1940
2218
  const [, title = "", options = "{}"] = match;
1941
2219
  const defaultLineNumbers = parseLineNumbersOption(options) ?? config.lineNumbers;
1942
- const matches = Array.from(code.matchAll(RE_CODE_BLOCK));
2220
+ const resolvedCode = slide ? resolveMagicMoveSnippetImports(code, userRoot, slide, watchFiles) : code;
2221
+ const matches = Array.from(resolvedCode.matchAll(RE_CODE_BLOCK));
1943
2222
  if (!matches.length) throw new Error("Magic Move block must contain at least one code block");
1944
2223
  const ranges = matches.map((i) => normalizeRangeStr(i[3]));
1945
2224
  const steps = await Promise.all(matches.map(async (i) => {
1946
2225
  const lang = i[1];
1947
2226
  const lineNumbers = parseLineNumbersOption(i[4]) ?? defaultLineNumbers;
1948
- const code$1 = i[6].trimEnd();
1949
- const options$1 = {
2227
+ const code = i[6].trimEnd();
2228
+ const options = {
1950
2229
  ...shikiOptions,
1951
2230
  lang
1952
2231
  };
1953
- const { tokens, bg, fg: fg$1, rootStyle, themeName } = await shiki.codeToTokens(code$1, options$1);
2232
+ const { tokens, bg, fg, rootStyle, themeName } = await shiki.codeToTokens(code, options);
1954
2233
  return {
1955
- ...toKeyedTokens(code$1, tokens, JSON.stringify([lang, "themes" in options$1 ? options$1.themes : options$1.theme]), lineNumbers),
2234
+ ...toKeyedTokens(code, tokens, JSON.stringify([lang, "themes" in options ? options.themes : options.theme]), lineNumbers),
1956
2235
  bg,
1957
- fg: fg$1,
2236
+ fg,
1958
2237
  rootStyle,
1959
2238
  themeName,
1960
2239
  lang
@@ -1962,7 +2241,6 @@ var magic_move_default = defineCodeblockTransformer(async ({ info, fence, code,
1962
2241
  }));
1963
2242
  return `<ShikiMagicMove v-bind="${options}" steps-lz="${lz.compressToBase64(JSON.stringify(steps))}" :title='${JSON.stringify(title)}' :step-ranges='${JSON.stringify(ranges)}' />`;
1964
2243
  });
1965
-
1966
2244
  //#endregion
1967
2245
  //#region node/syntax/codeblock/mermaid.ts
1968
2246
  const RE_MERMAID = /^mermaid\s*(\{[^\n]*\})?/;
@@ -1972,7 +2250,6 @@ var mermaid_default = defineCodeblockTransformer(async ({ info, code }) => {
1972
2250
  const [, options] = match;
1973
2251
  return `<Mermaid ${options ? `v-bind="${options}"` : ""} code-lz="${lz.compressToBase64(code.trim())}" />`;
1974
2252
  });
1975
-
1976
2253
  //#endregion
1977
2254
  //#region node/syntax/codeblock/monaco.ts
1978
2255
  const RE_MONACO = /^([\w'-]+)?\s*\{(monaco[\w-]*)\}\s*(\{[^}]*\})?(.*)$/;
@@ -1991,7 +2268,6 @@ var monaco_default = defineCodeblockTransformer(async ({ info, code, options: {
1991
2268
  } else encoded = lz.compressToBase64(code);
1992
2269
  return `<Monaco ${options ? `v-bind="${options}"` : ""} ${monaco === "monaco-run" ? "runnable" : ""} lang="${lang}" code-lz="${encoded}" ${diff} />`;
1993
2270
  });
1994
-
1995
2271
  //#endregion
1996
2272
  //#region node/syntax/codeblock/plant-uml.ts
1997
2273
  const RE_PLANT_UML = /^plantuml\s*(\{[^\n]*\})?/;
@@ -2001,7 +2277,6 @@ var plant_uml_default = defineCodeblockTransformer(async ({ info, code, options:
2001
2277
  const [, options] = match;
2002
2278
  return `<PlantUml ${options ? `v-bind="${options}"` : ""} code="${encode(code.trim())}"${plantUmlServer === void 0 ? "" : ` server=${JSON.stringify(plantUmlServer)}`} />`;
2003
2279
  });
2004
-
2005
2280
  //#endregion
2006
2281
  //#region node/syntax/codeblock/wrapper.ts
2007
2282
  const RE_BLOCK_INFO = /^([\w'-]+)?(?:[ \t]*|[ \t][ \w\t'-]*)(?:\[([^\]]*)\])?[ \t]*(?:\{([\w,|\-*]+)\})?[ \t]*(\{[^}]*\})?(.*)$/;
@@ -2012,7 +2287,6 @@ var wrapper_default = defineCodeblockTransformer(async ({ info, renderHighlighte
2012
2287
  const code = await renderHighlighted({ info: `${lang} ${rest}` });
2013
2288
  return `<CodeBlockWrapper ${optionsProp} title=${JSON.stringify(title)} :ranges='${JSON.stringify(ranges)}'>${escapeVueInCode(code)}</CodeBlockWrapper>`;
2014
2289
  });
2015
-
2016
2290
  //#endregion
2017
2291
  //#region node/syntax/codeblock/index.ts
2018
2292
  function MarkdownItCodeblocks(md, options, extraTransformers) {
@@ -2048,7 +2322,6 @@ function MarkdownItCodeblocks(md, options, extraTransformers) {
2048
2322
  throw new Error("Should not reach here");
2049
2323
  };
2050
2324
  }
2051
-
2052
2325
  //#endregion
2053
2326
  //#region node/syntax/drag.ts
2054
2327
  const dragComponentRegex = /<(v-?drag-?\w*)([\s>])/i;
@@ -2056,8 +2329,8 @@ const dragDirectiveRegex = /(?<![</\w])v-drag(=".*?")?/i;
2056
2329
  function MarkdownItVDrag(md, markdownTransformMap) {
2057
2330
  const visited = /* @__PURE__ */ new WeakSet();
2058
2331
  const sourceMapConsumers = /* @__PURE__ */ new WeakMap();
2059
- function getSourceMapConsumer(id$2) {
2060
- const s = id$2 && markdownTransformMap.get(id$2);
2332
+ function getSourceMapConsumer(id) {
2333
+ const s = id && markdownTransformMap.get(id);
2061
2334
  if (!s) return void 0;
2062
2335
  let smc = sourceMapConsumers.get(s);
2063
2336
  if (smc) return smc;
@@ -2107,7 +2380,6 @@ function MarkdownItVDrag(md, markdownTransformMap) {
2107
2380
  });
2108
2381
  };
2109
2382
  }
2110
-
2111
2383
  //#endregion
2112
2384
  //#region node/syntax/escape-code.ts
2113
2385
  const RE_CODE_TAG_OPEN = /^<code/;
@@ -2117,7 +2389,6 @@ function MarkdownItEscapeInlineCode(md) {
2117
2389
  return (await codeInline(tokens, idx, options, env, self)).replace(RE_CODE_TAG_OPEN, "<code v-pre");
2118
2390
  };
2119
2391
  }
2120
-
2121
2392
  //#endregion
2122
2393
  //#region node/syntax/scoped.ts
2123
2394
  const RE_STYLE_TAG_OPEN = /<style\b([^>]*)>/gi;
@@ -2134,7 +2405,6 @@ function MarkdownItStyleScoped(md) {
2134
2405
  const htmlInline = md.renderer.rules.html_inline;
2135
2406
  md.renderer.rules.html_inline = async (...args) => addScoped(await htmlInline(...args));
2136
2407
  }
2137
-
2138
2408
  //#endregion
2139
2409
  //#region node/syntax/shiki.ts
2140
2410
  async function MarkdownItShiki({ data: { config }, mode, utils: { shiki, shikiOptions } }) {
@@ -2152,7 +2422,10 @@ async function MarkdownItShiki({ data: { config }, mode, utils: { shiki, shikiOp
2152
2422
  ]);
2153
2423
  return transformerTwoslash({
2154
2424
  explicitTrigger: true,
2155
- twoslashOptions: { handbookOptions: { noErrorValidation: true } }
2425
+ twoslashOptions: {
2426
+ compilerOptions: { ignoreDeprecations: "6.0" },
2427
+ handbookOptions: { noErrorValidation: true }
2428
+ }
2156
2429
  });
2157
2430
  }
2158
2431
  const transformers = [
@@ -2179,7 +2452,6 @@ function transformerTwoslashConditional() {
2179
2452
  }
2180
2453
  };
2181
2454
  }
2182
-
2183
2455
  //#endregion
2184
2456
  //#region node/syntax/slot-sugar.ts
2185
2457
  const RE_SLOT_MARKER = /^::\s*([\w.\-:]+)\s*::\s*$/;
@@ -2230,167 +2502,6 @@ function MarkdownItSlotSugar(md) {
2230
2502
  state.tokens = newTokens;
2231
2503
  });
2232
2504
  }
2233
-
2234
- //#endregion
2235
- //#region node/vite/monacoWrite.ts
2236
- const monacoWriterWhitelist = /* @__PURE__ */ new Set();
2237
- function createMonacoWriterPlugin({ userRoot }) {
2238
- return {
2239
- name: "slidev:monaco-write",
2240
- apply: "serve",
2241
- configureServer(server) {
2242
- server.ws.on("connection", (socket) => {
2243
- socket.on("message", async (data) => {
2244
- let json;
2245
- try {
2246
- json = JSON.parse(data.toString());
2247
- } catch {
2248
- return;
2249
- }
2250
- if (json.type === "custom" && json.event === "slidev:monaco-write") {
2251
- const { file, content } = json.data;
2252
- if (!monacoWriterWhitelist.has(file)) {
2253
- console.error(`[Slidev] Unauthorized file write: ${file}`);
2254
- return;
2255
- }
2256
- const filepath = path.join(userRoot, file);
2257
- console.log("[Slidev] Writing file:", filepath);
2258
- await fs$1.writeFile(filepath, content, "utf-8");
2259
- }
2260
- });
2261
- });
2262
- }
2263
- };
2264
- }
2265
-
2266
- //#endregion
2267
- //#region node/syntax/snippet.ts
2268
- const RE_NEWLINE = /\r?\n/;
2269
- function dedent(text) {
2270
- const lines = text.split("\n");
2271
- const minIndentLength = lines.reduce((acc, line) => {
2272
- for (let i = 0; i < line.length; i++) if (line[i] !== " " && line[i] !== " ") return Math.min(i, acc);
2273
- return acc;
2274
- }, Number.POSITIVE_INFINITY);
2275
- if (minIndentLength < Number.POSITIVE_INFINITY) return lines.map((x) => x.slice(minIndentLength)).join("\n");
2276
- return text;
2277
- }
2278
- const markers = [
2279
- {
2280
- start: /^\s*\/\/\s*#?region\b\s*(.*?)\s*$/,
2281
- end: /^\s*\/\/\s*#?endregion\b\s*(.*?)\s*$/
2282
- },
2283
- {
2284
- start: /^\s*<!--\s*#?region\b\s*(.*?)\s*-->/,
2285
- end: /^\s*<!--\s*#?endregion\b\s*(.*?)\s*-->/
2286
- },
2287
- {
2288
- start: /^\s*\/\*\s*#region\b\s*(.*?)\s*\*\//,
2289
- end: /^\s*\/\*\s*#endregion\b\s*(.*?)\s*\*\//
2290
- },
2291
- {
2292
- start: /^\s*#[rR]egion\b\s*(.*?)\s*$/,
2293
- end: /^\s*#[eE]nd ?[rR]egion\b\s*(.*?)\s*$/
2294
- },
2295
- {
2296
- start: /^\s*#\s*#?region\b\s*(.*?)\s*$/,
2297
- end: /^\s*#\s*#?endregion\b\s*(.*?)\s*$/
2298
- },
2299
- {
2300
- start: /^\s*(?:--|::|@?REM)\s*#region\b\s*(.*?)\s*$/,
2301
- end: /^\s*(?:--|::|@?REM)\s*#endregion\b\s*(.*?)\s*$/
2302
- },
2303
- {
2304
- start: /^\s*#pragma\s+region\b\s*(.*?)\s*$/,
2305
- end: /^\s*#pragma\s+endregion\b\s*(.*?)\s*$/
2306
- },
2307
- {
2308
- start: /^\s*\(\*\s*#region\b\s*(.*?)\s*\*\)/,
2309
- end: /^\s*\(\*\s*#endregion\b\s*(.*?)\s*\*\)/
2310
- }
2311
- ];
2312
- function findRegion(lines, regionName) {
2313
- let chosen = null;
2314
- for (let i = 0; i < lines.length; i++) {
2315
- for (const re of markers) if (re.start.exec(lines[i])?.[1] === regionName) {
2316
- chosen = {
2317
- re,
2318
- start: i + 1
2319
- };
2320
- break;
2321
- }
2322
- if (chosen) break;
2323
- }
2324
- if (!chosen) return null;
2325
- let counter = 1;
2326
- for (let i = chosen.start; i < lines.length; i++) {
2327
- if (chosen.re.start.exec(lines[i])?.[1] === regionName) {
2328
- counter++;
2329
- continue;
2330
- }
2331
- const endRegion = chosen.re.end.exec(lines[i])?.[1];
2332
- if (endRegion === regionName || endRegion === "") {
2333
- if (--counter === 0) return {
2334
- ...chosen,
2335
- end: i
2336
- };
2337
- }
2338
- }
2339
- return null;
2340
- }
2341
- const RE_SNIPPET_IMPORT = /^<<<[ \t]*(\S.*?)(#[\w-]+)?[ \t]*(?:[ \t](\S+?))?[ \t]*(\{.*)?$/;
2342
- function MarkdownItSnippet(md, { userRoot, data: { watchFiles, slides } }) {
2343
- md.block.ruler.before("fence", "snippet_import", (state, startLine, _endLine, silent) => {
2344
- const pos = state.bMarks[startLine] + state.tShift[startLine];
2345
- const max = state.eMarks[startLine];
2346
- const match = state.src.slice(pos, max).match(RE_SNIPPET_IMPORT);
2347
- if (!match) return false;
2348
- if (silent) return true;
2349
- let [, filepath = "", regionName = "", lang = "", meta = ""] = match;
2350
- const slideNo = state.env.id?.match(regexSlideSourceId);
2351
- const slide = slideNo ? slides[slideNo[1] - 1] : null;
2352
- if (!slide) {
2353
- console.warn(yellow(`[markdown-it-snippet] Snippet syntax is not supported in ${state.env.id || "unknown source"}. Skipped.`));
2354
- return false;
2355
- }
2356
- const dir = path.dirname(slide.source.filepath);
2357
- const src = slash(filepath.startsWith("@/") ? path.resolve(userRoot, filepath.slice(2)) : path.resolve(dir, filepath));
2358
- lang = lang.trim() || path.extname(filepath).slice(1);
2359
- meta = meta.trim();
2360
- if (!(fs.existsSync(src) && fs.statSync(src).isFile())) throw new Error(`Code snippet path not found: ${src}`);
2361
- let content = fs.readFileSync(src, "utf8");
2362
- if (regionName) {
2363
- const lines = content.split(RE_NEWLINE);
2364
- const region = findRegion(lines, regionName.slice(1));
2365
- if (region) content = dedent(lines.slice(region.start, region.end).filter((l) => !(region.re.start.test(l) || region.re.end.test(l))).join("\n"));
2366
- }
2367
- if (meta.includes("{monaco-write}")) {
2368
- monacoWriterWhitelist.add(filepath);
2369
- lang = lang.trim();
2370
- meta = meta.replace("{monaco-write}", "").trim() || "{}";
2371
- const safeFilepath = JSON.stringify(filepath).slice(1, -1);
2372
- const encoded = lz.compressToBase64(content);
2373
- const token = state.push("html_block", "", 0);
2374
- token.content = `<Monaco writable="${safeFilepath}" code-lz="${encoded}" lang="${lang}" v-bind="${meta}" />\n`;
2375
- token.map = [startLine, startLine + 1];
2376
- } else {
2377
- watchFiles[src] ??= /* @__PURE__ */ new Set();
2378
- watchFiles[src].add(slide.index);
2379
- const token = state.push("fence", "code", 0);
2380
- token.info = `${lang} ${meta}`.trim();
2381
- token.content = content.endsWith("\n") ? content : `${content}\n`;
2382
- token.map = [startLine, startLine + 1];
2383
- }
2384
- state.line = startLine + 1;
2385
- return true;
2386
- }, { alt: [
2387
- "paragraph",
2388
- "reference",
2389
- "blockquote",
2390
- "list"
2391
- ] });
2392
- }
2393
-
2394
2505
  //#endregion
2395
2506
  //#region node/syntax/index.ts
2396
2507
  async function useMarkdownItPlugins(md, options, markdownTransformMap, codeblockTransformers) {
@@ -2413,7 +2524,6 @@ async function useMarkdownItPlugins(md, options, markdownTransformMap, codeblock
2413
2524
  md.use(MarkdownItStyleScoped);
2414
2525
  md.use(MarkdownItGitHubAlerts);
2415
2526
  }
2416
-
2417
2527
  //#endregion
2418
2528
  //#region node/vite/markdown.ts
2419
2529
  const RE_MD_EXT$1 = /\.md$/;
@@ -2446,13 +2556,13 @@ async function createMarkdownPlugin(options, { markdown: mdOptions }) {
2446
2556
  },
2447
2557
  transforms: {
2448
2558
  ...mdOptions?.transforms,
2449
- async before(code, id$2) {
2450
- if (options.data.markdownFiles[id$2]) return "";
2451
- code = await mdOptions?.transforms?.before?.(code, id$2) ?? code;
2452
- const match = id$2.match(regexSlideSourceId);
2559
+ async before(code, id) {
2560
+ if (options.data.markdownFiles[id]) return "";
2561
+ code = await mdOptions?.transforms?.before?.(code, id) ?? code;
2562
+ const match = id.match(regexSlideSourceId);
2453
2563
  if (!match) return code;
2454
2564
  const s = new MagicString(code);
2455
- markdownTransformMap.set(id$2, s);
2565
+ markdownTransformMap.set(id, s);
2456
2566
  const ctx = {
2457
2567
  s,
2458
2568
  slide: options.data.slides[+match[1] - 1],
@@ -2468,19 +2578,18 @@ async function createMarkdownPlugin(options, { markdown: mdOptions }) {
2468
2578
  }
2469
2579
  });
2470
2580
  }
2471
-
2472
2581
  //#endregion
2473
2582
  //#region node/vite/monacoTypes.ts
2474
2583
  function createMonacoTypesLoader({ userRoot, utils }) {
2475
2584
  return {
2476
2585
  name: "slidev:monaco-types-loader",
2477
- resolveId(id$2) {
2478
- if (id$2.startsWith("/@slidev-monaco-types/")) return id$2;
2586
+ resolveId(id) {
2587
+ if (id.startsWith("/@slidev-monaco-types/")) return id;
2479
2588
  return null;
2480
2589
  },
2481
- async load(id$2) {
2482
- if (!id$2.startsWith("/@slidev-monaco-types/")) return null;
2483
- const url = new URL(id$2, "http://localhost");
2590
+ async load(id) {
2591
+ if (!id.startsWith("/@slidev-monaco-types/")) return null;
2592
+ const url = new URL(id, "http://localhost");
2484
2593
  if (url.pathname === "/@slidev-monaco-types/resolve") {
2485
2594
  const query = new URLSearchParams(url.search);
2486
2595
  const pkg = query.get("pkg");
@@ -2490,7 +2599,7 @@ function createMonacoTypesLoader({ userRoot, utils }) {
2490
2599
  const root = slash(dirname(pkgJsonPath));
2491
2600
  const pkgJson = JSON.parse(await fs$1.readFile(pkgJsonPath, "utf-8"));
2492
2601
  let deps = Object.keys(pkgJson.dependencies ?? {});
2493
- deps = deps.filter((pkg$1) => !utils.isMonacoTypesIgnored(pkg$1));
2602
+ deps = deps.filter((pkg) => !utils.isMonacoTypesIgnored(pkg));
2494
2603
  return [`import "/@slidev-monaco-types/load?${new URLSearchParams({
2495
2604
  root,
2496
2605
  name: pkgJson.name
@@ -2519,7 +2628,6 @@ function createMonacoTypesLoader({ userRoot, utils }) {
2519
2628
  }
2520
2629
  };
2521
2630
  }
2522
-
2523
2631
  //#endregion
2524
2632
  //#region node/vite/patchMonacoSourceMap.ts
2525
2633
  const postfixRE = /[?#].*$/;
@@ -2533,20 +2641,19 @@ function createPatchMonacoSourceMapPlugin() {
2533
2641
  return {
2534
2642
  name: "slidev:patch-monaco-sourcemap",
2535
2643
  enforce: "pre",
2536
- load(id$2) {
2537
- if (!id$2.includes("node_modules/monaco-editor/esm/vs/base")) return;
2538
- return readFile(cleanUrl(id$2), "utf-8");
2644
+ load(id) {
2645
+ if (!id.includes("node_modules/monaco-editor/esm/vs/base")) return;
2646
+ return readFile(cleanUrl(id), "utf-8");
2539
2647
  }
2540
2648
  };
2541
2649
  }
2542
-
2543
2650
  //#endregion
2544
2651
  //#region node/vite/remoteAssets.ts
2545
2652
  async function createRemoteAssetsPlugin({ data: { config }, mode }, pluginOptions) {
2546
2653
  if (!(config.remoteAssets === true || config.remoteAssets === mode)) return;
2547
2654
  const { VitePluginRemoteAssets, DefaultRules } = await import("vite-plugin-remote-assets");
2548
2655
  return VitePluginRemoteAssets({
2549
- resolveMode: (id$2) => id$2.endsWith("index.html") ? "relative" : "@fs",
2656
+ resolveMode: (id) => id.endsWith("index.html") ? "relative" : "@fs",
2550
2657
  awaitDownload: mode === "build",
2551
2658
  ...pluginOptions.remoteAssets,
2552
2659
  rules: [
@@ -2559,7 +2666,6 @@ async function createRemoteAssetsPlugin({ data: { config }, mode }, pluginOption
2559
2666
  ]
2560
2667
  });
2561
2668
  }
2562
-
2563
2669
  //#endregion
2564
2670
  //#region node/integrations/drawings.ts
2565
2671
  function resolveDrawingsDir(options) {
@@ -2575,10 +2681,10 @@ async function loadDrawings(options) {
2575
2681
  suppressErrors: true
2576
2682
  });
2577
2683
  const obj = {};
2578
- await Promise.all(files.map(async (path$1) => {
2579
- const num = +basename(path$1, ".svg");
2684
+ await Promise.all(files.map(async (path) => {
2685
+ const num = +basename(path, ".svg");
2580
2686
  if (Number.isNaN(num)) return;
2581
- const lines = (await fs$1.readFile(path$1, "utf8")).split(/\n/g);
2687
+ const lines = (await fs$1.readFile(path, "utf8")).split(/\n/g);
2582
2688
  obj[num.toString()] = lines.slice(1, -1).join("\n");
2583
2689
  }));
2584
2690
  return obj;
@@ -2595,7 +2701,6 @@ async function writeDrawings(options, drawing) {
2595
2701
  await fs$1.writeFile(join(dir, `${key}.svg`), svg, "utf-8");
2596
2702
  }));
2597
2703
  }
2598
-
2599
2704
  //#endregion
2600
2705
  //#region node/integrations/snapshots.ts
2601
2706
  function resolveSnapshotsDir(options) {
@@ -2613,7 +2718,6 @@ async function writeSnapshots(options, data) {
2613
2718
  await fs$1.mkdir(dir, { recursive: true });
2614
2719
  await fs$1.writeFile(join(dir, "snapshots.json"), JSON.stringify(data, null, 2), "utf-8");
2615
2720
  }
2616
-
2617
2721
  //#endregion
2618
2722
  //#region node/vite/serverRef.ts
2619
2723
  async function createServerRefPlugin(options, pluginOptions) {
@@ -2642,7 +2746,6 @@ async function createServerRefPlugin(options, pluginOptions) {
2642
2746
  }
2643
2747
  });
2644
2748
  }
2645
-
2646
2749
  //#endregion
2647
2750
  //#region node/vite/staticCopy.ts
2648
2751
  async function createStaticCopyPlugin({ themeRoots, addonRoots }, pluginOptions) {
@@ -2658,7 +2761,6 @@ async function createStaticCopyPlugin({ themeRoots, addonRoots }, pluginOptions)
2658
2761
  ...pluginOptions.staticCopy
2659
2762
  });
2660
2763
  }
2661
-
2662
2764
  //#endregion
2663
2765
  //#region node/setups/unocss.ts
2664
2766
  async function setupUnocss({ clientRoot, roots, data, utils }) {
@@ -2687,7 +2789,6 @@ async function setupUnocss({ clientRoot, roots, data, utils }) {
2687
2789
  config.theme.fontFamily.serif ||= data.config.fonts.serif.join(",");
2688
2790
  return config;
2689
2791
  }
2690
-
2691
2792
  //#endregion
2692
2793
  //#region node/vite/unocss.ts
2693
2794
  async function createUnocssPlugin(options, pluginOptions) {
@@ -2697,7 +2798,6 @@ async function createUnocssPlugin(options, pluginOptions) {
2697
2798
  ...pluginOptions.unocss
2698
2799
  });
2699
2800
  }
2700
-
2701
2801
  //#endregion
2702
2802
  //#region node/vite/vue.ts
2703
2803
  const RE_VUE_EXT = /\.vue$/;
@@ -2758,7 +2858,6 @@ async function createVuePlugin(_options, pluginOptions) {
2758
2858
  });
2759
2859
  return [VueJsx(vuejsxOptions), VuePlugin];
2760
2860
  }
2761
-
2762
2861
  //#endregion
2763
2862
  //#region node/vite/index.ts
2764
2863
  function ViteSlidevPlugin(options, pluginOptions = {}, serverOptions = {}) {
@@ -2768,6 +2867,7 @@ function ViteSlidevPlugin(options, pluginOptions = {}, serverOptions = {}) {
2768
2867
  createLayoutWrapperPlugin(options),
2769
2868
  createContextInjectionPlugin(),
2770
2869
  createVuePlugin(options, pluginOptions),
2870
+ createSlideImportGuardPlugin(),
2771
2871
  createHmrPatchPlugin(),
2772
2872
  createComponentsPlugin(options, pluginOptions),
2773
2873
  createIconsPlugin(options, pluginOptions),
@@ -2784,7 +2884,6 @@ function ViteSlidevPlugin(options, pluginOptions = {}, serverOptions = {}) {
2784
2884
  setupVitePlugins(options)
2785
2885
  ]);
2786
2886
  }
2787
-
2788
2887
  //#endregion
2789
2888
  //#region node/commands/shared.ts
2790
2889
  const sharedMd = MarkdownExit({ html: true });
@@ -2814,6 +2913,11 @@ async function resolveViteConfigs(options, baseConfig, overrideConfigs, command,
2814
2913
  });
2815
2914
  return baseConfig;
2816
2915
  }
2817
-
2818
2916
  //#endregion
2819
- export { parser as a, resolveAddons as c, updateFrontmatterPatch as d, resolveOptions as i, version as l, ViteSlidevPlugin as n, getThemeMeta as o, createDataUtils as r, resolveTheme as s, resolveViteConfigs as t, loadSetups as u };
2917
+ //#region node/commands/serve.ts
2918
+ async function createServer$1(options, viteConfig = {}, serverOptions) {
2919
+ process.env.EDITOR = process.env.EDITOR || "code";
2920
+ return await createServer(await resolveViteConfigs(options, { optimizeDeps: { entries: [join(options.clientRoot, "main.ts")] } }, viteConfig, "serve", serverOptions));
2921
+ }
2922
+ //#endregion
2923
+ export { resolveOptions as a, resolveTheme as c, updateFrontmatterPatch as d, createDataUtils as i, version as l, resolveViteConfigs as n, parser as o, ViteSlidevPlugin as r, getThemeMeta as s, createServer$1 as t, loadSetups as u };