@gui-chat-plugin/sequence 0.5.4 → 0.6.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.
@@ -154,28 +154,31 @@ var t = 1280, n = 720, r = 6e4, i = "https://cdn.jsdelivr.net/npm/@tailwindcss/b
154
154
  "<": "&lt;",
155
155
  ">": "&gt;",
156
156
  "\"": "&quot;"
157
- }, p = (e) => e.replace(/[&<>"]/g, (e) => f[e] ?? e), ee = (e) => e.replace(/<(?=(meta|base|link)\b)/gi, "&lt;").replace(/shadowroot/gi, "data-no-shadow-root"), m = "*, *::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; }", te = `
157
+ }, p = (e) => e.replace(/[&<>"]/g, (e) => f[e] ?? e), m = (e) => e.replace(/<(?=(meta|base|link)\b)/gi, "&lt;").replace(/shadowroot/gi, "data-no-shadow-root"), h = "*, *::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; }", ee = `
158
158
  html, body { margin: 0; width: ${t}px; height: 720px; overflow: hidden; }
159
159
  html:not(.ready) body { visibility: hidden; }
160
- ${m}`;
161
- function ne(e) {
160
+ ${h}`, g = "{{image}}", _ = /(\bsrc\s*=\s*["']?|\burl\(\s*["']?)(?:\{\{image\}\}|%7B%7Bimage%7D%7D)/gi, te = /^data:image\/[a-z0-9.+-]+;base64,[a-z0-9+/=]+$/i, ne = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7", v = /(<pre\b[\s\S]*?<\/pre>|<code\b[\s\S]*?<\/code>)/gi, y = (e) => e.split(v).some((e, t) => t % 2 == 0 && new RegExp(_.source, "i").test(e)), re = (e, t) => {
161
+ let n = t && te.test(t) ? t : ne;
162
+ return e.split(v).map((e, t) => t % 2 == 1 ? e : e.replace(_, (e, t) => t + n)).join("");
163
+ };
164
+ function ie(e) {
162
165
  return `<!doctype html>
163
166
  <html lang="en">
164
167
  <head>
165
168
  <meta charset="utf-8">
166
169
  <meta http-equiv="Content-Security-Policy" content="${d}">
167
- <style id="slide-base">${te}</style>
170
+ <style id="slide-base">${ee}</style>
168
171
  <script>${u}<\/script>
169
172
  <script defer src="${i}" integrity="${a}" crossorigin="anonymous"><\/script>
170
173
  </head>
171
174
  <body class="bg-white text-slate-900 font-sans antialiased">
172
- ${ee(e)}
175
+ ${m(e)}
173
176
  </body>
174
177
  </html>`;
175
178
  }
176
179
  //#endregion
177
180
  //#region src/core/chartSlide.ts
178
- var h = [
181
+ var b = [
179
182
  "bar",
180
183
  "line",
181
184
  "pie",
@@ -184,32 +187,32 @@ var h = [
184
187
  "polarArea",
185
188
  "scatter",
186
189
  "bubble"
187
- ], g = "https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js", re = "sha384-jb8JQMbMoBUzgWatfe6COACi2ljcDdZQ2OxczGA3bGNeWe+6DChMTBJemed7ZnvJ", ie = "\n(() => {\n const fail = (why) => {\n document.getElementById(\"chart-error\").textContent = why;\n document.documentElement.classList.add(\"failed\");\n };\n addEventListener(\"DOMContentLoaded\", () => {\n if (!window.Chart) return fail(\"The chart couldn't be drawn: Chart.js didn't load.\");\n let config;\n try {\n config = JSON.parse(document.getElementById(\"chart-config\").textContent);\n } catch {\n return fail(\"The chart couldn't be drawn: its configuration isn't valid.\");\n }\n Chart.defaults.font.size = 22;\n Chart.defaults.color = \"#334155\";\n Chart.defaults.animation.duration = 1200;\n config.options = { ...config.options, responsive: true, maintainAspectRatio: false };\n try {\n new Chart(document.getElementById(\"chart\"), config);\n } catch (error) {\n fail(\"The chart couldn't be drawn: \" + (error && error.message ? error.message : error));\n }\n });\n})();", ae = [
190
+ ], ae = "https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js", oe = "sha384-jb8JQMbMoBUzgWatfe6COACi2ljcDdZQ2OxczGA3bGNeWe+6DChMTBJemed7ZnvJ", se = "\n(() => {\n const fail = (why) => {\n document.getElementById(\"chart-error\").textContent = why;\n document.documentElement.classList.add(\"failed\");\n };\n addEventListener(\"DOMContentLoaded\", () => {\n if (!window.Chart) return fail(\"The chart couldn't be drawn: Chart.js didn't load.\");\n let config;\n try {\n config = JSON.parse(document.getElementById(\"chart-config\").textContent);\n } catch {\n return fail(\"The chart couldn't be drawn: its configuration isn't valid.\");\n }\n Chart.defaults.font.size = 22;\n Chart.defaults.color = \"#334155\";\n Chart.defaults.animation.duration = 1200;\n config.options = { ...config.options, responsive: true, maintainAspectRatio: false };\n try {\n new Chart(document.getElementById(\"chart\"), config);\n } catch (error) {\n fail(\"The chart couldn't be drawn: \" + (error && error.message ? error.message : error));\n }\n });\n})();", ce = [
188
191
  "default-src 'none'",
189
- `script-src 'sha256-TfZZxJX+yWgzYLy7zqsMa85OJEaC+zNLIpKLDZVnUqA=' ${g}`,
192
+ `script-src 'sha256-TfZZxJX+yWgzYLy7zqsMa85OJEaC+zNLIpKLDZVnUqA=' ${ae}`,
190
193
  "style-src 'unsafe-inline'",
191
194
  "img-src data: blob:",
192
195
  "connect-src 'none'",
193
196
  "form-action 'none'",
194
197
  "base-uri 'none'"
195
- ].join("; "), oe = `
198
+ ].join("; "), le = `
196
199
  html, body { margin: 0; width: ${t}px; height: 720px; overflow: hidden; background: #ffffff; color: #0f172a; font-family: ui-sans-serif, system-ui, sans-serif; }
197
200
  body { box-sizing: border-box; padding: 40px 64px 48px; display: flex; flex-direction: column; gap: 24px; }
198
201
  h1 { margin: 0; font-size: 52px; font-weight: 800; color: #1e3a8a; line-height: 1.15; text-align: center; }
199
202
  .chart { position: relative; flex: 1; min-height: 0; }
200
203
  #chart-error { display: none; margin: auto; font-size: 28px; color: #b91c1c; }
201
204
  .failed .chart { display: none; }
202
- .failed #chart-error { display: block; }`, se = (e) => JSON.stringify(e).replace(/</g, "\\u003c");
203
- function ce(e, t) {
205
+ .failed #chart-error { display: block; }`, ue = (e) => JSON.stringify(e).replace(/</g, "\\u003c");
206
+ function de(e, t) {
204
207
  return `<!doctype html>
205
208
  <html lang="en">
206
209
  <head>
207
210
  <meta charset="utf-8">
208
- <meta http-equiv="Content-Security-Policy" content="${ae}">
209
- <style>${oe}</style>
210
- <script>${ie}<\/script>
211
- <script defer src="${g}" integrity="${re}" crossorigin="anonymous"><\/script>
212
- <script type="application/json" id="chart-config">${se(t)}<\/script>
211
+ <meta http-equiv="Content-Security-Policy" content="${ce}">
212
+ <style>${le}</style>
213
+ <script>${se}<\/script>
214
+ <script defer src="${ae}" integrity="${oe}" crossorigin="anonymous"><\/script>
215
+ <script type="application/json" id="chart-config">${ue(t)}<\/script>
213
216
  </head>
214
217
  <body>
215
218
  ${e ? `<h1>${p(e)}</h1>` : ""}
@@ -220,50 +223,53 @@ ${e ? `<h1>${p(e)}</h1>` : ""}
220
223
  }
221
224
  //#endregion
222
225
  //#region src/core/definitions.ts
223
- var _ = "presentSlide", le = "defineStoryboard", ue = "presentPanel", de = 4, fe = 12, pe = 3, v = /^[0-9a-f]{12}$/, y = (e) => typeof e == "object" && !!e && !Array.isArray(e), b = (e) => typeof e == "string" ? e.trim() : "", x = (e, t) => e.toLowerCase() === t.toLowerCase(), S = (e) => typeof e == "number" && Number.isInteger(e), C = "presentSlide needs slide and totalSlides (whole numbers, slide from 1 to totalSlides), and one of imagePrompt, html, markdown or chart", w = `presentSlide's slide is too long: keep its html, markdown or chart under ${r} characters`, T = `presentSlide's chart must be a Chart.js configuration: an object with type (${h.join(", ")}), data ({ labels, datasets }) and optionally options`;
224
- function me(e) {
226
+ var fe = "presentSlide", pe = "defineStoryboard", me = "presentPanel", he = 4, ge = 12, _e = 3, x = /^[0-9a-f]{12}$/, S = (e) => typeof e == "object" && !!e && !Array.isArray(e), C = (e) => typeof e == "string" ? e.trim() : "", w = (e, t) => e.toLowerCase() === t.toLowerCase(), T = (e) => typeof e == "number" && Number.isInteger(e), E = "presentSlide needs slide and totalSlides (whole numbers, slide from 1 to totalSlides), and one of imagePrompt, html, markdown or chart", D = `presentSlide's slide is too long: keep its html, markdown or chart under ${r} characters`, O = `presentSlide's slide has ${g} but no imagePrompt: give imagePrompt for the picture that goes there, or take ${g} out`, k = `presentSlide's chart must be a Chart.js configuration: an object with type (${b.join(", ")}), data ({ labels, datasets }) and optionally options`;
227
+ function ve(e) {
225
228
  let t = e;
226
229
  if (typeof t == "string") try {
227
230
  t = JSON.parse(t);
228
231
  } catch {
229
232
  return null;
230
233
  }
231
- if (!y(t) || !y(t.data)) return null;
234
+ if (!S(t) || !S(t.data)) return null;
232
235
  let n = t.type;
233
- return !h.some((e) => e === n) || t.options !== void 0 && !y(t.options) ? null : t;
236
+ return !b.some((e) => e === n) || t.options !== void 0 && !S(t.options) ? null : t;
234
237
  }
235
- function E(e) {
236
- let { slide: t, totalSlides: n, title: r, imagePrompt: i } = e, a = b(e.html), o = a ? "" : b(e.markdown), s = !a && !o && e.chart !== void 0 && e.chart !== null;
237
- if (!S(t) || !S(n) || t < 1 || n < t || !a && !o && !s && !b(i)) return C;
238
- let c = s ? me(e.chart) : null;
239
- return s && !c ? T : Math.max(a.length, o.length, c ? JSON.stringify(c).length : 0) > 6e4 ? w : {
238
+ function A(e) {
239
+ let { slide: t, totalSlides: n, title: r, imagePrompt: i } = e, a = C(e.html), o = a ? "" : C(e.markdown), s = !a && !o && e.chart !== void 0 && e.chart !== null;
240
+ if (!T(t) || !T(n) || t < 1 || n < t || !a && !o && !s && !C(i)) return E;
241
+ let c = s ? ve(e.chart) : null;
242
+ if (s && !c) return k;
243
+ if (Math.max(a.length, o.length, c ? JSON.stringify(c).length : 0) > 6e4) return D;
244
+ let l = !a && !o && !c, u = !!a && y(a);
245
+ return u && !C(i) ? O : {
240
246
  slide: t,
241
247
  totalSlides: n,
242
248
  title: typeof r == "string" ? r : "",
243
- imagePrompt: !a && !o && !c ? String(i) : "",
249
+ imagePrompt: l || u || o && C(i) ? String(i) : "",
244
250
  ...a && { html: a },
245
251
  ...o && { markdown: o },
246
252
  ...c && { chart: c },
247
253
  mode: e.mode === "steps" ? "steps" : "presentation"
248
254
  };
249
255
  }
250
- var D = "teach its subject as a presenter speaking to the audience, and cover everything on it: every section, point and number, in order, each in a sentence or more. The slide is replaced by the next one as soon as you stop talking, so a point you leave out is never explained. Begin with the content itself, never with the slide or your plan: no \"This slide is about…\", \"The first slide shows…\", \"Let's unpack this one\", \"Next, I'll…\". A line about the slide is not an explanation.", O = ({ slide: e, totalSlides: t, title: n, mode: r }) => {
256
+ var j = "teach its subject as a presenter speaking to the audience, and cover everything on it: every section, point and number, in order, each in a sentence or more. The slide is replaced by the next one as soon as you stop talking, so a point you leave out is never explained. Begin with the content itself, never with the slide or your plan: no \"This slide is about…\", \"The first slide shows…\", \"Let's unpack this one\", \"Next, I'll…\". A line about the slide is not an explanation.", M = ({ slide: e, totalSlides: t, title: n, mode: r }) => {
251
257
  let i = n ? ` ("${n}")` : "";
252
258
  if (r === "steps") {
253
259
  let n = `Step ${e} of ${t}${i}`;
254
260
  return e < t ? `${n} is now on the screen. Say what to do in this step, directly ("Crack two eggs into a bowl…", not "This step is about eggs"), then stop and wait while the user does it. When they say they're ready (next, done, go on), call presentSlide for step ${e + 1} with mode "steps". If they ask to go back or to see a step again, call presentSlide for that step.` : `${n}, the last one, is now on the screen. Say what to do, directly, then wrap up the guide once the user is done.`;
255
261
  }
256
262
  let a = `Slide ${e} of ${t}${i}`;
257
- return e < t ? `${a} is now on the screen. Explain it: ${D} This reply is only the explanation: don't call presentSlide in it. When you have finished, you will be asked 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: ${D} Then wrap up the slideshow.`;
258
- }, he = [
259
- `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.`,
263
+ return e < t ? `${a} is now on the screen. Explain it: ${j} This reply is only the explanation: don't call presentSlide in it. When you have finished, you will be asked 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: ${j} Then wrap up the slideshow.`;
264
+ }, ye = [
265
+ `For an HTML slide: 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. For one generated picture on the slide (a photo, a scene, an object beside the text), give imagePrompt too and put <img src="${g}" alt="..." class="..."> where it goes, sized by its classes (for example class="w-1/2 h-full object-cover rounded-2xl").`,
260
266
  "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).",
261
267
  "CSS animations, transitions and scripts don't play: animate only with data-animation. A <style> for layout is allowed (and Google Fonts by @import)."
262
- ].join(" "), ge = "For a Markdown slide, instead of imagePrompt: the slide in Markdown (GitHub's: headings, lists, bold, tables, code), with math in TeX between $...$ inline or $$...$$ for a displayed equation (on lines of its own). Start with a # heading, and keep it to what fits on one slide: a heading and a few lines, a list or an equation or two. Write a dollar sign that isn't math as \\$.", _e = `For a chart slide, instead of imagePrompt (for numbers: real figures you have, never a picture of a chart): a Chart.js configuration as JSON text, {"type": ..., "data": ...}: { type, data: { labels, datasets: [{ label, data, backgroundColor }] }, options }. type is one of ${h.join(", ")}. It is drawn under the slide's title, so leave out options.plugins.title; give the datasets colors, and the axes titles (options.scales.x.title) when their units aren't obvious. JSON values only: no functions.`, k = "When the user asks for a slideshow (or to explain something with slides), plan four to six slides (more when the subject or your instructions need them), 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. Explain the subject, not the slides: say what the slide teaches, not that a slide is about it, and explain everything on a slide before showing the next; put on a slide only what you will explain. Go on to the last slide without asking whether to continue. A slide is a generated picture (imagePrompt), a chart (chart), a text slide in Markdown (markdown) or a designed slide in HTML (html): use a picture for a scene, an object or a place; a chart for numbers to compare, a trend or proportions; Markdown for equations and formulas (TeX math), definitions, short lists and small tables; and HTML for designed layouts, comparisons, timelines and diagrams. A picture model draws words, numbers and math badly, so they go on the other kinds; a slideshow can mix them. Numbers go on a chart slide: when you have figures (from a search, a document or the user: revenue, market share, growth, prices, counts over time), show them in a chart with those exact values, labelled with their units and the year or period, and say where they come from. Figures over time, shares of a whole or values side by side are a chart, not a list or table on a Markdown or HTML slide. Never make a chart, graph or table a picture (imagePrompt): a picture of a chart has made-up bars and no real numbers. A slideshow about a business, a market or a comparison of companies has its figures on chart slides, not only in text. Never invent figures; with none to show, leave the chart out. A slide holds only its subject, never notes about your work (what you searched for, that a search succeeded). 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.", A = {
268
+ ].join(" "), be = `For a Markdown slide: the slide in Markdown (GitHub's: headings, lists, bold, tables, code), with math in TeX between $...$ inline or $$...$$ for a displayed equation (on lines of its own). Start with a # heading, and keep it to what fits on one slide: a heading and a few lines, a list or an equation or two. Write a dollar sign that isn't math as \\$. For one generated picture on the slide, give imagePrompt too and put ![what it shows](${g}) where it goes.`, xe = `For a chart slide, instead of imagePrompt (for numbers: real figures you have, never a picture of a chart): a Chart.js configuration as JSON text, {"type": ..., "data": ...}: { type, data: { labels, datasets: [{ label, data, backgroundColor }] }, options }. type is one of ${b.join(", ")}. It is drawn under the slide's title, so leave out options.plugins.title; give the datasets colors, and the axes titles (options.scales.x.title) when their units aren't obvious. JSON values only: no functions.`, N = "When the user asks for a slideshow (or to explain something with slides), plan four to six slides (more when the subject or your instructions need them), 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. Explain the subject, not the slides: say what the slide teaches, not that a slide is about it, and explain everything on a slide before showing the next; put on a slide only what you will explain. Go on to the last slide without asking whether to continue. A slide is a generated picture (imagePrompt), a chart (chart), a text slide in Markdown (markdown) or a designed slide in HTML (html): use a picture for a scene, an object or a place; a chart for numbers to compare, a trend or proportions; Markdown for equations and formulas (TeX math), definitions, short lists and small tables; and HTML for designed layouts, comparisons, timelines and diagrams. A picture model draws words, numbers and math badly, so they go on the other kinds; a slideshow can mix them. When a picture helps the text (the thing being explained, beside its key points), make an HTML or Markdown slide with one generated picture on it: imagePrompt for the picture, and {{image}} where it goes. Numbers go on a chart slide: when you have figures (from a search, a document or the user: revenue, market share, growth, prices, counts over time), show them in a chart with those exact values, labelled with their units and the year or period, and say where they come from. Figures over time, shares of a whole or values side by side are a chart, not a list or table on a Markdown or HTML slide. Never make a chart, graph or table a picture (imagePrompt): a picture of a chart has made-up bars and no real numbers. A slideshow about a business, a market or a comparison of companies has its figures on chart slides, not only in text. Never invent figures; with none to show, leave the chart out. A slide holds only its subject, never notes about your work (what you searched for, that a search succeeded). 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.", P = {
263
269
  type: "function",
264
- name: _,
265
- prompt: k,
266
- description: "Show one slide of a slideshow, full screen: a picture generated from imagePrompt, a chart (chart), a slide written in Markdown with TeX math (markdown), or a slide written in HTML (html). Give one of the four. 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.",
270
+ name: fe,
271
+ prompt: N,
272
+ description: "Show one slide of a slideshow, full screen: a picture generated from imagePrompt, a chart (chart), a slide written in Markdown with TeX math (markdown), or a slide written in HTML (html). Give one of the four; an HTML or Markdown slide can also hold one generated picture (imagePrompt, placed at {{image}}). 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.",
267
273
  parameters: {
268
274
  type: "object",
269
275
  properties: {
@@ -281,19 +287,19 @@ var D = "teach its subject as a presenter speaking to the audience, and cover ev
281
287
  },
282
288
  imagePrompt: {
283
289
  type: "string",
284
- description: "For a picture slide: the picture, a clear illustration of its point, with the title as its only large text. Be concrete. Never a chart, graph, table, dashboard, infographic, key figures or anything with numbers: those are chart, Markdown or HTML slides. For a step, show the action: hands, tools and the object. Leave it out for a chart, Markdown or HTML slide."
290
+ description: "For a picture slide: the picture, a clear illustration of its point, with the title as its only large text. Be concrete. Never a chart, graph, table, dashboard, infographic, key figures or anything with numbers: those are chart, Markdown or HTML slides. For a step, show the action: hands, tools and the object. With html or markdown, it is the one picture placed where the slide has {{image}}; leave it out for a chart, and for an HTML or Markdown slide without {{image}}."
285
291
  },
286
292
  html: {
287
293
  type: "string",
288
- description: he
294
+ description: ye
289
295
  },
290
296
  markdown: {
291
297
  type: "string",
292
- description: ge
298
+ description: be
293
299
  },
294
300
  chart: {
295
301
  type: "string",
296
- description: _e
302
+ description: xe
297
303
  },
298
304
  mode: {
299
305
  type: "string",
@@ -308,49 +314,49 @@ var D = "teach its subject as a presenter speaking to the audience, and cover ev
308
314
  ]
309
315
  }
310
316
  };
311
- function j(e) {
317
+ function F(e) {
312
318
  let { totalPanels: t } = e;
313
- if (!S(t) || t < 1 || t > 12) return "totalPanels must be a whole number from 1 to 12";
319
+ if (!T(t) || t < 1 || t > 12) return "totalPanels must be a whole number from 1 to 12";
314
320
  let n = [];
315
321
  for (let t of Array.isArray(e.characters) ? e.characters : []) {
316
- let e = y(t) ? b(t.name) : "", r = y(t) ? b(t.description) : "";
322
+ let e = S(t) ? C(t.name) : "", r = S(t) ? C(t.description) : "";
317
323
  if (!e || !r) return "every character needs a name and a description";
318
- if (n.some((t) => x(t.name, e))) return `two characters are named ${e}`;
324
+ if (n.some((t) => w(t.name, e))) return `two characters are named ${e}`;
319
325
  n.push({
320
326
  name: e,
321
327
  description: r
322
328
  });
323
329
  }
324
330
  return n.length < 1 || n.length > 4 ? "a storyboard has 1 to 4 characters" : {
325
- title: b(e.title),
326
- style: b(e.style),
331
+ title: C(e.title),
332
+ style: C(e.style),
327
333
  totalPanels: t,
328
334
  characters: n,
329
335
  interactive: e.interactive === !0
330
336
  };
331
337
  }
332
- var M = ({ title: e }) => `The cast of "${e}" is now on the screen. Introduce the characters briefly. This reply is only the introduction: don't call presentPanel in it. When you have finished, you will be asked for panel 1. If the user has asked you to stop, or asked something else, answer them instead of going on.`, N = "presentPanel needs a storyboardId, a panel number (from 1) and an imagePrompt";
333
- function P(e) {
334
- let { panel: t } = e, n = b(e.storyboardId), r = b(e.imagePrompt);
335
- if (!n || !r || !S(t) || t < 1) return null;
336
- let i = (e) => (Array.isArray(e) ? e : []).map(b).filter(Boolean);
338
+ var I = ({ title: e }) => `The cast of "${e}" is now on the screen. Introduce the characters briefly. This reply is only the introduction: don't call presentPanel in it. When you have finished, you will be asked for panel 1. If the user has asked you to stop, or asked something else, answer them instead of going on.`, L = "presentPanel needs a storyboardId, a panel number (from 1) and an imagePrompt";
339
+ function R(e) {
340
+ let { panel: t } = e, n = C(e.storyboardId), r = C(e.imagePrompt);
341
+ if (!n || !r || !T(t) || t < 1) return null;
342
+ let i = (e) => (Array.isArray(e) ? e : []).map(C).filter(Boolean);
337
343
  return {
338
344
  storyboardId: n,
339
345
  panel: t,
340
346
  characters: i(e.characters),
341
347
  imagePrompt: r,
342
- caption: b(e.caption),
348
+ caption: C(e.caption),
343
349
  choices: i(e.choices).slice(0, 3)
344
350
  };
345
351
  }
346
- function F(e, t, n) {
352
+ function z(e, t, n) {
347
353
  let { id: r, totalPanels: i } = e;
348
354
  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, aloud, as a storyteller. This reply is only the telling: don't call presentPanel in it. When you have finished, you will be asked for panel ${t + 1}. 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.`;
349
355
  }
350
- var ve = "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.", I = {
356
+ var B = "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.", V = {
351
357
  type: "function",
352
- name: le,
353
- prompt: ve,
358
+ name: pe,
359
+ prompt: B,
354
360
  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.",
355
361
  parameters: {
356
362
  type: "object",
@@ -397,9 +403,9 @@ var ve = "When the user asks for a story, a picture book, a comic or a storyboar
397
403
  "characters"
398
404
  ]
399
405
  }
400
- }, L = {
406
+ }, H = {
401
407
  type: "function",
402
- name: ue,
408
+ name: me,
403
409
  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.",
404
410
  parameters: {
405
411
  type: "object",
@@ -438,60 +444,60 @@ var ve = "When the user asks for a story, a picture book, a comic or a storyboar
438
444
  "imagePrompt"
439
445
  ]
440
446
  }
441
- }, R = (e) => typeof e == "object" && !!e && !Array.isArray(e), ye = (e) => R(e) && typeof e.message == "string";
442
- function z(e) {
443
- let t = R(e?.data) ? e.data : {};
447
+ }, U = (e) => typeof e == "object" && !!e && !Array.isArray(e), Se = (e) => U(e) && typeof e.message == "string";
448
+ function W(e) {
449
+ let t = U(e?.data) ? e.data : {};
444
450
  return {
445
451
  ...typeof t.imageData == "string" && { imageData: t.imageData },
446
452
  ...typeof t.imagePath == "string" && { imagePath: t.imagePath }
447
453
  };
448
454
  }
449
- function B(e) {
450
- let t = R(e?.data) ? e.data : {};
455
+ function G(e) {
456
+ let t = U(e?.data) ? e.data : {};
451
457
  return typeof t.html == "string" ? t.html : "";
452
458
  }
453
- function V(e) {
454
- let t = R(e?.data) ? e.data : {};
455
- return R(t.chart) ? JSON.stringify(t.chart) : "";
459
+ function K(e) {
460
+ let t = U(e?.data) ? e.data : {};
461
+ return U(t.chart) ? JSON.stringify(t.chart) : "";
456
462
  }
457
- var be = (e) => !!z(e).imageData || !!B(e) || !!V(e);
458
- function xe(e, t) {
459
- let n = z(e), r = z(t);
463
+ var Ce = (e) => !!W(e).imageData || !!G(e) || !!K(e);
464
+ function we(e, t) {
465
+ let n = W(e), r = W(t);
460
466
  if (n.imagePath && r.imagePath) return n.imagePath === r.imagePath;
461
467
  if (n.imageData) return n.imageData === r.imageData;
462
- let i = B(e);
463
- if (i) return i === B(t);
464
- let a = V(e);
465
- return !!a && a === V(t);
468
+ let i = G(e);
469
+ if (i) return i === G(t);
470
+ let a = K(e);
471
+ return !!a && a === K(t);
466
472
  }
467
- var H = (e, t) => e.userSpokeAt === void 0 || e.userSpokeAt > t, U = () => crypto.randomUUID().replace(/-/g, "").slice(0, 12), Se = "artifacts/";
468
- async function W(e, t) {
473
+ var q = (e, t) => e.userSpokeAt === void 0 || e.userSpokeAt > t, Te = () => crypto.randomUUID().replace(/-/g, "").slice(0, 12), Ee = "artifacts/";
474
+ async function De(e, t) {
469
475
  let n = e.files?.artifacts;
470
476
  if (!e.app?.editImages || !n) return [];
471
477
  let r = [];
472
- for (let e of t) if (e.startsWith(Se)) try {
478
+ for (let e of t) if (e.startsWith(Ee)) try {
473
479
  await n.exists(e.slice(10)) && r.push(e);
474
480
  } catch {}
475
481
  return r;
476
482
  }
477
- async function G(e, t, n = []) {
483
+ async function J(e, t, n = []) {
478
484
  let r = e.app, i = r?.editImages, a = r?.generateImage;
479
485
  try {
480
486
  let e;
481
487
  if (n.length && i) e = await i(t, [...n]);
482
488
  else if (a) e = await a(t);
483
489
  else return { message: "image generation isn't available" };
484
- return ye(e) ? e : { message: "image generation returned an unrecognized result" };
490
+ return Se(e) ? e : { message: "image generation returned an unrecognized result" };
485
491
  } catch (e) {
486
492
  return { message: `image generation failed: ${e instanceof Error ? e.message : String(e)}` };
487
493
  }
488
494
  }
489
- var Ce = 50;
490
- function K(e) {
495
+ var Oe = 50;
496
+ function ke(e) {
491
497
  let t = /* @__PURE__ */ new Map();
492
498
  return (n) => {
493
499
  let r = n.conversationId ?? "", i = t.get(r);
494
- if (i === void 0 ? i = e() : t.delete(r), t.set(r, i), t.size > Ce) {
500
+ if (i === void 0 ? i = e() : t.delete(r), t.set(r, i), t.size > Oe) {
495
501
  let e = t.keys().next().value;
496
502
  e !== void 0 && t.delete(e);
497
503
  }
@@ -500,41 +506,45 @@ function K(e) {
500
506
  }
501
507
  //#endregion
502
508
  //#region src/core/markdownSlide.ts
503
- var q = "slide-md", we = `
504
- .${q} { box-sizing: border-box; flex-shrink: 0; width: ${t}px; height: 720px; padding: 56px 80px; overflow: hidden; display: flex; flex-direction: column; justify-content: center; gap: 0.5em; background: #ffffff; color: #0f172a; font-family: ui-sans-serif, system-ui, sans-serif; line-height: 1.35; }
505
- .${q} > * { margin: 0; }
506
- .${q} h1 { font-size: 1.9em; font-weight: 800; color: #1e3a8a; line-height: 1.15; }
507
- .${q} h2 { font-size: 1.5em; font-weight: 700; color: #1e40af; line-height: 1.2; }
508
- .${q} h3 { font-size: 1.2em; font-weight: 700; color: #334155; }
509
- .${q} ul, .${q} ol { padding-left: 1.3em; display: flex; flex-direction: column; gap: 0.3em; }
510
- .${q} ul { list-style: disc; }
511
- .${q} ol { list-style: decimal; }
512
- .${q} li > ul, .${q} li > ol { margin-top: 0.3em; font-size: 0.9em; }
513
- .${q} li::marker { color: #2563eb; }
514
- .${q} strong { font-weight: 700; color: #1e3a8a; }
515
- .${q} em { font-style: italic; }
516
- .${q} a { color: #2563eb; text-decoration: underline; }
517
- .${q} code { font-family: ui-monospace, monospace; font-size: 0.85em; background: #f1f5f9; border-radius: 0.2em; padding: 0.05em 0.3em; }
518
- .${q} pre { background: #0f172a; color: #e2e8f0; border-radius: 0.4em; padding: 0.6em 0.8em; font-size: 0.75em; overflow: hidden; }
519
- .${q} pre code { background: none; padding: 0; color: inherit; }
520
- .${q} blockquote { border-left: 0.2em solid #93c5fd; padding-left: 0.8em; color: #475569; font-style: italic; }
521
- .${q} table { border-collapse: collapse; font-size: 0.85em; align-self: flex-start; }
522
- .${q} th, .${q} td { border: 1px solid #cbd5e1; padding: 0.25em 0.7em; text-align: left; }
523
- .${q} th { background: #eff6ff; font-weight: 700; }
524
- .${q} hr { border: 0; border-top: 2px solid #e2e8f0; }
525
- .${q} img { max-width: 100%; max-height: 60%; }
526
- .${q} .math-display { display: block; text-align: center; font-size: 1.15em; }
527
- .${q} math { font-family: "Latin Modern Math", "STIX Two Math", "Cambria Math", math; }
528
- .${q} mtd { padding: 0.1em 0.4em; }
529
- .${q} mtd:first-child { padding-left: 0; }
530
- .${q} mtd:last-child { padding-right: 0; }
531
- .${q} .math-error { color: #b91c1c; font-family: ui-monospace, monospace; }`;
532
- function Te(e) {
509
+ var Y = "slide-md", Ae = "slide-md-split", X = "slide-md-text", je = "slide-md-picture", Me = .8, Ne = `
510
+ .${Y} { box-sizing: border-box; flex-shrink: 0; width: ${t}px; height: 720px; padding: 56px 80px; overflow: hidden; display: flex; flex-direction: column; justify-content: center; gap: 0.5em; background: #ffffff; color: #0f172a; font-family: ui-sans-serif, system-ui, sans-serif; line-height: 1.35; }
511
+ .${Y} > * { margin: 0; }
512
+ .${Y} h1 { font-size: 1.9em; font-weight: 800; color: #1e3a8a; line-height: 1.15; }
513
+ .${Y} h2 { font-size: 1.5em; font-weight: 700; color: #1e40af; line-height: 1.2; }
514
+ .${Y} h3 { font-size: 1.2em; font-weight: 700; color: #334155; }
515
+ .${Y} ul, .${Y} ol { padding-left: 1.3em; display: flex; flex-direction: column; gap: 0.3em; }
516
+ .${Y} ul { list-style: disc; }
517
+ .${Y} ol { list-style: decimal; }
518
+ .${Y} li > ul, .${Y} li > ol { margin-top: 0.3em; font-size: 0.9em; }
519
+ .${Y} li::marker { color: #2563eb; }
520
+ .${Y} strong { font-weight: 700; color: #1e3a8a; }
521
+ .${Y} em { font-style: italic; }
522
+ .${Y} a { color: #2563eb; text-decoration: underline; }
523
+ .${Y} code { font-family: ui-monospace, monospace; font-size: 0.85em; background: #f1f5f9; border-radius: 0.2em; padding: 0.05em 0.3em; }
524
+ .${Y} pre { background: #0f172a; color: #e2e8f0; border-radius: 0.4em; padding: 0.6em 0.8em; font-size: 0.75em; overflow: hidden; }
525
+ .${Y} pre code { background: none; padding: 0; color: inherit; }
526
+ .${Y} blockquote { border-left: 0.2em solid #93c5fd; padding-left: 0.8em; color: #475569; font-style: italic; }
527
+ .${Y} table { border-collapse: collapse; font-size: 0.85em; align-self: flex-start; }
528
+ .${Y} th, .${Y} td { border: 1px solid #cbd5e1; padding: 0.25em 0.7em; text-align: left; }
529
+ .${Y} th { background: #eff6ff; font-weight: 700; }
530
+ .${Y} hr { border: 0; border-top: 2px solid #e2e8f0; }
531
+ .${Y} img { max-width: 100%; max-height: 60%; }
532
+ .${Y}.${Ae} { flex-direction: row; align-items: center; gap: 48px; }
533
+ .${Y} .${X} { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; justify-content: center; gap: 0.5em; }
534
+ .${Y} .${X} > * { margin: 0; }
535
+ .${Y} .${je} { flex: 0 0 44%; width: 44%; height: 100%; max-width: none; max-height: 100%; object-fit: cover; border-radius: 0.6em; box-shadow: 0 10px 30px rgba(15, 23, 42, 0.18); }
536
+ .${Y} .math-display { display: block; text-align: center; font-size: 1.15em; }
537
+ .${Y} math { font-family: "Latin Modern Math", "STIX Two Math", "Cambria Math", math; }
538
+ .${Y} mtd { padding: 0.1em 0.4em; }
539
+ .${Y} mtd:first-child { padding-left: 0; }
540
+ .${Y} mtd:last-child { padding-right: 0; }
541
+ .${Y} .math-error { color: #b91c1c; font-family: ui-monospace, monospace; }`;
542
+ function Pe(e) {
533
543
  let t = e.split("\n").filter((e) => e.trim()).length, n = e.length;
534
544
  return t <= 5 && n <= 250 ? 40 : t <= 8 && n <= 450 ? 34 : t <= 12 && n <= 700 ? 28 : 24;
535
545
  }
536
- var Ee = /^[ \t]*(?:\$\$([\s\S]+?)\$\$|\\\[([\s\S]+?)\\\])[ \t]*(?:\n|$)/, De = /^(?:\$\$(.+?)\$\$|\$(?!\s)((?:\\.|[^\\$\n])+?)(?<!\s)\$(?!\d)|\\\((.+?)\\\))/;
537
- function Oe(e) {
546
+ var Fe = /^[ \t]*(?:\$\$([\s\S]+?)\$\$|\\\[([\s\S]+?)\\\])[ \t]*(?:\n|$)/, Ie = /^(?:\$\$(.+?)\$\$|\$(?!\s)((?:\\.|[^\\$\n])+?)(?<!\s)\$(?!\d)|\\\((.+?)\\\))/;
547
+ function Le(e) {
538
548
  return [{
539
549
  name: "blockMath",
540
550
  level: "block",
@@ -543,7 +553,7 @@ function Oe(e) {
543
553
  return t ? t.index + (t[1] ?? "").length : void 0;
544
554
  },
545
555
  tokenizer(e) {
546
- let t = Ee.exec(e);
556
+ let t = Fe.exec(e);
547
557
  if (t) return {
548
558
  type: "blockMath",
549
559
  raw: t[0],
@@ -556,7 +566,7 @@ function Oe(e) {
556
566
  level: "inline",
557
567
  start: (e) => e.match(/(?<!\\)\$|\\\(/)?.index,
558
568
  tokenizer(e) {
559
- let t = De.exec(e);
569
+ let t = Ie.exec(e);
560
570
  if (t) return {
561
571
  type: "inlineMath",
562
572
  raw: t[0],
@@ -567,11 +577,11 @@ function Oe(e) {
567
577
  renderer: (t) => e(String(t.text), t.display === !0)
568
578
  }];
569
579
  }
570
- var ke = /(<\/mi>|<\/mn>|<\/mrow>|<mo[^>]*>[)\]]<\/mo>)?(<mi(?: mathvariant="normal")?>[A-Za-z]{2,}<\/mi>)<mo>\u2061<\/mo>/g, Ae = "<mspace width=\"0.1667em\"></mspace>", je = (e) => e.replace(ke, (e, t, n) => `${t ? t + Ae : ""}${n}<mo lspace="0" rspace="0.1667em">\u2061</mo>`);
571
- async function J(e) {
580
+ var Re = /(<\/mi>|<\/mn>|<\/mrow>|<mo[^>]*>[)\]]<\/mo>)?(<mi(?: mathvariant="normal")?>[A-Za-z]{2,}<\/mi>)<mo>\u2061<\/mo>/g, ze = "<mspace width=\"0.1667em\"></mspace>", Be = (e) => e.replace(Re, (e, t, n) => `${t ? t + ze : ""}${n}<mo lspace="0" rspace="0.1667em">\u2061</mo>`);
581
+ async function Ve(e) {
572
582
  let [{ Marked: t }, { default: n }] = await Promise.all([import("marked"), import("katex")]), r = (e, t) => {
573
583
  try {
574
- return je(n.renderToString(e, {
584
+ return Be(n.renderToString(e, {
575
585
  output: "mathml",
576
586
  displayMode: t,
577
587
  throwOnError: !0
@@ -583,28 +593,38 @@ async function J(e) {
583
593
  gfm: !0,
584
594
  breaks: !1
585
595
  });
586
- i.use({ extensions: Oe(r) });
587
- let a = await i.parse(e);
588
- return `<style>${we}</style>
589
- <div class="${q}" data-fit style="font-size: ${Te(e)}px">
590
- ${a}</div>`;
596
+ i.use({ extensions: Le(r) });
597
+ let a = i.lexer(e), o = a.findIndex((e) => e.type === "paragraph" && e.tokens?.length === 1 && e.tokens[0]?.type === "image" && e.tokens[0].href.trim() === "{{image}}");
598
+ if (o >= 0) {
599
+ let [t] = a.splice(o, 1), n = t?.type === "paragraph" ? t.tokens?.[0] : void 0, r = n?.type === "image" ? n.text : "", s = i.parser(a), c = e.replace(t?.raw ?? "", "");
600
+ return `<style>${Ne}</style>
601
+ <div class="${Y} ${Ae}" data-fit style="font-size: ${Math.round(Pe(c) * Me)}px">
602
+ <div class="${X}">
603
+ ${s}</div>
604
+ <img class="${je}" src="${g}" alt="${p(r)}">
605
+ </div>`;
606
+ }
607
+ let s = await i.parse(e);
608
+ return `<style>${Ne}</style>
609
+ <div class="${Y}" data-fit style="font-size: ${Pe(e)}px">
610
+ ${s}</div>`;
591
611
  }
592
612
  //#endregion
593
613
  //#region src/core/records.ts
594
- var Y = "slideshows", X = "storyboards", Me = {}, Ne = /* @__PURE__ */ new WeakMap(), Pe = /* @__PURE__ */ new WeakMap();
595
- function Fe(e) {
596
- let t = Ne.get(e);
597
- return t || Ne.set(e, t = /* @__PURE__ */ new Map()), t;
614
+ var He = "slideshows", Z = "storyboards", Ue = {}, We = /* @__PURE__ */ new WeakMap(), Ge = /* @__PURE__ */ new WeakMap();
615
+ function Ke(e) {
616
+ let t = We.get(e);
617
+ return t || We.set(e, t = /* @__PURE__ */ new Map()), t;
598
618
  }
599
- function Ie(t, n) {
600
- let r = Pe.get(t);
601
- r || Pe.set(t, r = /* @__PURE__ */ new Map());
619
+ function qe(t, n) {
620
+ let r = Ge.get(t);
621
+ r || Ge.set(t, r = /* @__PURE__ */ new Map());
602
622
  let i = r.get(n);
603
623
  return i || r.set(n, i = e()), i;
604
624
  }
605
- var Le = (e, t) => `${e}/${t}.json`;
606
- async function Re(e, t) {
607
- let n = Fe(e ?? Me), r = n.get(t);
625
+ var Je = (e, t) => `${e}/${t}.json`;
626
+ async function Ye(e, t) {
627
+ let n = Ke(e ?? Ue), r = n.get(t);
608
628
  if (r) return r;
609
629
  if (!e) return null;
610
630
  try {
@@ -614,14 +634,14 @@ async function Re(e, t) {
614
634
  return null;
615
635
  }
616
636
  }
617
- async function ze(e, t, n) {
618
- return v.test(n) ? Re(e, Le(t, n)) : null;
637
+ async function Xe(e, t, n) {
638
+ return x.test(n) ? Ye(e, Je(t, n)) : null;
619
639
  }
620
- async function Z(e, t, n, r) {
621
- let i = Le(t, n), a = e ?? Me;
622
- return Ie(a, i)(async () => {
623
- let t = r(await Re(e, i));
624
- if (Fe(a).set(i, t), !e) return !1;
640
+ async function Q(e, t, n, r) {
641
+ let i = Je(t, n), a = e ?? Ue;
642
+ return qe(a, i)(async () => {
643
+ let t = r(await Ye(e, i));
644
+ if (Ke(a).set(i, t), !e) return !1;
625
645
  try {
626
646
  return await e.write(i, JSON.stringify(t, null, 2)), !0;
627
647
  } catch (e) {
@@ -629,12 +649,12 @@ async function Z(e, t, n, r) {
629
649
  }
630
650
  });
631
651
  }
632
- var Q = (e) => `the ${e} could not be saved, so it lasts only until the app or server restarts`, Be = 6e4;
633
- function Ve() {
652
+ var $ = (e) => `the ${e} could not be saved, so it lasts only until the app or server restarts`, Ze = 6e4;
653
+ function Qe() {
634
654
  let e = /* @__PURE__ */ new Map();
635
655
  return { claim: (t) => {
636
656
  let n = Date.now();
637
- for (let [t, r] of e) n - r.at > Be && e.delete(t);
657
+ for (let [t, r] of e) n - r.at > Ze && e.delete(t);
638
658
  let r = e.get(t);
639
659
  if (r) return { earlier: r.shown };
640
660
  let i = () => void 0, a = new Promise((e) => i = e);
@@ -648,7 +668,7 @@ function Ve() {
648
668
  }
649
669
  //#endregion
650
670
  //#region src/core/presentSlide.ts
651
- function He({ slide: e, totalSlides: t, mode: n }) {
671
+ function $e({ slide: e, totalSlides: t, mode: n }) {
652
672
  return n === "steps" ? {
653
673
  step: e,
654
674
  total: t,
@@ -666,7 +686,7 @@ function He({ slide: e, totalSlides: t, mode: n }) {
666
686
  nextCall: `call presentSlide for slide ${e + 1} of ${t}`
667
687
  };
668
688
  }
669
- var Ue = (e, { slide: t, totalSlides: n, title: r, imagePrompt: i, html: a, markdown: o, chart: s }) => JSON.stringify([
689
+ var et = (e, { slide: t, totalSlides: n, title: r, imagePrompt: i, html: a, markdown: o, chart: s }) => JSON.stringify([
670
690
  e,
671
691
  t,
672
692
  n,
@@ -675,19 +695,19 @@ var Ue = (e, { slide: t, totalSlides: n, title: r, imagePrompt: i, html: a, mark
675
695
  a,
676
696
  o,
677
697
  s
678
- ]), We = K(() => ({
698
+ ]), tt = ke(() => ({
679
699
  latest: {
680
700
  presentation: null,
681
701
  steps: null
682
702
  },
683
703
  lastShown: null,
684
- repeats: Ve()
704
+ repeats: Qe()
685
705
  }));
686
- function Ge(e, t) {
706
+ function nt(e, t) {
687
707
  let n = e.latest[t.mode], r = n?.totalSlides === t.totalSlides && (t.slide !== 1 || n.firstTitle === t.title);
688
708
  if (n && r) return n;
689
709
  let i = {
690
- id: U(),
710
+ id: Te(),
691
711
  mode: t.mode,
692
712
  totalSlides: t.totalSlides,
693
713
  firstTitle: t.slide === 1 ? t.title : "",
@@ -697,56 +717,84 @@ function Ge(e, t) {
697
717
  };
698
718
  return e.latest[t.mode] = i, i;
699
719
  }
700
- function Ke(e, t, n, r) {
720
+ function rt(e, t, n, r) {
701
721
  t.current = n.slide, t.shownAt = Date.now(), e.lastShown = t;
702
722
  let i = n.mode === "steps" ? "step" : "slide", { uuid: a, ...o } = r;
703
723
  return {
704
724
  ...o,
705
725
  message: `${i} ${n.slide} of ${n.totalSlides} is on the screen again, as it was`,
706
- instructions: O(n),
726
+ instructions: M(n),
707
727
  instructionsRequired: !0,
708
- sequence: He(n)
728
+ sequence: $e(n)
709
729
  };
710
730
  }
711
- function qe(e, t) {
731
+ function it(e, t) {
712
732
  if (e.mode !== "steps") return e.title ? `A presentation slide titled "${e.title}". ${e.imagePrompt}` : e.imagePrompt;
713
733
  let n = e.title ? `, "${e.title}"` : "";
714
734
  return [
715
735
  `An instructional illustration of step ${e.slide} of ${e.totalSlides}${n}. ${e.imagePrompt}`,
716
- t ? "The reference image is the previous step: keep the same objects, hands, tools and setting, and show what this step changes." : "",
736
+ t ? at : "",
717
737
  "Show the action clearly, with little or no text."
718
738
  ].filter(Boolean).join(" ");
719
739
  }
720
- async function Je(e, t, n) {
721
- if (n.html) return {
722
- html: n.html,
723
- prompt: ""
724
- };
740
+ var at = "The reference image is the previous step: keep the same objects, hands, tools and setting, and show what this step changes.";
741
+ async function ot(e, t, n) {
742
+ if (n.mode !== "steps") return [];
743
+ let r = W(t.slides.get(n.slide - 1)).imagePath;
744
+ return r ? await De(e, [r]) : [];
745
+ }
746
+ var st = (e, t) => [
747
+ e.mode === "steps" ? `An instructional illustration for step ${e.slide} of ${e.totalSlides}${e.title ? `, "${e.title}"` : ""}. ${e.imagePrompt}` : `A picture for a presentation slide${e.title ? ` titled "${e.title}"` : ""}. ${e.imagePrompt}`,
748
+ t ? at : "",
749
+ e.markdown ? "Keep the subject in the middle: the picture is cropped to a tall frame." : "",
750
+ "No text, letters or numbers in the picture."
751
+ ].filter(Boolean).join(" ");
752
+ async function ct(e, t, n) {
725
753
  if (n.chart) return {
726
754
  chart: n.chart,
727
755
  prompt: ""
728
756
  };
729
- if (n.markdown) return {
730
- html: await J(n.markdown),
731
- markdown: n.markdown,
732
- prompt: ""
733
- };
734
- let r = t.slides.get(n.slide - 1), i = n.mode === "steps" ? z(r).imagePath : void 0, a = i ? await W(e, [i]) : [], o = qe(n, a.length > 0), s = await G(e, o, a), { imageData: c, imagePath: l } = z(s);
735
- return c ? {
736
- imageData: c,
737
- ...l && { imagePath: l },
738
- prompt: o
757
+ if (n.html || n.markdown) {
758
+ let r = n.html ? { html: n.html } : {
759
+ html: await Ve(n.markdown ?? ""),
760
+ markdown: n.markdown ?? ""
761
+ }, i = y(r.html);
762
+ if (i && !n.imagePrompt) return { failed: {
763
+ message: O,
764
+ sequence: null
765
+ } };
766
+ if (!i) return {
767
+ ...r,
768
+ prompt: ""
769
+ };
770
+ let a = await ot(e, t, n), o = st(n, a.length > 0), s = await J(e, o, a), { imageData: c, imagePath: l } = W(s);
771
+ return c ? {
772
+ ...r,
773
+ imageData: c,
774
+ ...l && { imagePath: l },
775
+ prompt: o
776
+ } : {
777
+ ...r,
778
+ prompt: o,
779
+ pictureFailed: s.message
780
+ };
781
+ }
782
+ let r = await ot(e, t, n), i = it(n, r.length > 0), a = await J(e, i, r), { imageData: o, imagePath: s } = W(a);
783
+ return o ? {
784
+ imageData: o,
785
+ ...s && { imagePath: s },
786
+ prompt: i
739
787
  } : { failed: {
740
- ...s,
788
+ ...a,
741
789
  sequence: null
742
790
  } };
743
791
  }
744
- async function Ye(e, t, n) {
745
- let r = await Je(e, t, n);
792
+ async function lt(e, t, n) {
793
+ let r = await ct(e, t, n);
746
794
  if ("failed" in r) return r.failed;
747
- let { imageData: i, imagePath: a, html: o, markdown: s, chart: c, prompt: l } = r, u = t.id, d = await Z(e.files?.artifacts, Y, u, (e) => {
795
+ let { imageData: i, imagePath: a, html: o, markdown: s, chart: c, prompt: l, pictureFailed: u } = r, d = t.id, f = await Q(e.files?.artifacts, He, d, (e) => {
748
796
  let t = e ?? {
749
- id: u,
797
+ id: d,
750
798
  title: "",
751
799
  mode: n.mode,
752
800
  totalSlides: n.totalSlides,
@@ -754,46 +802,47 @@ async function Ye(e, t, n) {
754
802
  };
755
803
  return n.slide === 1 && (t.title = n.title), t.slides[String(n.slide)] = {
756
804
  title: n.title,
757
- imagePrompt: n.imagePrompt,
805
+ imagePrompt: o && !l ? "" : n.imagePrompt,
758
806
  ...a && { imagePath: a },
759
807
  ...o && { html: o },
760
808
  ...s && { markdown: s },
761
809
  ...c && { chart: c }
762
810
  }, t;
763
- }), f = {
811
+ }), p = {
764
812
  ...i && { imageData: i },
765
813
  ...a && { imagePath: a },
766
814
  ...o && { html: o },
767
815
  ...s && { markdown: s },
768
816
  ...c && { chart: c },
769
817
  prompt: l,
770
- slideshowId: u,
818
+ slideshowId: d,
771
819
  slide: n.slide,
772
820
  totalSlides: n.totalSlides,
773
821
  title: n.title,
774
822
  mode: n.mode
775
- }, p = n.mode === "steps" ? "step" : "slide";
823
+ }, m = n.mode === "steps" ? "step" : "slide";
776
824
  return {
777
- data: f,
825
+ data: p,
778
826
  title: n.title || `Slide ${n.slide}`,
779
827
  message: [
780
- `${p} ${n.slide} of ${n.totalSlides} of slideshow "${u}" is on the screen`,
828
+ `${m} ${n.slide} of ${n.totalSlides} of slideshow "${d}" is on the screen`,
781
829
  a ? `saved to ${a}` : "",
782
- d ? "" : Q("slideshow")
830
+ u ? `its picture couldn't be drawn (${u}), so the slide is shown without it` : "",
831
+ f ? "" : $("slideshow")
783
832
  ].filter(Boolean).join("; "),
784
- instructions: O(n),
833
+ instructions: M(n),
785
834
  instructionsRequired: !0,
786
- sequence: He(n)
835
+ sequence: $e(n)
787
836
  };
788
837
  }
789
- async function Xe(e, t) {
790
- let n = E(t);
838
+ async function ut(e, t) {
839
+ let n = A(t);
791
840
  if (typeof n == "string") return {
792
841
  message: n,
793
842
  sequence: null
794
843
  };
795
- let r = We(e), i = Ge(r, n), a = n.mode === "steps";
796
- if (a && n.slide > i.current && i.current > 0 && !H(e, i.shownAt)) {
844
+ let r = tt(e), i = nt(r, n), a = n.mode === "steps";
845
+ if (a && n.slide > i.current && i.current > 0 && !q(e, i.shownAt)) {
797
846
  console.info(`[sequence] holding step ${n.slide} for the user`);
798
847
  let e = i.shownAt === Infinity ? "is still being drawn" : "is still on the screen";
799
848
  return {
@@ -802,15 +851,15 @@ async function Xe(e, t) {
802
851
  };
803
852
  }
804
853
  let o = a ? i.slides.get(n.slide) : void 0;
805
- if (o) return xe(e.currentResult, o) ? {
854
+ if (o) return we(e.currentResult, o) ? {
806
855
  message: `step ${n.slide} of ${n.totalSlides} is already on the screen`,
807
856
  cancelled: !0
808
- } : Ke(r, i, n, o);
809
- let s = r.repeats.claim(Ue(i.id, n));
857
+ } : rt(r, i, n, o);
858
+ let s = r.repeats.claim(et(i.id, n));
810
859
  if ("earlier" in s) {
811
- if (!await s.earlier) return Xe(e, t);
860
+ if (!await s.earlier) return ut(e, t);
812
861
  let a = i.slides.get(n.slide);
813
- return a && r.lastShown !== i ? Ke(r, i, n, a) : {
862
+ return a && r.lastShown !== i ? rt(r, i, n, a) : {
814
863
  message: `slide ${n.slide} of ${n.totalSlides} is already on the screen`,
815
864
  cancelled: !0
816
865
  };
@@ -822,22 +871,22 @@ async function Xe(e, t) {
822
871
  i.current = n.slide, i.shownAt = Infinity;
823
872
  let u = !1;
824
873
  try {
825
- let t = await Ye(e, i, n);
826
- return u = be(t), u && (i.slides.set(n.slide, t), i.current = n.slide, i.shownAt = Date.now(), r.lastShown = i), t;
874
+ let t = await lt(e, i, n);
875
+ return u = Ce(t), u && (i.slides.set(n.slide, t), i.current = n.slide, i.shownAt = Date.now(), r.lastShown = i), t;
827
876
  } finally {
828
877
  c(u), !u && i.current === n.slide && (i.current = l.current, i.shownAt = l.shownAt);
829
878
  }
830
879
  }
831
880
  //#endregion
832
881
  //#region src/core/storyboard.ts
833
- var Ze = ({ id: e, title: t, totalPanels: n }) => ({
882
+ var dt = ({ id: e, title: t, totalPanels: n }) => ({
834
883
  step: 0,
835
884
  total: n,
836
885
  kind: "story",
837
886
  label: `The cast of "${t}"`,
838
887
  onShown: "introduce the characters",
839
888
  nextCall: `call presentPanel for panel 1 of ${n} with storyboardId "${e}"`
840
- }), Qe = ({ id: e, totalPanels: t }, n, r) => ({
889
+ }), ft = ({ id: e, totalPanels: t }, n, r) => ({
841
890
  step: n,
842
891
  total: t,
843
892
  kind: "story",
@@ -845,21 +894,21 @@ var Ze = ({ id: e, title: t, totalPanels: n }) => ({
845
894
  onShown: "tell that part of the story",
846
895
  nextCall: `call presentPanel for panel ${n + 1} of ${t} with storyboardId "${e}"`,
847
896
  ...r.length > 0 && { waitsForUser: !0 }
848
- }), $e = (e, t) => e ? `${e}. ${t}` : t, et = (e, { name: t, description: n }) => $e(e, `Character reference sheet of ${t}: ${n}. Full body, front, side and back views, on a plain white background. No text or labels.`);
849
- async function tt(e, t) {
850
- let n = j(t);
897
+ }), pt = (e, t) => e ? `${e}. ${t}` : t, mt = (e, { name: t, description: n }) => pt(e, `Character reference sheet of ${t}: ${n}. Full body, front, side and back views, on a plain white background. No text or labels.`);
898
+ async function ht(e, t) {
899
+ let n = F(t);
851
900
  if (typeof n == "string") return {
852
901
  message: n,
853
902
  sequence: null
854
903
  };
855
- let r = await Promise.all(n.characters.map((t) => G(e, et(n.style, t)))), i = r.map(z), a = r.find((e, t) => !i[t]?.imageData);
904
+ let r = await Promise.all(n.characters.map((t) => J(e, mt(n.style, t)))), i = r.map(W), a = r.find((e, t) => !i[t]?.imageData);
856
905
  if (i.every(({ imageData: e }) => !e) && a) return {
857
906
  ...a,
858
907
  message: `the character sheets couldn't be made: ${a.message}`,
859
908
  sequence: null
860
909
  };
861
910
  let o = {
862
- id: U(),
911
+ id: Te(),
863
912
  ...n,
864
913
  characters: n.characters.map((e, t) => {
865
914
  let n = i[t]?.imagePath;
@@ -869,7 +918,7 @@ async function tt(e, t) {
869
918
  };
870
919
  }),
871
920
  panels: {}
872
- }, s = await Z(e.files?.artifacts, X, 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;
921
+ }, s = await Q(e.files?.artifacts, Z, 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;
873
922
  return {
874
923
  data: {
875
924
  storyboardId: o.id,
@@ -890,39 +939,39 @@ async function tt(e, t) {
890
939
  `storyboard "${o.id}" is ready with ${o.totalPanels} panels; the cast is on the screen`,
891
940
  c.length ? `character sheets saved to ${c.join(", ")}` : "",
892
941
  l.length ? `no sheet for ${l.join("; ")}: they will be drawn from their description` : "",
893
- s ? "" : Q("storyboard")
942
+ s ? "" : $("storyboard")
894
943
  ].filter(Boolean).join("; "),
895
- instructions: M(o),
944
+ instructions: I(o),
896
945
  instructionsRequired: !0,
897
- sequence: Ze(o)
946
+ sequence: dt(o)
898
947
  };
899
948
  }
900
- function nt(e, t, n) {
901
- let r = [$e(e.style, `Panel ${t.panel} of ${e.totalPanels} of the illustrated story "${e.title}". ${t.imagePrompt}`)], i = 0, a = n.map(({ character: e, hasSheet: t }) => t ? `${e.name} is the character in reference image ${++i}` : `${e.name}: ${e.description}`);
949
+ function gt(e, t, n) {
950
+ let r = [pt(e.style, `Panel ${t.panel} of ${e.totalPanels} of the illustrated story "${e.title}". ${t.imagePrompt}`)], i = 0, a = n.map(({ character: e, hasSheet: t }) => t ? `${e.name} is the character in reference image ${++i}` : `${e.name}: ${e.description}`);
902
951
  return a.length && r.push(`${a.join(". ")}.`), i && r.push("Draw each character exactly as in their reference image: the same face, hair, clothes and colors. Use the reference images only for how the characters look, not for their pose or the background."), r.push("No captions, speech bubbles or other text in the picture."), r.join(" ");
903
952
  }
904
- async function rt(e, t, n) {
953
+ async function _t(e, t, n) {
905
954
  let r = [], i = [];
906
955
  for (let a of n.characters) {
907
- let n = t.characters.find((e) => x(e.name, a));
956
+ let n = t.characters.find((e) => w(e.name, a));
908
957
  if (!n) r.push(a);
909
958
  else if (!i.some((e) => e.character === n)) {
910
- let [t] = n.imagePath ? await W(e, [n.imagePath]) : [];
959
+ let [t] = n.imagePath ? await De(e, [n.imagePath]) : [];
911
960
  i.push({
912
961
  character: n,
913
962
  sheet: t ?? null
914
963
  });
915
964
  }
916
965
  }
917
- let a = i.map(({ sheet: e }) => e).filter((e) => !!e), o = nt(t, n, i.map(({ character: e, sheet: t }) => ({
966
+ let a = i.map(({ sheet: e }) => e).filter((e) => !!e), o = gt(t, n, i.map(({ character: e, sheet: t }) => ({
918
967
  character: e,
919
968
  hasSheet: !!t
920
- }))), s = await G(e, o, a), { imageData: c, imagePath: l } = z(s);
969
+ }))), s = await J(e, o, a), { imageData: c, imagePath: l } = W(s);
921
970
  if (!c) return {
922
971
  ...s,
923
972
  sequence: null
924
973
  };
925
- let u = n.panel < t.totalPanels && n.choices.length >= 2 ? n.choices : [], d = await Z(e.files?.artifacts, X, t.id, (e) => {
974
+ let u = n.panel < t.totalPanels && n.choices.length >= 2 ? n.choices : [], d = await Q(e.files?.artifacts, Z, t.id, (e) => {
926
975
  let r = e ?? t;
927
976
  return u.length && (r.interactive = !0), r.panels[String(n.panel)] = {
928
977
  caption: n.caption,
@@ -948,25 +997,25 @@ async function rt(e, t, n) {
948
997
  `panel ${n.panel} of ${t.totalPanels} is on the screen`,
949
998
  l ? `saved to ${l}` : "",
950
999
  r.length ? `not in the cast, so drawn from the prompt alone: ${r.join(", ")}` : "",
951
- d ? "" : Q("storyboard")
1000
+ d ? "" : $("storyboard")
952
1001
  ].filter(Boolean).join("; "),
953
- instructions: F(t, n.panel, u),
1002
+ instructions: z(t, n.panel, u),
954
1003
  instructionsRequired: !0,
955
- sequence: Qe(t, n.panel, u)
1004
+ sequence: ft(t, n.panel, u)
956
1005
  };
957
1006
  }
958
- var it = K(() => ({
959
- repeats: Ve(),
1007
+ var vt = ke(() => ({
1008
+ repeats: Qe(),
960
1009
  awaitingChoice: /* @__PURE__ */ new Map()
961
1010
  }));
962
- async function $(e, t) {
963
- let n = P(t);
1011
+ async function yt(e, t) {
1012
+ let n = R(t);
964
1013
  if (!n) return {
965
- message: N,
1014
+ message: L,
966
1015
  sequence: null
967
1016
  };
968
- let { storyboardId: r, panel: i } = n, { repeats: a, awaitingChoice: o } = it(e), s = o.get(r);
969
- if (s && i > s.panel && !H(e, s.shownAt)) return console.info(`[sequence] holding panel ${i} for the user`), {
1017
+ let { storyboardId: r, panel: i } = n, { repeats: a, awaitingChoice: o } = vt(e), s = o.get(r);
1018
+ if (s && i > s.panel && !q(e, s.shownAt)) return console.info(`[sequence] holding panel ${i} for the user`), {
970
1019
  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.`,
971
1020
  cancelled: !0
972
1021
  };
@@ -974,7 +1023,7 @@ async function $(e, t) {
974
1023
  if ("earlier" in c) return await c.earlier ? {
975
1024
  message: `panel ${i} is already on the screen`,
976
1025
  cancelled: !0
977
- } : $(e, t);
1026
+ } : yt(e, t);
978
1027
  let { settle: l } = c, u = {
979
1028
  panel: i,
980
1029
  shownAt: Infinity
@@ -982,7 +1031,7 @@ async function $(e, t) {
982
1031
  o.set(r, u);
983
1032
  let f = () => o.get(r) === u, p = !1;
984
1033
  try {
985
- let t = await ze(e.files?.artifacts, X, r);
1034
+ let t = await Xe(e.files?.artifacts, Z, r);
986
1035
  if (!t) return {
987
1036
  message: `there is no storyboard "${r}"; call defineStoryboard first`,
988
1037
  sequence: null
@@ -991,8 +1040,8 @@ async function $(e, t) {
991
1040
  message: `storyboard "${t.id}" has ${t.totalPanels} panels`,
992
1041
  sequence: null
993
1042
  };
994
- let a = await rt(e, t, n);
995
- p = !!z(a).imageData;
1043
+ let a = await _t(e, t, n);
1044
+ p = !!W(a).imageData;
996
1045
  let s = a.data;
997
1046
  return p && f() && (s?.choices?.length ? o.set(r, {
998
1047
  panel: i,
@@ -1004,21 +1053,21 @@ async function $(e, t) {
1004
1053
  }
1005
1054
  //#endregion
1006
1055
  //#region src/core/index.ts
1007
- var at = {
1008
- toolDefinition: A,
1056
+ var bt = {
1057
+ toolDefinition: P,
1009
1058
  generatingMessage: "Making the slide...",
1010
1059
  isEnabled: () => !0,
1011
- execute: (e, t) => Xe(e, t)
1012
- }, ot = {
1013
- toolDefinition: I,
1060
+ execute: (e, t) => ut(e, t)
1061
+ }, xt = {
1062
+ toolDefinition: V,
1014
1063
  generatingMessage: "Drawing the characters...",
1015
1064
  isEnabled: () => !0,
1016
- execute: (e, t) => tt(e, t)
1017
- }, st = {
1018
- toolDefinition: L,
1065
+ execute: (e, t) => ht(e, t)
1066
+ }, St = {
1067
+ toolDefinition: H,
1019
1068
  generatingMessage: "Drawing the panel...",
1020
1069
  isEnabled: () => !0,
1021
- execute: (e, t) => $(e, t)
1070
+ execute: (e, t) => yt(e, t)
1022
1071
  };
1023
1072
  //#endregion
1024
- export { O as A, ne as B, ve as C, E as D, P as E, s as F, m as I, l as L, ce as M, r as N, j as O, o as P, n as R, w as S, F as T, A as _, X as a, C as b, le as c, pe as d, fe as f, _ as g, L as h, Y as i, h as j, x as k, I as l, ue as m, st as n, ze as o, N as p, at as r, J as s, ot as t, de as u, k as v, M as w, T as x, v as y, t as z };
1073
+ export { w as A, g as B, O as C, R as D, z as E, o as F, y as H, s as I, h as L, b as M, de as N, A as O, r as P, l as R, D as S, I as T, ie as U, t as V, re as W, P as _, Z as a, E as b, pe as c, _e as d, ge as f, fe as g, H as h, He as i, M as j, F as k, V as l, me as m, St as n, Xe as o, L as p, bt as r, Ve as s, xt as t, he as u, N as v, B as w, k as x, x as y, n as z };