@classic-homes/slides 0.3.0 → 0.5.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/README.md +24 -1
- package/dist/{chunk-2IPLZ3SA.js → chunk-GX6P2SE6.js} +17 -3
- package/dist/chunk-GX6P2SE6.js.map +1 -0
- package/dist/{chunk-GXGDPBAR.js → chunk-OUAMH2TP.js} +219 -6
- package/dist/chunk-OUAMH2TP.js.map +1 -0
- package/dist/{chunk-YI7A4EWX.js → chunk-TEE3OGRQ.js} +2 -2
- package/dist/cli.js +23 -4
- package/dist/cli.js.map +1 -1
- package/dist/{render-DcyKuBRD.d.ts → images-8N30SsCW.d.ts} +62 -1
- package/dist/index.d.ts +21 -4
- package/dist/index.js +13 -3
- package/dist/index.js.map +1 -1
- package/dist/{mcp-PUA45IS7.js → mcp-3WAVCLQ2.js} +4 -4
- package/dist/node.d.ts +15 -3
- package/dist/node.js +4 -2
- package/package.json +1 -1
- package/dist/chunk-2IPLZ3SA.js.map +0 -1
- package/dist/chunk-GXGDPBAR.js.map +0 -1
- /package/dist/{chunk-YI7A4EWX.js.map → chunk-TEE3OGRQ.js.map} +0 -0
- /package/dist/{mcp-PUA45IS7.js.map → mcp-3WAVCLQ2.js.map} +0 -0
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
LAYOUT_CATEGORIES,
|
|
5
5
|
baseSlide,
|
|
6
6
|
getLayout
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-OUAMH2TP.js";
|
|
8
8
|
|
|
9
9
|
// src/catalog.ts
|
|
10
10
|
import { z } from "zod";
|
|
@@ -104,4 +104,4 @@ export {
|
|
|
104
104
|
deckJsonSchema,
|
|
105
105
|
AUTHORING_GUIDE
|
|
106
106
|
};
|
|
107
|
-
//# sourceMappingURL=chunk-
|
|
107
|
+
//# sourceMappingURL=chunk-TEE3OGRQ.js.map
|
package/dist/cli.js
CHANGED
|
@@ -4,18 +4,19 @@ import {
|
|
|
4
4
|
deckJsonSchema,
|
|
5
5
|
describeLayout,
|
|
6
6
|
listLayouts
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-TEE3OGRQ.js";
|
|
8
8
|
import {
|
|
9
9
|
buildDeckFile,
|
|
10
|
+
exportDeckFile,
|
|
10
11
|
fileImageResolver,
|
|
11
12
|
loadDeckFile
|
|
12
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-GX6P2SE6.js";
|
|
13
14
|
import {
|
|
14
15
|
DeckError,
|
|
15
16
|
formatIssues,
|
|
16
17
|
renderDeck,
|
|
17
18
|
validateDeck
|
|
18
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-OUAMH2TP.js";
|
|
19
20
|
|
|
20
21
|
// src/node/cli.ts
|
|
21
22
|
import { watch } from "fs";
|
|
@@ -30,12 +31,14 @@ Usage
|
|
|
30
31
|
classic-slides new <file.yaml> [--starter basic|journey] Start a deck from a starter
|
|
31
32
|
classic-slides build <file.yaml> [-o out.html] Render one self-contained HTML file
|
|
32
33
|
classic-slides dev <file.yaml> [--port 4321] Live preview; reloads on save
|
|
34
|
+
classic-slides export <file.yaml> [-o out.json] Portable JSON with images inlined, for import
|
|
33
35
|
classic-slides validate <file.yaml> Check for errors and crowded slides
|
|
34
36
|
classic-slides layouts [name] List layouts, or show one in detail
|
|
35
37
|
classic-slides guide Print the authoring guide
|
|
36
38
|
classic-slides schema Print the deck JSON Schema
|
|
37
39
|
classic-slides mcp [--root dir] Run the MCP server on stdio
|
|
38
40
|
`;
|
|
41
|
+
var IMPORT_WARN_MB = 10;
|
|
39
42
|
var pkgRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
40
43
|
async function main() {
|
|
41
44
|
const { positionals, values } = parseArgs({
|
|
@@ -76,6 +79,22 @@ Next: classic-slides dev ${basename(target)}`);
|
|
|
76
79
|
console.log(`\u2714 ${r.out} \u2014 ${r.slideCount} slides, ${(r.bytes / 1024 / 1024).toFixed(2)} MB`);
|
|
77
80
|
return;
|
|
78
81
|
}
|
|
82
|
+
case "export": {
|
|
83
|
+
if (!arg) throw new Error("Usage: classic-slides export <file.yaml>");
|
|
84
|
+
const r = await exportDeckFile(arg, {
|
|
85
|
+
out: values.out,
|
|
86
|
+
onWarning: (w) => console.warn(`\u26A0 ${w}`)
|
|
87
|
+
});
|
|
88
|
+
for (const w of r.warnings) console.warn(`\u26A0 Not inlined: ${w.src} \u2014 ${w.message}`);
|
|
89
|
+
const mb = r.bytes / 1024 / 1024;
|
|
90
|
+
console.log(`\u2714 ${r.out} \u2014 ${mb.toFixed(2)} MB`);
|
|
91
|
+
if (mb > IMPORT_WARN_MB)
|
|
92
|
+
console.warn(
|
|
93
|
+
`\u26A0 Over ${IMPORT_WARN_MB} MB; the deck editor may refuse it. Resize large photos (~2000px wide).`
|
|
94
|
+
);
|
|
95
|
+
process.exitCode = r.warnings.length ? 1 : 0;
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
79
98
|
case "validate": {
|
|
80
99
|
if (!arg) throw new Error("Usage: classic-slides validate <file.yaml>");
|
|
81
100
|
const v = validateDeck(await loadDeckFile(resolve(arg)));
|
|
@@ -107,7 +126,7 @@ ${"".padEnd(12)} Use for: ${l.whenToUse}
|
|
|
107
126
|
case "mcp": {
|
|
108
127
|
let mcp;
|
|
109
128
|
try {
|
|
110
|
-
mcp = await import("./mcp-
|
|
129
|
+
mcp = await import("./mcp-3WAVCLQ2.js");
|
|
111
130
|
} catch (e) {
|
|
112
131
|
if (e.code === "ERR_MODULE_NOT_FOUND") {
|
|
113
132
|
throw new Error(
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/node/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * classic-slides — build branded Classic Homes decks from YAML.\n */\nimport { watch } from 'node:fs';\nimport { access, copyFile, mkdir } from 'node:fs/promises';\nimport { createServer } from 'node:http';\nimport { basename, dirname, join, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { parseArgs } from 'node:util';\nimport { AUTHORING_GUIDE, deckJsonSchema, describeLayout, listLayouts } from '../catalog.js';\nimport { renderDeck } from '../render.js';\nimport { DeckError, formatIssues, validateDeck } from '../validate.js';\nimport { buildDeckFile, fileImageResolver, loadDeckFile } from './index.js';\n\nconst HELP = `classic-slides — branded Classic Homes presentations\n\nUsage\n classic-slides new <file.yaml> [--starter basic|journey] Start a deck from a starter\n classic-slides build <file.yaml> [-o out.html] Render one self-contained HTML file\n classic-slides dev <file.yaml> [--port 4321] Live preview; reloads on save\n classic-slides validate <file.yaml> Check for errors and crowded slides\n classic-slides layouts [name] List layouts, or show one in detail\n classic-slides guide Print the authoring guide\n classic-slides schema Print the deck JSON Schema\n classic-slides mcp [--root dir] Run the MCP server on stdio\n`;\n\nconst pkgRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');\n\nasync function main() {\n const { positionals, values } = parseArgs({\n allowPositionals: true,\n options: {\n out: { type: 'string', short: 'o' },\n port: { type: 'string', default: '4321' },\n starter: { type: 'string', default: 'basic' },\n root: { type: 'string' },\n help: { type: 'boolean', short: 'h' },\n },\n });\n const [cmd, arg] = positionals;\n\n if (!cmd || values.help) return void process.stdout.write(HELP);\n\n switch (cmd) {\n case 'new': {\n if (!arg) throw new Error('Usage: classic-slides new <file.yaml>');\n const target = resolve(arg.endsWith('.yaml') || arg.endsWith('.yml') ? arg : `${arg}.yaml`);\n if (\n await access(target).then(\n () => true,\n () => false\n )\n )\n throw new Error(`${target} already exists.`);\n const starter = join(pkgRoot, 'starters', `${values.starter}.yaml`);\n await mkdir(dirname(target), { recursive: true });\n await copyFile(starter, target);\n console.log(`Created ${target}\\nNext: classic-slides dev ${basename(target)}`);\n return;\n }\n case 'build': {\n if (!arg) throw new Error('Usage: classic-slides build <file.yaml>');\n const r = await buildDeckFile(arg, {\n out: values.out,\n onWarning: (w) => console.warn(`⚠ ${w}`),\n });\n if (r.warnings.length) console.warn(formatIssues(r.warnings));\n console.log(`✔ ${r.out} — ${r.slideCount} slides, ${(r.bytes / 1024 / 1024).toFixed(2)} MB`);\n return;\n }\n case 'validate': {\n if (!arg) throw new Error('Usage: classic-slides validate <file.yaml>');\n const v = validateDeck(await loadDeckFile(resolve(arg)));\n console.log(v.issues.length ? formatIssues(v.issues) : '✔ Valid, no warnings');\n process.exitCode = v.ok ? 0 : 1;\n return;\n }\n case 'dev':\n return dev(arg, Number(values.port));\n case 'layouts': {\n if (arg) {\n const d = describeLayout(arg);\n if (!d) throw new Error(`Unknown layout \"${arg}\".`);\n console.log(JSON.stringify(d, null, 2));\n } else {\n for (const l of listLayouts())\n console.log(\n `${l.name.padEnd(12)} ${l.description}\\n${''.padEnd(12)} Use for: ${l.whenToUse}\\n`\n );\n }\n return;\n }\n case 'guide':\n return void console.log(AUTHORING_GUIDE);\n case 'schema':\n return void console.log(JSON.stringify(deckJsonSchema(), null, 2));\n case 'mcp': {\n // The MCP SDK is an optional peer so apps that only render decks don't install it.\n let mcp: typeof import('./mcp.js');\n try {\n mcp = await import('./mcp.js');\n } catch (e) {\n if ((e as { code?: string }).code === 'ERR_MODULE_NOT_FOUND') {\n throw new Error(\n 'The MCP server needs @modelcontextprotocol/sdk. Run it with:\\n npx -y -p @classic-homes/slides -p @modelcontextprotocol/sdk classic-slides mcp'\n );\n }\n throw e;\n }\n return mcp.runStdio(values.root);\n }\n default:\n throw new Error(`Unknown command \"${cmd}\".\\n\\n${HELP}`);\n }\n}\n\n/** Preview server: renders on every request and reloads the page when the deck folder changes. */\nasync function dev(file: string | undefined, port: number) {\n if (!file) throw new Error('Usage: classic-slides dev <file.yaml>');\n const abs = resolve(file);\n const dir = dirname(abs);\n const clients = new Set<import('node:http').ServerResponse>();\n const reload = `<script>new EventSource('/__reload').onmessage=()=>location.reload()</script>`;\n\n const errorPage = (msg: string) =>\n `<!doctype html><meta charset=\"utf-8\"><title>Deck error</title><body style=\"font:15px/1.5 ui-monospace,monospace;padding:40px;background:#fdf2f2;color:#7f1d1d\"><h2 style=\"font-family:system-ui\">Deck has problems</h2><pre style=\"white-space:pre-wrap\">${msg\n .replace(/&/g, '&')\n .replace(/</g, '<')}</pre>${reload}`;\n\n createServer(async (req, res) => {\n if (req.url === '/__reload') {\n res.writeHead(200, {\n 'content-type': 'text/event-stream',\n 'cache-control': 'no-cache',\n connection: 'keep-alive',\n });\n res.write(': ok\\n\\n');\n clients.add(res);\n req.on('close', () => clients.delete(res));\n return;\n }\n let html: string;\n try {\n const deck = await loadDeckFile(abs);\n const r = await renderDeck(deck, {\n resolveImage: fileImageResolver(dir),\n embedSource: false,\n });\n html = r.html.replace('</body>', `${reload}</body>`);\n if (r.warnings.length) console.warn(formatIssues(r.warnings));\n } catch (e) {\n html = errorPage(\n e instanceof DeckError ? formatIssues(e.issues) : e instanceof Error ? e.message : String(e)\n );\n }\n res.writeHead(200, { 'content-type': 'text/html; charset=utf-8', 'cache-control': 'no-store' });\n res.end(html);\n }).listen(port, () =>\n console.log(`Previewing ${file} at http://localhost:${port} (Ctrl+C to stop)`)\n );\n\n let timer: NodeJS.Timeout | undefined;\n watch(dir, { recursive: true }, (_, name) => {\n if (name && /\\.html$/.test(name)) return;\n clearTimeout(timer);\n timer = setTimeout(() => clients.forEach((c) => c.write('data: reload\\n\\n')), 120);\n });\n}\n\nmain().catch((e) => {\n console.error(e instanceof DeckError ? e.message : `✖ ${e instanceof Error ? e.message : e}`);\n process.exit(1);\n});\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/node/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * classic-slides — build branded Classic Homes decks from YAML.\n */\nimport { watch } from 'node:fs';\nimport { access, copyFile, mkdir } from 'node:fs/promises';\nimport { createServer } from 'node:http';\nimport { basename, dirname, join, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { parseArgs } from 'node:util';\nimport { AUTHORING_GUIDE, deckJsonSchema, describeLayout, listLayouts } from '../catalog.js';\nimport { renderDeck } from '../render.js';\nimport { DeckError, formatIssues, validateDeck } from '../validate.js';\nimport { buildDeckFile, exportDeckFile, fileImageResolver, loadDeckFile } from './index.js';\n\nconst HELP = `classic-slides — branded Classic Homes presentations\n\nUsage\n classic-slides new <file.yaml> [--starter basic|journey] Start a deck from a starter\n classic-slides build <file.yaml> [-o out.html] Render one self-contained HTML file\n classic-slides dev <file.yaml> [--port 4321] Live preview; reloads on save\n classic-slides export <file.yaml> [-o out.json] Portable JSON with images inlined, for import\n classic-slides validate <file.yaml> Check for errors and crowded slides\n classic-slides layouts [name] List layouts, or show one in detail\n classic-slides guide Print the authoring guide\n classic-slides schema Print the deck JSON Schema\n classic-slides mcp [--root dir] Run the MCP server on stdio\n`;\n\n/** Size above which hosted deck imports are likely to be refused. */\nconst IMPORT_WARN_MB = 10;\n\nconst pkgRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');\n\nasync function main() {\n const { positionals, values } = parseArgs({\n allowPositionals: true,\n options: {\n out: { type: 'string', short: 'o' },\n port: { type: 'string', default: '4321' },\n starter: { type: 'string', default: 'basic' },\n root: { type: 'string' },\n help: { type: 'boolean', short: 'h' },\n },\n });\n const [cmd, arg] = positionals;\n\n if (!cmd || values.help) return void process.stdout.write(HELP);\n\n switch (cmd) {\n case 'new': {\n if (!arg) throw new Error('Usage: classic-slides new <file.yaml>');\n const target = resolve(arg.endsWith('.yaml') || arg.endsWith('.yml') ? arg : `${arg}.yaml`);\n if (\n await access(target).then(\n () => true,\n () => false\n )\n )\n throw new Error(`${target} already exists.`);\n const starter = join(pkgRoot, 'starters', `${values.starter}.yaml`);\n await mkdir(dirname(target), { recursive: true });\n await copyFile(starter, target);\n console.log(`Created ${target}\\nNext: classic-slides dev ${basename(target)}`);\n return;\n }\n case 'build': {\n if (!arg) throw new Error('Usage: classic-slides build <file.yaml>');\n const r = await buildDeckFile(arg, {\n out: values.out,\n onWarning: (w) => console.warn(`⚠ ${w}`),\n });\n if (r.warnings.length) console.warn(formatIssues(r.warnings));\n console.log(`✔ ${r.out} — ${r.slideCount} slides, ${(r.bytes / 1024 / 1024).toFixed(2)} MB`);\n return;\n }\n case 'export': {\n if (!arg) throw new Error('Usage: classic-slides export <file.yaml>');\n const r = await exportDeckFile(arg, {\n out: values.out,\n onWarning: (w) => console.warn(`⚠ ${w}`),\n });\n for (const w of r.warnings) console.warn(`⚠ Not inlined: ${w.src} — ${w.message}`);\n const mb = r.bytes / 1024 / 1024;\n console.log(`✔ ${r.out} — ${mb.toFixed(2)} MB`);\n if (mb > IMPORT_WARN_MB)\n console.warn(\n `⚠ Over ${IMPORT_WARN_MB} MB; the deck editor may refuse it. Resize large photos (~2000px wide).`\n );\n process.exitCode = r.warnings.length ? 1 : 0;\n return;\n }\n case 'validate': {\n if (!arg) throw new Error('Usage: classic-slides validate <file.yaml>');\n const v = validateDeck(await loadDeckFile(resolve(arg)));\n console.log(v.issues.length ? formatIssues(v.issues) : '✔ Valid, no warnings');\n process.exitCode = v.ok ? 0 : 1;\n return;\n }\n case 'dev':\n return dev(arg, Number(values.port));\n case 'layouts': {\n if (arg) {\n const d = describeLayout(arg);\n if (!d) throw new Error(`Unknown layout \"${arg}\".`);\n console.log(JSON.stringify(d, null, 2));\n } else {\n for (const l of listLayouts())\n console.log(\n `${l.name.padEnd(12)} ${l.description}\\n${''.padEnd(12)} Use for: ${l.whenToUse}\\n`\n );\n }\n return;\n }\n case 'guide':\n return void console.log(AUTHORING_GUIDE);\n case 'schema':\n return void console.log(JSON.stringify(deckJsonSchema(), null, 2));\n case 'mcp': {\n // The MCP SDK is an optional peer so apps that only render decks don't install it.\n let mcp: typeof import('./mcp.js');\n try {\n mcp = await import('./mcp.js');\n } catch (e) {\n if ((e as { code?: string }).code === 'ERR_MODULE_NOT_FOUND') {\n throw new Error(\n 'The MCP server needs @modelcontextprotocol/sdk. Run it with:\\n npx -y -p @classic-homes/slides -p @modelcontextprotocol/sdk classic-slides mcp'\n );\n }\n throw e;\n }\n return mcp.runStdio(values.root);\n }\n default:\n throw new Error(`Unknown command \"${cmd}\".\\n\\n${HELP}`);\n }\n}\n\n/** Preview server: renders on every request and reloads the page when the deck folder changes. */\nasync function dev(file: string | undefined, port: number) {\n if (!file) throw new Error('Usage: classic-slides dev <file.yaml>');\n const abs = resolve(file);\n const dir = dirname(abs);\n const clients = new Set<import('node:http').ServerResponse>();\n const reload = `<script>new EventSource('/__reload').onmessage=()=>location.reload()</script>`;\n\n const errorPage = (msg: string) =>\n `<!doctype html><meta charset=\"utf-8\"><title>Deck error</title><body style=\"font:15px/1.5 ui-monospace,monospace;padding:40px;background:#fdf2f2;color:#7f1d1d\"><h2 style=\"font-family:system-ui\">Deck has problems</h2><pre style=\"white-space:pre-wrap\">${msg\n .replace(/&/g, '&')\n .replace(/</g, '<')}</pre>${reload}`;\n\n createServer(async (req, res) => {\n if (req.url === '/__reload') {\n res.writeHead(200, {\n 'content-type': 'text/event-stream',\n 'cache-control': 'no-cache',\n connection: 'keep-alive',\n });\n res.write(': ok\\n\\n');\n clients.add(res);\n req.on('close', () => clients.delete(res));\n return;\n }\n let html: string;\n try {\n const deck = await loadDeckFile(abs);\n const r = await renderDeck(deck, {\n resolveImage: fileImageResolver(dir),\n embedSource: false,\n });\n html = r.html.replace('</body>', `${reload}</body>`);\n if (r.warnings.length) console.warn(formatIssues(r.warnings));\n } catch (e) {\n html = errorPage(\n e instanceof DeckError ? formatIssues(e.issues) : e instanceof Error ? e.message : String(e)\n );\n }\n res.writeHead(200, { 'content-type': 'text/html; charset=utf-8', 'cache-control': 'no-store' });\n res.end(html);\n }).listen(port, () =>\n console.log(`Previewing ${file} at http://localhost:${port} (Ctrl+C to stop)`)\n );\n\n let timer: NodeJS.Timeout | undefined;\n watch(dir, { recursive: true }, (_, name) => {\n if (name && /\\.html$/.test(name)) return;\n clearTimeout(timer);\n timer = setTimeout(() => clients.forEach((c) => c.write('data: reload\\n\\n')), 120);\n });\n}\n\nmain().catch((e) => {\n console.error(e instanceof DeckError ? e.message : `✖ ${e instanceof Error ? e.message : e}`);\n process.exit(1);\n});\n"],"mappings":"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","names":[]}
|
|
@@ -561,7 +561,31 @@ interface RenderOptions {
|
|
|
561
561
|
speakerNotes?: boolean;
|
|
562
562
|
/** Permit kiosk auto-advance in an isolated presentation host (editor previews stay paused). */
|
|
563
563
|
allowEmbeddedKiosk?: boolean;
|
|
564
|
+
/**
|
|
565
|
+
* Click-to-edit for editor previews. Embeds each slide's text and image
|
|
566
|
+
* fields so that, inside an iframe, clicking a title, bullet or picture
|
|
567
|
+
* posts `{ type: 'classic-slides:select', index, path }` to the parent
|
|
568
|
+
* (`index` is the deck slide, `path` the field, or null for the slide
|
|
569
|
+
* itself), and the parent can outline a field with
|
|
570
|
+
* `{ type: 'classic-slides:highlight', index, path }`. Links inside slides
|
|
571
|
+
* stop navigating. Off by default; never use it for shared or exported decks.
|
|
572
|
+
*/
|
|
573
|
+
editorMarkers?: boolean;
|
|
574
|
+
}
|
|
575
|
+
/** A field the editor runtime can match a clicked element to. */
|
|
576
|
+
interface FieldMarker {
|
|
577
|
+
/** Path inside the slide, e.g. ["title"] or ["items", 2, "text"] */
|
|
578
|
+
path: (string | number)[];
|
|
579
|
+
/** Visible text of a text field, whitespace collapsed */
|
|
580
|
+
text?: string;
|
|
581
|
+
/** Resolved src of an image field */
|
|
582
|
+
img?: string;
|
|
564
583
|
}
|
|
584
|
+
/**
|
|
585
|
+
* The text and image fields of one slide, for click-to-edit matching.
|
|
586
|
+
* `resolveImage` maps an authored src to the src rendered in the page.
|
|
587
|
+
*/
|
|
588
|
+
declare function fieldMarkers(slide: Record<string, unknown>, resolveImage?: (src: string) => string): FieldMarker[];
|
|
565
589
|
interface RenderResult {
|
|
566
590
|
html: string;
|
|
567
591
|
deck: Deck;
|
|
@@ -577,4 +601,41 @@ declare function renderDeck(input: unknown, options?: RenderOptions): Promise<Re
|
|
|
577
601
|
/** Pulls the embedded deck source back out of a rendered HTML file. */
|
|
578
602
|
declare function extractDeckSource(html: string): unknown | undefined;
|
|
579
603
|
|
|
580
|
-
|
|
604
|
+
/**
|
|
605
|
+
* Rewrites every image src in a deck: inline them as data URIs for a portable
|
|
606
|
+
* single-file export, or swap data URIs for hosted URLs on import.
|
|
607
|
+
*/
|
|
608
|
+
|
|
609
|
+
interface MapImagesOptions extends ValidateOptions {
|
|
610
|
+
/** Images rewritten at once. Default 4. */
|
|
611
|
+
concurrency?: number;
|
|
612
|
+
}
|
|
613
|
+
interface InlineImagesResult {
|
|
614
|
+
/** A copy of the input deck with image srcs replaced. */
|
|
615
|
+
deck: unknown;
|
|
616
|
+
/** Images left as they were because the resolver failed. */
|
|
617
|
+
warnings: {
|
|
618
|
+
src: string;
|
|
619
|
+
message: string;
|
|
620
|
+
}[];
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* Calls `fn` once per distinct image src and returns a copy of `input` with
|
|
624
|
+
* each src replaced by the result. The deck is validated first so images
|
|
625
|
+
* written as plain strings (`image: photo.jpg`) are found too; the copy keeps
|
|
626
|
+
* the author's shape (strings stay strings, no schema defaults are added).
|
|
627
|
+
* Throws `DeckError` if the deck is invalid, or the first error from `fn`.
|
|
628
|
+
*/
|
|
629
|
+
declare function mapDeckImages(input: unknown, fn: (src: string) => string | Promise<string>, options?: MapImagesOptions): Promise<unknown>;
|
|
630
|
+
/**
|
|
631
|
+
* Inlines every image as a data URI so the deck is one self-contained file.
|
|
632
|
+
* Images the resolver can't load are left as-is and reported in `warnings`.
|
|
633
|
+
*/
|
|
634
|
+
declare function inlineDeckImages(input: unknown, resolve: ImageResolver, options?: MapImagesOptions): Promise<InlineImagesResult>;
|
|
635
|
+
/**
|
|
636
|
+
* Replaces every data-URI image with the src `upload` returns (e.g. a hosted
|
|
637
|
+
* URL). Other srcs are untouched. Errors from `upload` are thrown.
|
|
638
|
+
*/
|
|
639
|
+
declare function externalizeDeckImages(input: unknown, upload: (dataUri: string) => string | Promise<string>, options?: MapImagesOptions): Promise<unknown>;
|
|
640
|
+
|
|
641
|
+
export { type ValidationResult as A, type BrandPalette as B, CLASSIC_HOMES_BRAND as C, type Deck as D, checkPalette as E, type FieldMarker as F, collectImageSources as G, externalizeDeckImages as H, type ImageInput as I, extractDeckSource as J, fieldMarkers as K, type LayoutCategory as L, type MapImagesOptions as M, formatIssues as N, formatPath as O, PREVIEW_SIZE as P, getLayout as Q, type RenderOptions as R, type SlideData as S, inlineDeckImages as T, mapDeckImages as U, type ValidateOptions as V, renderDeck as W, resolveBrand as X, validateBrandProfile as Y, validateDeck as Z, BrandPaletteSchema as a, type BrandProfile as b, type BrandProfileInput as c, BrandProfileSchema as d, CLASSIC_HOMES_PALETTE as e, type DeckBrand as f, DeckBrandSchema as g, DeckError as h, type DeckInput as i, DeckSchema as j, type DeckSettings as k, DeckSettingsSchema as l, type ImageResolver as m, type ImageValue as n, type InlineImagesResult as o, type ItemValue as p, LAYOUTS as q, LAYOUT_CATEGORIES as r, LAYOUT_CATEGORY_ORDER as s, type LayoutDef as t, type LayoutIssue as u, type LayoutName as v, type RenderResult as w, type ResolvedBrand as x, type SlideInput as y, SlideSchema as z };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { L as LayoutCategory, B as BrandPalette } from './
|
|
2
|
-
export { a as BrandPaletteSchema, b as BrandProfile, c as BrandProfileInput, d as BrandProfileSchema, C as CLASSIC_HOMES_BRAND, e as CLASSIC_HOMES_PALETTE, D as Deck, f as DeckBrand, g as DeckBrandSchema, h as DeckError, i as DeckInput, j as DeckSchema, k as DeckSettings, l as DeckSettingsSchema, I as ImageInput, m as ImageResolver, n as ImageValue, o as
|
|
1
|
+
import { L as LayoutCategory, B as BrandPalette } from './images-8N30SsCW.js';
|
|
2
|
+
export { a as BrandPaletteSchema, b as BrandProfile, c as BrandProfileInput, d as BrandProfileSchema, C as CLASSIC_HOMES_BRAND, e as CLASSIC_HOMES_PALETTE, D as Deck, f as DeckBrand, g as DeckBrandSchema, h as DeckError, i as DeckInput, j as DeckSchema, k as DeckSettings, l as DeckSettingsSchema, F as FieldMarker, I as ImageInput, m as ImageResolver, n as ImageValue, o as InlineImagesResult, p as ItemValue, q as LAYOUTS, r as LAYOUT_CATEGORIES, s as LAYOUT_CATEGORY_ORDER, t as LayoutDef, u as LayoutIssue, v as LayoutName, M as MapImagesOptions, P as PREVIEW_SIZE, R as RenderOptions, w as RenderResult, x as ResolvedBrand, S as SlideData, y as SlideInput, z as SlideSchema, V as ValidateOptions, A as ValidationResult, E as checkPalette, G as collectImageSources, H as externalizeDeckImages, J as extractDeckSource, K as fieldMarkers, N as formatIssues, O as formatPath, Q as getLayout, T as inlineDeckImages, U as mapDeckImages, W as renderDeck, X as resolveBrand, Y as validateBrandProfile, Z as validateDeck } from './images-8N30SsCW.js';
|
|
3
3
|
import * as zod_to_json_schema from 'zod-to-json-schema';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
|
|
@@ -155,6 +155,8 @@ interface FieldBase<K extends string> {
|
|
|
155
155
|
* - point: {x, y} in % of an image (hotspot picker)
|
|
156
156
|
*/
|
|
157
157
|
hint?: 'url' | 'video-url' | 'chart' | 'grid' | 'point';
|
|
158
|
+
/** Rarely changed; editors should tuck it behind an "Advanced" section. */
|
|
159
|
+
advanced?: boolean;
|
|
158
160
|
}
|
|
159
161
|
/** Deck-level fields for a settings panel: brand overrides and presentation settings. */
|
|
160
162
|
declare function deckEditorFields(): {
|
|
@@ -179,6 +181,21 @@ interface LayoutEditorInfo {
|
|
|
179
181
|
declare function commonSlideFields(): EditorField[];
|
|
180
182
|
declare function layoutEditorInfo(name: string): LayoutEditorInfo | undefined;
|
|
181
183
|
declare function allLayoutEditorInfo(): LayoutEditorInfo[];
|
|
184
|
+
/**
|
|
185
|
+
* One deck holding every layout's starting slide, in palette order, for
|
|
186
|
+
* rendering layout thumbnails once (render it, then show slide N of the
|
|
187
|
+
* result per layout). `slideFor[layout]` is that layout's slide index.
|
|
188
|
+
*/
|
|
189
|
+
declare function layoutGalleryDeck(): {
|
|
190
|
+
deck: {
|
|
191
|
+
title: string;
|
|
192
|
+
journey: {
|
|
193
|
+
steps: string[];
|
|
194
|
+
};
|
|
195
|
+
slides: Record<string, unknown>[];
|
|
196
|
+
};
|
|
197
|
+
slideFor: Record<string, number>;
|
|
198
|
+
};
|
|
182
199
|
/**
|
|
183
200
|
* Stand-in image for new slides: a neutral frame reading "Add a photo".
|
|
184
201
|
* It validates (so a fresh slide previews immediately) but lint warns until
|
|
@@ -289,6 +306,6 @@ interface EmbedOptions {
|
|
|
289
306
|
declare function videoEmbedUrl(ref: VideoRef, o: EmbedOptions): string;
|
|
290
307
|
|
|
291
308
|
/** CSP source for the inline presenter runtime: script-src '<hash>'. */
|
|
292
|
-
declare const RUNTIME_SCRIPT_HASH = "sha256-
|
|
309
|
+
declare const RUNTIME_SCRIPT_HASH = "sha256-gElvQAb4VPvKu4UeyJRVKuoHYNp8NGhXwx2EhL7NB88=";
|
|
293
310
|
|
|
294
|
-
export { AUTHORING_GUIDE, BrandPalette, CHART_TYPES, ChartSpec, type ChartSpecInput, type ChartSpecValue, type ChartType, type EditableDeck, type EditorField, LOGO_SVG, LayoutCategory, type LayoutEditorInfo, PALETTE, PLACEHOLDER_IMAGE, RUNTIME_SCRIPT_HASH, type SlideRef, type VideoRef, addSlide, allLayoutEditorInfo, blankSlide, chartOption, commonSlideFields, deckEditorFields, deckJsonSchema, describeChart, describeLayout, ensureSlideIds, escapeHtml, findSlide, formatValue, inline, isPlaceholderImage, layoutEditorInfo, listLayouts, logoLockup, moveSlide, newSlideId, outline, parseDeckSource, parseVideoUrl, prose, removeSlide, renderChartSvg, slideKey, stringifyDeck, updateSlide, videoEmbedUrl };
|
|
311
|
+
export { AUTHORING_GUIDE, BrandPalette, CHART_TYPES, ChartSpec, type ChartSpecInput, type ChartSpecValue, type ChartType, type EditableDeck, type EditorField, LOGO_SVG, LayoutCategory, type LayoutEditorInfo, PALETTE, PLACEHOLDER_IMAGE, RUNTIME_SCRIPT_HASH, type SlideRef, type VideoRef, addSlide, allLayoutEditorInfo, blankSlide, chartOption, commonSlideFields, deckEditorFields, deckJsonSchema, describeChart, describeLayout, ensureSlideIds, escapeHtml, findSlide, formatValue, inline, isPlaceholderImage, layoutEditorInfo, layoutGalleryDeck, listLayouts, logoLockup, moveSlide, newSlideId, outline, parseDeckSource, parseVideoUrl, prose, removeSlide, renderChartSvg, slideKey, stringifyDeck, updateSlide, videoEmbedUrl };
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
deckJsonSchema,
|
|
4
4
|
describeLayout,
|
|
5
5
|
listLayouts
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-TEE3OGRQ.js";
|
|
7
7
|
import {
|
|
8
8
|
BrandPaletteSchema,
|
|
9
9
|
BrandProfileSchema,
|
|
@@ -34,16 +34,21 @@ import {
|
|
|
34
34
|
describeChart,
|
|
35
35
|
ensureSlideIds,
|
|
36
36
|
escapeHtml,
|
|
37
|
+
externalizeDeckImages,
|
|
37
38
|
extractDeckSource,
|
|
39
|
+
fieldMarkers,
|
|
38
40
|
findSlide,
|
|
39
41
|
formatIssues,
|
|
40
42
|
formatPath,
|
|
41
43
|
formatValue,
|
|
42
44
|
getLayout,
|
|
43
45
|
inline,
|
|
46
|
+
inlineDeckImages,
|
|
44
47
|
isPlaceholderImage,
|
|
45
48
|
layoutEditorInfo,
|
|
49
|
+
layoutGalleryDeck,
|
|
46
50
|
logoLockup,
|
|
51
|
+
mapDeckImages,
|
|
47
52
|
moveSlide,
|
|
48
53
|
newSlideId,
|
|
49
54
|
outline,
|
|
@@ -60,10 +65,10 @@ import {
|
|
|
60
65
|
validateBrandProfile,
|
|
61
66
|
validateDeck,
|
|
62
67
|
videoEmbedUrl
|
|
63
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-OUAMH2TP.js";
|
|
64
69
|
|
|
65
70
|
// src/generated/runtime-hash.ts
|
|
66
|
-
var RUNTIME_SCRIPT_HASH = "sha256-
|
|
71
|
+
var RUNTIME_SCRIPT_HASH = "sha256-gElvQAb4VPvKu4UeyJRVKuoHYNp8NGhXwx2EhL7NB88=";
|
|
67
72
|
export {
|
|
68
73
|
AUTHORING_GUIDE,
|
|
69
74
|
BrandPaletteSchema,
|
|
@@ -98,17 +103,22 @@ export {
|
|
|
98
103
|
describeLayout,
|
|
99
104
|
ensureSlideIds,
|
|
100
105
|
escapeHtml,
|
|
106
|
+
externalizeDeckImages,
|
|
101
107
|
extractDeckSource,
|
|
108
|
+
fieldMarkers,
|
|
102
109
|
findSlide,
|
|
103
110
|
formatIssues,
|
|
104
111
|
formatPath,
|
|
105
112
|
formatValue,
|
|
106
113
|
getLayout,
|
|
107
114
|
inline,
|
|
115
|
+
inlineDeckImages,
|
|
108
116
|
isPlaceholderImage,
|
|
109
117
|
layoutEditorInfo,
|
|
118
|
+
layoutGalleryDeck,
|
|
110
119
|
listLayouts,
|
|
111
120
|
logoLockup,
|
|
121
|
+
mapDeckImages,
|
|
112
122
|
moveSlide,
|
|
113
123
|
newSlideId,
|
|
114
124
|
outline,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/generated/runtime-hash.ts"],"sourcesContent":["// Generated by scripts/embed-fonts.ts. Do not edit.\n/** CSP source for the inline presenter runtime: script-src '<hash>'. */\nexport const RUNTIME_SCRIPT_HASH = 'sha256-
|
|
1
|
+
{"version":3,"sources":["../src/generated/runtime-hash.ts"],"sourcesContent":["// Generated by scripts/embed-fonts.ts. Do not edit.\n/** CSP source for the inline presenter runtime: script-src '<hash>'. */\nexport const RUNTIME_SCRIPT_HASH = 'sha256-gElvQAb4VPvKu4UeyJRVKuoHYNp8NGhXwx2EhL7NB88=';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEO,IAAM,sBAAsB;","names":[]}
|
|
@@ -2,13 +2,13 @@ import {
|
|
|
2
2
|
AUTHORING_GUIDE,
|
|
3
3
|
describeLayout,
|
|
4
4
|
listLayouts
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-TEE3OGRQ.js";
|
|
6
6
|
import {
|
|
7
7
|
buildDeckFile,
|
|
8
8
|
confinedPath,
|
|
9
9
|
loadDeckFile,
|
|
10
10
|
saveDeckFile
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-GX6P2SE6.js";
|
|
12
12
|
import {
|
|
13
13
|
addSlide,
|
|
14
14
|
formatIssues,
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
stringifyDeck,
|
|
19
19
|
updateSlide,
|
|
20
20
|
validateDeck
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-OUAMH2TP.js";
|
|
22
22
|
|
|
23
23
|
// src/node/mcp.ts
|
|
24
24
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -320,4 +320,4 @@ export {
|
|
|
320
320
|
createSlidesMcpServer,
|
|
321
321
|
runStdio
|
|
322
322
|
};
|
|
323
|
-
//# sourceMappingURL=mcp-
|
|
323
|
+
//# sourceMappingURL=mcp-3WAVCLQ2.js.map
|
package/dist/node.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as RenderOptions,
|
|
2
|
-
export {
|
|
1
|
+
import { R as RenderOptions, w as RenderResult, o as InlineImagesResult, m as ImageResolver } from './images-8N30SsCW.js';
|
|
2
|
+
export { W as renderDeck } from './images-8N30SsCW.js';
|
|
3
3
|
import 'zod';
|
|
4
4
|
|
|
5
5
|
/** Largest single image we inline without warning. Big photos bloat the deck file. */
|
|
@@ -23,5 +23,17 @@ declare function buildDeckFile(path: string, options?: BuildOptions): Promise<Re
|
|
|
23
23
|
out: string;
|
|
24
24
|
bytes: number;
|
|
25
25
|
}>;
|
|
26
|
+
interface ExportOptions extends FileResolverOptions {
|
|
27
|
+
out?: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Writes a portable copy of a deck file: JSON with every image inlined as a
|
|
31
|
+
* data URI, ready to import into a hosted deck editor. Defaults to
|
|
32
|
+
* `<name>.deck.json` next to the source.
|
|
33
|
+
*/
|
|
34
|
+
declare function exportDeckFile(path: string, options?: ExportOptions): Promise<InlineImagesResult & {
|
|
35
|
+
out: string;
|
|
36
|
+
bytes: number;
|
|
37
|
+
}>;
|
|
26
38
|
|
|
27
|
-
export { type BuildOptions, type FileResolverOptions, IMAGE_WARN_BYTES, buildDeckFile, fileImageResolver, loadDeckFile, saveDeckFile };
|
|
39
|
+
export { type BuildOptions, type ExportOptions, type FileResolverOptions, IMAGE_WARN_BYTES, buildDeckFile, exportDeckFile, fileImageResolver, loadDeckFile, saveDeckFile };
|
package/dist/node.js
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
IMAGE_WARN_BYTES,
|
|
3
3
|
buildDeckFile,
|
|
4
|
+
exportDeckFile,
|
|
4
5
|
fileImageResolver,
|
|
5
6
|
loadDeckFile,
|
|
6
7
|
saveDeckFile
|
|
7
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-GX6P2SE6.js";
|
|
8
9
|
import {
|
|
9
10
|
renderDeck
|
|
10
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-OUAMH2TP.js";
|
|
11
12
|
export {
|
|
12
13
|
IMAGE_WARN_BYTES,
|
|
13
14
|
buildDeckFile,
|
|
15
|
+
exportDeckFile,
|
|
14
16
|
fileImageResolver,
|
|
15
17
|
loadDeckFile,
|
|
16
18
|
renderDeck,
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/node/index.ts","../src/node/paths.ts"],"sourcesContent":["/** Node-only helpers: read deck files, inline local images, write HTML. */\nimport { readFile, stat, writeFile } from 'node:fs/promises';\nimport { dirname, extname, isAbsolute, join, resolve } from 'node:path';\nimport { confinedPath } from './paths.js';\nimport { parseDeckSource, stringifyDeck } from '../parse.js';\nimport {\n renderDeck,\n type ImageResolver,\n type RenderOptions,\n type RenderResult,\n} from '../render.js';\n\nconst MIME: Record<string, string> = {\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.png': 'image/png',\n '.webp': 'image/webp',\n '.gif': 'image/gif',\n '.svg': 'image/svg+xml',\n '.avif': 'image/avif',\n};\n\n/** Largest single image we inline without warning. Big photos bloat the deck file. */\nexport const IMAGE_WARN_BYTES = 800 * 1024;\n\nexport interface FileResolverOptions {\n /** Restrict local image reads and build paths to this root (used by the MCP server). */\n rootDir?: string;\n /** Fetch https images and inline them so the deck works offline. Default true. */\n inlineRemote?: boolean;\n onWarning?: (message: string) => void;\n}\n\n/** Resolves image paths relative to the deck file and inlines them as data URIs. */\nexport function fileImageResolver(\n baseDir: string,\n options: FileResolverOptions = {}\n): ImageResolver {\n const warn = options.onWarning ?? (() => {});\n return async (src) => {\n if (src.startsWith('data:')) return src;\n if (/^https?:/.test(src)) {\n if (options.inlineRemote === false) return src;\n const res = await fetch(src);\n if (!res.ok) throw new Error(`Image ${src} returned HTTP ${res.status}`);\n const type = res.headers.get('content-type') ?? 'application/octet-stream';\n const buf = Buffer.from(await res.arrayBuffer());\n if (buf.length > IMAGE_WARN_BYTES)\n warn(`${src} is ${(buf.length / 1024).toFixed(0)} KB; consider a smaller copy.`);\n return `data:${type};base64,${buf.toString('base64')}`;\n }\n const candidate = isAbsolute(src) ? src : join(baseDir, src);\n const path = options.rootDir ? confinedPath(options.rootDir, candidate) : candidate;\n const type = MIME[extname(path).toLowerCase()];\n if (!type)\n throw new Error(`Unsupported image type for \"${src}\". Use jpg, png, webp, gif, svg or avif.`);\n let buf: Buffer;\n try {\n buf = await readFile(path);\n } catch {\n throw new Error(`Image not found: \"${src}\" (looked in ${path})`);\n }\n if (buf.length > IMAGE_WARN_BYTES)\n warn(`${src} is ${(buf.length / 1024).toFixed(0)} KB; consider resizing to ~2000px wide.`);\n return `data:${type};base64,${buf.toString('base64')}`;\n };\n}\n\nexport async function loadDeckFile(path: string): Promise<unknown> {\n return parseDeckSource(await readFile(path, 'utf8'));\n}\n\nexport async function saveDeckFile(path: string, deck: unknown): Promise<void> {\n const text = path.endsWith('.json') ? JSON.stringify(deck, null, 2) + '\\n' : stringifyDeck(deck);\n await writeFile(path, text);\n}\n\nexport interface BuildOptions extends Omit<RenderOptions, 'resolveImage'>, FileResolverOptions {\n out?: string;\n}\n\n/** Renders a deck file to a self-contained HTML file next to it (or at `out`). */\nexport async function buildDeckFile(\n path: string,\n options: BuildOptions = {}\n): Promise<RenderResult & { out: string; bytes: number }> {\n const abs = options.rootDir ? confinedPath(options.rootDir, resolve(path)) : resolve(path);\n const deck = await loadDeckFile(abs);\n const result = await renderDeck(deck, {\n ...options,\n resolveImage: fileImageResolver(dirname(abs), options),\n });\n const candidate = options.out\n ? resolve(options.out)\n : abs.replace(/\\.(ya?ml|json)$/i, '') + '.html';\n const out = options.rootDir ? confinedPath(options.rootDir, candidate) : candidate;\n await writeFile(out, result.html);\n return { ...result, out, bytes: (await stat(out)).size };\n}\n\nexport { renderDeck };\n","/** Canonical containment for existing files and new output files. */\nimport { lstatSync, realpathSync } from 'node:fs';\nimport { dirname, relative, resolve, sep } from 'node:path';\n\nexport function confinedPath(root: string, path: string): string {\n const canonicalRoot = realpathSync(root);\n const absolute = resolve(path);\n let ancestor = absolute;\n for (;;) {\n try {\n const canonical = resolve(realpathSync(ancestor), relative(ancestor, absolute));\n if (canonical !== canonicalRoot && !canonical.startsWith(canonicalRoot + sep)) {\n throw new Error(`Path \"${path}\" is outside the deck root ${root}.`);\n }\n return canonical;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT' || ancestor === dirname(ancestor))\n throw error;\n if (lstatSync(ancestor, { throwIfNoEntry: false })?.isSymbolicLink()) {\n throw new Error(`Cannot follow dangling symlink \"${ancestor}\".`);\n }\n ancestor = dirname(ancestor);\n }\n }\n}\n"],"mappings":"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","names":["dirname","resolve","type","buf","resolve","dirname"]}
|