mulmocast 2.1.39 → 2.1.40

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.
Files changed (54) hide show
  1. package/README.md +43 -0
  2. package/lib/actions/pdf.js +18 -15
  3. package/lib/slide/blocks.d.ts +5 -0
  4. package/lib/slide/blocks.js +97 -0
  5. package/lib/slide/index.d.ts +5 -0
  6. package/lib/slide/index.js +7 -0
  7. package/lib/slide/layouts/big_quote.d.ts +2 -0
  8. package/lib/slide/layouts/big_quote.js +19 -0
  9. package/lib/slide/layouts/columns.d.ts +2 -0
  10. package/lib/slide/layouts/columns.js +56 -0
  11. package/lib/slide/layouts/comparison.d.ts +2 -0
  12. package/lib/slide/layouts/comparison.js +28 -0
  13. package/lib/slide/layouts/funnel.d.ts +2 -0
  14. package/lib/slide/layouts/funnel.js +27 -0
  15. package/lib/slide/layouts/grid.d.ts +2 -0
  16. package/lib/slide/layouts/grid.js +43 -0
  17. package/lib/slide/layouts/index.d.ts +3 -0
  18. package/lib/slide/layouts/index.js +43 -0
  19. package/lib/slide/layouts/matrix.d.ts +2 -0
  20. package/lib/slide/layouts/matrix.js +53 -0
  21. package/lib/slide/layouts/split.d.ts +2 -0
  22. package/lib/slide/layouts/split.js +38 -0
  23. package/lib/slide/layouts/stats.d.ts +2 -0
  24. package/lib/slide/layouts/stats.js +23 -0
  25. package/lib/slide/layouts/table.d.ts +2 -0
  26. package/lib/slide/layouts/table.js +46 -0
  27. package/lib/slide/layouts/timeline.d.ts +2 -0
  28. package/lib/slide/layouts/timeline.js +24 -0
  29. package/lib/slide/layouts/title.d.ts +2 -0
  30. package/lib/slide/layouts/title.js +17 -0
  31. package/lib/slide/render.d.ts +3 -0
  32. package/lib/slide/render.js +29 -0
  33. package/lib/slide/schema.d.ts +4009 -0
  34. package/lib/slide/schema.js +330 -0
  35. package/lib/slide/utils.d.ts +32 -0
  36. package/lib/slide/utils.js +112 -0
  37. package/lib/types/schema.d.ts +4487 -38
  38. package/lib/types/schema.js +11 -0
  39. package/lib/types/slide.d.ts +4009 -0
  40. package/lib/types/slide.js +330 -0
  41. package/lib/utils/context.d.ts +1169 -9
  42. package/lib/utils/image_plugins/index.js +14 -1
  43. package/lib/utils/image_plugins/slide.d.ts +5 -0
  44. package/lib/utils/image_plugins/slide.js +35 -0
  45. package/package.json +8 -8
  46. package/scripts/test/golden_age_of_discovery.json +270 -0
  47. package/scripts/test/test_slide_01.json +105 -0
  48. package/scripts/test/test_slide_11.json +144 -0
  49. package/scripts/test/test_slide_12.json +887 -0
  50. package/scripts/test/test_slide_showcase_corporate.json +497 -0
  51. package/scripts/test/test_slide_showcase_creative.json +545 -0
  52. package/scripts/test/test_slide_showcase_minimal.json +501 -0
  53. package/scripts/test/test_slide_showcase_pop.json +547 -0
  54. package/scripts/test/test_slide_showcase_warm.json +486 -0
