@ox-content/vite-plugin-vue 0.17.0 → 1.1.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.
package/dist/index.cjs CHANGED
@@ -1,4 +1,5 @@
1
- //#region rolldown:runtime
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region \0rolldown/runtime.js
2
3
  var __create = Object.create;
3
4
  var __defProp = Object.defineProperty;
4
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -6,16 +7,12 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
6
7
  var __getProtoOf = Object.getPrototypeOf;
7
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
9
  var __copyProps = (to, from, except, desc) => {
9
- if (from && typeof from === "object" || typeof from === "function") {
10
- for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
- key = keys[i];
12
- if (!__hasOwnProp.call(to, key) && key !== except) {
13
- __defProp(to, key, {
14
- get: ((k) => from[k]).bind(null, key),
15
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
- });
17
- }
18
- }
10
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
+ get: ((k) => from[k]).bind(null, key),
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ });
19
16
  }
20
17
  return to;
21
18
  };
@@ -23,14 +20,12 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
23
20
  value: mod,
24
21
  enumerable: true
25
22
  }) : target, mod));
26
-
27
23
  //#endregion
28
24
  let fs = require("fs");
29
25
  fs = __toESM(fs);
30
- let path$1 = require("path");
31
- path$1 = __toESM(path$1);
26
+ let path = require("path");
27
+ path = __toESM(path);
32
28
  let _ox_content_vite_plugin = require("@ox-content/vite-plugin");
33
-
34
29
  //#region src/transform.ts
35
30
  /**
36
31
  * Markdown to Vue SFC transformation.
@@ -77,50 +72,52 @@ async function transformMarkdownWithVue(code, id, options) {
77
72
  lastIndex = matchEnd;
78
73
  }
79
74
  processedContent += markdownContent.slice(lastIndex);
75
+ const baseOptions = {
76
+ srcDir: options.srcDir,
77
+ outDir: options.outDir,
78
+ base: options.base,
79
+ ssg: {
80
+ enabled: false,
81
+ extension: ".html",
82
+ clean: false,
83
+ bare: false,
84
+ generateOgImage: false
85
+ },
86
+ gfm: options.gfm,
87
+ frontmatter: false,
88
+ toc: options.toc,
89
+ tocMaxDepth: options.tocMaxDepth,
90
+ codeAnnotations: options.codeAnnotations,
91
+ footnotes: true,
92
+ tables: true,
93
+ taskLists: true,
94
+ strikethrough: true,
95
+ highlight: false,
96
+ highlightTheme: "github-dark",
97
+ highlightLangs: [],
98
+ mermaid: false,
99
+ ogImage: false,
100
+ ogImageOptions: {
101
+ vuePlugin: "vitejs",
102
+ width: 1200,
103
+ height: 630,
104
+ cache: true,
105
+ concurrency: 1
106
+ },
107
+ transformers: [],
108
+ docs: false,
109
+ ogViewer: false,
110
+ search: {
111
+ enabled: false,
112
+ limit: 10,
113
+ prefix: true,
114
+ placeholder: "Search...",
115
+ hotkey: "k"
116
+ },
117
+ i18n: false
118
+ };
80
119
  return {
81
- code: generateVueSFC(injectIslandMarkers((await (0, _ox_content_vite_plugin.transformMarkdown)(processedContent, id, {
82
- srcDir: options.srcDir,
83
- outDir: options.outDir,
84
- base: options.base,
85
- ssg: {
86
- enabled: false,
87
- extension: ".html",
88
- clean: false,
89
- bare: false,
90
- generateOgImage: false
91
- },
92
- gfm: options.gfm,
93
- frontmatter: false,
94
- toc: options.toc,
95
- tocMaxDepth: options.tocMaxDepth,
96
- footnotes: true,
97
- tables: true,
98
- taskLists: true,
99
- strikethrough: true,
100
- highlight: false,
101
- highlightTheme: "github-dark",
102
- highlightLangs: [],
103
- mermaid: false,
104
- ogImage: false,
105
- ogImageOptions: {
106
- vuePlugin: "vitejs",
107
- width: 1200,
108
- height: 630,
109
- cache: true,
110
- concurrency: 1
111
- },
112
- transformers: [],
113
- docs: false,
114
- ogViewer: false,
115
- search: {
116
- enabled: false,
117
- limit: 10,
118
- prefix: true,
119
- placeholder: "Search...",
120
- hotkey: "k"
121
- },
122
- i18n: false
123
- })).html, islands), usedComponents, islands, frontmatter, options, id),
120
+ code: generateVueSFC(injectIslandMarkers((await (0, _ox_content_vite_plugin.transformMarkdown)(processedContent, id, baseOptions)).html, islands), usedComponents, islands, frontmatter, options, id),
124
121
  map: null,
125
122
  usedComponents,
126
123
  frontmatter
@@ -239,13 +236,13 @@ function parseProps(propsString) {
239
236
  * Generates a Vue component as JavaScript module from the processed Markdown.
240
237
  */
