mulmocast 2.6.15 → 2.6.17
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/lib/actions/index.d.ts +1 -0
- package/lib/actions/index.js +1 -0
- package/lib/actions/viewer.d.ts +3 -0
- package/lib/actions/viewer.js +173 -0
- package/lib/cli/bin.js +0 -0
- package/lib/cli/commands/viewer/builder.d.ts +20 -0
- package/lib/cli/commands/viewer/builder.js +6 -0
- package/lib/cli/commands/viewer/handler.d.ts +4 -0
- package/lib/cli/commands/viewer/handler.js +11 -0
- package/lib/cli/commands/viewer/index.d.ts +4 -0
- package/lib/cli/commands/viewer/index.js +4 -0
- package/lib/cli/main.js +2 -0
- package/lib/mcp/server.js +0 -0
- package/lib/types/schema.d.ts +458 -457
- package/lib/types/schema.js +3 -2
- package/lib/types/type.d.ts +1 -1
- package/lib/utils/context.d.ts +729 -728
- package/lib/utils/context.js +1 -0
- package/lib/utils/image_plugins/slide.d.ts +1 -1
- package/lib/utils/image_plugins/slide.js +1 -1
- package/package.json +12 -11
- package/lib/data/styles.d.ts +0 -255
- package/lib/data/styles.js +0 -284
- package/lib/slide/blocks.d.ts +0 -13
- package/lib/slide/blocks.js +0 -251
- package/lib/slide/index.d.ts +0 -6
- package/lib/slide/index.js +0 -7
- package/lib/slide/layouts/big_quote.d.ts +0 -2
- package/lib/slide/layouts/big_quote.js +0 -19
- package/lib/slide/layouts/columns.d.ts +0 -2
- package/lib/slide/layouts/columns.js +0 -53
- package/lib/slide/layouts/comparison.d.ts +0 -2
- package/lib/slide/layouts/comparison.js +0 -25
- package/lib/slide/layouts/funnel.d.ts +0 -2
- package/lib/slide/layouts/funnel.js +0 -25
- package/lib/slide/layouts/grid.d.ts +0 -2
- package/lib/slide/layouts/grid.js +0 -38
- package/lib/slide/layouts/index.d.ts +0 -3
- package/lib/slide/layouts/index.js +0 -46
- package/lib/slide/layouts/matrix.d.ts +0 -2
- package/lib/slide/layouts/matrix.js +0 -53
- package/lib/slide/layouts/split.d.ts +0 -2
- package/lib/slide/layouts/split.js +0 -51
- package/lib/slide/layouts/stats.d.ts +0 -2
- package/lib/slide/layouts/stats.js +0 -23
- package/lib/slide/layouts/table.d.ts +0 -2
- package/lib/slide/layouts/table.js +0 -10
- package/lib/slide/layouts/timeline.d.ts +0 -2
- package/lib/slide/layouts/timeline.js +0 -27
- package/lib/slide/layouts/title.d.ts +0 -2
- package/lib/slide/layouts/title.js +0 -19
- package/lib/slide/layouts/waterfall.d.ts +0 -2
- package/lib/slide/layouts/waterfall.js +0 -63
- package/lib/slide/render.d.ts +0 -17
- package/lib/slide/render.js +0 -101
- package/lib/slide/schema.d.ts +0 -9309
- package/lib/slide/schema.js +0 -434
- package/lib/slide/utils.d.ts +0 -76
- package/lib/slide/utils.js +0 -243
- package/lib/types/slide.d.ts +0 -9309
- package/lib/types/slide.js +0 -434
- package/lib/utils/browser_pool.d.ts +0 -5
- package/lib/utils/browser_pool.js +0 -39
- package/lib/utils/markdown.d.ts +0 -3
- package/lib/utils/markdown.js +0 -49
package/lib/actions/index.d.ts
CHANGED
package/lib/actions/index.js
CHANGED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { localizedText } from "../utils/utils.js";
|
|
4
|
+
import { writingMessage } from "../utils/file.js";
|
|
5
|
+
import { MulmoStudioContextMethods } from "../methods/mulmo_studio_context.js";
|
|
6
|
+
import { escapeHtml } from "@mulmocast/deck";
|
|
7
|
+
const imageMimeTypes = {
|
|
8
|
+
png: "image/png",
|
|
9
|
+
jpg: "image/jpeg",
|
|
10
|
+
jpeg: "image/jpeg",
|
|
11
|
+
gif: "image/gif",
|
|
12
|
+
webp: "image/webp",
|
|
13
|
+
svg: "image/svg+xml",
|
|
14
|
+
};
|
|
15
|
+
const imageToDataUri = (filePath) => {
|
|
16
|
+
if (!fs.existsSync(filePath)) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
const ext = path.extname(filePath).slice(1).toLowerCase();
|
|
20
|
+
const mime = imageMimeTypes[ext] ?? "image/png";
|
|
21
|
+
const base64 = fs.readFileSync(filePath).toString("base64");
|
|
22
|
+
return `data:${mime};base64,${base64}`;
|
|
23
|
+
};
|
|
24
|
+
const collectSlides = (context) => {
|
|
25
|
+
const { studio, multiLingual, lang = "en" } = context;
|
|
26
|
+
const slides = [];
|
|
27
|
+
studio.script.beats.forEach((beat, index) => {
|
|
28
|
+
const studioBeat = studio.beats[index];
|
|
29
|
+
// Prefer the HTML-rendered frame over the source image, matching pdf.ts / movie.ts.
|
|
30
|
+
const source = studioBeat?.htmlImageFile ?? studioBeat?.imageFile;
|
|
31
|
+
if (!source)
|
|
32
|
+
return;
|
|
33
|
+
const dataUri = imageToDataUri(source);
|
|
34
|
+
if (!dataUri)
|
|
35
|
+
return;
|
|
36
|
+
slides.push({
|
|
37
|
+
dataUri,
|
|
38
|
+
caption: localizedText(beat, multiLingual?.[index], lang),
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
return slides;
|
|
42
|
+
};
|
|
43
|
+
const viewerStyles = `
|
|
44
|
+
html, body { margin: 0; padding: 0; height: 100vh; overflow: hidden; background: #000; }
|
|
45
|
+
#deck { position: relative; width: 100vw; height: 100vh; }
|
|
46
|
+
section.slide {
|
|
47
|
+
position: absolute;
|
|
48
|
+
inset: 0;
|
|
49
|
+
display: flex;
|
|
50
|
+
flex-direction: column;
|
|
51
|
+
align-items: center;
|
|
52
|
+
justify-content: center;
|
|
53
|
+
visibility: hidden;
|
|
54
|
+
padding: 24px;
|
|
55
|
+
box-sizing: border-box;
|
|
56
|
+
}
|
|
57
|
+
section.slide.active { visibility: visible; }
|
|
58
|
+
section.slide img {
|
|
59
|
+
max-width: 100%;
|
|
60
|
+
max-height: 80vh;
|
|
61
|
+
object-fit: contain;
|
|
62
|
+
user-select: none;
|
|
63
|
+
}
|
|
64
|
+
section.slide p.caption {
|
|
65
|
+
color: #eee;
|
|
66
|
+
margin-top: 16px;
|
|
67
|
+
text-align: center;
|
|
68
|
+
font-family: system-ui, -apple-system, sans-serif;
|
|
69
|
+
max-width: 80ch;
|
|
70
|
+
max-height: 15vh;
|
|
71
|
+
overflow: hidden;
|
|
72
|
+
}
|
|
73
|
+
#counter {
|
|
74
|
+
position: fixed;
|
|
75
|
+
right: 16px;
|
|
76
|
+
bottom: 12px;
|
|
77
|
+
color: #aaa;
|
|
78
|
+
font-family: system-ui, -apple-system, sans-serif;
|
|
79
|
+
font-size: 14px;
|
|
80
|
+
user-select: none;
|
|
81
|
+
pointer-events: none;
|
|
82
|
+
}
|
|
83
|
+
`;
|
|
84
|
+
const viewerScript = `
|
|
85
|
+
(function () {
|
|
86
|
+
const slides = document.querySelectorAll("section.slide");
|
|
87
|
+
const counter = document.getElementById("counter");
|
|
88
|
+
if (slides.length === 0) return;
|
|
89
|
+
let current = 0;
|
|
90
|
+
const show = (i) => {
|
|
91
|
+
slides[current].classList.remove("active");
|
|
92
|
+
current = Math.max(0, Math.min(slides.length - 1, i));
|
|
93
|
+
slides[current].classList.add("active");
|
|
94
|
+
counter.textContent = (current + 1) + " / " + slides.length;
|
|
95
|
+
};
|
|
96
|
+
document.addEventListener("keydown", (e) => {
|
|
97
|
+
if (e.key === "ArrowRight" || e.key === " " || e.key === "PageDown") {
|
|
98
|
+
e.preventDefault();
|
|
99
|
+
show(current + 1);
|
|
100
|
+
} else if (e.key === "ArrowLeft" || e.key === "PageUp") {
|
|
101
|
+
e.preventDefault();
|
|
102
|
+
show(current - 1);
|
|
103
|
+
} else if (e.key === "Home") {
|
|
104
|
+
e.preventDefault();
|
|
105
|
+
show(0);
|
|
106
|
+
} else if (e.key === "End") {
|
|
107
|
+
e.preventDefault();
|
|
108
|
+
show(slides.length - 1);
|
|
109
|
+
} else if (e.key === "f" || e.key === "F") {
|
|
110
|
+
if (!document.fullscreenElement) {
|
|
111
|
+
document.documentElement.requestFullscreen && document.documentElement.requestFullscreen();
|
|
112
|
+
} else {
|
|
113
|
+
document.exitFullscreen && document.exitFullscreen();
|
|
114
|
+
}
|
|
115
|
+
} else if (e.key === "Escape") {
|
|
116
|
+
document.exitFullscreen && document.exitFullscreen();
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
document.addEventListener("click", () => show(current + 1));
|
|
120
|
+
show(0);
|
|
121
|
+
})();
|
|
122
|
+
`;
|
|
123
|
+
const generateViewerHtml = (context) => {
|
|
124
|
+
const title = context.studio.script.title || "MulmoCast Viewer";
|
|
125
|
+
const slides = collectSlides(context);
|
|
126
|
+
const slidesHtml = slides
|
|
127
|
+
.map((s, i) => {
|
|
128
|
+
const captionHtml = s.caption.trim() ? `<p class="caption">${escapeHtml(s.caption)}</p>` : "";
|
|
129
|
+
const cls = i === 0 ? "slide active" : "slide";
|
|
130
|
+
return ` <section class="${cls}"><img src="${s.dataUri}" alt="Slide ${i + 1}" />${captionHtml}</section>`;
|
|
131
|
+
})
|
|
132
|
+
.join("\n");
|
|
133
|
+
return `<!doctype html>
|
|
134
|
+
<html lang="en">
|
|
135
|
+
<head>
|
|
136
|
+
<meta charset="UTF-8" />
|
|
137
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
138
|
+
<title>${escapeHtml(title)}</title>
|
|
139
|
+
<style>${viewerStyles}</style>
|
|
140
|
+
</head>
|
|
141
|
+
<body>
|
|
142
|
+
<div id="deck">
|
|
143
|
+
${slidesHtml}
|
|
144
|
+
</div>
|
|
145
|
+
<div id="counter"></div>
|
|
146
|
+
<script>${viewerScript}</script>
|
|
147
|
+
</body>
|
|
148
|
+
</html>
|
|
149
|
+
`;
|
|
150
|
+
};
|
|
151
|
+
export const viewerFilePath = (context) => {
|
|
152
|
+
const { studio, fileDirs, lang = "en" } = context;
|
|
153
|
+
const langSuffix = studio.script.lang !== lang ? `_${lang}` : "";
|
|
154
|
+
const filename = `${studio.filename}${langSuffix}_viewer.html`;
|
|
155
|
+
return path.join(fileDirs.outDirPath, filename);
|
|
156
|
+
};
|
|
157
|
+
const generateViewer = (context) => {
|
|
158
|
+
const outputPath = viewerFilePath(context);
|
|
159
|
+
const htmlContent = generateViewerHtml(context);
|
|
160
|
+
fs.writeFileSync(outputPath, htmlContent, "utf8");
|
|
161
|
+
writingMessage(outputPath);
|
|
162
|
+
};
|
|
163
|
+
export const viewer = async (context) => {
|
|
164
|
+
try {
|
|
165
|
+
MulmoStudioContextMethods.setSessionState(context, "viewer", true);
|
|
166
|
+
generateViewer(context);
|
|
167
|
+
MulmoStudioContextMethods.setSessionState(context, "viewer", false, true);
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
MulmoStudioContextMethods.setSessionState(context, "viewer", false, false);
|
|
171
|
+
throw error;
|
|
172
|
+
}
|
|
173
|
+
};
|
package/lib/cli/bin.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Argv } from "yargs";
|
|
2
|
+
export declare const builder: (yargs: Argv) => Argv<{
|
|
3
|
+
o: string | undefined;
|
|
4
|
+
} & {
|
|
5
|
+
b: string | undefined;
|
|
6
|
+
} & {
|
|
7
|
+
l: string | undefined;
|
|
8
|
+
} & {
|
|
9
|
+
f: boolean;
|
|
10
|
+
} & {
|
|
11
|
+
g: boolean;
|
|
12
|
+
} & {
|
|
13
|
+
backup: boolean;
|
|
14
|
+
} & {
|
|
15
|
+
p: string | undefined;
|
|
16
|
+
} & {
|
|
17
|
+
file: string | undefined;
|
|
18
|
+
} & {
|
|
19
|
+
i: string | undefined;
|
|
20
|
+
}>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { images, viewer } from "../../../actions/index.js";
|
|
2
|
+
import { initializeContext, runTranslateIfNeeded } from "../../helpers.js";
|
|
3
|
+
export const handler = async (argv) => {
|
|
4
|
+
const context = await initializeContext(argv);
|
|
5
|
+
if (!context) {
|
|
6
|
+
process.exit(1);
|
|
7
|
+
}
|
|
8
|
+
await runTranslateIfNeeded(context);
|
|
9
|
+
await images(context);
|
|
10
|
+
await viewer(context);
|
|
11
|
+
};
|
package/lib/cli/main.js
CHANGED
|
@@ -12,6 +12,7 @@ import * as pdfCmd from "./commands/pdf/index.js";
|
|
|
12
12
|
import * as markdownCmd from "./commands/markdown/index.js";
|
|
13
13
|
import * as bundleCmd from "./commands/bundle/index.js";
|
|
14
14
|
import * as htmlCmd from "./commands/html/index.js";
|
|
15
|
+
import * as viewerCmd from "./commands/viewer/index.js";
|
|
15
16
|
import * as toolCmd from "./commands/tool/index.js";
|
|
16
17
|
import { GraphAILogger } from "graphai";
|
|
17
18
|
dotenv.config({ quiet: true });
|
|
@@ -42,6 +43,7 @@ export const cliMain = async () => {
|
|
|
42
43
|
.command(markdownCmd)
|
|
43
44
|
.command(bundleCmd)
|
|
44
45
|
.command(htmlCmd)
|
|
46
|
+
.command(viewerCmd)
|
|
45
47
|
.command(toolCmd)
|
|
46
48
|
.demandCommand()
|
|
47
49
|
.strict()
|
package/lib/mcp/server.js
CHANGED
|
File without changes
|