@@ -0,0 +1,46 @@
1
+ import { escapeHtml, c, slideHeader, renderCalloutBar } from "../utils.js";
2
+ const resolveCellColor = (cellObj, isRowHeader) => {
3
+ if (cellObj.color)
4
+ return `text-${c(cellObj.color)}`;
5
+ if (isRowHeader)
6
+ return "text-d-text";
7
+ return "text-d-muted";
8
+ };
9
+ const renderCellValue = (cell, isRowHeader) => {
10
+ const cellObj = typeof cell === "object" && cell !== null ? cell : { text: String(cell) };
11
+ const colorCls = resolveCellColor(cellObj, isRowHeader);
12
+ const boldCls = cellObj.bold || isRowHeader ? "font-bold" : "";
13
+ return `<td class="px-4 py-3 text-sm ${colorCls} ${boldCls} font-body border-b border-d-alt">${escapeHtml(cellObj.text)}</td>`;
14
+ };
15
+ export const layoutTable = (data) => {
16
+ const parts = [slideHeader(data)];
17
+ const headers = data.headers || [];
18
+ const rows = data.rows || [];
19
+ const striped = data.striped !== false;
20
+ parts.push(`<div class="px-12 mt-5 flex-1 overflow-auto">`);
21
+ parts.push(`<table class="w-full border-collapse">`);
22
+ parts.push(`<thead>`);
23
+ parts.push(`<tr>`);
24
+ headers.forEach((h) => {
25
+ parts.push(` <th class="text-left px-4 py-3 text-sm font-bold text-d-text font-body border-b-2 border-d-alt">${escapeHtml(h)}</th>`);
26
+ });
27
+ parts.push(`</tr>`);
28
+ parts.push(`</thead>`);
29
+ parts.push(`<tbody>`);
30
+ rows.forEach((row, ri) => {
31
+ const bgCls = striped && ri % 2 === 1 ? "bg-d-alt/30" : "";
32
+ parts.push(`<tr class="${bgCls}">`);
33
+ (row || []).forEach((cell, ci) => {
34
+ const isRowHeader = ci === 0 && !!data.rowHeaders;
35
+ parts.push(` ${renderCellValue(cell, isRowHeader)}`);
36
+ });
37
+ parts.push(`</tr>`);
38
+ });
39
+ parts.push(`</tbody>`);
40
+ parts.push(`</table>`);
41
+ parts.push(`</div>`);
42
+ if (data.callout) {
43
+ parts.push(`<div class="mt-auto pb-4">${renderCalloutBar(data.callout)}</div>`);
44
+ }
45
+ return parts.join("\n");
46
+ };
@@ -0,0 +1,2 @@
1
+ import type { TimelineSlide } from "../schema.js";
2
+ export declare const layoutTimeline: (data: TimelineSlide) => string;
@@ -0,0 +1,24 @@
1
+ import { escapeHtml, nl2br, c, slideHeader } from "../utils.js";
2
+ export const layoutTimeline = (data) => {
3
+ const parts = [slideHeader(data)];
4
+ const items = data.items || [];
5
+ parts.push(`<div class="flex items-start px-12 mt-8 flex-1 relative">`);
6
+ parts.push(`<div class="absolute left-16 right-16 top-[52px] h-[2px] bg-d-alt"></div>`);
7
+ items.forEach((item) => {
8
+ const color = item.color || data.accentColor || "primary";
9
+ const dotBorder = item.done ? `bg-${c(color)}` : `bg-d-alt`;
10
+ const dotInner = item.done ? "bg-d-text" : `bg-${c(color)}`;
11
+ parts.push(`<div class="flex-1 flex flex-col items-center text-center relative z-10">`);
12
+ parts.push(` <div class="w-10 h-10 rounded-full ${dotBorder} flex items-center justify-center shadow-lg">`);
13
+ parts.push(` <div class="w-4 h-4 rounded-full ${dotInner}"></div>`);
14
+ parts.push(` </div>`);
15
+ parts.push(` <p class="text-sm font-bold text-${c(color)} font-body mt-4">${escapeHtml(item.date)}</p>`);
16
+ parts.push(` <p class="text-base font-bold text-d-text font-body mt-2">${escapeHtml(item.title)}</p>`);
17
+ if (item.description) {
18
+ parts.push(` <p class="text-sm text-d-muted font-body mt-1 px-3">${nl2br(item.description)}</p>`);
19
+ }
20
+ parts.push(`</div>`);
21
+ });
22
+ parts.push(`</div>`);
23
+ return parts.join("\n");
24
+ };
@@ -0,0 +1,2 @@
1
+ import type { TitleSlide } from "../schema.js";
2
+ export declare const layoutTitle: (data: TitleSlide) => string;
@@ -0,0 +1,17 @@
1
+ import { nl2br } from "../utils.js";
2
+ export const layoutTitle = (data) => {
3
+ return [
4
+ `<div class="h-[3px] bg-d-primary"></div>`,
5
+ `<div class="absolute -top-20 -right-8 w-[360px] h-[360px] rounded-full bg-d-primary opacity-10"></div>`,
6
+ `<div class="absolute -bottom-12 -left-16 w-[280px] h-[280px] rounded-full bg-d-accent opacity-10"></div>`,
7
+ `<div class="flex flex-col justify-center h-full px-16 relative z-10">`,
8
+ ` <h1 class="text-[60px] leading-tight font-title font-bold text-d-text">${nl2br(data.title)}</h1>`,
9
+ data.subtitle ? ` <p class="text-2xl text-d-muted mt-6 font-body">${nl2br(data.subtitle)}</p>` : "",
10
+ data.author ? ` <p class="text-lg text-d-dim mt-10 font-body">${nl2br(data.author)}</p>` : "",
11
+ data.note ? ` <div class="bg-d-card px-4 py-2 mt-6 inline-block rounded"><p class="text-sm text-d-dim font-body">${nl2br(data.note)}</p></div>` : "",
12
+ `</div>`,
13
+ `<div class="absolute bottom-0 left-0 right-0 h-[3px] bg-d-accent"></div>`,
14
+ ]
15
+ .filter(Boolean)
16
+ .join("\n");
17
+ };
@@ -0,0 +1,3 @@
1
+ import type { SlideTheme, SlideLayout } from "./schema.js";
2
+ /** Generate a complete HTML document for a single slide */
3
+ export declare const generateSlideHTML: (theme: SlideTheme, slide: SlideLayout) => string;
@@ -0,0 +1,29 @@
1
+ import { escapeHtml, buildTailwindConfig, sanitizeHex } from "./utils.js";
2
+ import { renderSlideContent } from "./layouts/index.js";
3
+ /** Generate a complete HTML document for a single slide */
4
+ export const generateSlideHTML = (theme, slide) => {
5
+ const content = renderSlideContent(slide);
6
+ const twConfig = buildTailwindConfig(theme);
7
+ const slideStyle = slide.style;
8
+ const bgCls = slideStyle?.bgColor ? "" : "bg-d-bg";
9
+ const inlineStyle = slideStyle?.bgColor ? ` style="background-color:#${sanitizeHex(slideStyle.bgColor)}"` : "";
10
+ const footer = slideStyle?.footer ? `<p class="absolute bottom-2 right-4 text-xs text-d-dim font-body">${escapeHtml(slideStyle.footer)}</p>` : "";
11
+ return `<!DOCTYPE html>
12
+ <html lang="en" class="h-full">
13
+ <head>
14
+ <meta charset="UTF-8">
15
+ <meta name="viewport" content="width=1280">
16
+ <script src="https://cdn.tailwindcss.com"></script>
17
+ <script>tailwind.config = ${twConfig}</script>
18
+ <style>
19
+ html, body { height: 100%; margin: 0; padding: 0; overflow: hidden; }
20
+ </style>
21
+ </head>
22
+ <body class="h-full">
23
+ <div class="relative overflow-hidden ${bgCls} w-full h-full flex flex-col"${inlineStyle}>
24
+ ${content}
25
+ ${footer}
26
+ </div>
27
+ </body>
28
+ </html>`;
29
+ };