241
238
  function generateVueSFC(content, usedComponents, islands, frontmatter, options, id) {
242
- const mdDir = path$1.dirname(id);
239
+ const mdDir = path.dirname(id);
243
240
  const root = options.root || process.cwd();
244
241
  const componentImports = usedComponents.map((name) => {
245
242
  const componentPath = options.components.get(name);
246
243
  if (!componentPath) return "";
247
- const absolutePath = path$1.resolve(root, componentPath.replace(/^\.\//, ""));
248
- const relativePath = path$1.relative(mdDir, absolutePath).replace(/\\/g, "/");
244
+ const absolutePath = path.resolve(root, componentPath.replace(/^\.\//, ""));
245
+ const relativePath = path.relative(mdDir, absolutePath).replace(/\\/g, "/");
249
246
  return `import ${name} from '${relativePath.startsWith(".") ? relativePath : "./" + relativePath}';`;
250
247
  }).filter(Boolean).join("\n");
251
248
  const componentMap = usedComponents.map((name) => ` ${name},`).join("\n");
@@ -332,7 +329,6 @@ export default defineComponent({
332
329
  });
333
330
  `;
334
331
  }
335
-
336
332
  //#endregion
337
333
  //#region src/environment.ts
338
334
  /**
@@ -368,7 +364,6 @@ function createVueMarkdownEnvironment(mode, options) {
368
364
  ...!isSSR && { dev: { warmup: ["./src/**/*.vue", "./docs/**/*.md"] } }
369
365
  };
370
366
  }
371
-
372
367
  //#endregion
373
368
  //#region src/index.ts
374
369
  /**
@@ -461,7 +456,7 @@ function oxContentVue(options = {}) {
461
456
  name: "ox-content:vue-hmr",
462
457
  apply: "serve",
463
458
  handleHotUpdate({ file, server, modules }) {
464
- if (Array.from(componentMap.values()).some((path) => file.endsWith(path.replace(/^\.\//, "")))) {
459
+ if (Array.from(componentMap.values()).some((path$1) => file.endsWith(path$1.replace(/^\.\//, "")))) {
465
460
  const mdModules = Array.from(server.moduleGraph.idToModuleMap.values()).filter((mod) => mod.file?.endsWith(".md"));
466
461
  if (mdModules.length > 0) {
467
462
  server.ws.send({
@@ -475,13 +470,14 @@ function oxContentVue(options = {}) {
475
470
  return modules;
476
471
  }
477
472
  };
478
- const environmentPlugin = (0, _ox_content_vite_plugin.oxContent)(options).find((p) => p.name === "ox-content:environment");
479
- return [
473
+ const environmentPlugin = (0, _ox_content_vite_plugin.oxContent)(options).flatMap((plugin) => Array.isArray(plugin) ? plugin : [plugin]).find((plugin) => plugin.name === "ox-content:environment");
474
+ const plugins = [
480
475
  vueTransformPlugin,
481
476
  vueEnvironmentPlugin,
482
- vueHmrPlugin,
483
- ...environmentPlugin ? [environmentPlugin] : []
477
+ vueHmrPlugin
484
478
  ];
479
+ if (environmentPlugin) plugins.push(environmentPlugin);
480
+ return plugins;
485
481
  }
486
482
  /**
487
483
  * Resolves Vue integration options with defaults.
@@ -495,11 +491,26 @@ function resolveVueOptions(options) {
495
491
  frontmatter: options.frontmatter ?? true,
496
492
  toc: options.toc ?? true,
497
493
  tocMaxDepth: options.tocMaxDepth ?? 3,
494
+ codeAnnotations: resolveCodeAnnotationsOptions(options.codeAnnotations),
498
495
  components: options.components ?? {},
499
496
  reactivityTransform: options.reactivityTransform ?? false,
500
497
  customBlocks: options.customBlocks ?? true
501
498
  };
502
499
  }
500
+ function resolveCodeAnnotationsOptions(options) {
501
+ if (!options) return {
502
+ enabled: false,
503
+ metaKey: "annotate"
504
+ };
505
+ if (options === true) return {
506
+ enabled: true,
507
+ metaKey: "annotate"
508
+ };
509
+ return {
510
+ enabled: true,
511
+ metaKey: options.metaKey ?? "annotate"
512
+ };
513
+ }
503
514
  /**
504
515
  * Generates the runtime module for Vue markdown rendering.
505
516
  */
@@ -553,8 +564,8 @@ export function useOxContent() {
553
564
  function generateComponentsModule(componentMap) {
554
565
  const imports = [];
555
566
  const exports = [];
556
- componentMap.forEach((path, name) => {
557
- imports.push(`import ${name} from '${path}';`);
567
+ componentMap.forEach((path$2, name) => {
568
+ imports.push(`import ${name} from '${path$2}';`);
558
569
  exports.push(` ${name},`);
559
570
  });
560
571
  return `
@@ -577,8 +588,8 @@ async function resolveComponentsGlob(componentsOption, root) {
577
588
  for (const pattern of patterns) {
578
589
  const files = await globFiles(pattern, root);
579
590
  for (const file of files) {
580
- const componentName = toPascalCase(path$1.basename(file, path$1.extname(file)));
581
- result[componentName] = "./" + path$1.relative(root, file).replace(/\\/g, "/");
591
+ const componentName = toPascalCase(path.basename(file, path.extname(file)));
592
+ result[componentName] = "./" + path.relative(root, file).replace(/\\/g, "/");
582
593
  }
583
594
  }
584
595
  return result;
@@ -589,18 +600,18 @@ async function resolveComponentsGlob(componentsOption, root) {
589
600
  async function globFiles(pattern, root) {
590
601
  const files = [];
591
602
  if (!pattern.includes("*")) {
592
- const fullPath = path$1.resolve(root, pattern);
603
+ const fullPath = path.resolve(root, pattern);
593
604
  if (fs.existsSync(fullPath)) files.push(fullPath);
594
605
  return files;
595
606
  }
596
607
  const parts = pattern.split("*");
597
- const baseDir = path$1.resolve(root, parts[0]);
608
+ const baseDir = path.resolve(root, parts[0]);
598
609
  const ext = parts[1] || "";
599
610
  if (!fs.existsSync(baseDir)) return files;
600
611
  if (pattern.includes("**")) await walkDir(baseDir, files, ext);
601
612
  else {
602
613
  const entries = await fs.promises.readdir(baseDir, { withFileTypes: true });
603
- for (const entry of entries) if (entry.isFile() && entry.name.endsWith(ext)) files.push(path$1.join(baseDir, entry.name));
614
+ for (const entry of entries) if (entry.isFile() && entry.name.endsWith(ext)) files.push(path.join(baseDir, entry.name));
604
615
  }
605
616
  return files;
606
617
  }
@@ -610,7 +621,7 @@ async function globFiles(pattern, root) {
610
621
  async function walkDir(dir, files, ext) {
611
622
  const entries = await fs.promises.readdir(dir, { withFileTypes: true });
612
623
  for (const entry of entries) {
613
- const fullPath = path$1.join(dir, entry.name);
624
+ const fullPath = path.join(dir, entry.name);
614
625
  if (entry.isDirectory()) await walkDir(fullPath, files, ext);
615
626
  else if (entry.isFile() && entry.name.endsWith(ext)) files.push(fullPath);
616
627
  }
@@ -621,12 +632,11 @@ async function walkDir(dir, files, ext) {
621
632
  function toPascalCase(str) {
622
633
  return str.replace(/[-_](\w)/g, (_, c) => c.toUpperCase()).replace(/^\w/, (c) => c.toUpperCase());
623
634
  }
624
-
625
635
  //#endregion
626
- Object.defineProperty(exports, 'oxContent', {
627
- enumerable: true,
628
- get: function () {
629
- return _ox_content_vite_plugin.oxContent;
630
- }
636
+ Object.defineProperty(exports, "oxContent", {
637
+ enumerable: true,
638
+ get: function() {
639
+ return _ox_content_vite_plugin.oxContent;
640
+ }
631
641
  });
632
- exports.oxContentVue = oxContentVue;
642
+ exports.oxContentVue = oxContentVue;
package/dist/index.d.cts CHANGED
@@ -2,7 +2,13 @@ import { PluginOption } from "vite";
2
2
  import { OxContentOptions, oxContent } from "@ox-content/vite-plugin";
3
3
 
4
4
  //#region src/types.d.ts
5
-
5
+ interface CodeAnnotationsOptions {
6
+ metaKey?: string;
7
+ }
8
+ interface ResolvedCodeAnnotationsOptions {
9
+ enabled: boolean;
10
+ metaKey: string;
11
+ }
6
12
  /**
7
13
  * Component registration map.
8
14
  * Key is the component name to use in Markdown, value is the import path.
@@ -56,6 +62,7 @@ interface VueIntegrationOptions extends OxContentOptions {
56
62
  * @default true
57
63
  */
58
64
  components?: ComponentsOption;
65
+ codeAnnotations?: boolean | CodeAnnotationsOptions;
59
66
  reactivityTransform?: boolean;
60
67
  customBlocks?: boolean;
61
68
  }
@@ -70,6 +77,7 @@ interface ResolvedVueOptions {
70
77
  frontmatter: boolean;
71
78
  toc: boolean;
72
79
  tocMaxDepth: number;
80
+ codeAnnotations: ResolvedCodeAnnotationsOptions;
73
81
  components: ComponentsOption;
74
82
  reactivityTransform: boolean;
75
83
  customBlocks: boolean;
@@ -144,7 +152,6 @@ interface TocEntry {
144
152
  slug: string;
145
153
  children?: TocEntry[];
146
154
  }
147
- //# sourceMappingURL=types.d.ts.map
148
155
  //#endregion
149
156
  //#region src/index.d.ts
150
157
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/types.ts","../src/index.ts"],"sourcesContent":[],"mappings":";;;;;AAUA;AAoBA;AAKA;;AA2Be,KApDH,aAAA,GAAgB,MAoDb,CAAA,MAAA,EAAA,MAAA,CAAA;;;AAQf;AAgBA;AAgBA;AA0BA;;;;;;AAsBA;;;;AChGA;;;AAAmE,KDxBvD,gBAAA,GAAmB,aCwBoC,GAAA,MAAA,GAAA,MAAA,EAAA;;;;UDnBlD,qBAAA,SAA8B;;;;;;;;;;;;;;;;;;;;;;;;;eA2BhC;;;;;;;UAQE,kBAAA;;;;;;;;cAQH;;;;;;;UAQG,kBAAA;;;;;;;;;;eAUF;;;;;UAME,eAAA;;;;;;;;SAQR;;;;;;;;;;;;;;;;;UAkBQ,qBAAA;;;;;;;;WAQN;;;;eAII;;;;OAIR;;;;;UAMU,QAAA;;;;aAIJ;;;;;;;AApFb;AAgBA;AAgBA;AA0BA;;;;;;AAsBA;;;;AChGA;;;;;;;;iBAAgB,YAAA,WAAsB,wBAA6B"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/types.ts","../src/index.ts"],"mappings":";;;;UAMiB,sBAAA;EACf,OAAA;AAAA;AAAA,UAGe,8BAAA;EACf,OAAA;EACA,OAAA;AAAA;;;;AAOF;KAAY,aAAA,GAAgB,MAAA;;;;AAoB5B;;;;;AAKA;;;;;;;;;;KALY,gBAAA,GAAmB,aAAA;;;;UAKd,qBAAA,SAA8B,gBAAA;EA8BjC;;AAMd;;;;;;;;;;;;;;EASc;;;;EAEA;AAMd;;;EA1BE,UAAA,GAAa,gBAAA;EACb,eAAA,aAA4B,sBAAA;EAC5B,mBAAA;EACA,YAAA;AAAA;;;;UAMe,kBAAA;EACf,MAAA;EACA,MAAA;EACA,IAAA;EACA,GAAA;EACA,WAAA;EACA,GAAA;EACA,WAAA;EACA,eAAA,EAAiB,8BAAA;EACjB,UAAA,EAAY,gBAAA;EACZ,mBAAA;EACA,YAAA;AAAA;;;;UAMe,kBAAA;EACf,IAAA;EACA,GAAA;EAwDa;;;EApDb,cAAA;EAgDA;;;EA5CA,WAAA,EAAa,MAAA;AAAA;;AAsDf;;UAhDiB,eAAA;EAoDI;;;EAhDnB,IAAA;EAgDA;;;EA5CA,KAAA,EAAO,MAAA;;;;EAIP,QAAA;ECvE0B;;;ED2E1B,EAAA;EC3E2B;;;ED+E3B,OAAA;AAAA;;;;UAMe,qBAAA;;;;EAIf,IAAA;;;;EAIA,OAAA,EAAS,eAAA;;;;EAIT,WAAA,EAAa,MAAA;;;;EAIb,GAAA,EAAK,QAAA;AAAA;;;;UAMU,QAAA;EACf,KAAA;EACA,IAAA;EACA,IAAA;EACA,QAAA,GAAW,QAAA;AAAA;;;AA3Jb;;;;;AASA;;;;;AAoBA;;;;;AAKA;;;;;;;;AAlCA,iBC4CgB,YAAA,CAAa,OAAA,GAAS,qBAAA,GAA6B,YAAA"}
@@ -2,7 +2,13 @@ import { OxContentOptions, oxContent } from "@ox-content/vite-plugin";
2
2
  import { PluginOption } from "vite";
3
3
 
4
4
  //#region src/types.d.ts
5
-
5
+ interface CodeAnnotationsOptions {
6
+ metaKey?: string;
7
+ }
8
+ interface ResolvedCodeAnnotationsOptions {
9
+ enabled: boolean;
10
+ metaKey: string;
11
+ }
6
12
  /**
7
13
  * Component registration map.
8
14
  * Key is the component name to use in Markdown, value is the import path.
@@ -56,6 +62,7 @@ interface VueIntegrationOptions extends OxContentOptions {
56
62
  * @default true
57
63
  */
58
64
  components?: ComponentsOption;
65
+ codeAnnotations?: boolean | CodeAnnotationsOptions;
59
66
  reactivityTransform?: boolean;
60
67
  customBlocks?: boolean;
61
68
  }
@@ -70,6 +77,7 @@ interface ResolvedVueOptions {
70
77
  frontmatter: boolean;
71
78
  toc: boolean;
72
79
  tocMaxDepth: number;
80
+ codeAnnotations: ResolvedCodeAnnotationsOptions;
73
81
  components: ComponentsOption;
74
82
  reactivityTransform: boolean;
75
83
  customBlocks: boolean;
@@ -144,7 +152,6 @@ interface TocEntry {
144
152
  slug: string;
145
153
  children?: TocEntry[];
146
154
  }
147
- //# sourceMappingURL=types.d.ts.map
148
155
  //#endregion
149
156
  //#region src/index.d.ts
150
157
  /**
@@ -173,4 +180,4 @@ interface TocEntry {
173
180
  declare function oxContentVue(options?: VueIntegrationOptions): PluginOption[];
174
181
  //#endregion
175
182
  export { type ComponentIsland, type ComponentsMap, type ComponentsOption, type ParsedMarkdownContent, type ResolvedVueOptions, type TocEntry, type VueIntegrationOptions, type VueTransformResult, oxContent, oxContentVue };
176
- //# sourceMappingURL=index.d.ts.map
183
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/index.ts"],"mappings":";;;;UAMiB,sBAAA;EACf,OAAA;AAAA;AAAA,UAGe,8BAAA;EACf,OAAA;EACA,OAAA;AAAA;;;;AAOF;KAAY,aAAA,GAAgB,MAAA;;;;AAoB5B;;;;;AAKA;;;;;;;;;;KALY,gBAAA,GAAmB,aAAA;;;;UAKd,qBAAA,SAA8B,gBAAA;EA8BjC;;AAMd;;;;;;;;;;;;;;EASc;;;;EAEA;AAMd;;;EA1BE,UAAA,GAAa,gBAAA;EACb,eAAA,aAA4B,sBAAA;EAC5B,mBAAA;EACA,YAAA;AAAA;;;;UAMe,kBAAA;EACf,MAAA;EACA,MAAA;EACA,IAAA;EACA,GAAA;EACA,WAAA;EACA,GAAA;EACA,WAAA;EACA,eAAA,EAAiB,8BAAA;EACjB,UAAA,EAAY,gBAAA;EACZ,mBAAA;EACA,YAAA;AAAA;;;;UAMe,kBAAA;EACf,IAAA;EACA,GAAA;EAwDa;;;EApDb,cAAA;EAgDA;;;EA5CA,WAAA,EAAa,MAAA;AAAA;;AAsDf;;UAhDiB,eAAA;EAoDI;;;EAhDnB,IAAA;EAgDA;;;EA5CA,KAAA,EAAO,MAAA;;;;EAIP,QAAA;ECvE0B;;;ED2E1B,EAAA;EC3E2B;;;ED+E3B,OAAA;AAAA;;;;UAMe,qBAAA;;;;EAIf,IAAA;;;;EAIA,OAAA,EAAS,eAAA;;;;EAIT,WAAA,EAAa,MAAA;;;;EAIb,GAAA,EAAK,QAAA;AAAA;;;;UAMU,QAAA;EACf,KAAA;EACA,IAAA;EACA,IAAA;EACA,QAAA,GAAW,QAAA;AAAA;;;AA3Jb;;;;;AASA;;;;;AAoBA;;;;;AAKA;;;;;;;;AAlCA,iBC4CgB,YAAA,CAAa,OAAA,GAAS,qBAAA,GAA6B,YAAA"}
@@ -1,7 +1,6 @@
1
1
  import * as fs from "fs";
2
2
  import * as path from "path";
3
3
  import { oxContent, oxContent as oxContent$1, transformMarkdown } from "@ox-content/vite-plugin";
4
-
5
4
  //#region src/transform.ts
6
5
  /**
7
6
  * Markdown to Vue SFC transformation.
@@ -48,50 +47,52 @@ async function transformMarkdownWithVue(code, id, options) {
48
47
  lastIndex = matchEnd;
49
48
  }
50
49
  processedContent += markdownContent.slice(lastIndex);
50
+ const baseOptions = {
51
+ srcDir: options.srcDir,
52
+ outDir: options.outDir,
53
+ base: options.base,
54
+ ssg: {
55
+ enabled: false,
56
+ extension: ".html",
57
+ clean: false,
58
+ bare: false,
59
+ generateOgImage: false
60
+ },
61
+ gfm: options.gfm,
62
+ frontmatter: false,
63
+ toc: options.toc,
64
+ tocMaxDepth: options.tocMaxDepth,
65
+ codeAnnotations: options.codeAnnotations,
66
+ footnotes: true,
67
+ tables: true,
68
+ taskLists: true,
69
+ strikethrough: true,
70
+ highlight: false,
71
+ highlightTheme: "github-dark",
72
+ highlightLangs: [],
73
+ mermaid: false,
74
+ ogImage: false,
75
+ ogImageOptions: {
76
+ vuePlugin: "vitejs",
77
+ width: 1200,
78
+ height: 630,
79
+ cache: true,
80
+ concurrency: 1
81
+ },
82
+ transformers: [],
83
+ docs: false,
84
+ ogViewer: false,
85
+ search: {
86
+ enabled: false,
87
+ limit: 10,
88
+ prefix: true,
89
+ placeholder: "Search...",
90
+ hotkey: "k"
91
+ },
92
+ i18n: false
93
+ };
51
94
  return {
52
- code: generateVueSFC(injectIslandMarkers((await transformMarkdown(processedContent, id, {
53
- srcDir: options.srcDir,
54
- outDir: options.outDir,
55
- base: options.base,
56
- ssg: {
57
- enabled: false,
58
- extension: ".html",
59
- clean: false,
60
- bare: false,
61
- generateOgImage: false
62
- },
63
- gfm: options.gfm,
64
- frontmatter: false,
65
- toc: options.toc,
66
- tocMaxDepth: options.tocMaxDepth,
67
- footnotes: true,
68
- tables: true,
69
- taskLists: true,
70
- strikethrough: true,
71
- highlight: false,
72
- highlightTheme: "github-dark",
73
- highlightLangs: [],
74
- mermaid: false,
75
- ogImage: false,
76
- ogImageOptions: {
77
- vuePlugin: "vitejs",
78
- width: 1200,
79
- height: 630,
80
- cache: true,
81
- concurrency: 1
82
- },
83
- transformers: [],
84
- docs: false,
85
- ogViewer: false,
86
- search: {
87
- enabled: false,
88
- limit: 10,
89
- prefix: true,
90
- placeholder: "Search...",
91
- hotkey: "k"
92
- },
93
- i18n: false
94
- })).html, islands), usedComponents, islands, frontmatter, options, id),
95
+ code: generateVueSFC(injectIslandMarkers((await transformMarkdown(processedContent, id, baseOptions)).html, islands), usedComponents, islands, frontmatter, options, id),
95
96
  map: null,
96
97
  usedComponents,
97
98
  frontmatter
@@ -303,7 +304,6 @@ export default defineComponent({
303
304
  });
304
305
  `;
305
306
  }
306
-
307
307
  //#endregion
308
308
  //#region src/environment.ts
309
309
  /**
@@ -339,7 +339,6 @@ function createVueMarkdownEnvironment(mode, options) {
339
339
  ...!isSSR && { dev: { warmup: ["./src/**/*.vue", "./docs/**/*.md"] } }
340
340
  };
341
341
  }
342
-
343
342
  //#endregion
344
343
  //#region src/index.ts
345
344
  /**
@@ -446,13 +445,14 @@ function oxContentVue(options = {}) {
446
445
  return modules;
447
446
  }
448
447
  };
449
- const environmentPlugin = oxContent$1(options).find((p) => p.name === "ox-content:environment");
450
- return [
448
+ const environmentPlugin = oxContent$1(options).flatMap((plugin) => Array.isArray(plugin) ? plugin : [plugin]).find((plugin) => plugin.name === "ox-content:environment");
449
+ const plugins = [
451
450
  vueTransformPlugin,
452
451
  vueEnvironmentPlugin,
453
- vueHmrPlugin,
454
- ...environmentPlugin ? [environmentPlugin] : []
452
+ vueHmrPlugin
455
453
  ];
454
+ if (environmentPlugin) plugins.push(environmentPlugin);
455
+ return plugins;
456
456
  }
457
457
  /**
458
458
  * Resolves Vue integration options with defaults.
@@ -466,11 +466,26 @@ function resolveVueOptions(options) {
466
466
  frontmatter: options.frontmatter ?? true,
467
467
  toc: options.toc ?? true,
468
468
  tocMaxDepth: options.tocMaxDepth ?? 3,
469
+ codeAnnotations: resolveCodeAnnotationsOptions(options.codeAnnotations),
469
470
  components: options.components ?? {},
470
471
  reactivityTransform: options.reactivityTransform ?? false,
471
472
  customBlocks: options.customBlocks ?? true
472
473
  };
473
474
  }
475
+ function resolveCodeAnnotationsOptions(options) {
476
+ if (!options) return {
477
+ enabled: false,
478
+ metaKey: "annotate"
479
+ };
480
+ if (options === true) return {
481
+ enabled: true,
482
+ metaKey: "annotate"
483
+ };
484
+ return {
485
+ enabled: true,
486
+ metaKey: options.metaKey ?? "annotate"
487
+ };
488
+ }
474
489
  /**
475
490
  * Generates the runtime module for Vue markdown rendering.
476
491
  */
@@ -592,7 +607,7 @@ async function walkDir(dir, files, ext) {
592
607
  function toPascalCase(str) {
593
608
  return str.replace(/[-_](\w)/g, (_, c) => c.toUpperCase()).replace(/^\w/, (c) => c.toUpperCase());
594
609
  }
595
-
596
610
  //#endregion
597
611
  export { oxContent, oxContentVue };
598
- //# sourceMappingURL=index.js.map
612
+
613
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["baseTransformMarkdown","oxContent"],"sources":["../src/transform.ts","../src/environment.ts","../src/index.ts"],"sourcesContent":["/**\n * Markdown to Vue SFC transformation.\n */\n\nimport * as path from \"path\";\nimport { transformMarkdown as baseTransformMarkdown } from \"@ox-content/vite-plugin\";\nimport type { ResolvedVueOptions, VueTransformResult, ComponentIsland } from \"./types\";\n\n// Regex to match Vue-like component tags in Markdown\nconst COMPONENT_REGEX = /<([A-Z][a-zA-Z0-9]*)\\s*([^>]*?)\\s*(?:\\/>|>([\\s\\S]*?)<\\/\\1>)/g;\n\n// Regex to parse component props\nconst PROP_REGEX =\n /(?::|v-bind:)?([a-zA-Z0-9-]+)(?:=(?:\"([^\"]*)\"|'([^']*)'|{([^}]*)}|\\[([^\\]]*)\\]))?/g;\n\nconst ISLAND_MARKER_PREFIX = \"OXCONTENT-ISLAND-\";\nconst ISLAND_MARKER_SUFFIX = \"-PLACEHOLDER\";\n\ninterface Range {\n start: number;\n end: number;\n}\n\n/**\n * Options for transformMarkdownWithVue.\n */\ninterface TransformOptions extends Omit<ResolvedVueOptions, \"components\"> {\n components: Map<string, string>;\n root?: string;\n}\n\n/**\n * Transforms Markdown content with Vue component support.\n */\nexport async function transformMarkdownWithVue(\n code: string,\n id: string,\n options: TransformOptions,\n): Promise<VueTransformResult> {\n const { components } = options;\n const usedComponents: string[] = [];\n const islands: ComponentIsland[] = [];\n let islandIndex = 0;\n\n // Extract frontmatter\n const { content: markdownContent, frontmatter } = extractFrontmatter(code);\n\n // Find and extract component usages\n const fenceRanges = collectFenceRanges(markdownContent);\n let processedContent = \"\";\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n COMPONENT_REGEX.lastIndex = 0;\n while ((match = COMPONENT_REGEX.exec(markdownContent)) !== null) {\n const [fullMatch, componentName, propsString, rawIslandContent] = match;\n const matchStart = match.index;\n const matchEnd = matchStart + fullMatch.length;\n\n // Check if component is registered\n if (!components.has(componentName) || isInRanges(matchStart, matchEnd, fenceRanges)) {\n processedContent += markdownContent.slice(lastIndex, matchEnd);\n lastIndex = matchEnd;\n continue;\n }\n\n if (!usedComponents.includes(componentName)) {\n usedComponents.push(componentName);\n }\n\n // Parse props\n const props = parseProps(propsString);\n\n // Create island placeholder\n const islandId = `ox-island-${islandIndex++}`;\n const islandContent =\n typeof rawIslandContent === \"string\" ? rawIslandContent.trim() : undefined;\n islands.push({\n name: componentName,\n props,\n position: matchStart,\n id: islandId,\n content: islandContent,\n });\n\n // Replace component with island marker text\n processedContent += markdownContent.slice(lastIndex, matchStart) + createIslandMarker(islandId);\n lastIndex = matchEnd;\n }\n processedContent += markdownContent.slice(lastIndex);\n\n // Transform Markdown to HTML using ox-content\n const baseOptions = {\n srcDir: options.srcDir,\n outDir: options.outDir,\n base: options.base,\n ssg: {\n enabled: false,\n extension: \".html\",\n clean: false,\n bare: false,\n generateOgImage: false,\n },\n gfm: options.gfm,\n frontmatter: false, // Already extracted\n toc: options.toc,\n tocMaxDepth: options.tocMaxDepth,\n codeAnnotations: options.codeAnnotations,\n footnotes: true,\n tables: true,\n taskLists: true,\n strikethrough: true,\n highlight: false,\n highlightTheme: \"github-dark\",\n highlightLangs: [],\n mermaid: false,\n ogImage: false,\n ogImageOptions: {\n vuePlugin: \"vitejs\",\n width: 1200,\n height: 630,\n cache: true,\n concurrency: 1,\n },\n transformers: [],\n docs: false,\n ogViewer: false,\n search: {\n enabled: false,\n limit: 10,\n prefix: true,\n placeholder: \"Search...\",\n hotkey: \"k\",\n },\n i18n: false,\n } as Parameters<typeof baseTransformMarkdown>[2] & {\n codeAnnotations?: TransformOptions[\"codeAnnotations\"];\n };\n\n const transformed = await baseTransformMarkdown(processedContent, id, baseOptions);\n\n // Generate Vue SFC code\n const htmlWithIslands = injectIslandMarkers(transformed.html, islands);\n const sfcCode = generateVueSFC(\n htmlWithIslands,\n usedComponents,\n islands,\n frontmatter,\n options,\n id,\n );\n\n return {\n code: sfcCode,\n map: null,\n usedComponents,\n frontmatter,\n };\n}\n\nfunction createIslandMarker(islandId: string): string {\n return `${ISLAND_MARKER_PREFIX}${islandId}${ISLAND_MARKER_SUFFIX}`;\n}\n\nfunction collectFenceRanges(content: string): Range[] {\n const ranges: Range[] = [];\n let inFence = false;\n let fenceChar = \"\";\n let fenceLength = 0;\n let fenceStart = 0;\n let pos = 0;\n\n while (pos < content.length) {\n const lineEnd = content.indexOf(\"\\n\", pos);\n const next = lineEnd === -1 ? content.length : lineEnd + 1;\n const line = content.slice(pos, lineEnd === -1 ? content.length : lineEnd);\n const fenceMatch = line.match(/^\\s{0,3}([`~]{3,})/);\n\n if (fenceMatch) {\n const marker = fenceMatch[1];\n if (!inFence) {\n inFence = true;\n fenceChar = marker[0];\n fenceLength = marker.length;\n fenceStart = pos;\n } else if (marker[0] === fenceChar && marker.length >= fenceLength) {\n inFence = false;\n ranges.push({ start: fenceStart, end: next });\n fenceChar = \"\";\n fenceLength = 0;\n }\n }\n\n pos = next;\n }\n\n if (inFence) {\n ranges.push({ start: fenceStart, end: content.length });\n }\n\n return ranges;\n}\n\nfunction isInRanges(start: number, end: number, ranges: Range[]): boolean {\n for (const range of ranges) {\n if (start < range.end && end > range.start) {\n return true;\n }\n }\n return false;\n}\n\nfunction injectIslandMarkers(html: string, islands: ComponentIsland[]): string {\n let output = html;\n\n for (const island of islands) {\n const marker = createIslandMarker(island.id);\n const propsAttr =\n Object.keys(island.props).length > 0\n ? ` data-ox-props='${JSON.stringify(island.props).replace(/'/g, \"&#39;\")}'`\n : \"\";\n const contentAttr = island.content\n ? ` data-ox-content='${island.content.replace(/'/g, \"&#39;\")}'`\n : \"\";\n const attrs = `data-ox-island=\"${island.name}\"${propsAttr}${contentAttr}`;\n output = output.replaceAll(`<p>${marker}</p>`, `<div ${attrs}></div>`);\n output = output.replaceAll(marker, `<span ${attrs}></span>`);\n }\n\n return output;\n}\n\n/**\n * Extracts frontmatter from Markdown content.\n */\nfunction extractFrontmatter(content: string): {\n content: string;\n frontmatter: Record<string, unknown>;\n} {\n const frontmatterRegex = /^---\\n([\\s\\S]*?)\\n---\\n/;\n const match = frontmatterRegex.exec(content);\n\n if (!match) {\n return { content, frontmatter: {} };\n }\n\n const frontmatterStr = match[1];\n const frontmatter: Record<string, unknown> = {};\n\n // Simple YAML-like parsing\n for (const line of frontmatterStr.split(\"\\n\")) {\n const colonIndex = line.indexOf(\":\");\n if (colonIndex > 0) {\n const key = line.slice(0, colonIndex).trim();\n let value: unknown = line.slice(colonIndex + 1).trim();\n\n // Try to parse as JSON for complex values\n try {\n value = JSON.parse(value as string);\n } catch {\n // Keep as string if not valid JSON\n // Remove quotes if present\n if (\n typeof value === \"string\" &&\n ((value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\")))\n ) {\n value = value.slice(1, -1);\n }\n }\n\n frontmatter[key] = value;\n }\n }\n\n return {\n content: content.slice(match[0].length),\n frontmatter,\n };\n}\n\n/**\n * Parses component props from a string.\n */\nfunction parseProps(propsString: string): Record<string, unknown> {\n const props: Record<string, unknown> = {};\n\n if (!propsString) return props;\n\n let match: RegExpExecArray | null;\n while ((match = PROP_REGEX.exec(propsString)) !== null) {\n const [, name, doubleQuoted, singleQuoted, braceValue, bracketValue] = match;\n\n if (name) {\n if (doubleQuoted !== undefined) {\n props[name] = doubleQuoted;\n } else if (singleQuoted !== undefined) {\n props[name] = singleQuoted;\n } else if (braceValue !== undefined) {\n // Try to parse as JSON\n try {\n props[name] = JSON.parse(`{${braceValue}}`);\n } catch {\n props[name] = braceValue;\n }\n } else if (bracketValue !== undefined) {\n try {\n props[name] = JSON.parse(`[${bracketValue}]`);\n } catch {\n props[name] = bracketValue;\n }\n } else {\n // Boolean prop\n props[name] = true;\n }\n }\n }\n\n return props;\n}\n\n/**\n * Generates a Vue component as JavaScript module from the processed Markdown.\n */\nfunction generateVueSFC(\n content: string,\n usedComponents: string[],\n islands: ComponentIsland[],\n frontmatter: Record<string, unknown>,\n options: TransformOptions,\n id: string,\n): string {\n const mdDir = path.dirname(id);\n const root = options.root || process.cwd();\n\n const componentImports = usedComponents\n .map((name) => {\n const componentPath = options.components.get(name);\n if (!componentPath) return \"\";\n // Convert relative-to-root path to relative-to-md-file path\n const absolutePath = path.resolve(root, componentPath.replace(/^\\.\\//, \"\"));\n const relativePath = path.relative(mdDir, absolutePath).replace(/\\\\/g, \"/\");\n // Ensure the path starts with ./ or ../\n const importPath = relativePath.startsWith(\".\") ? relativePath : \"./\" + relativePath;\n return `import ${name} from '${importPath}';`;\n })\n .filter(Boolean)\n .join(\"\\n\");\n\n const componentMap = usedComponents.map((name) => ` ${name},`).join(\"\\n\");\n\n // If no islands, generate simpler code without island runtime\n if (islands.length === 0) {\n return `\nimport { h, ref, defineComponent } from 'vue';\n\nexport const frontmatter = ${JSON.stringify(frontmatter)};\n\nconst rawHtml = ${JSON.stringify(content)};\n\nexport default defineComponent({\n name: 'MarkdownContent',\n setup(_, { expose }) {\n expose({ frontmatter });\n\n return () =>\n h('div', {\n class: 'ox-content',\n innerHTML: rawHtml,\n });\n },\n});\n`;\n }\n\n return `\nimport { h, ref, onMounted, onBeforeUnmount, defineComponent, render } from 'vue';\nimport { initIslands } from '@ox-content/islands';\n${componentImports}\n\nexport const frontmatter = ${JSON.stringify(frontmatter)};\n\nconst rawHtml = ${JSON.stringify(content)};\nconst components = {\n${componentMap}\n};\n\nfunction createVueHydrate(container) {\n const mountedTargets = [];\n\n return (element, props) => {\n const componentName = element.dataset.oxIsland;\n const Component = components[componentName];\n if (!Component) return;\n\n const islandContent = element.dataset.oxContent || element.innerHTML;\n const children = islandContent\n ? { default: () => h('div', { innerHTML: islandContent }) }\n : undefined;\n\n const vnode = h(Component, props, children);\n render(vnode, element);\n mountedTargets.push(element);\n\n return () => render(null, element);\n };\n}\n\nexport default defineComponent({\n name: 'MarkdownContent',\n setup(_, { expose }) {\n const container = ref(null);\n let controller;\n\n onMounted(() => {\n if (container.value) {\n controller = initIslands(createVueHydrate(container.value), {\n selector: '.ox-content [data-ox-island]',\n });\n }\n });\n\n onBeforeUnmount(() => {\n if (controller) controller.destroy();\n });\n\n expose({ frontmatter });\n\n return () =>\n h('div', {\n class: 'ox-content',\n ref: container,\n innerHTML: rawHtml,\n });\n },\n});\n`;\n}\n","/**\n * Vite Environment API configuration for Vue integration.\n */\n\nimport type { EnvironmentOptions } from \"vite\";\nimport type { ResolvedVueOptions } from \"./types\";\n\n/**\n * Creates a Vite environment for Vue markdown processing.\n *\n * @param mode - 'ssr' for server-side rendering, 'client' for client hydration\n * @param options - Resolved Vue integration options\n */\nexport function createVueMarkdownEnvironment(\n mode: \"ssr\" | \"client\",\n options: ResolvedVueOptions,\n): EnvironmentOptions {\n const isSSR = mode === \"ssr\";\n\n return {\n build: {\n outDir: isSSR ? `${options.outDir}/.ox-content/ssr` : `${options.outDir}/.ox-content/client`,\n\n ssr: isSSR,\n\n rollupOptions: {\n input: isSSR ? undefined : undefined,\n output: {\n format: isSSR ? \"esm\" : \"esm\",\n entryFileNames: isSSR ? \"[name].js\" : \"[name].[hash].js\",\n chunkFileNames: isSSR ? \"chunks/[name].js\" : \"chunks/[name].[hash].js\",\n },\n },\n\n // SSR-specific optimizations\n ...(isSSR && {\n target: \"node18\",\n minify: false,\n }),\n },\n\n resolve: {\n conditions: isSSR ? [\"node\", \"import\"] : [\"browser\", \"import\"],\n },\n\n optimizeDeps: {\n // Pre-bundle Vue for faster cold starts\n include: isSSR ? [] : [\"vue\"],\n\n // Exclude ox-content packages from optimization (they're local)\n exclude: [\"@ox-content/vite-plugin\", \"@ox-content/vite-plugin-vue\"],\n },\n\n // Development server options (client only)\n ...(!isSSR && {\n dev: {\n warmup: [\"./src/**/*.vue\", \"./docs/**/*.md\"],\n },\n }),\n };\n}\n\n/**\n * Creates environment-specific virtual modules.\n */\nexport function createVirtualModules(\n mode: \"ssr\" | \"client\",\n _options: ResolvedVueOptions,\n): Record<string, string> {\n const isSSR = mode === \"ssr\";\n\n return {\n // Environment detection module\n \"virtual:ox-content/env\": `\n export const isSSR = ${isSSR};\n export const isClient = ${!isSSR};\n export const mode = '${mode}';\n `,\n\n // Hydration utilities\n \"virtual:ox-content/hydration\": isSSR\n ? `\n // SSR: No-op hydration\n export function hydrate() {}\n export function createSSRApp(component) {\n return component;\n }\n `\n : `\n import { createApp } from 'vue';\n\n export function hydrate(component, container, props = {}) {\n const app = createApp(component, props);\n app.mount(container);\n return app;\n }\n\n export function createClientApp(component) {\n return createApp(component);\n }\n `,\n };\n}\n","/**\n * Vite Plugin for Ox Content Vue Integration\n *\n * Uses Vite's Environment API to enable embedding Vue components in Markdown.\n * Provides SSR and client environments for proper hydration.\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport type { Plugin, PluginOption, ResolvedConfig } from \"vite\";\nimport { oxContent } from \"@ox-content/vite-plugin\";\nimport { transformMarkdownWithVue } from \"./transform\";\nimport { createVueMarkdownEnvironment } from \"./environment\";\nimport type {\n VueIntegrationOptions,\n ResolvedVueOptions,\n ComponentsMap,\n ComponentsOption,\n} from \"./types\";\n\nexport type {\n VueIntegrationOptions,\n ResolvedVueOptions,\n ComponentsOption,\n ComponentsMap,\n VueTransformResult,\n ComponentIsland,\n ParsedMarkdownContent,\n TocEntry,\n} from \"./types\";\n\n/**\n * Creates the Ox Content Vue integration plugin with Environment API support.\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import { defineConfig } from 'vite';\n * import vue from '@vitejs/plugin-vue';\n * import { oxContentVue } from 'vite-plugin-ox-content-vue';\n *\n * export default defineConfig({\n * plugins: [\n * vue(),\n * oxContentVue({\n * srcDir: 'docs',\n * components: {\n * Counter: './src/components/Counter.vue',\n * },\n * }),\n * ],\n * });\n * ```\n */\nexport function oxContentVue(options: VueIntegrationOptions = {}): PluginOption[] {\n const resolved = resolveVueOptions(options);\n let componentMap = new Map<string, string>();\n let config: ResolvedConfig;\n\n // Pre-resolve components if it's a map (not glob)\n if (typeof options.components === \"object\" && !Array.isArray(options.components)) {\n componentMap = new Map(Object.entries(options.components));\n }\n\n // Main Vue transformation plugin\n const vueTransformPlugin: Plugin = {\n name: \"ox-content:vue-transform\",\n enforce: \"pre\",\n\n async configResolved(resolvedConfig) {\n config = resolvedConfig;\n\n // Resolve glob patterns for components\n const componentsOption = options.components;\n if (componentsOption) {\n const resolvedComponents = await resolveComponentsGlob(componentsOption, config.root);\n componentMap = new Map(Object.entries(resolvedComponents));\n }\n },\n\n async transform(code, id) {\n if (!id.endsWith(\".md\")) {\n return null;\n }\n\n const result = await transformMarkdownWithVue(code, id, {\n ...resolved,\n components: componentMap,\n root: config.root,\n });\n\n return {\n code: result.code,\n map: result.map,\n };\n },\n };\n\n // Environment API plugin for Vue-specific SSR/client handling\n const vueEnvironmentPlugin: Plugin = {\n name: \"ox-content:vue-environment\",\n\n config() {\n return {\n environments: {\n // SSR environment for Vue component rendering\n oxcontent_ssr: createVueMarkdownEnvironment(\"ssr\", resolved),\n // Client environment for hydration\n oxcontent_client: createVueMarkdownEnvironment(\"client\", resolved),\n },\n };\n },\n\n // Environment-specific module resolution\n resolveId: {\n order: \"pre\",\n async handler(id, _importer, _options) {\n // Handle virtual modules for Vue markdown runtime\n if (id === \"virtual:ox-content-vue/runtime\") {\n return \"\\0virtual:ox-content-vue/runtime\";\n }\n\n if (id === \"virtual:ox-content-vue/components\") {\n return \"\\0virtual:ox-content-vue/components\";\n }\n\n return null;\n },\n },\n\n load: {\n order: \"pre\",\n async handler(id) {\n if (id === \"\\0virtual:ox-content-vue/runtime\") {\n return generateRuntimeModule(resolved);\n }\n\n if (id === \"\\0virtual:ox-content-vue/components\") {\n return generateComponentsModule(componentMap);\n }\n\n return null;\n },\n },\n\n // Per-environment build hooks\n applyToEnvironment(environment) {\n return (\n environment.name === \"oxcontent_ssr\" ||\n environment.name === \"oxcontent_client\" ||\n environment.name === \"client\" ||\n environment.name === \"ssr\"\n );\n },\n };\n\n // HMR plugin for component updates\n const vueHmrPlugin: Plugin = {\n name: \"ox-content:vue-hmr\",\n apply: \"serve\",\n\n handleHotUpdate({ file, server, modules }) {\n // Check if updated file is a registered component\n const isComponent = Array.from(componentMap.values()).some((path) =>\n file.endsWith(path.replace(/^\\.\\//, \"\")),\n );\n\n if (isComponent) {\n // Invalidate all Markdown modules that might use this component\n const mdModules = Array.from(server.moduleGraph.idToModuleMap.values()).filter((mod) =>\n mod.file?.endsWith(\".md\"),\n );\n\n if (mdModules.length > 0) {\n server.ws.send({\n type: \"custom\",\n event: \"ox-content:vue-update\",\n data: { file },\n });\n return [...modules, ...mdModules];\n }\n }\n\n return modules;\n },\n };\n\n // Get base ox-content plugins (environment plugin only)\n const basePlugins = oxContent(options).flatMap((plugin) =>\n Array.isArray(plugin) ? plugin : [plugin],\n ) as Plugin[];\n const environmentPlugin = basePlugins.find((plugin) => plugin.name === \"ox-content:environment\");\n const plugins: Plugin[] = [vueTransformPlugin, vueEnvironmentPlugin, vueHmrPlugin];\n\n if (environmentPlugin) {\n plugins.push(environmentPlugin);\n }\n\n return plugins;\n}\n\n/**\n * Resolves Vue integration options with defaults.\n */\nfunction resolveVueOptions(options: VueIntegrationOptions): ResolvedVueOptions {\n return {\n srcDir: options.srcDir ?? \"docs\",\n outDir: options.outDir ?? \"dist\",\n base: options.base ?? \"/\",\n gfm: options.gfm ?? true,\n frontmatter: options.frontmatter ?? true,\n toc: options.toc ?? true,\n tocMaxDepth: options.tocMaxDepth ?? 3,\n codeAnnotations: resolveCodeAnnotationsOptions(options.codeAnnotations),\n components: options.components ?? {},\n // Vue-specific options\n reactivityTransform: options.reactivityTransform ?? false,\n customBlocks: options.customBlocks ?? true,\n };\n}\n\nfunction resolveCodeAnnotationsOptions(\n options: VueIntegrationOptions[\"codeAnnotations\"],\n): ResolvedVueOptions[\"codeAnnotations\"] {\n if (!options) {\n return {\n enabled: false,\n metaKey: \"annotate\",\n };\n }\n\n if (options === true) {\n return {\n enabled: true,\n metaKey: \"annotate\",\n };\n }\n\n return {\n enabled: true,\n metaKey: options.metaKey ?? \"annotate\",\n };\n}\n\n/**\n * Generates the runtime module for Vue markdown rendering.\n */\nfunction generateRuntimeModule(_options: ResolvedVueOptions): string {\n return `\nimport { h, defineComponent, ref, onMounted } from 'vue';\n\nexport const OxContentRenderer = defineComponent({\n name: 'OxContentRenderer',\n props: {\n content: { type: Object, required: true },\n components: { type: Object, default: () => ({}) },\n },\n setup(props) {\n const mounted = ref(false);\n\n onMounted(() => {\n mounted.value = true;\n });\n\n return () => {\n if (!props.content) return null;\n\n const { html, frontmatter, toc, islands } = props.content;\n\n // Render static HTML with component islands\n return h('div', {\n class: 'ox-content',\n innerHTML: mounted.value ? undefined : html,\n }, mounted.value ? renderWithIslands(html, islands, props.components) : undefined);\n };\n },\n});\n\nfunction renderWithIslands(html, islands, components) {\n // Parse and render islands with Vue components\n // This is a simplified version - full implementation would use proper parsing\n return h('div', { innerHTML: html });\n}\n\nexport function useOxContent() {\n return {\n OxContentRenderer,\n };\n}\n`;\n}\n\n/**\n * Generates the components registration module.\n */\nfunction generateComponentsModule(componentMap: Map<string, string>): string {\n const imports: string[] = [];\n const exports: string[] = [];\n\n componentMap.forEach((path, name) => {\n imports.push(`import ${name} from '${path}';`);\n exports.push(` ${name},`);\n });\n\n return `\n${imports.join(\"\\n\")}\n\nexport const components = {\n${exports.join(\"\\n\")}\n};\n\nexport default components;\n`;\n}\n\n/**\n * Resolves component glob patterns to a component map.\n */\nasync function resolveComponentsGlob(\n componentsOption: ComponentsOption,\n root: string,\n): Promise<ComponentsMap> {\n // If it's already a map, return as-is\n if (typeof componentsOption === \"object\" && !Array.isArray(componentsOption)) {\n return componentsOption;\n }\n\n const patterns = Array.isArray(componentsOption) ? componentsOption : [componentsOption];\n\n const result: ComponentsMap = {};\n\n for (const pattern of patterns) {\n const files = await globFiles(pattern, root);\n\n for (const file of files) {\n // Derive component name from file name (PascalCase)\n const baseName = path.basename(file, path.extname(file));\n const componentName = toPascalCase(baseName);\n const relativePath = \"./\" + path.relative(root, file).replace(/\\\\/g, \"/\");\n\n result[componentName] = relativePath;\n }\n }\n\n return result;\n}\n\n/**\n * Simple glob matcher for component files.\n */\nasync function globFiles(pattern: string, root: string): Promise<string[]> {\n const files: string[] = [];\n\n // Parse glob pattern\n const isGlob = pattern.includes(\"*\");\n\n if (!isGlob) {\n // It's a direct path\n const fullPath = path.resolve(root, pattern);\n if (fs.existsSync(fullPath)) {\n files.push(fullPath);\n }\n return files;\n }\n\n // Handle glob patterns like './src/components/*.vue'\n const parts = pattern.split(\"*\");\n const baseDir = path.resolve(root, parts[0]);\n const ext = parts[1] || \"\";\n\n if (!fs.existsSync(baseDir)) {\n return files;\n }\n\n // Handle ** recursive pattern\n if (pattern.includes(\"**\")) {\n await walkDir(baseDir, files, ext);\n } else {\n // Single level glob\n const entries = await fs.promises.readdir(baseDir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isFile() && entry.name.endsWith(ext)) {\n files.push(path.join(baseDir, entry.name));\n }\n }\n }\n\n return files;\n}\n\n/**\n * Recursively walks a directory.\n */\nasync function walkDir(dir: string, files: string[], ext: string): Promise<void> {\n const entries = await fs.promises.readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n await walkDir(fullPath, files, ext);\n } else if (entry.isFile() && entry.name.endsWith(ext)) {\n files.push(fullPath);\n }\n }\n}\n\n/**\n * Converts a string to PascalCase.\n */\nfunction toPascalCase(str: string): string {\n return str.replace(/[-_](\\w)/g, (_, c) => c.toUpperCase()).replace(/^\\w/, (c) => c.toUpperCase());\n}\n\n// Re-export\nexport { oxContent } from \"@ox-content/vite-plugin\";\n"],"mappings":";;;;;;;AASA,MAAM,kBAAkB;AAGxB,MAAM,aACJ;AAEF,MAAM,uBAAuB;AAC7B,MAAM,uBAAuB;;;;AAkB7B,eAAsB,yBACpB,MACA,IACA,SAC6B;CAC7B,MAAM,EAAE,eAAe;CACvB,MAAM,iBAA2B,EAAE;CACnC,MAAM,UAA6B,EAAE;CACrC,IAAI,cAAc;CAGlB,MAAM,EAAE,SAAS,iBAAiB,gBAAgB,mBAAmB,KAAK;CAG1E,MAAM,cAAc,mBAAmB,gBAAgB;CACvD,IAAI,mBAAmB;CACvB,IAAI,YAAY;CAChB,IAAI;AAEJ,iBAAgB,YAAY;AAC5B,SAAQ,QAAQ,gBAAgB,KAAK,gBAAgB,MAAM,MAAM;EAC/D,MAAM,CAAC,WAAW,eAAe,aAAa,oBAAoB;EAClE,MAAM,aAAa,MAAM;EACzB,MAAM,WAAW,aAAa,UAAU;AAGxC,MAAI,CAAC,WAAW,IAAI,cAAc,IAAI,WAAW,YAAY,UAAU,YAAY,EAAE;AACnF,uBAAoB,gBAAgB,MAAM,WAAW,SAAS;AAC9D,eAAY;AACZ;;AAGF,MAAI,CAAC,eAAe,SAAS,cAAc,CACzC,gBAAe,KAAK,cAAc;EAIpC,MAAM,QAAQ,WAAW,YAAY;EAGrC,MAAM,WAAW,aAAa;EAC9B,MAAM,gBACJ,OAAO,qBAAqB,WAAW,iBAAiB,MAAM,GAAG,KAAA;AACnE,UAAQ,KAAK;GACX,MAAM;GACN;GACA,UAAU;GACV,IAAI;GACJ,SAAS;GACV,CAAC;AAGF,sBAAoB,gBAAgB,MAAM,WAAW,WAAW,GAAG,mBAAmB,SAAS;AAC/F,cAAY;;AAEd,qBAAoB,gBAAgB,MAAM,UAAU;CAGpD,MAAM,cAAc;EAClB,QAAQ,QAAQ;EAChB,QAAQ,QAAQ;EAChB,MAAM,QAAQ;EACd,KAAK;GACH,SAAS;GACT,WAAW;GACX,OAAO;GACP,MAAM;GACN,iBAAiB;GAClB;EACD,KAAK,QAAQ;EACb,aAAa;EACb,KAAK,QAAQ;EACb,aAAa,QAAQ;EACrB,iBAAiB,QAAQ;EACzB,WAAW;EACX,QAAQ;EACR,WAAW;EACX,eAAe;EACf,WAAW;EACX,gBAAgB;EAChB,gBAAgB,EAAE;EAClB,SAAS;EACT,SAAS;EACT,gBAAgB;GACd,WAAW;GACX,OAAO;GACP,QAAQ;GACR,OAAO;GACP,aAAa;GACd;EACD,cAAc,EAAE;EAChB,MAAM;EACN,UAAU;EACV,QAAQ;GACN,SAAS;GACT,OAAO;GACP,QAAQ;GACR,aAAa;GACb,QAAQ;GACT;EACD,MAAM;EACP;AAiBD,QAAO;EACL,MAVc,eADQ,qBAHJ,MAAMA,kBAAsB,kBAAkB,IAAI,YAAY,EAG1B,MAAM,QAAQ,EAGpE,gBACA,SACA,aACA,SACA,GACD;EAIC,KAAK;EACL;EACA;EACD;;AAGH,SAAS,mBAAmB,UAA0B;AACpD,QAAO,GAAG,uBAAuB,WAAW;;AAG9C,SAAS,mBAAmB,SAA0B;CACpD,MAAM,SAAkB,EAAE;CAC1B,IAAI,UAAU;CACd,IAAI,YAAY;CAChB,IAAI,cAAc;CAClB,IAAI,aAAa;CACjB,IAAI,MAAM;AAEV,QAAO,MAAM,QAAQ,QAAQ;EAC3B,MAAM,UAAU,QAAQ,QAAQ,MAAM,IAAI;EAC1C,MAAM,OAAO,YAAY,KAAK,QAAQ,SAAS,UAAU;EAEzD,MAAM,aADO,QAAQ,MAAM,KAAK,YAAY,KAAK,QAAQ,SAAS,QAAQ,CAClD,MAAM,qBAAqB;AAEnD,MAAI,YAAY;GACd,MAAM,SAAS,WAAW;AAC1B,OAAI,CAAC,SAAS;AACZ,cAAU;AACV,gBAAY,OAAO;AACnB,kBAAc,OAAO;AACrB,iBAAa;cACJ,OAAO,OAAO,aAAa,OAAO,UAAU,aAAa;AAClE,cAAU;AACV,WAAO,KAAK;KAAE,OAAO;KAAY,KAAK;KAAM,CAAC;AAC7C,gBAAY;AACZ,kBAAc;;;AAIlB,QAAM;;AAGR,KAAI,QACF,QAAO,KAAK;EAAE,OAAO;EAAY,KAAK,QAAQ;EAAQ,CAAC;AAGzD,QAAO;;AAGT,SAAS,WAAW,OAAe,KAAa,QAA0B;AACxE,MAAK,MAAM,SAAS,OAClB,KAAI,QAAQ,MAAM,OAAO,MAAM,MAAM,MACnC,QAAO;AAGX,QAAO;;AAGT,SAAS,oBAAoB,MAAc,SAAoC;CAC7E,IAAI,SAAS;AAEb,MAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,SAAS,mBAAmB,OAAO,GAAG;EAC5C,MAAM,YACJ,OAAO,KAAK,OAAO,MAAM,CAAC,SAAS,IAC/B,mBAAmB,KAAK,UAAU,OAAO,MAAM,CAAC,QAAQ,MAAM,QAAQ,CAAC,KACvE;EACN,MAAM,cAAc,OAAO,UACvB,qBAAqB,OAAO,QAAQ,QAAQ,MAAM,QAAQ,CAAC,KAC3D;EACJ,MAAM,QAAQ,mBAAmB,OAAO,KAAK,GAAG,YAAY;AAC5D,WAAS,OAAO,WAAW,MAAM,OAAO,OAAO,QAAQ,MAAM,SAAS;AACtE,WAAS,OAAO,WAAW,QAAQ,SAAS,MAAM,UAAU;;AAG9D,QAAO;;;;;AAMT,SAAS,mBAAmB,SAG1B;CAEA,MAAM,QADmB,0BACM,KAAK,QAAQ;AAE5C,KAAI,CAAC,MACH,QAAO;EAAE;EAAS,aAAa,EAAE;EAAE;CAGrC,MAAM,iBAAiB,MAAM;CAC7B,MAAM,cAAuC,EAAE;AAG/C,MAAK,MAAM,QAAQ,eAAe,MAAM,KAAK,EAAE;EAC7C,MAAM,aAAa,KAAK,QAAQ,IAAI;AACpC,MAAI,aAAa,GAAG;GAClB,MAAM,MAAM,KAAK,MAAM,GAAG,WAAW,CAAC,MAAM;GAC5C,IAAI,QAAiB,KAAK,MAAM,aAAa,EAAE,CAAC,MAAM;AAGtD,OAAI;AACF,YAAQ,KAAK,MAAM,MAAgB;WAC7B;AAGN,QACE,OAAO,UAAU,aACf,MAAM,WAAW,KAAI,IAAI,MAAM,SAAS,KAAI,IAC3C,MAAM,WAAW,IAAI,IAAI,MAAM,SAAS,IAAI,EAE/C,SAAQ,MAAM,MAAM,GAAG,GAAG;;AAI9B,eAAY,OAAO;;;AAIvB,QAAO;EACL,SAAS,QAAQ,MAAM,MAAM,GAAG,OAAO;EACvC;EACD;;;;;AAMH,SAAS,WAAW,aAA8C;CAChE,MAAM,QAAiC,EAAE;AAEzC,KAAI,CAAC,YAAa,QAAO;CAEzB,IAAI;AACJ,SAAQ,QAAQ,WAAW,KAAK,YAAY,MAAM,MAAM;EACtD,MAAM,GAAG,MAAM,cAAc,cAAc,YAAY,gBAAgB;AAEvE,MAAI,KACF,KAAI,iBAAiB,KAAA,EACnB,OAAM,QAAQ;WACL,iBAAiB,KAAA,EAC1B,OAAM,QAAQ;WACL,eAAe,KAAA,EAExB,KAAI;AACF,SAAM,QAAQ,KAAK,MAAM,IAAI,WAAW,GAAG;UACrC;AACN,SAAM,QAAQ;;WAEP,iBAAiB,KAAA,EAC1B,KAAI;AACF,SAAM,QAAQ,KAAK,MAAM,IAAI,aAAa,GAAG;UACvC;AACN,SAAM,QAAQ;;MAIhB,OAAM,QAAQ;;AAKpB,QAAO;;;;;AAMT,SAAS,eACP,SACA,gBACA,SACA,aACA,SACA,IACQ;CACR,MAAM,QAAQ,KAAK,QAAQ,GAAG;CAC9B,MAAM,OAAO,QAAQ,QAAQ,QAAQ,KAAK;CAE1C,MAAM,mBAAmB,eACtB,KAAK,SAAS;EACb,MAAM,gBAAgB,QAAQ,WAAW,IAAI,KAAK;AAClD,MAAI,CAAC,cAAe,QAAO;EAE3B,MAAM,eAAe,KAAK,QAAQ,MAAM,cAAc,QAAQ,SAAS,GAAG,CAAC;EAC3E,MAAM,eAAe,KAAK,SAAS,OAAO,aAAa,CAAC,QAAQ,OAAO,IAAI;AAG3E,SAAO,UAAU,KAAK,SADH,aAAa,WAAW,IAAI,GAAG,eAAe,OAAO,aAC9B;GAC1C,CACD,OAAO,QAAQ,CACf,KAAK,KAAK;CAEb,MAAM,eAAe,eAAe,KAAK,SAAS,KAAK,KAAK,GAAG,CAAC,KAAK,KAAK;AAG1E,KAAI,QAAQ,WAAW,EACrB,QAAO;;;6BAGkB,KAAK,UAAU,YAAY,CAAC;;kBAEvC,KAAK,UAAU,QAAQ,CAAC;;;;;;;;;;;;;;;AAiBxC,QAAO;;;EAGP,iBAAiB;;6BAEU,KAAK,UAAU,YAAY,CAAC;;kBAEvC,KAAK,UAAU,QAAQ,CAAC;;EAExC,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACnXf,SAAgB,6BACd,MACA,SACoB;CACpB,MAAM,QAAQ,SAAS;AAEvB,QAAO;EACL,OAAO;GACL,QAAQ,QAAQ,GAAG,QAAQ,OAAO,oBAAoB,GAAG,QAAQ,OAAO;GAExE,KAAK;GAEL,eAAe;IACb,OAAO,QAAQ,KAAA,IAAY,KAAA;IAC3B,QAAQ;KACN,QAAQ,QAAQ,QAAQ;KACxB,gBAAgB,QAAQ,cAAc;KACtC,gBAAgB,QAAQ,qBAAqB;KAC9C;IACF;GAGD,GAAI,SAAS;IACX,QAAQ;IACR,QAAQ;IACT;GACF;EAED,SAAS,EACP,YAAY,QAAQ,CAAC,QAAQ,SAAS,GAAG,CAAC,WAAW,SAAS,EAC/D;EAED,cAAc;GAEZ,SAAS,QAAQ,EAAE,GAAG,CAAC,MAAM;GAG7B,SAAS,CAAC,2BAA2B,8BAA8B;GACpE;EAGD,GAAI,CAAC,SAAS,EACZ,KAAK,EACH,QAAQ,CAAC,kBAAkB,iBAAiB,EAC7C,EACF;EACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACLH,SAAgB,aAAa,UAAiC,EAAE,EAAkB;CAChF,MAAM,WAAW,kBAAkB,QAAQ;CAC3C,IAAI,+BAAe,IAAI,KAAqB;CAC5C,IAAI;AAGJ,KAAI,OAAO,QAAQ,eAAe,YAAY,CAAC,MAAM,QAAQ,QAAQ,WAAW,CAC9E,gBAAe,IAAI,IAAI,OAAO,QAAQ,QAAQ,WAAW,CAAC;CAI5D,MAAM,qBAA6B;EACjC,MAAM;EACN,SAAS;EAET,MAAM,eAAe,gBAAgB;AACnC,YAAS;GAGT,MAAM,mBAAmB,QAAQ;AACjC,OAAI,kBAAkB;IACpB,MAAM,qBAAqB,MAAM,sBAAsB,kBAAkB,OAAO,KAAK;AACrF,mBAAe,IAAI,IAAI,OAAO,QAAQ,mBAAmB,CAAC;;;EAI9D,MAAM,UAAU,MAAM,IAAI;AACxB,OAAI,CAAC,GAAG,SAAS,MAAM,CACrB,QAAO;GAGT,MAAM,SAAS,MAAM,yBAAyB,MAAM,IAAI;IACtD,GAAG;IACH,YAAY;IACZ,MAAM,OAAO;IACd,CAAC;AAEF,UAAO;IACL,MAAM,OAAO;IACb,KAAK,OAAO;IACb;;EAEJ;CAGD,MAAM,uBAA+B;EACnC,MAAM;EAEN,SAAS;AACP,UAAO,EACL,cAAc;IAEZ,eAAe,6BAA6B,OAAO,SAAS;IAE5D,kBAAkB,6BAA6B,UAAU,SAAS;IACnE,EACF;;EAIH,WAAW;GACT,OAAO;GACP,MAAM,QAAQ,IAAI,WAAW,UAAU;AAErC,QAAI,OAAO,iCACT,QAAO;AAGT,QAAI,OAAO,oCACT,QAAO;AAGT,WAAO;;GAEV;EAED,MAAM;GACJ,OAAO;GACP,MAAM,QAAQ,IAAI;AAChB,QAAI,OAAO,mCACT,QAAO,sBAAsB,SAAS;AAGxC,QAAI,OAAO,sCACT,QAAO,yBAAyB,aAAa;AAG/C,WAAO;;GAEV;EAGD,mBAAmB,aAAa;AAC9B,UACE,YAAY,SAAS,mBACrB,YAAY,SAAS,sBACrB,YAAY,SAAS,YACrB,YAAY,SAAS;;EAG1B;CAGD,MAAM,eAAuB;EAC3B,MAAM;EACN,OAAO;EAEP,gBAAgB,EAAE,MAAM,QAAQ,WAAW;AAMzC,OAJoB,MAAM,KAAK,aAAa,QAAQ,CAAC,CAAC,MAAM,SAC1D,KAAK,SAAS,KAAK,QAAQ,SAAS,GAAG,CAAC,CACzC,EAEgB;IAEf,MAAM,YAAY,MAAM,KAAK,OAAO,YAAY,cAAc,QAAQ,CAAC,CAAC,QAAQ,QAC9E,IAAI,MAAM,SAAS,MAAM,CAC1B;AAED,QAAI,UAAU,SAAS,GAAG;AACxB,YAAO,GAAG,KAAK;MACb,MAAM;MACN,OAAO;MACP,MAAM,EAAE,MAAM;MACf,CAAC;AACF,YAAO,CAAC,GAAG,SAAS,GAAG,UAAU;;;AAIrC,UAAO;;EAEV;CAMD,MAAM,oBAHcC,YAAU,QAAQ,CAAC,SAAS,WAC9C,MAAM,QAAQ,OAAO,GAAG,SAAS,CAAC,OAAO,CAC1C,CACqC,MAAM,WAAW,OAAO,SAAS,yBAAyB;CAChG,MAAM,UAAoB;EAAC;EAAoB;EAAsB;EAAa;AAElF,KAAI,kBACF,SAAQ,KAAK,kBAAkB;AAGjC,QAAO;;;;;AAMT,SAAS,kBAAkB,SAAoD;AAC7E,QAAO;EACL,QAAQ,QAAQ,UAAU;EAC1B,QAAQ,QAAQ,UAAU;EAC1B,MAAM,QAAQ,QAAQ;EACtB,KAAK,QAAQ,OAAO;EACpB,aAAa,QAAQ,eAAe;EACpC,KAAK,QAAQ,OAAO;EACpB,aAAa,QAAQ,eAAe;EACpC,iBAAiB,8BAA8B,QAAQ,gBAAgB;EACvE,YAAY,QAAQ,cAAc,EAAE;EAEpC,qBAAqB,QAAQ,uBAAuB;EACpD,cAAc,QAAQ,gBAAgB;EACvC;;AAGH,SAAS,8BACP,SACuC;AACvC,KAAI,CAAC,QACH,QAAO;EACL,SAAS;EACT,SAAS;EACV;AAGH,KAAI,YAAY,KACd,QAAO;EACL,SAAS;EACT,SAAS;EACV;AAGH,QAAO;EACL,SAAS;EACT,SAAS,QAAQ,WAAW;EAC7B;;;;;AAMH,SAAS,sBAAsB,UAAsC;AACnE,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+CT,SAAS,yBAAyB,cAA2C;CAC3E,MAAM,UAAoB,EAAE;CAC5B,MAAM,UAAoB,EAAE;AAE5B,cAAa,SAAS,MAAM,SAAS;AACnC,UAAQ,KAAK,UAAU,KAAK,SAAS,KAAK,IAAI;AAC9C,UAAQ,KAAK,KAAK,KAAK,GAAG;GAC1B;AAEF,QAAO;EACP,QAAQ,KAAK,KAAK,CAAC;;;EAGnB,QAAQ,KAAK,KAAK,CAAC;;;;;;;;;AAUrB,eAAe,sBACb,kBACA,MACwB;AAExB,KAAI,OAAO,qBAAqB,YAAY,CAAC,MAAM,QAAQ,iBAAiB,CAC1E,QAAO;CAGT,MAAM,WAAW,MAAM,QAAQ,iBAAiB,GAAG,mBAAmB,CAAC,iBAAiB;CAExF,MAAM,SAAwB,EAAE;AAEhC,MAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,QAAQ,MAAM,UAAU,SAAS,KAAK;AAE5C,OAAK,MAAM,QAAQ,OAAO;GAGxB,MAAM,gBAAgB,aADL,KAAK,SAAS,MAAM,KAAK,QAAQ,KAAK,CAAC,CACZ;AAG5C,UAAO,iBAFc,OAAO,KAAK,SAAS,MAAM,KAAK,CAAC,QAAQ,OAAO,IAAI;;;AAM7E,QAAO;;;;;AAMT,eAAe,UAAU,SAAiB,MAAiC;CACzE,MAAM,QAAkB,EAAE;AAK1B,KAAI,CAFW,QAAQ,SAAS,IAAI,EAEvB;EAEX,MAAM,WAAW,KAAK,QAAQ,MAAM,QAAQ;AAC5C,MAAI,GAAG,WAAW,SAAS,CACzB,OAAM,KAAK,SAAS;AAEtB,SAAO;;CAIT,MAAM,QAAQ,QAAQ,MAAM,IAAI;CAChC,MAAM,UAAU,KAAK,QAAQ,MAAM,MAAM,GAAG;CAC5C,MAAM,MAAM,MAAM,MAAM;AAExB,KAAI,CAAC,GAAG,WAAW,QAAQ,CACzB,QAAO;AAIT,KAAI,QAAQ,SAAS,KAAK,CACxB,OAAM,QAAQ,SAAS,OAAO,IAAI;MAC7B;EAEL,MAAM,UAAU,MAAM,GAAG,SAAS,QAAQ,SAAS,EAAE,eAAe,MAAM,CAAC;AAC3E,OAAK,MAAM,SAAS,QAClB,KAAI,MAAM,QAAQ,IAAI,MAAM,KAAK,SAAS,IAAI,CAC5C,OAAM,KAAK,KAAK,KAAK,SAAS,MAAM,KAAK,CAAC;;AAKhD,QAAO;;;;;AAMT,eAAe,QAAQ,KAAa,OAAiB,KAA4B;CAC/E,MAAM,UAAU,MAAM,GAAG,SAAS,QAAQ,KAAK,EAAE,eAAe,MAAM,CAAC;AAEvE,MAAK,MAAM,SAAS,SAAS;EAC3B,MAAM,WAAW,KAAK,KAAK,KAAK,MAAM,KAAK;AAE3C,MAAI,MAAM,aAAa,CACrB,OAAM,QAAQ,UAAU,OAAO,IAAI;WAC1B,MAAM,QAAQ,IAAI,MAAM,KAAK,SAAS,IAAI,CACnD,OAAM,KAAK,SAAS;;;;;;AAQ1B,SAAS,aAAa,KAAqB;AACzC,QAAO,IAAI,QAAQ,cAAc,GAAG,MAAM,EAAE,aAAa,CAAC,CAAC,QAAQ,QAAQ,MAAM,EAAE,aAAa,CAAC"}
package/package.json CHANGED
@@ -1,58 +1,59 @@
1
1
  {
2
2
  "name": "@ox-content/vite-plugin-vue",
3
- "version": "0.17.0",
3
+ "version": "1.1.0",
4
4
  "description": "Vue integration for Ox Content - Embed Vue components in Markdown",
5
+ "keywords": [
6
+ "markdown",
7
+ "mdx",
8
+ "ox-content",
9
+ "vite",
10
+ "vite-plugin",
11
+ "vue"
12
+ ],
13
+ "license": "MIT",
14
+ "author": "ubugeeei",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/ubugeeei/ox-content.git",
18
+ "directory": "npm/vite-plugin-ox-content-vue"
19
+ },
20
+ "files": [
21
+ "dist"
22
+ ],
5
23
  "type": "module",
6
- "main": "./dist/index.js",
7
- "types": "./dist/index.d.ts",
24
+ "main": "./dist/index.cjs",
25
+ "types": "./dist/index.d.mts",
8
26
  "exports": {
9
27
  ".": {
10
- "import": "./dist/index.js",
11
- "types": "./dist/index.d.ts"
28
+ "import": "./dist/index.mjs",
29
+ "require": "./dist/index.cjs",
30
+ "types": "./dist/index.d.mts"
12
31
  }
13
32
  },
14
- "files": [
15
- "dist"
16
- ],
17
- "peerDependencies": {
18
- "vite": "^8.0.0",
19
- "vue": "^3.5.0"
33
+ "publishConfig": {
34
+ "access": "public",
35
+ "provenance": true
20
36
  },
21
37
  "dependencies": {
22
- "@ox-content/vite-plugin": "0.17.0",
23
- "@ox-content/islands": "0.17.0"
38
+ "@ox-content/vite-plugin": "1.1.0",
39
+ "@ox-content/islands": "1.1.0"
24
40
  },
25
41
  "devDependencies": {
26
42
  "@types/node": "^22.0.0",
27
- "@vitejs/plugin-vue": "^6.0.0",
28
- "tsdown": "^0.12.0",
29
43
  "@typescript/native-preview": "^7.0.0-dev.20250601",
44
+ "@vitejs/plugin-vue": "^6.0.0",
30
45
  "typescript": "^5.7.0",
31
- "vite": "^8.0.0",
46
+ "vite": "npm:@voidzero-dev/vite-plus-core@0.1.11",
47
+ "vite-plus": "0.1.11",
32
48
  "vue": "^3.5.0"
33
49
  },
34
- "keywords": [
35
- "vite",
36
- "vite-plugin",
37
- "vue",
38
- "markdown",
39
- "ox-content",
40
- "mdx"
41
- ],
42
- "license": "MIT",
43
- "author": "ubugeeei",
44
- "repository": {
45
- "type": "git",
46
- "url": "https://github.com/ubugeeei/ox-content.git",
47
- "directory": "npm/vite-plugin-ox-content-vue"
48
- },
49
- "publishConfig": {
50
- "provenance": true,
51
- "access": "public"
50
+ "peerDependencies": {
51
+ "vite": "npm:@voidzero-dev/vite-plus-core@0.1.11",
52
+ "vue": "^3.5.0"
52
53
  },
53
54
  "scripts": {
54
- "build": "tsdown",
55
- "dev": "tsdown --watch",
55
+ "build": "vp pack",
56
+ "dev": "vp pack --watch",
56
57
  "typecheck": "tsgo --noEmit"
57
58
  }
58
59
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/index.ts"],"sourcesContent":[],"mappings":";;;;;AAUA;AAoBA;AAKA;;AA2Be,KApDH,aAAA,GAAgB,MAoDb,CAAA,MAAA,EAAA,MAAA,CAAA;;;AAQf;AAgBA;AAgBA;AA0BA;;;;;;AAsBA;;;;AChGA;;;AAAmE,KDxBvD,gBAAA,GAAmB,aCwBoC,GAAA,MAAA,GAAA,MAAA,EAAA;;;;UDnBlD,qBAAA,SAA8B;;;;;;;;;;;;;;;;;;;;;;;;;eA2BhC;;;;;;;UAQE,kBAAA;;;;;;;;cAQH;;;;;;;UAQG,kBAAA;;;;;;;;;;eAUF;;;;;UAME,eAAA;;;;;;;;SAQR;;;;;;;;;;;;;;;;;UAkBQ,qBAAA;;;;;;;;WAQN;;;;eAII;;;;OAIR;;;;;UAMU,QAAA;;;;aAIJ;;;;;;;AApFb;AAgBA;AAgBA;AA0BA;;;;;;AAsBA;;;;AChGA;;;;;;;;iBAAgB,YAAA,WAAsB,wBAA6B"}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":["baseTransformMarkdown","oxContent"],"sources":["../src/transform.ts","../src/environment.ts","../src/index.ts"],"sourcesContent":["/**\n * Markdown to Vue SFC transformation.\n */\n\nimport * as path from \"path\";\nimport { transformMarkdown as baseTransformMarkdown } from \"@ox-content/vite-plugin\";\nimport type { ResolvedVueOptions, VueTransformResult, ComponentIsland } from \"./types\";\n\n// Regex to match Vue-like component tags in Markdown\nconst COMPONENT_REGEX = /<([A-Z][a-zA-Z0-9]*)\\s*([^>]*?)\\s*(?:\\/>|>([\\s\\S]*?)<\\/\\1>)/g;\n\n// Regex to parse component props\nconst PROP_REGEX =\n /(?::|v-bind:)?([a-zA-Z0-9-]+)(?:=(?:\"([^\"]*)\"|'([^']*)'|{([^}]*)}|\\[([^\\]]*)\\]))?/g;\n\nconst ISLAND_MARKER_PREFIX = \"OXCONTENT-ISLAND-\";\nconst ISLAND_MARKER_SUFFIX = \"-PLACEHOLDER\";\n\ninterface Range {\n start: number;\n end: number;\n}\n\n/**\n * Options for transformMarkdownWithVue.\n */\ninterface TransformOptions extends Omit<ResolvedVueOptions, \"components\"> {\n components: Map<string, string>;\n root?: string;\n}\n\n/**\n * Transforms Markdown content with Vue component support.\n */\nexport async function transformMarkdownWithVue(\n code: string,\n id: string,\n options: TransformOptions,\n): Promise<VueTransformResult> {\n const { components } = options;\n const usedComponents: string[] = [];\n const islands: ComponentIsland[] = [];\n let islandIndex = 0;\n\n // Extract frontmatter\n const { content: markdownContent, frontmatter } = extractFrontmatter(code);\n\n // Find and extract component usages\n const fenceRanges = collectFenceRanges(markdownContent);\n let processedContent = \"\";\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n COMPONENT_REGEX.lastIndex = 0;\n while ((match = COMPONENT_REGEX.exec(markdownContent)) !== null) {\n const [fullMatch, componentName, propsString, rawIslandContent] = match;\n const matchStart = match.index;\n const matchEnd = matchStart + fullMatch.length;\n\n // Check if component is registered\n if (!components.has(componentName) || isInRanges(matchStart, matchEnd, fenceRanges)) {\n processedContent += markdownContent.slice(lastIndex, matchEnd);\n lastIndex = matchEnd;\n continue;\n }\n\n if (!usedComponents.includes(componentName)) {\n usedComponents.push(componentName);\n }\n\n // Parse props\n const props = parseProps(propsString);\n\n // Create island placeholder\n const islandId = `ox-island-${islandIndex++}`;\n const islandContent =\n typeof rawIslandContent === \"string\" ? rawIslandContent.trim() : undefined;\n islands.push({\n name: componentName,\n props,\n position: matchStart,\n id: islandId,\n content: islandContent,\n });\n\n // Replace component with island marker text\n processedContent += markdownContent.slice(lastIndex, matchStart) + createIslandMarker(islandId);\n lastIndex = matchEnd;\n }\n processedContent += markdownContent.slice(lastIndex);\n\n // Transform Markdown to HTML using ox-content\n const transformed = await baseTransformMarkdown(processedContent, id, {\n srcDir: options.srcDir,\n outDir: options.outDir,\n base: options.base,\n ssg: {\n enabled: false,\n extension: \".html\",\n clean: false,\n bare: false,\n generateOgImage: false,\n },\n gfm: options.gfm,\n frontmatter: false, // Already extracted\n toc: options.toc,\n tocMaxDepth: options.tocMaxDepth,\n footnotes: true,\n tables: true,\n taskLists: true,\n strikethrough: true,\n highlight: false,\n highlightTheme: \"github-dark\",\n highlightLangs: [],\n mermaid: false,\n ogImage: false,\n ogImageOptions: {\n vuePlugin: \"vitejs\",\n width: 1200,\n height: 630,\n cache: true,\n concurrency: 1,\n },\n transformers: [],\n docs: false,\n ogViewer: false,\n search: {\n enabled: false,\n limit: 10,\n prefix: true,\n placeholder: \"Search...\",\n hotkey: \"k\",\n },\n i18n: false,\n });\n\n // Generate Vue SFC code\n const htmlWithIslands = injectIslandMarkers(transformed.html, islands);\n const sfcCode = generateVueSFC(\n htmlWithIslands,\n usedComponents,\n islands,\n frontmatter,\n options,\n id,\n );\n\n return {\n code: sfcCode,\n map: null,\n usedComponents,\n frontmatter,\n };\n}\n\nfunction createIslandMarker(islandId: string): string {\n return `${ISLAND_MARKER_PREFIX}${islandId}${ISLAND_MARKER_SUFFIX}`;\n}\n\nfunction collectFenceRanges(content: string): Range[] {\n const ranges: Range[] = [];\n let inFence = false;\n let fenceChar = \"\";\n let fenceLength = 0;\n let fenceStart = 0;\n let pos = 0;\n\n while (pos < content.length) {\n const lineEnd = content.indexOf(\"\\n\", pos);\n const next = lineEnd === -1 ? content.length : lineEnd + 1;\n const line = content.slice(pos, lineEnd === -1 ? content.length : lineEnd);\n const fenceMatch = line.match(/^\\s{0,3}([`~]{3,})/);\n\n if (fenceMatch) {\n const marker = fenceMatch[1];\n if (!inFence) {\n inFence = true;\n fenceChar = marker[0];\n fenceLength = marker.length;\n fenceStart = pos;\n } else if (marker[0] === fenceChar && marker.length >= fenceLength) {\n inFence = false;\n ranges.push({ start: fenceStart, end: next });\n fenceChar = \"\";\n fenceLength = 0;\n }\n }\n\n pos = next;\n }\n\n if (inFence) {\n ranges.push({ start: fenceStart, end: content.length });\n }\n\n return ranges;\n}\n\nfunction isInRanges(start: number, end: number, ranges: Range[]): boolean {\n for (const range of ranges) {\n if (start < range.end && end > range.start) {\n return true;\n }\n }\n return false;\n}\n\nfunction injectIslandMarkers(html: string, islands: ComponentIsland[]): string {\n let output = html;\n\n for (const island of islands) {\n const marker = createIslandMarker(island.id);\n const propsAttr =\n Object.keys(island.props).length > 0\n ? ` data-ox-props='${JSON.stringify(island.props).replace(/'/g, \"&#39;\")}'`\n : \"\";\n const contentAttr = island.content\n ? ` data-ox-content='${island.content.replace(/'/g, \"&#39;\")}'`\n : \"\";\n const attrs = `data-ox-island=\"${island.name}\"${propsAttr}${contentAttr}`;\n output = output.replaceAll(`<p>${marker}</p>`, `<div ${attrs}></div>`);\n output = output.replaceAll(marker, `<span ${attrs}></span>`);\n }\n\n return output;\n}\n\n/**\n * Extracts frontmatter from Markdown content.\n */\nfunction extractFrontmatter(content: string): {\n content: string;\n frontmatter: Record<string, unknown>;\n} {\n const frontmatterRegex = /^---\\n([\\s\\S]*?)\\n---\\n/;\n const match = frontmatterRegex.exec(content);\n\n if (!match) {\n return { content, frontmatter: {} };\n }\n\n const frontmatterStr = match[1];\n const frontmatter: Record<string, unknown> = {};\n\n // Simple YAML-like parsing\n for (const line of frontmatterStr.split(\"\\n\")) {\n const colonIndex = line.indexOf(\":\");\n if (colonIndex > 0) {\n const key = line.slice(0, colonIndex).trim();\n let value: unknown = line.slice(colonIndex + 1).trim();\n\n // Try to parse as JSON for complex values\n try {\n value = JSON.parse(value as string);\n } catch {\n // Keep as string if not valid JSON\n // Remove quotes if present\n if (\n typeof value === \"string\" &&\n ((value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\")))\n ) {\n value = value.slice(1, -1);\n }\n }\n\n frontmatter[key] = value;\n }\n }\n\n return {\n content: content.slice(match[0].length),\n frontmatter,\n };\n}\n\n/**\n * Parses component props from a string.\n */\nfunction parseProps(propsString: string): Record<string, unknown> {\n const props: Record<string, unknown> = {};\n\n if (!propsString) return props;\n\n let match: RegExpExecArray | null;\n while ((match = PROP_REGEX.exec(propsString)) !== null) {\n const [, name, doubleQuoted, singleQuoted, braceValue, bracketValue] = match;\n\n if (name) {\n if (doubleQuoted !== undefined) {\n props[name] = doubleQuoted;\n } else if (singleQuoted !== undefined) {\n props[name] = singleQuoted;\n } else if (braceValue !== undefined) {\n // Try to parse as JSON\n try {\n props[name] = JSON.parse(`{${braceValue}}`);\n } catch {\n props[name] = braceValue;\n }\n } else if (bracketValue !== undefined) {\n try {\n props[name] = JSON.parse(`[${bracketValue}]`);\n } catch {\n props[name] = bracketValue;\n }\n } else {\n // Boolean prop\n props[name] = true;\n }\n }\n }\n\n return props;\n}\n\n/**\n * Generates a Vue component as JavaScript module from the processed Markdown.\n */\nfunction generateVueSFC(\n content: string,\n usedComponents: string[],\n islands: ComponentIsland[],\n frontmatter: Record<string, unknown>,\n options: TransformOptions,\n id: string,\n): string {\n const mdDir = path.dirname(id);\n const root = options.root || process.cwd();\n\n const componentImports = usedComponents\n .map((name) => {\n const componentPath = options.components.get(name);\n if (!componentPath) return \"\";\n // Convert relative-to-root path to relative-to-md-file path\n const absolutePath = path.resolve(root, componentPath.replace(/^\\.\\//, \"\"));\n const relativePath = path.relative(mdDir, absolutePath).replace(/\\\\/g, \"/\");\n // Ensure the path starts with ./ or ../\n const importPath = relativePath.startsWith(\".\") ? relativePath : \"./\" + relativePath;\n return `import ${name} from '${importPath}';`;\n })\n .filter(Boolean)\n .join(\"\\n\");\n\n const componentMap = usedComponents.map((name) => ` ${name},`).join(\"\\n\");\n\n // If no islands, generate simpler code without island runtime\n if (islands.length === 0) {\n return `\nimport { h, ref, defineComponent } from 'vue';\n\nexport const frontmatter = ${JSON.stringify(frontmatter)};\n\nconst rawHtml = ${JSON.stringify(content)};\n\nexport default defineComponent({\n name: 'MarkdownContent',\n setup(_, { expose }) {\n expose({ frontmatter });\n\n return () =>\n h('div', {\n class: 'ox-content',\n innerHTML: rawHtml,\n });\n },\n});\n`;\n }\n\n return `\nimport { h, ref, onMounted, onBeforeUnmount, defineComponent, render } from 'vue';\nimport { initIslands } from '@ox-content/islands';\n${componentImports}\n\nexport const frontmatter = ${JSON.stringify(frontmatter)};\n\nconst rawHtml = ${JSON.stringify(content)};\nconst components = {\n${componentMap}\n};\n\nfunction createVueHydrate(container) {\n const mountedTargets = [];\n\n return (element, props) => {\n const componentName = element.dataset.oxIsland;\n const Component = components[componentName];\n if (!Component) return;\n\n const islandContent = element.dataset.oxContent || element.innerHTML;\n const children = islandContent\n ? { default: () => h('div', { innerHTML: islandContent }) }\n : undefined;\n\n const vnode = h(Component, props, children);\n render(vnode, element);\n mountedTargets.push(element);\n\n return () => render(null, element);\n };\n}\n\nexport default defineComponent({\n name: 'MarkdownContent',\n setup(_, { expose }) {\n const container = ref(null);\n let controller;\n\n onMounted(() => {\n if (container.value) {\n controller = initIslands(createVueHydrate(container.value), {\n selector: '.ox-content [data-ox-island]',\n });\n }\n });\n\n onBeforeUnmount(() => {\n if (controller) controller.destroy();\n });\n\n expose({ frontmatter });\n\n return () =>\n h('div', {\n class: 'ox-content',\n ref: container,\n innerHTML: rawHtml,\n });\n },\n});\n`;\n}\n","/**\n * Vite Environment API configuration for Vue integration.\n */\n\nimport type { EnvironmentOptions } from \"vite\";\nimport type { ResolvedVueOptions } from \"./types\";\n\n/**\n * Creates a Vite environment for Vue markdown processing.\n *\n * @param mode - 'ssr' for server-side rendering, 'client' for client hydration\n * @param options - Resolved Vue integration options\n */\nexport function createVueMarkdownEnvironment(\n mode: \"ssr\" | \"client\",\n options: ResolvedVueOptions,\n): EnvironmentOptions {\n const isSSR = mode === \"ssr\";\n\n return {\n build: {\n outDir: isSSR ? `${options.outDir}/.ox-content/ssr` : `${options.outDir}/.ox-content/client`,\n\n ssr: isSSR,\n\n rollupOptions: {\n input: isSSR ? undefined : undefined,\n output: {\n format: isSSR ? \"esm\" : \"esm\",\n entryFileNames: isSSR ? \"[name].js\" : \"[name].[hash].js\",\n chunkFileNames: isSSR ? \"chunks/[name].js\" : \"chunks/[name].[hash].js\",\n },\n },\n\n // SSR-specific optimizations\n ...(isSSR && {\n target: \"node18\",\n minify: false,\n }),\n },\n\n resolve: {\n conditions: isSSR ? [\"node\", \"import\"] : [\"browser\", \"import\"],\n },\n\n optimizeDeps: {\n // Pre-bundle Vue for faster cold starts\n include: isSSR ? [] : [\"vue\"],\n\n // Exclude ox-content packages from optimization (they're local)\n exclude: [\"@ox-content/vite-plugin\", \"@ox-content/vite-plugin-vue\"],\n },\n\n // Development server options (client only)\n ...(!isSSR && {\n dev: {\n warmup: [\"./src/**/*.vue\", \"./docs/**/*.md\"],\n },\n }),\n };\n}\n\n/**\n * Creates environment-specific virtual modules.\n */\nexport function createVirtualModules(\n mode: \"ssr\" | \"client\",\n _options: ResolvedVueOptions,\n): Record<string, string> {\n const isSSR = mode === \"ssr\";\n\n return {\n // Environment detection module\n \"virtual:ox-content/env\": `\n export const isSSR = ${isSSR};\n export const isClient = ${!isSSR};\n export const mode = '${mode}';\n `,\n\n // Hydration utilities\n \"virtual:ox-content/hydration\": isSSR\n ? `\n // SSR: No-op hydration\n export function hydrate() {}\n export function createSSRApp(component) {\n return component;\n }\n `\n : `\n import { createApp } from 'vue';\n\n export function hydrate(component, container, props = {}) {\n const app = createApp(component, props);\n app.mount(container);\n return app;\n }\n\n export function createClientApp(component) {\n return createApp(component);\n }\n `,\n };\n}\n","/**\n * Vite Plugin for Ox Content Vue Integration\n *\n * Uses Vite's Environment API to enable embedding Vue components in Markdown.\n * Provides SSR and client environments for proper hydration.\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport type { Plugin, PluginOption, ResolvedConfig } from \"vite\";\nimport { oxContent } from \"@ox-content/vite-plugin\";\nimport { transformMarkdownWithVue } from \"./transform\";\nimport { createVueMarkdownEnvironment } from \"./environment\";\nimport type {\n VueIntegrationOptions,\n ResolvedVueOptions,\n ComponentsMap,\n ComponentsOption,\n} from \"./types\";\n\nexport type {\n VueIntegrationOptions,\n ResolvedVueOptions,\n ComponentsOption,\n ComponentsMap,\n VueTransformResult,\n ComponentIsland,\n ParsedMarkdownContent,\n TocEntry,\n} from \"./types\";\n\n/**\n * Creates the Ox Content Vue integration plugin with Environment API support.\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import { defineConfig } from 'vite';\n * import vue from '@vitejs/plugin-vue';\n * import { oxContentVue } from 'vite-plugin-ox-content-vue';\n *\n * export default defineConfig({\n * plugins: [\n * vue(),\n * oxContentVue({\n * srcDir: 'docs',\n * components: {\n * Counter: './src/components/Counter.vue',\n * },\n * }),\n * ],\n * });\n * ```\n */\nexport function oxContentVue(options: VueIntegrationOptions = {}): PluginOption[] {\n const resolved = resolveVueOptions(options);\n let componentMap = new Map<string, string>();\n let config: ResolvedConfig;\n\n // Pre-resolve components if it's a map (not glob)\n if (typeof options.components === \"object\" && !Array.isArray(options.components)) {\n componentMap = new Map(Object.entries(options.components));\n }\n\n // Main Vue transformation plugin\n const vueTransformPlugin: Plugin = {\n name: \"ox-content:vue-transform\",\n enforce: \"pre\",\n\n async configResolved(resolvedConfig) {\n config = resolvedConfig;\n\n // Resolve glob patterns for components\n const componentsOption = options.components;\n if (componentsOption) {\n const resolvedComponents = await resolveComponentsGlob(componentsOption, config.root);\n componentMap = new Map(Object.entries(resolvedComponents));\n }\n },\n\n async transform(code, id) {\n if (!id.endsWith(\".md\")) {\n return null;\n }\n\n const result = await transformMarkdownWithVue(code, id, {\n ...resolved,\n components: componentMap,\n root: config.root,\n });\n\n return {\n code: result.code,\n map: result.map,\n };\n },\n };\n\n // Environment API plugin for Vue-specific SSR/client handling\n const vueEnvironmentPlugin: Plugin = {\n name: \"ox-content:vue-environment\",\n\n config() {\n return {\n environments: {\n // SSR environment for Vue component rendering\n oxcontent_ssr: createVueMarkdownEnvironment(\"ssr\", resolved),\n // Client environment for hydration\n oxcontent_client: createVueMarkdownEnvironment(\"client\", resolved),\n },\n };\n },\n\n // Environment-specific module resolution\n resolveId: {\n order: \"pre\",\n async handler(id, _importer, _options) {\n // Handle virtual modules for Vue markdown runtime\n if (id === \"virtual:ox-content-vue/runtime\") {\n return \"\\0virtual:ox-content-vue/runtime\";\n }\n\n if (id === \"virtual:ox-content-vue/components\") {\n return \"\\0virtual:ox-content-vue/components\";\n }\n\n return null;\n },\n },\n\n load: {\n order: \"pre\",\n async handler(id) {\n if (id === \"\\0virtual:ox-content-vue/runtime\") {\n return generateRuntimeModule(resolved);\n }\n\n if (id === \"\\0virtual:ox-content-vue/components\") {\n return generateComponentsModule(componentMap);\n }\n\n return null;\n },\n },\n\n // Per-environment build hooks\n applyToEnvironment(environment) {\n return (\n environment.name === \"oxcontent_ssr\" ||\n environment.name === \"oxcontent_client\" ||\n environment.name === \"client\" ||\n environment.name === \"ssr\"\n );\n },\n };\n\n // HMR plugin for component updates\n const vueHmrPlugin: Plugin = {\n name: \"ox-content:vue-hmr\",\n apply: \"serve\",\n\n handleHotUpdate({ file, server, modules }) {\n // Check if updated file is a registered component\n const isComponent = Array.from(componentMap.values()).some((path) =>\n file.endsWith(path.replace(/^\\.\\//, \"\")),\n );\n\n if (isComponent) {\n // Invalidate all Markdown modules that might use this component\n const mdModules = Array.from(server.moduleGraph.idToModuleMap.values()).filter((mod) =>\n mod.file?.endsWith(\".md\"),\n );\n\n if (mdModules.length > 0) {\n server.ws.send({\n type: \"custom\",\n event: \"ox-content:vue-update\",\n data: { file },\n });\n return [...modules, ...mdModules];\n }\n }\n\n return modules;\n },\n };\n\n // Get base ox-content plugins (environment plugin only)\n const basePlugins = oxContent(options);\n const environmentPlugin = basePlugins.find((p) => p.name === \"ox-content:environment\");\n\n return [\n vueTransformPlugin,\n vueEnvironmentPlugin,\n vueHmrPlugin,\n ...(environmentPlugin ? [environmentPlugin] : []),\n ];\n}\n\n/**\n * Resolves Vue integration options with defaults.\n */\nfunction resolveVueOptions(options: VueIntegrationOptions): ResolvedVueOptions {\n return {\n srcDir: options.srcDir ?? \"docs\",\n outDir: options.outDir ?? \"dist\",\n base: options.base ?? \"/\",\n gfm: options.gfm ?? true,\n frontmatter: options.frontmatter ?? true,\n toc: options.toc ?? true,\n tocMaxDepth: options.tocMaxDepth ?? 3,\n components: options.components ?? {},\n // Vue-specific options\n reactivityTransform: options.reactivityTransform ?? false,\n customBlocks: options.customBlocks ?? true,\n };\n}\n\n/**\n * Generates the runtime module for Vue markdown rendering.\n */\nfunction generateRuntimeModule(_options: ResolvedVueOptions): string {\n return `\nimport { h, defineComponent, ref, onMounted } from 'vue';\n\nexport const OxContentRenderer = defineComponent({\n name: 'OxContentRenderer',\n props: {\n content: { type: Object, required: true },\n components: { type: Object, default: () => ({}) },\n },\n setup(props) {\n const mounted = ref(false);\n\n onMounted(() => {\n mounted.value = true;\n });\n\n return () => {\n if (!props.content) return null;\n\n const { html, frontmatter, toc, islands } = props.content;\n\n // Render static HTML with component islands\n return h('div', {\n class: 'ox-content',\n innerHTML: mounted.value ? undefined : html,\n }, mounted.value ? renderWithIslands(html, islands, props.components) : undefined);\n };\n },\n});\n\nfunction renderWithIslands(html, islands, components) {\n // Parse and render islands with Vue components\n // This is a simplified version - full implementation would use proper parsing\n return h('div', { innerHTML: html });\n}\n\nexport function useOxContent() {\n return {\n OxContentRenderer,\n };\n}\n`;\n}\n\n/**\n * Generates the components registration module.\n */\nfunction generateComponentsModule(componentMap: Map<string, string>): string {\n const imports: string[] = [];\n const exports: string[] = [];\n\n componentMap.forEach((path, name) => {\n imports.push(`import ${name} from '${path}';`);\n exports.push(` ${name},`);\n });\n\n return `\n${imports.join(\"\\n\")}\n\nexport const components = {\n${exports.join(\"\\n\")}\n};\n\nexport default components;\n`;\n}\n\n/**\n * Resolves component glob patterns to a component map.\n */\nasync function resolveComponentsGlob(\n componentsOption: ComponentsOption,\n root: string,\n): Promise<ComponentsMap> {\n // If it's already a map, return as-is\n if (typeof componentsOption === \"object\" && !Array.isArray(componentsOption)) {\n return componentsOption;\n }\n\n const patterns = Array.isArray(componentsOption) ? componentsOption : [componentsOption];\n\n const result: ComponentsMap = {};\n\n for (const pattern of patterns) {\n const files = await globFiles(pattern, root);\n\n for (const file of files) {\n // Derive component name from file name (PascalCase)\n const baseName = path.basename(file, path.extname(file));\n const componentName = toPascalCase(baseName);\n const relativePath = \"./\" + path.relative(root, file).replace(/\\\\/g, \"/\");\n\n result[componentName] = relativePath;\n }\n }\n\n return result;\n}\n\n/**\n * Simple glob matcher for component files.\n */\nasync function globFiles(pattern: string, root: string): Promise<string[]> {\n const files: string[] = [];\n\n // Parse glob pattern\n const isGlob = pattern.includes(\"*\");\n\n if (!isGlob) {\n // It's a direct path\n const fullPath = path.resolve(root, pattern);\n if (fs.existsSync(fullPath)) {\n files.push(fullPath);\n }\n return files;\n }\n\n // Handle glob patterns like './src/components/*.vue'\n const parts = pattern.split(\"*\");\n const baseDir = path.resolve(root, parts[0]);\n const ext = parts[1] || \"\";\n\n if (!fs.existsSync(baseDir)) {\n return files;\n }\n\n // Handle ** recursive pattern\n if (pattern.includes(\"**\")) {\n await walkDir(baseDir, files, ext);\n } else {\n // Single level glob\n const entries = await fs.promises.readdir(baseDir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isFile() && entry.name.endsWith(ext)) {\n files.push(path.join(baseDir, entry.name));\n }\n }\n }\n\n return files;\n}\n\n/**\n * Recursively walks a directory.\n */\nasync function walkDir(dir: string, files: string[], ext: string): Promise<void> {\n const entries = await fs.promises.readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n await walkDir(fullPath, files, ext);\n } else if (entry.isFile() && entry.name.endsWith(ext)) {\n files.push(fullPath);\n }\n }\n}\n\n/**\n * Converts a string to PascalCase.\n */\nfunction toPascalCase(str: string): string {\n return str.replace(/[-_](\\w)/g, (_, c) => c.toUpperCase()).replace(/^\\w/, (c) => c.toUpperCase());\n}\n\n// Re-export\nexport { oxContent } from \"@ox-content/vite-plugin\";\n"],"mappings":";;;;;;;;AASA,MAAM,kBAAkB;AAGxB,MAAM,aACJ;AAEF,MAAM,uBAAuB;AAC7B,MAAM,uBAAuB;;;;AAkB7B,eAAsB,yBACpB,MACA,IACA,SAC6B;CAC7B,MAAM,EAAE,eAAe;CACvB,MAAM,iBAA2B,EAAE;CACnC,MAAM,UAA6B,EAAE;CACrC,IAAI,cAAc;CAGlB,MAAM,EAAE,SAAS,iBAAiB,gBAAgB,mBAAmB,KAAK;CAG1E,MAAM,cAAc,mBAAmB,gBAAgB;CACvD,IAAI,mBAAmB;CACvB,IAAI,YAAY;CAChB,IAAI;AAEJ,iBAAgB,YAAY;AAC5B,SAAQ,QAAQ,gBAAgB,KAAK,gBAAgB,MAAM,MAAM;EAC/D,MAAM,CAAC,WAAW,eAAe,aAAa,oBAAoB;EAClE,MAAM,aAAa,MAAM;EACzB,MAAM,WAAW,aAAa,UAAU;AAGxC,MAAI,CAAC,WAAW,IAAI,cAAc,IAAI,WAAW,YAAY,UAAU,YAAY,EAAE;AACnF,uBAAoB,gBAAgB,MAAM,WAAW,SAAS;AAC9D,eAAY;AACZ;;AAGF,MAAI,CAAC,eAAe,SAAS,cAAc,CACzC,gBAAe,KAAK,cAAc;EAIpC,MAAM,QAAQ,WAAW,YAAY;EAGrC,MAAM,WAAW,aAAa;EAC9B,MAAM,gBACJ,OAAO,qBAAqB,WAAW,iBAAiB,MAAM,GAAG;AACnE,UAAQ,KAAK;GACX,MAAM;GACN;GACA,UAAU;GACV,IAAI;GACJ,SAAS;GACV,CAAC;AAGF,sBAAoB,gBAAgB,MAAM,WAAW,WAAW,GAAG,mBAAmB,SAAS;AAC/F,cAAY;;AAEd,qBAAoB,gBAAgB,MAAM,UAAU;AA0DpD,QAAO;EACL,MAVc,eADQ,qBA7CJ,MAAMA,kBAAsB,kBAAkB,IAAI;GACpE,QAAQ,QAAQ;GAChB,QAAQ,QAAQ;GAChB,MAAM,QAAQ;GACd,KAAK;IACH,SAAS;IACT,WAAW;IACX,OAAO;IACP,MAAM;IACN,iBAAiB;IAClB;GACD,KAAK,QAAQ;GACb,aAAa;GACb,KAAK,QAAQ;GACb,aAAa,QAAQ;GACrB,WAAW;GACX,QAAQ;GACR,WAAW;GACX,eAAe;GACf,WAAW;GACX,gBAAgB;GAChB,gBAAgB,EAAE;GAClB,SAAS;GACT,SAAS;GACT,gBAAgB;IACd,WAAW;IACX,OAAO;IACP,QAAQ;IACR,OAAO;IACP,aAAa;IACd;GACD,cAAc,EAAE;GAChB,MAAM;GACN,UAAU;GACV,QAAQ;IACN,SAAS;IACT,OAAO;IACP,QAAQ;IACR,aAAa;IACb,QAAQ;IACT;GACD,MAAM;GACP,CAAC,EAGsD,MAAM,QAAQ,EAGpE,gBACA,SACA,aACA,SACA,GACD;EAIC,KAAK;EACL;EACA;EACD;;AAGH,SAAS,mBAAmB,UAA0B;AACpD,QAAO,GAAG,uBAAuB,WAAW;;AAG9C,SAAS,mBAAmB,SAA0B;CACpD,MAAM,SAAkB,EAAE;CAC1B,IAAI,UAAU;CACd,IAAI,YAAY;CAChB,IAAI,cAAc;CAClB,IAAI,aAAa;CACjB,IAAI,MAAM;AAEV,QAAO,MAAM,QAAQ,QAAQ;EAC3B,MAAM,UAAU,QAAQ,QAAQ,MAAM,IAAI;EAC1C,MAAM,OAAO,YAAY,KAAK,QAAQ,SAAS,UAAU;EAEzD,MAAM,aADO,QAAQ,MAAM,KAAK,YAAY,KAAK,QAAQ,SAAS,QAAQ,CAClD,MAAM,qBAAqB;AAEnD,MAAI,YAAY;GACd,MAAM,SAAS,WAAW;AAC1B,OAAI,CAAC,SAAS;AACZ,cAAU;AACV,gBAAY,OAAO;AACnB,kBAAc,OAAO;AACrB,iBAAa;cACJ,OAAO,OAAO,aAAa,OAAO,UAAU,aAAa;AAClE,cAAU;AACV,WAAO,KAAK;KAAE,OAAO;KAAY,KAAK;KAAM,CAAC;AAC7C,gBAAY;AACZ,kBAAc;;;AAIlB,QAAM;;AAGR,KAAI,QACF,QAAO,KAAK;EAAE,OAAO;EAAY,KAAK,QAAQ;EAAQ,CAAC;AAGzD,QAAO;;AAGT,SAAS,WAAW,OAAe,KAAa,QAA0B;AACxE,MAAK,MAAM,SAAS,OAClB,KAAI,QAAQ,MAAM,OAAO,MAAM,MAAM,MACnC,QAAO;AAGX,QAAO;;AAGT,SAAS,oBAAoB,MAAc,SAAoC;CAC7E,IAAI,SAAS;AAEb,MAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,SAAS,mBAAmB,OAAO,GAAG;EAC5C,MAAM,YACJ,OAAO,KAAK,OAAO,MAAM,CAAC,SAAS,IAC/B,mBAAmB,KAAK,UAAU,OAAO,MAAM,CAAC,QAAQ,MAAM,QAAQ,CAAC,KACvE;EACN,MAAM,cAAc,OAAO,UACvB,qBAAqB,OAAO,QAAQ,QAAQ,MAAM,QAAQ,CAAC,KAC3D;EACJ,MAAM,QAAQ,mBAAmB,OAAO,KAAK,GAAG,YAAY;AAC5D,WAAS,OAAO,WAAW,MAAM,OAAO,OAAO,QAAQ,MAAM,SAAS;AACtE,WAAS,OAAO,WAAW,QAAQ,SAAS,MAAM,UAAU;;AAG9D,QAAO;;;;;AAMT,SAAS,mBAAmB,SAG1B;CAEA,MAAM,QADmB,0BACM,KAAK,QAAQ;AAE5C,KAAI,CAAC,MACH,QAAO;EAAE;EAAS,aAAa,EAAE;EAAE;CAGrC,MAAM,iBAAiB,MAAM;CAC7B,MAAM,cAAuC,EAAE;AAG/C,MAAK,MAAM,QAAQ,eAAe,MAAM,KAAK,EAAE;EAC7C,MAAM,aAAa,KAAK,QAAQ,IAAI;AACpC,MAAI,aAAa,GAAG;GAClB,MAAM,MAAM,KAAK,MAAM,GAAG,WAAW,CAAC,MAAM;GAC5C,IAAI,QAAiB,KAAK,MAAM,aAAa,EAAE,CAAC,MAAM;AAGtD,OAAI;AACF,YAAQ,KAAK,MAAM,MAAgB;WAC7B;AAGN,QACE,OAAO,UAAU,aACf,MAAM,WAAW,KAAI,IAAI,MAAM,SAAS,KAAI,IAC3C,MAAM,WAAW,IAAI,IAAI,MAAM,SAAS,IAAI,EAE/C,SAAQ,MAAM,MAAM,GAAG,GAAG;;AAI9B,eAAY,OAAO;;;AAIvB,QAAO;EACL,SAAS,QAAQ,MAAM,MAAM,GAAG,OAAO;EACvC;EACD;;;;;AAMH,SAAS,WAAW,aAA8C;CAChE,MAAM,QAAiC,EAAE;AAEzC,KAAI,CAAC,YAAa,QAAO;CAEzB,IAAI;AACJ,SAAQ,QAAQ,WAAW,KAAK,YAAY,MAAM,MAAM;EACtD,MAAM,GAAG,MAAM,cAAc,cAAc,YAAY,gBAAgB;AAEvE,MAAI,KACF,KAAI,iBAAiB,OACnB,OAAM,QAAQ;WACL,iBAAiB,OAC1B,OAAM,QAAQ;WACL,eAAe,OAExB,KAAI;AACF,SAAM,QAAQ,KAAK,MAAM,IAAI,WAAW,GAAG;UACrC;AACN,SAAM,QAAQ;;WAEP,iBAAiB,OAC1B,KAAI;AACF,SAAM,QAAQ,KAAK,MAAM,IAAI,aAAa,GAAG;UACvC;AACN,SAAM,QAAQ;;MAIhB,OAAM,QAAQ;;AAKpB,QAAO;;;;;AAMT,SAAS,eACP,SACA,gBACA,SACA,aACA,SACA,IACQ;CACR,MAAM,QAAQ,KAAK,QAAQ,GAAG;CAC9B,MAAM,OAAO,QAAQ,QAAQ,QAAQ,KAAK;CAE1C,MAAM,mBAAmB,eACtB,KAAK,SAAS;EACb,MAAM,gBAAgB,QAAQ,WAAW,IAAI,KAAK;AAClD,MAAI,CAAC,cAAe,QAAO;EAE3B,MAAM,eAAe,KAAK,QAAQ,MAAM,cAAc,QAAQ,SAAS,GAAG,CAAC;EAC3E,MAAM,eAAe,KAAK,SAAS,OAAO,aAAa,CAAC,QAAQ,OAAO,IAAI;AAG3E,SAAO,UAAU,KAAK,SADH,aAAa,WAAW,IAAI,GAAG,eAAe,OAAO,aAC9B;GAC1C,CACD,OAAO,QAAQ,CACf,KAAK,KAAK;CAEb,MAAM,eAAe,eAAe,KAAK,SAAS,KAAK,KAAK,GAAG,CAAC,KAAK,KAAK;AAG1E,KAAI,QAAQ,WAAW,EACrB,QAAO;;;6BAGkB,KAAK,UAAU,YAAY,CAAC;;kBAEvC,KAAK,UAAU,QAAQ,CAAC;;;;;;;;;;;;;;;AAiBxC,QAAO;;;EAGP,iBAAiB;;6BAEU,KAAK,UAAU,YAAY,CAAC;;kBAEvC,KAAK,UAAU,QAAQ,CAAC;;EAExC,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC9Wf,SAAgB,6BACd,MACA,SACoB;CACpB,MAAM,QAAQ,SAAS;AAEvB,QAAO;EACL,OAAO;GACL,QAAQ,QAAQ,GAAG,QAAQ,OAAO,oBAAoB,GAAG,QAAQ,OAAO;GAExE,KAAK;GAEL,eAAe;IACb,OAAO,QAAQ,SAAY;IAC3B,QAAQ;KACN,QAAQ,QAAQ,QAAQ;KACxB,gBAAgB,QAAQ,cAAc;KACtC,gBAAgB,QAAQ,qBAAqB;KAC9C;IACF;GAGD,GAAI,SAAS;IACX,QAAQ;IACR,QAAQ;IACT;GACF;EAED,SAAS,EACP,YAAY,QAAQ,CAAC,QAAQ,SAAS,GAAG,CAAC,WAAW,SAAS,EAC/D;EAED,cAAc;GAEZ,SAAS,QAAQ,EAAE,GAAG,CAAC,MAAM;GAG7B,SAAS,CAAC,2BAA2B,8BAA8B;GACpE;EAGD,GAAI,CAAC,SAAS,EACZ,KAAK,EACH,QAAQ,CAAC,kBAAkB,iBAAiB,EAC7C,EACF;EACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACLH,SAAgB,aAAa,UAAiC,EAAE,EAAkB;CAChF,MAAM,WAAW,kBAAkB,QAAQ;CAC3C,IAAI,+BAAe,IAAI,KAAqB;CAC5C,IAAI;AAGJ,KAAI,OAAO,QAAQ,eAAe,YAAY,CAAC,MAAM,QAAQ,QAAQ,WAAW,CAC9E,gBAAe,IAAI,IAAI,OAAO,QAAQ,QAAQ,WAAW,CAAC;CAI5D,MAAM,qBAA6B;EACjC,MAAM;EACN,SAAS;EAET,MAAM,eAAe,gBAAgB;AACnC,YAAS;GAGT,MAAM,mBAAmB,QAAQ;AACjC,OAAI,kBAAkB;IACpB,MAAM,qBAAqB,MAAM,sBAAsB,kBAAkB,OAAO,KAAK;AACrF,mBAAe,IAAI,IAAI,OAAO,QAAQ,mBAAmB,CAAC;;;EAI9D,MAAM,UAAU,MAAM,IAAI;AACxB,OAAI,CAAC,GAAG,SAAS,MAAM,CACrB,QAAO;GAGT,MAAM,SAAS,MAAM,yBAAyB,MAAM,IAAI;IACtD,GAAG;IACH,YAAY;IACZ,MAAM,OAAO;IACd,CAAC;AAEF,UAAO;IACL,MAAM,OAAO;IACb,KAAK,OAAO;IACb;;EAEJ;CAGD,MAAM,uBAA+B;EACnC,MAAM;EAEN,SAAS;AACP,UAAO,EACL,cAAc;IAEZ,eAAe,6BAA6B,OAAO,SAAS;IAE5D,kBAAkB,6BAA6B,UAAU,SAAS;IACnE,EACF;;EAIH,WAAW;GACT,OAAO;GACP,MAAM,QAAQ,IAAI,WAAW,UAAU;AAErC,QAAI,OAAO,iCACT,QAAO;AAGT,QAAI,OAAO,oCACT,QAAO;AAGT,WAAO;;GAEV;EAED,MAAM;GACJ,OAAO;GACP,MAAM,QAAQ,IAAI;AAChB,QAAI,OAAO,mCACT,QAAO,sBAAsB,SAAS;AAGxC,QAAI,OAAO,sCACT,QAAO,yBAAyB,aAAa;AAG/C,WAAO;;GAEV;EAGD,mBAAmB,aAAa;AAC9B,UACE,YAAY,SAAS,mBACrB,YAAY,SAAS,sBACrB,YAAY,SAAS,YACrB,YAAY,SAAS;;EAG1B;CAGD,MAAM,eAAuB;EAC3B,MAAM;EACN,OAAO;EAEP,gBAAgB,EAAE,MAAM,QAAQ,WAAW;AAMzC,OAJoB,MAAM,KAAK,aAAa,QAAQ,CAAC,CAAC,MAAM,SAC1D,KAAK,SAAS,KAAK,QAAQ,SAAS,GAAG,CAAC,CACzC,EAEgB;IAEf,MAAM,YAAY,MAAM,KAAK,OAAO,YAAY,cAAc,QAAQ,CAAC,CAAC,QAAQ,QAC9E,IAAI,MAAM,SAAS,MAAM,CAC1B;AAED,QAAI,UAAU,SAAS,GAAG;AACxB,YAAO,GAAG,KAAK;MACb,MAAM;MACN,OAAO;MACP,MAAM,EAAE,MAAM;MACf,CAAC;AACF,YAAO,CAAC,GAAG,SAAS,GAAG,UAAU;;;AAIrC,UAAO;;EAEV;CAID,MAAM,oBADcC,YAAU,QAAQ,CACA,MAAM,MAAM,EAAE,SAAS,yBAAyB;AAEtF,QAAO;EACL;EACA;EACA;EACA,GAAI,oBAAoB,CAAC,kBAAkB,GAAG,EAAE;EACjD;;;;;AAMH,SAAS,kBAAkB,SAAoD;AAC7E,QAAO;EACL,QAAQ,QAAQ,UAAU;EAC1B,QAAQ,QAAQ,UAAU;EAC1B,MAAM,QAAQ,QAAQ;EACtB,KAAK,QAAQ,OAAO;EACpB,aAAa,QAAQ,eAAe;EACpC,KAAK,QAAQ,OAAO;EACpB,aAAa,QAAQ,eAAe;EACpC,YAAY,QAAQ,cAAc,EAAE;EAEpC,qBAAqB,QAAQ,uBAAuB;EACpD,cAAc,QAAQ,gBAAgB;EACvC;;;;;AAMH,SAAS,sBAAsB,UAAsC;AACnE,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+CT,SAAS,yBAAyB,cAA2C;CAC3E,MAAM,UAAoB,EAAE;CAC5B,MAAM,UAAoB,EAAE;AAE5B,cAAa,SAAS,MAAM,SAAS;AACnC,UAAQ,KAAK,UAAU,KAAK,SAAS,KAAK,IAAI;AAC9C,UAAQ,KAAK,KAAK,KAAK,GAAG;GAC1B;AAEF,QAAO;EACP,QAAQ,KAAK,KAAK,CAAC;;;EAGnB,QAAQ,KAAK,KAAK,CAAC;;;;;;;;;AAUrB,eAAe,sBACb,kBACA,MACwB;AAExB,KAAI,OAAO,qBAAqB,YAAY,CAAC,MAAM,QAAQ,iBAAiB,CAC1E,QAAO;CAGT,MAAM,WAAW,MAAM,QAAQ,iBAAiB,GAAG,mBAAmB,CAAC,iBAAiB;CAExF,MAAM,SAAwB,EAAE;AAEhC,MAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,QAAQ,MAAM,UAAU,SAAS,KAAK;AAE5C,OAAK,MAAM,QAAQ,OAAO;GAGxB,MAAM,gBAAgB,aADL,KAAK,SAAS,MAAM,KAAK,QAAQ,KAAK,CAAC,CACZ;AAG5C,UAAO,iBAFc,OAAO,KAAK,SAAS,MAAM,KAAK,CAAC,QAAQ,OAAO,IAAI;;;AAM7E,QAAO;;;;;AAMT,eAAe,UAAU,SAAiB,MAAiC;CACzE,MAAM,QAAkB,EAAE;AAK1B,KAAI,CAFW,QAAQ,SAAS,IAAI,EAEvB;EAEX,MAAM,WAAW,KAAK,QAAQ,MAAM,QAAQ;AAC5C,MAAI,GAAG,WAAW,SAAS,CACzB,OAAM,KAAK,SAAS;AAEtB,SAAO;;CAIT,MAAM,QAAQ,QAAQ,MAAM,IAAI;CAChC,MAAM,UAAU,KAAK,QAAQ,MAAM,MAAM,GAAG;CAC5C,MAAM,MAAM,MAAM,MAAM;AAExB,KAAI,CAAC,GAAG,WAAW,QAAQ,CACzB,QAAO;AAIT,KAAI,QAAQ,SAAS,KAAK,CACxB,OAAM,QAAQ,SAAS,OAAO,IAAI;MAC7B;EAEL,MAAM,UAAU,MAAM,GAAG,SAAS,QAAQ,SAAS,EAAE,eAAe,MAAM,CAAC;AAC3E,OAAK,MAAM,SAAS,QAClB,KAAI,MAAM,QAAQ,IAAI,MAAM,KAAK,SAAS,IAAI,CAC5C,OAAM,KAAK,KAAK,KAAK,SAAS,MAAM,KAAK,CAAC;;AAKhD,QAAO;;;;;AAMT,eAAe,QAAQ,KAAa,OAAiB,KAA4B;CAC/E,MAAM,UAAU,MAAM,GAAG,SAAS,QAAQ,KAAK,EAAE,eAAe,MAAM,CAAC;AAEvE,MAAK,MAAM,SAAS,SAAS;EAC3B,MAAM,WAAW,KAAK,KAAK,KAAK,MAAM,KAAK;AAE3C,MAAI,MAAM,aAAa,CACrB,OAAM,QAAQ,UAAU,OAAO,IAAI;WAC1B,MAAM,QAAQ,IAAI,MAAM,KAAK,SAAS,IAAI,CACnD,OAAM,KAAK,SAAS;;;;;;AAQ1B,SAAS,aAAa,KAAqB;AACzC,QAAO,IAAI,QAAQ,cAAc,GAAG,MAAM,EAAE,aAAa,CAAC,CAAC,QAAQ,QAAQ,MAAM,EAAE,aAAa,CAAC"}