@gui-chat-plugin/sequence 0.3.1 → 0.4.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/CHANGELOG.md +15 -0
- package/README.md +12 -5
- package/dist/core/index.d.ts +1 -1
- package/dist/core/slideHtml.d.ts +17 -5
- package/dist/{core-BJ7q9fgr.js → core-D3XJ6n_I.js} +134 -136
- package/dist/core-OZRdlavD.cjs +145 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +2 -2
- package/dist/style.css +1 -1
- package/dist/vue.cjs +1 -1
- package/dist/vue.js +45 -45
- package/package.json +1 -1
- package/dist/core-CPlicVIg.cjs +0 -46
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
import { createSerialLock as e } from "gui-chat-protocol";
|
|
2
2
|
//#region src/core/slideHtml.ts
|
|
3
3
|
var t = 1280, n = 720, r = 6e4, i = "https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.3.3/dist/index.global.js", a = "sha384-2ql948lIdLcGEE0/qxNiudyTjgauA3RDJERu5xW75kFCvSl5a9odyQYCb6tEjnmB", o = [
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
"slide-in-right",
|
|
9
|
-
"zoom-in",
|
|
10
|
-
"pop",
|
|
11
|
-
"draw"
|
|
12
|
-
], s = "\n@theme {\n --animate-fade-in: fade-in 0.8s ease-out both;\n --animate-fade-up: fade-up 0.8s ease-out both;\n --animate-fade-down: fade-down 0.8s ease-out both;\n --animate-slide-in-left: slide-in-left 0.8s ease-out both;\n --animate-slide-in-right: slide-in-right 0.8s ease-out both;\n --animate-zoom-in: zoom-in 0.8s ease-out both;\n --animate-pop: pop 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) both;\n --animate-draw: draw 1.5s ease-in-out both;\n @keyframes fade-in { from { opacity: 0 } to { opacity: 1 } }\n @keyframes fade-up { from { opacity: 0; transform: translateY(40px) } to { opacity: 1; transform: none } }\n @keyframes fade-down { from { opacity: 0; transform: translateY(-40px) } to { opacity: 1; transform: none } }\n @keyframes slide-in-left { from { opacity: 0; transform: translateX(-80px) } to { opacity: 1; transform: none } }\n @keyframes slide-in-right { from { opacity: 0; transform: translateX(80px) } to { opacity: 1; transform: none } }\n @keyframes zoom-in { from { opacity: 0; transform: scale(0.8) } to { opacity: 1; transform: none } }\n @keyframes pop { from { opacity: 0; transform: scale(0.5) } to { opacity: 1; transform: none } }\n @keyframes draw { from { stroke-dashoffset: var(--draw-length, 1000) } to { stroke-dashoffset: 0 } }\n}", c = "\n(() => {\n const show = () => document.documentElement.classList.add(\"ready\");\n const ready = () => requestAnimationFrame(() => requestAnimationFrame(show));\n const check = () =>\n document.querySelector(\"style:not([type]):not(#slide-base)\") ? ready() : setTimeout(check, 30);\n addEventListener(\"DOMContentLoaded\", check);\n setTimeout(show, 1000);\n addEventListener(\"click\", (event) => {\n if (event.target instanceof Element && event.target.closest(\"a, area\")) event.preventDefault();\n }, true);\n})();", l = [
|
|
4
|
+
"animate",
|
|
5
|
+
"counter",
|
|
6
|
+
"typewriter"
|
|
7
|
+
], s = 8, c = "\n(() => {\n const EASE = {\n linear: (t) => t,\n easeIn: (t) => t * t,\n easeOut: (t) => 1 - (1 - t) * (1 - t),\n easeInOut: (t) => (t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2),\n };\n const AUTO_END = 8;\n const TRANSFORMS = [\n [\"data-translate-x\", \"translateX\", \"px\"],\n [\"data-translate-y\", \"translateY\", \"px\"],\n [\"data-scale\", \"scale\", \"\"],\n [\"data-rotate\", \"rotate\", \"deg\"],\n [\"data-rotate-x\", \"rotateX\", \"deg\"],\n [\"data-rotate-y\", \"rotateY\", \"deg\"],\n [\"data-rotate-z\", \"rotateZ\", \"deg\"],\n ];\n const STYLES = [\n [\"data-opacity\", \"opacity\", \"\"],\n [\"data-width\", \"width\", \"px\"],\n [\"data-height\", \"height\", \"px\"],\n ];\n const number = (value, fallback) => {\n const n = Number(value);\n return value !== null && value.trim() !== \"\" && Number.isFinite(n) ? n : fallback;\n };\n const range = (value, unit) => {\n if (value === null) return null;\n const parts = value.split(\",\").map((part) => part.trim());\n const from = Number(parts[0]);\n const to = Number(parts[1]);\n if (!Number.isFinite(from) || !Number.isFinite(to)) return null;\n return { from, to, unit: parts[2] || unit };\n };\n const ranges = (el, table) =>\n table\n .map(([attr, name, unit]) => [name, range(el.getAttribute(attr), unit)])\n .filter(([, r]) => r);\n let entries = [];\n const collect = () => {\n entries = [...document.querySelectorAll(\"[data-animation]\")].map((el) => {\n const kind = el.getAttribute(\"data-animation\");\n const end = el.getAttribute(\"data-end\");\n const entry = {\n el,\n kind,\n start: number(el.getAttribute(\"data-start\"), 0),\n end: end === null || end.trim() === \"auto\" ? null : number(end, null),\n ease: EASE[el.getAttribute(\"data-easing\")] || EASE.linear,\n };\n if (kind === \"animate\") {\n entry.transforms = ranges(el, TRANSFORMS);\n entry.styles = ranges(el, STYLES);\n } else if (kind === \"counter\") {\n entry.from = number(el.getAttribute(\"data-from\"), 0);\n entry.to = number(el.getAttribute(\"data-to\"), 0);\n entry.decimals = Math.max(0, Math.round(number(el.getAttribute(\"data-decimals\"), 0)));\n entry.prefix = el.getAttribute(\"data-prefix\") || \"\";\n entry.suffix = el.getAttribute(\"data-suffix\") || \"\";\n } else if (kind === \"typewriter\") {\n entry.text = el.getAttribute(\"data-text\") ?? el.textContent;\n } else {\n return null;\n }\n return entry;\n }).filter(Boolean);\n };\n const seek = (t) => {\n for (const e of entries) {\n const end = e.end ?? AUTO_END;\n const span = end - e.start;\n const p = span > 0 ? Math.min(1, Math.max(0, (t - e.start) / span)) : t >= e.start ? 1 : 0;\n const k = e.ease(p);\n const at = (r) => r.from + (r.to - r.from) * k;\n if (e.kind === \"animate\") {\n if (e.transforms.length) {\n e.el.style.transform = e.transforms.map(([name, r]) => name + \"(\" + at(r) + r.unit + \")\").join(\" \");\n }\n for (const [name, r] of e.styles) e.el.style[name] = at(r) + r.unit;\n } else if (e.kind === \"counter\") {\n e.el.textContent = e.prefix + (e.from + (e.to - e.from) * k).toFixed(e.decimals) + e.suffix;\n } else {\n e.el.textContent = e.text.slice(0, Math.floor(e.text.length * k));\n }\n }\n };\n window.__slideSeek = seek;\n const play = () => {\n const last = Math.max(0, ...entries.map((e) => e.end ?? AUTO_END));\n const begun = performance.now();\n const tick = (now) => {\n const t = (now - begun) / 1000;\n seek(t);\n if (t <= last) requestAnimationFrame(tick);\n };\n requestAnimationFrame(tick);\n };\n // Collected once the body is parsed: at DOMContentLoaded, or earlier when\n // the fallback shows the slide while a slow Tailwind still holds\n // DOMContentLoaded back (the body is parsed by then: readyState is\n // \"interactive\" before deferred scripts run). Played once both are done.\n let collected = false;\n let shown = false;\n const init = () => {\n if (collected || document.readyState === \"loading\") return;\n collected = true;\n collect();\n seek(0);\n if (shown) play();\n };\n const show = () => {\n if (shown) return;\n init();\n shown = true;\n document.documentElement.classList.add(\"ready\");\n if (collected) play();\n };\n const ready = () => requestAnimationFrame(() => requestAnimationFrame(show));\n const check = () =>\n document.querySelector(\"style:not([type]):not(#slide-base)\") ? ready() : setTimeout(check, 30);\n addEventListener(\"DOMContentLoaded\", () => {\n init();\n check();\n });\n setTimeout(show, 1000);\n addEventListener(\"click\", (event) => {\n if (event.target instanceof Element && event.target.closest(\"a, area\")) event.preventDefault();\n }, true);\n})();", l = [
|
|
13
8
|
"default-src 'none'",
|
|
14
|
-
`script-src 'sha256-
|
|
9
|
+
`script-src 'sha256-0zsqCvkCfq5Z1iJCn46NiAtSAyIr/JDkyNs/Fae1J+Y=' ${i}`,
|
|
15
10
|
"style-src 'unsafe-inline' https://fonts.googleapis.com",
|
|
16
11
|
"font-src https://fonts.gstatic.com data:",
|
|
17
12
|
"img-src data: blob:",
|
|
@@ -19,20 +14,19 @@ var t = 1280, n = 720, r = 6e4, i = "https://cdn.jsdelivr.net/npm/@tailwindcss/b
|
|
|
19
14
|
"connect-src 'none'",
|
|
20
15
|
"form-action 'none'",
|
|
21
16
|
"base-uri 'none'"
|
|
22
|
-
].join("; "), u = (e) => e.replace(/<(?=(meta|base|link)\b)/gi, "<").replace(/shadowroot/gi, "data-no-shadow-root"), d = `
|
|
17
|
+
].join("; "), u = (e) => e.replace(/<(?=(meta|base|link)\b)/gi, "<").replace(/shadowroot/gi, "data-no-shadow-root"), d = "*, *::before, *::after { animation-play-state: paused !important; animation-duration: 0s !important; animation-delay: 0s !important; animation-iteration-count: 1 !important; animation-fill-mode: both !important; transition: none !important; }", f = `
|
|
23
18
|
html, body { margin: 0; width: ${t}px; height: 720px; overflow: hidden; }
|
|
24
19
|
html:not(.ready) body { visibility: hidden; }
|
|
25
|
-
|
|
26
|
-
function
|
|
20
|
+
${d}`;
|
|
21
|
+
function p(e) {
|
|
27
22
|
return `<!doctype html>
|
|
28
23
|
<html lang="en">
|
|
29
24
|
<head>
|
|
30
25
|
<meta charset="utf-8">
|
|
31
26
|
<meta http-equiv="Content-Security-Policy" content="${l}">
|
|
32
|
-
<style id="slide-base">${
|
|
27
|
+
<style id="slide-base">${f}</style>
|
|
33
28
|
<script>${c}<\/script>
|
|
34
29
|
<script defer src="${i}" integrity="${a}" crossorigin="anonymous"><\/script>
|
|
35
|
-
<style type="text/tailwindcss">${s}</style>
|
|
36
30
|
</head>
|
|
37
31
|
<body class="bg-white text-slate-900 font-sans antialiased">
|
|
38
32
|
${u(e)}
|
|
@@ -41,10 +35,10 @@ ${u(e)}
|
|
|
41
35
|
}
|
|
42
36
|
//#endregion
|
|
43
37
|
//#region src/core/definitions.ts
|
|
44
|
-
var
|
|
45
|
-
function
|
|
46
|
-
let { slide: t, totalSlides: n, title: r, imagePrompt: i } = e, a =
|
|
47
|
-
return !
|
|
38
|
+
var m = "presentSlide", h = "defineStoryboard", g = "presentPanel", ee = 4, te = 12, ne = 3, _ = /^[0-9a-f]{12}$/, v = (e) => typeof e == "object" && !!e && !Array.isArray(e), y = (e) => typeof e == "string" ? e.trim() : "", b = (e, t) => e.toLowerCase() === t.toLowerCase(), x = (e) => typeof e == "number" && Number.isInteger(e), S = "presentSlide needs slide and totalSlides (whole numbers, slide from 1 to totalSlides), and either an imagePrompt or html", C = `presentSlide's html is too long: keep a slide under ${r} characters`;
|
|
39
|
+
function w(e) {
|
|
40
|
+
let { slide: t, totalSlides: n, title: r, imagePrompt: i } = e, a = y(e.html);
|
|
41
|
+
return !x(t) || !x(n) || t < 1 || n < t || !a && !y(i) ? S : a.length > 6e4 ? C : {
|
|
48
42
|
slide: t,
|
|
49
43
|
totalSlides: n,
|
|
50
44
|
title: typeof r == "string" ? r : "",
|
|
@@ -53,7 +47,7 @@ function ie(e) {
|
|
|
53
47
|
mode: e.mode === "steps" ? "steps" : "presentation"
|
|
54
48
|
};
|
|
55
49
|
}
|
|
56
|
-
var
|
|
50
|
+
var T = ({ slide: e, totalSlides: t, title: n, mode: r }) => {
|
|
57
51
|
let i = n ? ` ("${n}")` : "";
|
|
58
52
|
if (r === "steps") {
|
|
59
53
|
let n = `Step ${e} of ${t}${i}`;
|
|
@@ -61,10 +55,14 @@ var S = ({ slide: e, totalSlides: t, title: n, mode: r }) => {
|
|
|
61
55
|
}
|
|
62
56
|
let a = `Slide ${e} of ${t}${i}`;
|
|
63
57
|
return e < t ? `${a} is now on the screen. Explain it, then, in this same reply and without waiting for the user, call presentSlide for slide ${e + 1}. If the user has asked you to stop, or asked something else, since the slideshow began, answer them instead of going on.` : `${a}, the last one, is now on the screen. Explain it, then wrap up the slideshow.`;
|
|
64
|
-
},
|
|
58
|
+
}, re = [
|
|
59
|
+
`For an HTML slide, instead of imagePrompt: the slide's content, the inside of <body> only (no <html>, <head> or <body> tags), for a ${t}x720 px canvas, which it should fill (start with a <div class="w-full h-full ...">). Style it with Tailwind CSS v4 classes, which are loaded for you: a clear layout, a large title (text-6xl or so), few words in large type, a color scheme, and inline SVG or emoji for icons and diagrams. There is no network: no <img> from URLs, no links to follow.`,
|
|
60
|
+
"Animate it so it builds up as you explain it, with MulmoCast's data-animation attributes (the same ones make it move in a movie of the slideshow): data-animation=\"animate\" with data-opacity=\"0,1\", data-translate-x, data-translate-y (px), data-scale, data-rotate (deg), data-width or data-height (\"0,80,%\"), each \"from,to\"; data-animation=\"counter\" with data-from, data-to, data-decimals, data-prefix, data-suffix; data-animation=\"typewriter\" (its text, or data-text). Give every one data-start and data-end in seconds, and optionally data-easing (linear, easeIn, easeOut, easeInOut); stagger the parts with later data-start values so they appear one after another over a few seconds (for example 0, 0.6, 1.2). Set the first frame inline too (style=\"opacity:0\" on an element that fades in).",
|
|
61
|
+
"CSS animations, transitions and scripts don't play: animate only with data-animation. A <style> for layout is allowed (and Google Fonts by @import)."
|
|
62
|
+
].join(" "), ie = "When the user asks for a slideshow (or to explain something with slides), plan four to six slides, then show them one at a time with presentSlide: slide 1 first, and each next slide only after you have explained the one on the screen. Go on to the last slide without asking whether to continue. A slide is a generated picture (imagePrompt) or a designed slide in HTML (html): use a picture for a scene, an object or a place, and HTML for words, numbers, lists, comparisons, timelines and diagrams, which a picture model draws badly; a slideshow can mix them. When the user asks for HTML slides (slides in HTML, an HTML presentation), this is the tool: make them HTML slides with presentSlide, one call per slide, not one HTML page. When the user wants to be shown how to do something they will do along with you (cooking, folding, fixing, an exercise), make it a step-by-step guide instead: mode \"steps\", one slide per step, and after each step wait for the user to say they are ready. Use generateImage for a single picture, not for slides.", E = {
|
|
65
63
|
type: "function",
|
|
66
|
-
name:
|
|
67
|
-
prompt:
|
|
64
|
+
name: m,
|
|
65
|
+
prompt: ie,
|
|
68
66
|
description: "Show one slide of a slideshow, full screen: a picture generated from imagePrompt, or a slide written in HTML (html). Call it once per slide, in order, starting with slide 1. With mode \"steps\" it is a step-by-step guide: one slide per step, and the next step waits for the user.",
|
|
69
67
|
parameters: {
|
|
70
68
|
type: "object",
|
|
@@ -87,7 +85,7 @@ var S = ({ slide: e, totalSlides: t, title: n, mode: r }) => {
|
|
|
87
85
|
},
|
|
88
86
|
html: {
|
|
89
87
|
type: "string",
|
|
90
|
-
description:
|
|
88
|
+
description: re
|
|
91
89
|
},
|
|
92
90
|
mode: {
|
|
93
91
|
type: "string",
|
|
@@ -102,49 +100,49 @@ var S = ({ slide: e, totalSlides: t, title: n, mode: r }) => {
|
|
|
102
100
|
]
|
|
103
101
|
}
|
|
104
102
|
};
|
|
105
|
-
function
|
|
103
|
+
function D(e) {
|
|
106
104
|
let { totalPanels: t } = e;
|
|
107
|
-
if (!
|
|
105
|
+
if (!x(t) || t < 1 || t > 12) return "totalPanels must be a whole number from 1 to 12";
|
|
108
106
|
let n = [];
|
|
109
107
|
for (let t of Array.isArray(e.characters) ? e.characters : []) {
|
|
110
|
-
let e =
|
|
108
|
+
let e = v(t) ? y(t.name) : "", r = v(t) ? y(t.description) : "";
|
|
111
109
|
if (!e || !r) return "every character needs a name and a description";
|
|
112
|
-
if (n.some((t) =>
|
|
110
|
+
if (n.some((t) => b(t.name, e))) return `two characters are named ${e}`;
|
|
113
111
|
n.push({
|
|
114
112
|
name: e,
|
|
115
113
|
description: r
|
|
116
114
|
});
|
|
117
115
|
}
|
|
118
116
|
return n.length < 1 || n.length > 4 ? "a storyboard has 1 to 4 characters" : {
|
|
119
|
-
title:
|
|
120
|
-
style:
|
|
117
|
+
title: y(e.title),
|
|
118
|
+
style: y(e.style),
|
|
121
119
|
totalPanels: t,
|
|
122
120
|
characters: n,
|
|
123
121
|
interactive: e.interactive === !0
|
|
124
122
|
};
|
|
125
123
|
}
|
|
126
|
-
var
|
|
127
|
-
function
|
|
128
|
-
let { panel: t } = e, n =
|
|
129
|
-
if (!n || !r || !
|
|
130
|
-
let i = (e) => (Array.isArray(e) ? e : []).map(
|
|
124
|
+
var O = ({ title: e, id: t }) => `The cast of "${e}" is now on the screen. Introduce the characters briefly, then, in this same reply and without waiting for the user, call presentPanel for panel 1 with storyboardId "${t}". If the user has asked you to stop, or asked something else, answer them instead of going on.`, k = "presentPanel needs a storyboardId, a panel number (from 1) and an imagePrompt";
|
|
125
|
+
function A(e) {
|
|
126
|
+
let { panel: t } = e, n = y(e.storyboardId), r = y(e.imagePrompt);
|
|
127
|
+
if (!n || !r || !x(t) || t < 1) return null;
|
|
128
|
+
let i = (e) => (Array.isArray(e) ? e : []).map(y).filter(Boolean);
|
|
131
129
|
return {
|
|
132
130
|
storyboardId: n,
|
|
133
131
|
panel: t,
|
|
134
132
|
characters: i(e.characters),
|
|
135
133
|
imagePrompt: r,
|
|
136
|
-
caption:
|
|
134
|
+
caption: y(e.caption),
|
|
137
135
|
choices: i(e.choices).slice(0, 3)
|
|
138
136
|
};
|
|
139
137
|
}
|
|
140
|
-
function
|
|
138
|
+
function j(e, t, n) {
|
|
141
139
|
let { id: r, totalPanels: i } = e;
|
|
142
140
|
return n.length ? `Panel ${t} of ${i} is now on the screen, with the user's choices: ${n.map((e, t) => `${t + 1}. ${e}`).join(" ")} Tell this part of the story, then read the choices out and ask the user which one they pick, and wait for their answer. Then call presentPanel for panel ${t + 1} with storyboardId "${r}", going on the way they chose.` : t < i ? `Panel ${t} of ${i} is now on the screen. Tell this part of the story, then, in this same reply and without waiting for the user, call presentPanel for panel ${t + 1} with storyboardId "${r}". If the user has asked you to stop, or asked something else, since the story began, answer them instead of going on.` : `Panel ${t} of ${i}, the last one, is now on the screen. Tell this part of the story, then bring it to an end.`;
|
|
143
141
|
}
|
|
144
|
-
var
|
|
142
|
+
var M = "When the user asks for a story, a picture book, a comic or a storyboard, tell it in pictures: first call defineStoryboard with the art style and the characters who appear more than once (it draws a reference sheet for each, so they look the same in every panel), then show the panels one at a time with presentPanel, naming the characters in each, and tell each part of the story when its panel appears. Go on to the last panel without asking whether to continue, unless the story is interactive. When the user wants to decide what happens (an adventure, a story for a child who wants to choose), set interactive, and give two or three choices on two or three of the panels: the story waits there for the user's pick and goes on their way; it still ends at the last panel whichever way it goes. Use presentSlide to explain a topic, not to tell a story.", N = {
|
|
145
143
|
type: "function",
|
|
146
|
-
name:
|
|
147
|
-
prompt:
|
|
144
|
+
name: h,
|
|
145
|
+
prompt: M,
|
|
148
146
|
description: "Start a story told in pictures: set its art style and draw a reference sheet for each recurring character, shown as the cast. Then call presentPanel for each panel, in order.",
|
|
149
147
|
parameters: {
|
|
150
148
|
type: "object",
|
|
@@ -191,9 +189,9 @@ var A = "When the user asks for a story, a picture book, a comic or a storyboard
|
|
|
191
189
|
"characters"
|
|
192
190
|
]
|
|
193
191
|
}
|
|
194
|
-
},
|
|
192
|
+
}, P = {
|
|
195
193
|
type: "function",
|
|
196
|
-
name:
|
|
194
|
+
name: g,
|
|
197
195
|
description: "Show one panel of a storyboard made with defineStoryboard: a picture of the scene with its characters drawn as in their reference sheets, and a caption. Call it once per panel, in order, starting with panel 1.",
|
|
198
196
|
parameters: {
|
|
199
197
|
type: "object",
|
|
@@ -232,54 +230,54 @@ var A = "When the user asks for a story, a picture book, a comic or a storyboard
|
|
|
232
230
|
"imagePrompt"
|
|
233
231
|
]
|
|
234
232
|
}
|
|
235
|
-
},
|
|
236
|
-
function
|
|
237
|
-
let t =
|
|
233
|
+
}, F = (e) => typeof e == "object" && !!e && !Array.isArray(e), ae = (e) => F(e) && typeof e.message == "string";
|
|
234
|
+
function I(e) {
|
|
235
|
+
let t = F(e?.data) ? e.data : {};
|
|
238
236
|
return {
|
|
239
237
|
...typeof t.imageData == "string" && { imageData: t.imageData },
|
|
240
238
|
...typeof t.imagePath == "string" && { imagePath: t.imagePath }
|
|
241
239
|
};
|
|
242
240
|
}
|
|
243
|
-
function
|
|
244
|
-
let t =
|
|
241
|
+
function L(e) {
|
|
242
|
+
let t = F(e?.data) ? e.data : {};
|
|
245
243
|
return typeof t.html == "string" ? t.html : "";
|
|
246
244
|
}
|
|
247
|
-
var
|
|
248
|
-
function
|
|
249
|
-
let n =
|
|
245
|
+
var oe = (e) => !!I(e).imageData || !!L(e);
|
|
246
|
+
function se(e, t) {
|
|
247
|
+
let n = I(e), r = I(t);
|
|
250
248
|
if (n.imagePath && r.imagePath) return n.imagePath === r.imagePath;
|
|
251
249
|
if (n.imageData) return n.imageData === r.imageData;
|
|
252
|
-
let i =
|
|
253
|
-
return !!i && i ===
|
|
250
|
+
let i = L(e);
|
|
251
|
+
return !!i && i === L(t);
|
|
254
252
|
}
|
|
255
|
-
var
|
|
256
|
-
async function
|
|
253
|
+
var R = (e, t) => e.userSpokeAt === void 0 || e.userSpokeAt > t, z = () => crypto.randomUUID().replace(/-/g, "").slice(0, 12), ce = "artifacts/";
|
|
254
|
+
async function B(e, t) {
|
|
257
255
|
let n = e.files?.artifacts;
|
|
258
256
|
if (!e.app?.editImages || !n) return [];
|
|
259
257
|
let r = [];
|
|
260
|
-
for (let e of t) if (e.startsWith(
|
|
258
|
+
for (let e of t) if (e.startsWith(ce)) try {
|
|
261
259
|
await n.exists(e.slice(10)) && r.push(e);
|
|
262
260
|
} catch {}
|
|
263
261
|
return r;
|
|
264
262
|
}
|
|
265
|
-
async function
|
|
263
|
+
async function V(e, t, n = []) {
|
|
266
264
|
let r = e.app, i = r?.editImages, a = r?.generateImage;
|
|
267
265
|
try {
|
|
268
266
|
let e;
|
|
269
267
|
if (n.length && i) e = await i(t, [...n]);
|
|
270
268
|
else if (a) e = await a(t);
|
|
271
269
|
else return { message: "image generation isn't available" };
|
|
272
|
-
return
|
|
270
|
+
return ae(e) ? e : { message: "image generation returned an unrecognized result" };
|
|
273
271
|
} catch (e) {
|
|
274
272
|
return { message: `image generation failed: ${e instanceof Error ? e.message : String(e)}` };
|
|
275
273
|
}
|
|
276
274
|
}
|
|
277
|
-
var
|
|
278
|
-
function
|
|
275
|
+
var le = 50;
|
|
276
|
+
function ue(e) {
|
|
279
277
|
let t = /* @__PURE__ */ new Map();
|
|
280
278
|
return (n) => {
|
|
281
279
|
let r = n.conversationId ?? "", i = t.get(r);
|
|
282
|
-
if (i === void 0 ? i = e() : t.delete(r), t.set(r, i), t.size >
|
|
280
|
+
if (i === void 0 ? i = e() : t.delete(r), t.set(r, i), t.size > le) {
|
|
283
281
|
let e = t.keys().next().value;
|
|
284
282
|
e !== void 0 && t.delete(e);
|
|
285
283
|
}
|
|
@@ -288,20 +286,20 @@ function B(e) {
|
|
|
288
286
|
}
|
|
289
287
|
//#endregion
|
|
290
288
|
//#region src/core/records.ts
|
|
291
|
-
var
|
|
292
|
-
function
|
|
293
|
-
let t =
|
|
294
|
-
return t ||
|
|
289
|
+
var H = "slideshows", U = "storyboards", W = {}, G = /* @__PURE__ */ new WeakMap(), K = /* @__PURE__ */ new WeakMap();
|
|
290
|
+
function q(e) {
|
|
291
|
+
let t = G.get(e);
|
|
292
|
+
return t || G.set(e, t = /* @__PURE__ */ new Map()), t;
|
|
295
293
|
}
|
|
296
294
|
function de(t, n) {
|
|
297
|
-
let r =
|
|
298
|
-
r ||
|
|
295
|
+
let r = K.get(t);
|
|
296
|
+
r || K.set(t, r = /* @__PURE__ */ new Map());
|
|
299
297
|
let i = r.get(n);
|
|
300
298
|
return i || r.set(n, i = e()), i;
|
|
301
299
|
}
|
|
302
|
-
var
|
|
303
|
-
async function
|
|
304
|
-
let n =
|
|
300
|
+
var J = (e, t) => `${e}/${t}.json`;
|
|
301
|
+
async function Y(e, t) {
|
|
302
|
+
let n = q(e ?? W), r = n.get(t);
|
|
305
303
|
if (r) return r;
|
|
306
304
|
if (!e) return null;
|
|
307
305
|
try {
|
|
@@ -311,14 +309,14 @@ async function J(e, t) {
|
|
|
311
309
|
return null;
|
|
312
310
|
}
|
|
313
311
|
}
|
|
314
|
-
async function
|
|
315
|
-
return
|
|
312
|
+
async function X(e, t, n) {
|
|
313
|
+
return _.test(n) ? Y(e, J(t, n)) : null;
|
|
316
314
|
}
|
|
317
|
-
async function
|
|
318
|
-
let i =
|
|
315
|
+
async function Z(e, t, n, r) {
|
|
316
|
+
let i = J(t, n), a = e ?? W;
|
|
319
317
|
return de(a, i)(async () => {
|
|
320
|
-
let t = r(await
|
|
321
|
-
if (
|
|
318
|
+
let t = r(await Y(e, i));
|
|
319
|
+
if (q(a).set(i, t), !e) return !1;
|
|
322
320
|
try {
|
|
323
321
|
return await e.write(i, JSON.stringify(t, null, 2)), !0;
|
|
324
322
|
} catch (e) {
|
|
@@ -326,8 +324,8 @@ async function X(e, t, n, r) {
|
|
|
326
324
|
}
|
|
327
325
|
});
|
|
328
326
|
}
|
|
329
|
-
var
|
|
330
|
-
function
|
|
327
|
+
var Q = (e) => `the ${e} could not be saved, so it lasts only until the app or server restarts`, fe = 6e4;
|
|
328
|
+
function $() {
|
|
331
329
|
let e = /* @__PURE__ */ new Map();
|
|
332
330
|
return { claim: (t) => {
|
|
333
331
|
let n = Date.now();
|
|
@@ -345,7 +343,7 @@ function pe() {
|
|
|
345
343
|
}
|
|
346
344
|
//#endregion
|
|
347
345
|
//#region src/core/presentSlide.ts
|
|
348
|
-
function
|
|
346
|
+
function pe({ slide: e, totalSlides: t, mode: n }) {
|
|
349
347
|
return n === "steps" ? {
|
|
350
348
|
step: e,
|
|
351
349
|
total: t,
|
|
@@ -363,26 +361,26 @@ function me({ slide: e, totalSlides: t, mode: n }) {
|
|
|
363
361
|
nextCall: `call presentSlide for slide ${e + 1} of ${t}`
|
|
364
362
|
};
|
|
365
363
|
}
|
|
366
|
-
var
|
|
364
|
+
var me = (e, { slide: t, totalSlides: n, title: r, imagePrompt: i, html: a }) => JSON.stringify([
|
|
367
365
|
e,
|
|
368
366
|
t,
|
|
369
367
|
n,
|
|
370
368
|
r,
|
|
371
369
|
i,
|
|
372
370
|
a
|
|
373
|
-
]),
|
|
371
|
+
]), he = ue(() => ({
|
|
374
372
|
latest: {
|
|
375
373
|
presentation: null,
|
|
376
374
|
steps: null
|
|
377
375
|
},
|
|
378
376
|
lastShown: null,
|
|
379
|
-
repeats:
|
|
377
|
+
repeats: $()
|
|
380
378
|
}));
|
|
381
|
-
function
|
|
379
|
+
function ge(e, t) {
|
|
382
380
|
let n = e.latest[t.mode], r = n?.totalSlides === t.totalSlides && (t.slide !== 1 || n.firstTitle === t.title);
|
|
383
381
|
if (n && r) return n;
|
|
384
382
|
let i = {
|
|
385
|
-
id:
|
|
383
|
+
id: z(),
|
|
386
384
|
mode: t.mode,
|
|
387
385
|
totalSlides: t.totalSlides,
|
|
388
386
|
firstTitle: t.slide === 1 ? t.title : "",
|
|
@@ -392,18 +390,18 @@ function _e(e, t) {
|
|
|
392
390
|
};
|
|
393
391
|
return e.latest[t.mode] = i, i;
|
|
394
392
|
}
|
|
395
|
-
function
|
|
393
|
+
function _e(e, t, n, r) {
|
|
396
394
|
t.current = n.slide, t.shownAt = Date.now(), e.lastShown = t;
|
|
397
395
|
let i = n.mode === "steps" ? "step" : "slide", { uuid: a, ...o } = r;
|
|
398
396
|
return {
|
|
399
397
|
...o,
|
|
400
398
|
message: `${i} ${n.slide} of ${n.totalSlides} is on the screen again, as it was`,
|
|
401
|
-
instructions:
|
|
399
|
+
instructions: T(n),
|
|
402
400
|
instructionsRequired: !0,
|
|
403
|
-
sequence:
|
|
401
|
+
sequence: pe(n)
|
|
404
402
|
};
|
|
405
403
|
}
|
|
406
|
-
function
|
|
404
|
+
function ve(e, t) {
|
|
407
405
|
if (e.mode !== "steps") return e.title ? `A presentation slide titled "${e.title}". ${e.imagePrompt}` : e.imagePrompt;
|
|
408
406
|
let n = e.title ? `, "${e.title}"` : "";
|
|
409
407
|
return [
|
|
@@ -412,12 +410,12 @@ function ye(e, t) {
|
|
|
412
410
|
"Show the action clearly, with little or no text."
|
|
413
411
|
].filter(Boolean).join(" ");
|
|
414
412
|
}
|
|
415
|
-
async function
|
|
413
|
+
async function ye(e, t, n) {
|
|
416
414
|
if (n.html) return {
|
|
417
415
|
html: n.html,
|
|
418
416
|
prompt: ""
|
|
419
417
|
};
|
|
420
|
-
let r = t.slides.get(n.slide - 1), i = n.mode === "steps" ?
|
|
418
|
+
let r = t.slides.get(n.slide - 1), i = n.mode === "steps" ? I(r).imagePath : void 0, a = i ? await B(e, [i]) : [], o = ve(n, a.length > 0), s = await V(e, o, a), { imageData: c, imagePath: l } = I(s);
|
|
421
419
|
return c ? {
|
|
422
420
|
imageData: c,
|
|
423
421
|
...l && { imagePath: l },
|
|
@@ -427,10 +425,10 @@ async function be(e, t, n) {
|
|
|
427
425
|
sequence: null
|
|
428
426
|
} };
|
|
429
427
|
}
|
|
430
|
-
async function
|
|
431
|
-
let r = await
|
|
428
|
+
async function be(e, t, n) {
|
|
429
|
+
let r = await ye(e, t, n);
|
|
432
430
|
if ("failed" in r) return r.failed;
|
|
433
|
-
let { imageData: i, imagePath: a, html: o, prompt: s } = r, c = t.id, l = await
|
|
431
|
+
let { imageData: i, imagePath: a, html: o, prompt: s } = r, c = t.id, l = await Z(e.files?.artifacts, H, c, (e) => {
|
|
434
432
|
let t = e ?? {
|
|
435
433
|
id: c,
|
|
436
434
|
title: "",
|
|
@@ -461,21 +459,21 @@ async function xe(e, t, n) {
|
|
|
461
459
|
message: [
|
|
462
460
|
`${d} ${n.slide} of ${n.totalSlides} of slideshow "${c}" is on the screen`,
|
|
463
461
|
a ? `saved to ${a}` : "",
|
|
464
|
-
l ? "" :
|
|
462
|
+
l ? "" : Q("slideshow")
|
|
465
463
|
].filter(Boolean).join("; "),
|
|
466
|
-
instructions:
|
|
464
|
+
instructions: T(n),
|
|
467
465
|
instructionsRequired: !0,
|
|
468
|
-
sequence:
|
|
466
|
+
sequence: pe(n)
|
|
469
467
|
};
|
|
470
468
|
}
|
|
471
|
-
async function
|
|
472
|
-
let n =
|
|
469
|
+
async function xe(e, t) {
|
|
470
|
+
let n = w(t);
|
|
473
471
|
if (typeof n == "string") return {
|
|
474
472
|
message: n,
|
|
475
473
|
sequence: null
|
|
476
474
|
};
|
|
477
|
-
let r =
|
|
478
|
-
if (a && n.slide > i.current && i.current > 0 && !
|
|
475
|
+
let r = he(e), i = ge(r, n), a = n.mode === "steps";
|
|
476
|
+
if (a && n.slide > i.current && i.current > 0 && !R(e, i.shownAt)) {
|
|
479
477
|
console.info(`[sequence] holding step ${n.slide} for the user`);
|
|
480
478
|
let e = i.shownAt === Infinity ? "is still being drawn" : "is still on the screen";
|
|
481
479
|
return {
|
|
@@ -484,15 +482,15 @@ async function Q(e, t) {
|
|
|
484
482
|
};
|
|
485
483
|
}
|
|
486
484
|
let o = a ? i.slides.get(n.slide) : void 0;
|
|
487
|
-
if (o) return
|
|
485
|
+
if (o) return se(e.currentResult, o) ? {
|
|
488
486
|
message: `step ${n.slide} of ${n.totalSlides} is already on the screen`,
|
|
489
487
|
cancelled: !0
|
|
490
|
-
} :
|
|
491
|
-
let s = r.repeats.claim(
|
|
488
|
+
} : _e(r, i, n, o);
|
|
489
|
+
let s = r.repeats.claim(me(i.id, n));
|
|
492
490
|
if ("earlier" in s) {
|
|
493
|
-
if (!await s.earlier) return
|
|
491
|
+
if (!await s.earlier) return xe(e, t);
|
|
494
492
|
let a = i.slides.get(n.slide);
|
|
495
|
-
return a && r.lastShown !== i ?
|
|
493
|
+
return a && r.lastShown !== i ? _e(r, i, n, a) : {
|
|
496
494
|
message: `slide ${n.slide} of ${n.totalSlides} is already on the screen`,
|
|
497
495
|
cancelled: !0
|
|
498
496
|
};
|
|
@@ -504,8 +502,8 @@ async function Q(e, t) {
|
|
|
504
502
|
i.current = n.slide, i.shownAt = Infinity;
|
|
505
503
|
let u = !1;
|
|
506
504
|
try {
|
|
507
|
-
let t = await
|
|
508
|
-
return u =
|
|
505
|
+
let t = await be(e, i, n);
|
|
506
|
+
return u = oe(t), u && (i.slides.set(n.slide, t), i.current = n.slide, i.shownAt = Date.now(), r.lastShown = i), t;
|
|
509
507
|
} finally {
|
|
510
508
|
c(u), !u && i.current === n.slide && (i.current = l.current, i.shownAt = l.shownAt);
|
|
511
509
|
}
|
|
@@ -529,19 +527,19 @@ var Se = ({ id: e, title: t, totalPanels: n }) => ({
|
|
|
529
527
|
...r.length > 0 && { waitsForUser: !0 }
|
|
530
528
|
}), we = (e, t) => e ? `${e}. ${t}` : t, Te = (e, { name: t, description: n }) => we(e, `Character reference sheet of ${t}: ${n}. Full body, front, side and back views, on a plain white background. No text or labels.`);
|
|
531
529
|
async function Ee(e, t) {
|
|
532
|
-
let n =
|
|
530
|
+
let n = D(t);
|
|
533
531
|
if (typeof n == "string") return {
|
|
534
532
|
message: n,
|
|
535
533
|
sequence: null
|
|
536
534
|
};
|
|
537
|
-
let r = await Promise.all(n.characters.map((t) =>
|
|
535
|
+
let r = await Promise.all(n.characters.map((t) => V(e, Te(n.style, t)))), i = r.map(I), a = r.find((e, t) => !i[t]?.imageData);
|
|
538
536
|
if (i.every(({ imageData: e }) => !e) && a) return {
|
|
539
537
|
...a,
|
|
540
538
|
message: `the character sheets couldn't be made: ${a.message}`,
|
|
541
539
|
sequence: null
|
|
542
540
|
};
|
|
543
541
|
let o = {
|
|
544
|
-
id:
|
|
542
|
+
id: z(),
|
|
545
543
|
...n,
|
|
546
544
|
characters: n.characters.map((e, t) => {
|
|
547
545
|
let n = i[t]?.imagePath;
|
|
@@ -551,7 +549,7 @@ async function Ee(e, t) {
|
|
|
551
549
|
};
|
|
552
550
|
}),
|
|
553
551
|
panels: {}
|
|
554
|
-
}, s = await
|
|
552
|
+
}, s = await Z(e.files?.artifacts, U, o.id, () => o), c = o.characters.filter((e) => e.imagePath).map((e) => `${e.name}: ${e.imagePath}`), l = n.characters.map(({ name: e }, t) => i[t]?.imageData ? null : `${e} (${r[t]?.message ?? ""})`).filter((e) => !!e), u = i.find((e) => e.imageData)?.imageData;
|
|
555
553
|
return {
|
|
556
554
|
data: {
|
|
557
555
|
storyboardId: o.id,
|
|
@@ -572,9 +570,9 @@ async function Ee(e, t) {
|
|
|
572
570
|
`storyboard "${o.id}" is ready with ${o.totalPanels} panels; the cast is on the screen`,
|
|
573
571
|
c.length ? `character sheets saved to ${c.join(", ")}` : "",
|
|
574
572
|
l.length ? `no sheet for ${l.join("; ")}: they will be drawn from their description` : "",
|
|
575
|
-
s ? "" :
|
|
573
|
+
s ? "" : Q("storyboard")
|
|
576
574
|
].filter(Boolean).join("; "),
|
|
577
|
-
instructions:
|
|
575
|
+
instructions: O(o),
|
|
578
576
|
instructionsRequired: !0,
|
|
579
577
|
sequence: Se(o)
|
|
580
578
|
};
|
|
@@ -586,10 +584,10 @@ function De(e, t, n) {
|
|
|
586
584
|
async function Oe(e, t, n) {
|
|
587
585
|
let r = [], i = [];
|
|
588
586
|
for (let a of n.characters) {
|
|
589
|
-
let n = t.characters.find((e) =>
|
|
587
|
+
let n = t.characters.find((e) => b(e.name, a));
|
|
590
588
|
if (!n) r.push(a);
|
|
591
589
|
else if (!i.some((e) => e.character === n)) {
|
|
592
|
-
let [t] = n.imagePath ? await
|
|
590
|
+
let [t] = n.imagePath ? await B(e, [n.imagePath]) : [];
|
|
593
591
|
i.push({
|
|
594
592
|
character: n,
|
|
595
593
|
sheet: t ?? null
|
|
@@ -599,12 +597,12 @@ async function Oe(e, t, n) {
|
|
|
599
597
|
let a = i.map(({ sheet: e }) => e).filter((e) => !!e), o = De(t, n, i.map(({ character: e, sheet: t }) => ({
|
|
600
598
|
character: e,
|
|
601
599
|
hasSheet: !!t
|
|
602
|
-
}))), s = await
|
|
600
|
+
}))), s = await V(e, o, a), { imageData: c, imagePath: l } = I(s);
|
|
603
601
|
if (!c) return {
|
|
604
602
|
...s,
|
|
605
603
|
sequence: null
|
|
606
604
|
};
|
|
607
|
-
let u = n.panel < t.totalPanels && n.choices.length >= 2 ? n.choices : [], d = await
|
|
605
|
+
let u = n.panel < t.totalPanels && n.choices.length >= 2 ? n.choices : [], d = await Z(e.files?.artifacts, U, t.id, (e) => {
|
|
608
606
|
let r = e ?? t;
|
|
609
607
|
return u.length && (r.interactive = !0), r.panels[String(n.panel)] = {
|
|
610
608
|
caption: n.caption,
|
|
@@ -630,25 +628,25 @@ async function Oe(e, t, n) {
|
|
|
630
628
|
`panel ${n.panel} of ${t.totalPanels} is on the screen`,
|
|
631
629
|
l ? `saved to ${l}` : "",
|
|
632
630
|
r.length ? `not in the cast, so drawn from the prompt alone: ${r.join(", ")}` : "",
|
|
633
|
-
d ? "" :
|
|
631
|
+
d ? "" : Q("storyboard")
|
|
634
632
|
].filter(Boolean).join("; "),
|
|
635
|
-
instructions:
|
|
633
|
+
instructions: j(t, n.panel, u),
|
|
636
634
|
instructionsRequired: !0,
|
|
637
635
|
sequence: Ce(t, n.panel, u)
|
|
638
636
|
};
|
|
639
637
|
}
|
|
640
|
-
var ke =
|
|
641
|
-
repeats:
|
|
638
|
+
var ke = ue(() => ({
|
|
639
|
+
repeats: $(),
|
|
642
640
|
awaitingChoice: /* @__PURE__ */ new Map()
|
|
643
641
|
}));
|
|
644
|
-
async function
|
|
645
|
-
let n =
|
|
642
|
+
async function Ae(e, t) {
|
|
643
|
+
let n = A(t);
|
|
646
644
|
if (!n) return {
|
|
647
|
-
message:
|
|
645
|
+
message: k,
|
|
648
646
|
sequence: null
|
|
649
647
|
};
|
|
650
648
|
let { storyboardId: r, panel: i } = n, { repeats: a, awaitingChoice: o } = ke(e), s = o.get(r);
|
|
651
|
-
if (s && i > s.panel && !
|
|
649
|
+
if (s && i > s.panel && !R(e, s.shownAt)) return console.info(`[sequence] holding panel ${i} for the user`), {
|
|
652
650
|
message: s.shownAt === Infinity ? `panel ${i} was not shown: panel ${s.panel} is still being drawn. Wait for it before going on.` : `panel ${i} was not shown: the user hasn't picked a choice yet, and panel ${s.panel} is still on the screen. Wait for their answer.`,
|
|
653
651
|
cancelled: !0
|
|
654
652
|
};
|
|
@@ -656,7 +654,7 @@ async function $(e, t) {
|
|
|
656
654
|
if ("earlier" in c) return await c.earlier ? {
|
|
657
655
|
message: `panel ${i} is already on the screen`,
|
|
658
656
|
cancelled: !0
|
|
659
|
-
} :
|
|
657
|
+
} : Ae(e, t);
|
|
660
658
|
let { settle: l } = c, u = {
|
|
661
659
|
panel: i,
|
|
662
660
|
shownAt: Infinity
|
|
@@ -664,7 +662,7 @@ async function $(e, t) {
|
|
|
664
662
|
o.set(r, u);
|
|
665
663
|
let f = () => o.get(r) === u, p = !1;
|
|
666
664
|
try {
|
|
667
|
-
let t = await
|
|
665
|
+
let t = await X(e.files?.artifacts, U, r);
|
|
668
666
|
if (!t) return {
|
|
669
667
|
message: `there is no storyboard "${r}"; call defineStoryboard first`,
|
|
670
668
|
sequence: null
|
|
@@ -674,7 +672,7 @@ async function $(e, t) {
|
|
|
674
672
|
sequence: null
|
|
675
673
|
};
|
|
676
674
|
let a = await Oe(e, t, n);
|
|
677
|
-
p = !!
|
|
675
|
+
p = !!I(a).imageData;
|
|
678
676
|
let s = a.data;
|
|
679
677
|
return p && f() && (s?.choices?.length ? o.set(r, {
|
|
680
678
|
panel: i,
|
|
@@ -686,21 +684,21 @@ async function $(e, t) {
|
|
|
686
684
|
}
|
|
687
685
|
//#endregion
|
|
688
686
|
//#region src/core/index.ts
|
|
689
|
-
var
|
|
690
|
-
toolDefinition:
|
|
687
|
+
var je = {
|
|
688
|
+
toolDefinition: E,
|
|
691
689
|
generatingMessage: "Making the slide...",
|
|
692
690
|
isEnabled: () => !0,
|
|
693
|
-
execute: (e, t) =>
|
|
694
|
-
},
|
|
695
|
-
toolDefinition:
|
|
691
|
+
execute: (e, t) => xe(e, t)
|
|
692
|
+
}, Me = {
|
|
693
|
+
toolDefinition: N,
|
|
696
694
|
generatingMessage: "Drawing the characters...",
|
|
697
695
|
isEnabled: () => !0,
|
|
698
696
|
execute: (e, t) => Ee(e, t)
|
|
699
|
-
},
|
|
700
|
-
toolDefinition:
|
|
697
|
+
}, Ne = {
|
|
698
|
+
toolDefinition: P,
|
|
701
699
|
generatingMessage: "Drawing the panel...",
|
|
702
700
|
isEnabled: () => !0,
|
|
703
|
-
execute: (e, t) =>
|
|
701
|
+
execute: (e, t) => Ae(e, t)
|
|
704
702
|
};
|
|
705
703
|
//#endregion
|
|
706
|
-
export { o as A,
|
|
704
|
+
export { o as A, j as C, b as D, D as E, p as F, d as M, n as N, T as O, t as P, O as S, w as T, ie as _, U as a, C as b, N as c, te as d, k as f, E as g, m as h, H as i, s as j, r as k, ee as l, P as m, Ne as n, X as o, g as p, je as r, h as s, Me as t, ne as u, _ as v, A as w, M as x, S as y };
|