contentbit 0.1.0 → 0.1.1

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/bin.js CHANGED
@@ -16154,7 +16154,17 @@ import { pathToFileURL } from "node:url";
16154
16154
  async function loadRegistry(registryPath) {
16155
16155
  const registry2 = createBlockRegistry().use(genericBlocks());
16156
16156
  if (registryPath) {
16157
- const mod = await import(pathToFileURL(registryPath).href);
16157
+ let mod;
16158
+ try {
16159
+ mod = await import(pathToFileURL(registryPath).href);
16160
+ } catch (err) {
16161
+ if (err instanceof Error && "code" in err && err.code === "ERR_UNKNOWN_FILE_EXTENSION") {
16162
+ throw new Error(
16163
+ `Importing a TypeScript registry needs Node 22.18+ (native type stripping): ${registryPath}`
16164
+ );
16165
+ }
16166
+ throw err;
16167
+ }
16158
16168
  if (!Array.isArray(mod.default)) {
16159
16169
  throw new Error(
16160
16170
  `--registry module must default-export an array of block definitions: ${registryPath}`
@@ -16178,10 +16188,131 @@ __export(init_exports, {
16178
16188
  initCommand: () => initCommand
16179
16189
  });
16180
16190
  import { spawn } from "node:child_process";
16191
+ import { existsSync } from "node:fs";
16181
16192
  import { mkdir, readFile, writeFile } from "node:fs/promises";
16182
16193
  import { join } from "node:path";
16183
16194
  import { parseArgs } from "node:util";
16184
- function detectPackageManager() {
16195
+ function blockComponentsTemplate(styled) {
16196
+ const body = styled ? ` return (
16197
+ <figure className="my-6 border-s-2 ps-4">
16198
+ <blockquote className="text-lg italic">{ctx.renderMarkdown(data.markdown)}</blockquote>
16199
+ <figcaption className="text-muted-foreground mt-2 text-sm">
16200
+ \u2014 {String(node.props.author)}
16201
+ {node.props.role ? \`, \${String(node.props.role)}\` : null}
16202
+ </figcaption>
16203
+ </figure>
16204
+ )` : ` return (
16205
+ <figure style={{ margin: '1.5rem 0', borderLeft: '2px solid #d4d4d4', paddingLeft: '1rem' }}>
16206
+ <blockquote style={{ fontStyle: 'italic' }}>{ctx.renderMarkdown(data.markdown)}</blockquote>
16207
+ <figcaption style={{ marginTop: '0.5rem', fontSize: '0.875rem', opacity: 0.7 }}>
16208
+ \u2014 {String(node.props.author)}
16209
+ {node.props.role ? \`, \${String(node.props.role)}\` : null}
16210
+ </figcaption>
16211
+ </figure>
16212
+ )`;
16213
+ return `import type { BlockComponent, BlockComponentProps } from '@contentbit/react'
16214
+
16215
+ // One React component per custom block, keyed by block name. Definitions
16216
+ // live in ./registry.ts \u2014 add a block there, add its component here, and
16217
+ // the rest of the app never changes.
16218
+ function QuoteBlock({ node, ctx }: BlockComponentProps) {
16219
+ const data = node.data as { markdown: string }
16220
+ ${body}
16221
+ }
16222
+
16223
+ export const blockComponents: Record<string, BlockComponent> = {
16224
+ quote: QuoteBlock,
16225
+ }
16226
+ `;
16227
+ }
16228
+ function reactComponent(styled, mdWired, blocksImport) {
16229
+ const mdImport = mdWired ? "import ReactMarkdown from 'react-markdown'\n" : "";
16230
+ const mdProp = mdWired ? "\n renderMarkdown={(md) => <ReactMarkdown>{md}</ReactMarkdown>}" : `
16231
+ // TODO: plug your Markdown library in here, e.g. react-markdown.
16232
+ // One function renders all prose: https://contentbit.dev/docs/guides/markdown
16233
+ // renderMarkdown={(md) => <Markdown source={md} />}`;
16234
+ const rendererImport = styled ? `
16235
+ // The styled pack installed by shadcn. Yours to edit.
16236
+ import { ContentRenderer } from '@/components/content-blocks/content-renderer'` : "";
16237
+ const renderer = styled ? "ContentRenderer" : "ContentBlocks";
16238
+ const reactImport = styled ? "" : "import { ContentBlocks } from '@contentbit/react'\n";
16239
+ return `'use client'
16240
+
16241
+ import { genericBlocks } from '@contentbit/blocks'
16242
+ import { createBlockRegistry, parseDocument, validateDocument } from '@contentbit/core'
16243
+ ${reactImport}${mdImport}${rendererImport}
16244
+ // Everything block-related lives in the blocks/ folder: definitions in
16245
+ // registry.ts (shared with the validate CLI), components in components.tsx.
16246
+ import customBlocks from '${blocksImport}/registry'
16247
+ import { blockComponents } from '${blocksImport}/components'
16248
+
16249
+ const registry = createBlockRegistry().use(genericBlocks()).use(customBlocks)
16250
+
16251
+ export function Content({ source }: { source: string }) {
16252
+ const result = validateDocument(parseDocument(source), registry)
16253
+ return (
16254
+ <${renderer}
16255
+ document={result.document}
16256
+ components={blockComponents}${mdProp}
16257
+ />
16258
+ )
16259
+ }
16260
+ `;
16261
+ }
16262
+ function htmlRenderScript(md) {
16263
+ const wiring = md === "marked" ? `import { marked } from 'marked'
16264
+
16265
+ const renderMarkdown = (md) => marked.parse(md, { async: false })` : md === "markdown-it" ? `import MarkdownIt from 'markdown-it'
16266
+
16267
+ const mdIt = new MarkdownIt() // html: false by default \u2014 raw HTML stays escaped
16268
+ const renderMarkdown = (md) => mdIt.render(md)` : `// TODO: plug a Markdown library in here (marked, markdown-it, remark).
16269
+ const renderMarkdown = undefined`;
16270
+ return `// Render content/example.md to example.html. Run: node scripts/render-example.mjs
16271
+ import { genericBlocks } from '@contentbit/blocks'
16272
+ import { createBlockRegistry, parseDocument, validateDocument } from '@contentbit/core'
16273
+ import { renderToHtml } from '@contentbit/html'
16274
+ import { readFile, writeFile } from 'node:fs/promises'
16275
+ ${wiring}
16276
+
16277
+ const source = await readFile('content/example.md', 'utf8')
16278
+ const registry = createBlockRegistry().use(genericBlocks())
16279
+ const result = validateDocument(parseDocument(source), registry)
16280
+ const html = renderToHtml(result.document, { renderMarkdown })
16281
+ await writeFile('example.html', html, 'utf8')
16282
+ console.log('wrote example.html')
16283
+ `;
16284
+ }
16285
+ function detectFramework(cwd, deps) {
16286
+ if ((deps["@tanstack/react-start"] || deps["@tanstack/react-router"]) && existsSync(join(cwd, "src/routes"))) {
16287
+ return {
16288
+ framework: "tanstack",
16289
+ componentPath: "src/components/content-blocks.tsx",
16290
+ pagePath: "src/routes/example.tsx"
16291
+ };
16292
+ }
16293
+ if (deps.next) {
16294
+ const appDir = existsSync(join(cwd, "src/app")) ? "src/app" : "app";
16295
+ if (existsSync(join(cwd, appDir))) {
16296
+ return {
16297
+ framework: "next",
16298
+ componentPath: "components/content-blocks.tsx",
16299
+ pagePath: `${appDir}/example/page.tsx`
16300
+ };
16301
+ }
16302
+ }
16303
+ return { framework: null, componentPath: "components/content-blocks.tsx", pagePath: null };
16304
+ }
16305
+ function detectPackageManager(cwd) {
16306
+ const locks = [
16307
+ ["pnpm-lock.yaml", "pnpm"],
16308
+ ["yarn.lock", "yarn"],
16309
+ ["bun.lock", "bun"],
16310
+ ["bun.lockb", "bun"],
16311
+ ["package-lock.json", "npm"]
16312
+ ];
16313
+ for (const [file2, pm] of locks) {
16314
+ if (existsSync(join(cwd, file2))) return pm;
16315
+ }
16185
16316
  const agent = process.env.npm_config_user_agent ?? "";
16186
16317
  for (const pm of ["pnpm", "yarn", "bun"]) {
16187
16318
  if (agent.startsWith(pm)) return pm;
@@ -16192,6 +16323,12 @@ function installArgs(pm, dev, pkgs) {
16192
16323
  const add = pm === "npm" ? "install" : "add";
16193
16324
  return dev ? [add, "-D", ...pkgs] : [add, ...pkgs];
16194
16325
  }
16326
+ function dlxCommand(pm) {
16327
+ if (pm === "pnpm") return ["pnpm", ["dlx"]];
16328
+ if (pm === "yarn") return ["yarn", ["dlx"]];
16329
+ if (pm === "bun") return ["bunx", []];
16330
+ return ["npx", ["--yes"]];
16331
+ }
16195
16332
  function runInstall(pm, args, cwd) {
16196
16333
  return new Promise((resolve) => {
16197
16334
  const child = spawn(pm, args, { cwd, stdio: "inherit", shell: process.platform === "win32" });
@@ -16214,9 +16351,12 @@ async function initCommand(args, io) {
16214
16351
  args,
16215
16352
  options: {
16216
16353
  target: { type: "string", short: "t" },
16354
+ md: { type: "string" },
16217
16355
  yes: { type: "boolean", short: "y", default: false },
16218
16356
  cwd: { type: "string", default: process.cwd() },
16219
- "no-install": { type: "boolean", default: false }
16357
+ "no-install": { type: "boolean", default: false },
16358
+ "no-page": { type: "boolean", default: false },
16359
+ "no-styled": { type: "boolean", default: false }
16220
16360
  }
16221
16361
  });
16222
16362
  const cwd = values.cwd;
@@ -16253,13 +16393,38 @@ async function initCommand(args, io) {
16253
16393
  } else {
16254
16394
  target = detected;
16255
16395
  }
16256
- const runtime = ["@contentbit/core", "@contentbit/blocks"];
16396
+ const choices = MD_CHOICES[target];
16397
+ let md;
16398
+ if (values.md) {
16399
+ if (!choices.includes(values.md)) {
16400
+ io.stderr(`Unknown markdown library "${values.md}". Use one of: ${choices.join(", ")}`);
16401
+ return 2;
16402
+ }
16403
+ md = values.md;
16404
+ } else if (choices.length > 1 && !values.yes && process.stdin.isTTY && process.stdout.isTTY) {
16405
+ const { isCancel, select } = await import("@clack/prompts");
16406
+ const answer = await select({
16407
+ message: "Markdown library for prose rendering?",
16408
+ initialValue: choices[0],
16409
+ options: choices.map((c) => ({
16410
+ value: c,
16411
+ label: c,
16412
+ hint: c === "none" ? "wire one yourself later" : "installed and wired for you"
16413
+ }))
16414
+ });
16415
+ if (isCancel(answer)) return 1;
16416
+ md = answer;
16417
+ } else {
16418
+ md = choices[0];
16419
+ }
16420
+ const runtime = ["@contentbit/core", "@contentbit/blocks", "zod"];
16257
16421
  if (target === "react") runtime.push("@contentbit/react");
16258
16422
  if (target === "html") runtime.push("@contentbit/html");
16423
+ if (md !== "none") runtime.push(md);
16259
16424
  if (values["no-install"]) {
16260
16425
  io.stdout(`skipped install: ${runtime.join(" ")} + contentbit (dev)`);
16261
16426
  } else {
16262
- const pm = detectPackageManager();
16427
+ const pm = detectPackageManager(cwd);
16263
16428
  io.stdout(`installing with ${pm}: ${runtime.join(" ")}`);
16264
16429
  if (await runInstall(pm, installArgs(pm, false, runtime), cwd) !== 0) {
16265
16430
  io.stderr("install failed");
@@ -16271,10 +16436,54 @@ async function initCommand(args, io) {
16271
16436
  }
16272
16437
  }
16273
16438
  const files = [
16274
- ["blocks/registry.mjs", REGISTRY_TEMPLATE],
16439
+ ["blocks/registry.ts", REGISTRY_TEMPLATE],
16275
16440
  ["content/example.md", EXAMPLE_CONTENT]
16276
16441
  ];
16277
- if (target === "react") files.push(["components/content-blocks.tsx", REACT_COMPONENT]);
16442
+ const layout = detectFramework(cwd, { ...pkg.dependencies, ...pkg.devDependencies });
16443
+ let styled = false;
16444
+ const componentsJsonPath = join(cwd, "components.json");
16445
+ if (target === "react" && !values["no-styled"] && existsSync(componentsJsonPath)) {
16446
+ const componentsJson = JSON.parse(await readFile(componentsJsonPath, "utf8"));
16447
+ componentsJson.registries ??= {};
16448
+ if (!componentsJson.registries["@contentbit"]) {
16449
+ componentsJson.registries["@contentbit"] = "https://contentbit.dev/r/{name}.json";
16450
+ await writeFile(componentsJsonPath, `${JSON.stringify(componentsJson, null, 2)}
16451
+ `, "utf8");
16452
+ io.stdout("added @contentbit registry to components.json");
16453
+ }
16454
+ if (values["no-install"]) {
16455
+ io.stdout("skipped: shadcn add @contentbit/generic-pack");
16456
+ styled = true;
16457
+ } else {
16458
+ const [bin, prefix] = dlxCommand(detectPackageManager(cwd));
16459
+ io.stdout("installing the styled pack: shadcn add @contentbit/generic-pack");
16460
+ const code2 = await runInstall(
16461
+ bin,
16462
+ [...prefix, "shadcn@latest", "add", "@contentbit/generic-pack", "--yes"],
16463
+ cwd
16464
+ );
16465
+ if (code2 === 0) styled = true;
16466
+ else io.stderr("styled pack install failed; falling back to headless defaults");
16467
+ }
16468
+ }
16469
+ if (target === "react") {
16470
+ const depth = layout.componentPath.split("/").length - 1;
16471
+ const blocksImport = `${"../".repeat(depth)}blocks`;
16472
+ files.push(["blocks/components.tsx", blockComponentsTemplate(styled)]);
16473
+ files.push([
16474
+ layout.componentPath,
16475
+ reactComponent(styled, md === "react-markdown", blocksImport)
16476
+ ]);
16477
+ if (!values["no-page"] && layout.pagePath) {
16478
+ files.push([layout.pagePath, layout.framework === "tanstack" ? TANSTACK_PAGE : NEXT_PAGE]);
16479
+ }
16480
+ }
16481
+ if (target === "html") {
16482
+ files.push([
16483
+ "scripts/render-example.mjs",
16484
+ htmlRenderScript(md)
16485
+ ]);
16486
+ }
16278
16487
  for (const [rel, content] of files) {
16279
16488
  const result = await scaffold(join(cwd, rel), content);
16280
16489
  io.stdout(`${result}: ${rel}`);
@@ -16282,57 +16491,77 @@ async function initCommand(args, io) {
16282
16491
  const fresh = JSON.parse(await readFile(pkgPath, "utf8"));
16283
16492
  fresh.scripts ??= {};
16284
16493
  if (!fresh.scripts["content:check"]) {
16285
- fresh.scripts["content:check"] = 'contentbit validate "content/**/*.md" --registry ./blocks/registry.mjs';
16494
+ fresh.scripts["content:check"] = 'contentbit validate "content/**/*.md" --registry ./blocks/registry.ts';
16286
16495
  await writeFile(pkgPath, `${JSON.stringify(fresh, null, 2)}
16287
16496
  `, "utf8");
16288
16497
  io.stdout("added script: content:check");
16289
16498
  }
16290
- const registry2 = await loadRegistry();
16499
+ let registry2;
16500
+ try {
16501
+ registry2 = await loadRegistry(join(cwd, "blocks/registry.ts"));
16502
+ } catch {
16503
+ registry2 = await loadRegistry();
16504
+ }
16291
16505
  const guide = registry2.toAuthoringGuide({ audience: "llm", includeExamples: true });
16292
16506
  await writeFile(join(cwd, "contentbit-guide.md"), guide, "utf8");
16293
16507
  io.stdout("created: contentbit-guide.md (LLM authoring instructions)");
16294
16508
  io.stdout("");
16295
16509
  io.stdout("Done. Next steps:");
16296
- io.stdout(` 1. Validate the starter content: ${detectPackageManager()} run content:check`);
16510
+ io.stdout(` 1. Validate the starter content: ${detectPackageManager(cwd)} run content:check`);
16297
16511
  if (target === "react") {
16298
- io.stdout(' 2. Render it: import { Content } from "./components/content-blocks"');
16512
+ if (!values["no-page"] && layout.pagePath) {
16513
+ io.stdout(" 2. Start the dev server and open /example to see the article rendered.");
16514
+ } else {
16515
+ io.stdout(' 2. Render it: import { Content } from "./components/content-blocks"');
16516
+ io.stdout(" <Content source={...content/example.md as a string} />");
16517
+ }
16299
16518
  io.stdout(" 3. Styled components: pnpm dlx shadcn@latest add @contentbit/generic-pack");
16300
16519
  } else if (target === "html") {
16301
- io.stdout(" 2. Render it: contentbit render content/example.md --target html");
16520
+ io.stdout(" 2. Render it: node scripts/render-example.mjs && open example.html");
16302
16521
  } else {
16303
16522
  io.stdout(" 2. Render it: contentbit render content/example.md --target markdown");
16304
16523
  }
16305
16524
  io.stdout(" Docs: https://contentbit.dev/docs");
16306
16525
  return 0;
16307
16526
  }
16308
- var TARGETS, REGISTRY_TEMPLATE, EXAMPLE_CONTENT, REACT_COMPONENT;
16527
+ var TARGETS, MD_CHOICES, REGISTRY_TEMPLATE, EXAMPLE_CONTENT, TANSTACK_PAGE, NEXT_PAGE;
16309
16528
  var init_init = __esm({
16310
16529
  "src/commands/init.ts"() {
16311
16530
  "use strict";
16312
16531
  init_load_registry();
16313
16532
  TARGETS = ["react", "html", "markdown"];
16314
- REGISTRY_TEMPLATE = `// Custom blocks for this project. The CLI and your app share this module:
16533
+ MD_CHOICES = {
16534
+ react: ["react-markdown", "none"],
16535
+ html: ["marked", "markdown-it", "none"],
16536
+ markdown: ["none"]
16537
+ };
16538
+ REGISTRY_TEMPLATE = `// Custom block definitions for this project. The CLI and your app share
16539
+ // this module \u2014 Node 22.18+ imports TypeScript directly:
16315
16540
  //
16316
- // contentbit validate "content/**/*.md" --registry ./blocks/registry.mjs
16541
+ // contentbit validate "content/**/*.md" --registry ./blocks/registry.ts
16317
16542
  //
16318
- // Define blocks with @contentbit/core and default-export them as an array.
16543
+ // Definitions stay framework-free (the CLI and every render target use
16544
+ // them); React components live next door in blocks/components.tsx.
16319
16545
  // Docs: https://contentbit.dev/docs/guides/custom-blocks
16320
- //
16321
- // import { defineBlock, pipeRows } from '@contentbit/core'
16322
- // import { z } from 'zod'
16323
- //
16324
- // const pricingTable = defineBlock({
16325
- // name: 'pricing-table',
16326
- // description: 'Compares product plans.',
16327
- // props: z.object({ currency: z.enum(['usd', 'eur']).default('usd') }),
16328
- // content: pipeRows({ columns: ['plan', 'price'], minRows: 2 }),
16329
- // authoring: {
16330
- // useWhen: ['Comparing pricing plans'],
16331
- // example: ':::pricing-table\\n- Starter | $0\\n- Pro | $12/mo\\n:::',
16332
- // },
16333
- // })
16546
+ import { defineBlock, markdownBody, type BlockDefinition } from '@contentbit/core'
16547
+ import { z } from 'zod'
16548
+
16549
+ export const quote = defineBlock({
16550
+ name: 'quote',
16551
+ description: 'A pull quote with an author.',
16552
+ props: z.object({
16553
+ author: z.string().min(1),
16554
+ role: z.string().optional(),
16555
+ }),
16556
+ content: markdownBody({ minLength: 3 }),
16557
+ authoring: {
16558
+ useWhen: ['Quoting a person to support a point'],
16559
+ avoidWhen: ['Highlighting your own remark, use callout instead'],
16560
+ example: ':::quote{author="Ada Lovelace"}\\nThe Analytical Engine weaves algebraic patterns.\\n:::',
16561
+ },
16562
+ })
16334
16563
 
16335
- export default []
16564
+ export default [quote] satisfies BlockDefinition<unknown>[]
16336
16565
  `;
16337
16566
  EXAMPLE_CONTENT = `# Hello, Content Blocks
16338
16567
 
@@ -16347,22 +16576,42 @@ Run the validate script and you will get file:line:col diagnostics.
16347
16576
  2. Run \`contentbit validate "content/**/*.md"\`.
16348
16577
  3. Render it with the target you picked at init.
16349
16578
  :::
16579
+
16580
+ This one is a **custom block**, defined in \`blocks/registry.ts\` and rendered
16581
+ by the \`QuoteBlock\` component, in about twenty lines:
16582
+
16583
+ :::quote{author="Ada Lovelace" role="Notes on the Analytical Engine, 1843"}
16584
+ The Analytical Engine weaves algebraic patterns just as the Jacquard loom
16585
+ weaves flowers and leaves.
16586
+ :::
16350
16587
  `;
16351
- REACT_COMPONENT = `import { genericBlocks } from '@contentbit/blocks'
16352
- import { createBlockRegistry, parseDocument, validateDocument } from '@contentbit/core'
16353
- import { ContentBlocks } from '@contentbit/react'
16588
+ TANSTACK_PAGE = `import { createFileRoute } from '@tanstack/react-router'
16354
16589
 
16355
- const registry = createBlockRegistry().use(genericBlocks())
16590
+ import { Content } from '../components/content-blocks'
16591
+ // Vite's ?raw import inlines the Markdown as a string at build time.
16592
+ import source from '../../content/example.md?raw'
16356
16593
 
16357
- export function Content({ source }: { source: string }) {
16358
- const result = validateDocument(parseDocument(source), registry)
16594
+ export const Route = createFileRoute('/example')({ component: ExamplePage })
16595
+
16596
+ function ExamplePage() {
16359
16597
  return (
16360
- <ContentBlocks
16361
- document={result.document}
16362
- // TODO: plug your Markdown library in here, e.g. react-markdown.
16363
- // One function renders all prose: https://contentbit.dev/docs/guides/markdown
16364
- // renderMarkdown={(md) => <Markdown source={md} />}
16365
- />
16598
+ <main style={{ maxWidth: '42rem', margin: '0 auto', padding: '3rem 1.5rem' }}>
16599
+ <Content source={source} />
16600
+ </main>
16601
+ )
16602
+ }
16603
+ `;
16604
+ NEXT_PAGE = `import { readFile } from 'node:fs/promises'
16605
+
16606
+ // If your project has no "@/" path alias, switch to a relative import.
16607
+ import { Content } from '@/components/content-blocks'
16608
+
16609
+ export default async function ExamplePage() {
16610
+ const source = await readFile('content/example.md', 'utf8')
16611
+ return (
16612
+ <main style={{ maxWidth: '42rem', margin: '0 auto', padding: '3rem 1.5rem' }}>
16613
+ <Content source={source} />
16614
+ </main>
16366
16615
  )
16367
16616
  }
16368
16617
  `;
@@ -16657,7 +16906,7 @@ import { writeFile as writeFile2 } from "node:fs/promises";
16657
16906
  // src/run.ts
16658
16907
  var USAGE = `Usage: contentbit <init|validate|render|instructions|docs> [options]
16659
16908
 
16660
- init [-t react|html|markdown] [-y] [--no-install]
16909
+ init [-t react|html|markdown] [--md ...] [-y] [--no-install] [--no-page]
16661
16910
 
16662
16911
  validate <globs...> [--registry <module.mjs>] [--strict-warnings]
16663
16912
  render <file> --target html|markdown [--registry <module.mjs>] [--out <file>]
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,WAAW,CAAA;AAmGnC,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA8GzE"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,WAAW,CAAA;AAiSnC,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAyMzE"}