@gui-chat-plugin/sequence 0.6.2 → 0.7.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,33 +154,33 @@ 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), 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 = `
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; }", g = `
158
158
  html, body { margin: 0; width: ${t}px; height: 720px; overflow: hidden; }
159
159
  html:not(.ready) body { visibility: hidden; }
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 = {
160
+ ${h}`, _ = "{{image}}", v = /(\bsrc\s*=\s*["']?|\burl\(\s*["']?)(?:\{\{image\}\}|%7B%7Bimage%7D%7D)/gi, ee = /^data:image\/[a-z0-9.+-]+;base64,[a-z0-9+/=]+$/i, te = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7", y = /(<pre\b[\s\S]*?<\/pre>|<code\b[\s\S]*?<\/code>)/gi, b = (e) => e.split(y).some((e, t) => t % 2 == 0 && new RegExp(v.source, "i").test(e)), ne = {
161
161
  "&amp;": "&",
162
162
  "&lt;": "<",
163
163
  "&gt;": ">",
164
164
  "&quot;": "\"",
165
165
  "&#39;": "'"
166
- }, ie = (e) => {
167
- for (let t of e.split(v).filter((e, t) => t % 2 == 0)) for (let e of t.match(/<img\b[^>]*>/gi) ?? []) {
168
- if (!new RegExp(_.source, "i").test(e)) continue;
166
+ }, re = (e) => {
167
+ for (let t of e.split(y).filter((e, t) => t % 2 == 0)) for (let e of t.match(/<img\b[^>]*>/gi) ?? []) {
168
+ if (!new RegExp(v.source, "i").test(e)) continue;
169
169
  let t = /\balt\s*=\s*(?:"([^"]*)"|'([^']*)')/i.exec(e);
170
- return (t?.[1] ?? t?.[2] ?? "").replace(/&(?:amp|lt|gt|quot|#39);/g, (e) => re[e] ?? e).trim();
170
+ return (t?.[1] ?? t?.[2] ?? "").replace(/&(?:amp|lt|gt|quot|#39);/g, (e) => ne[e] ?? e).trim();
171
171
  }
172
172
  return "";
173
- }, ae = (e, t) => {
174
- let n = t && te.test(t) ? t : ne;
175
- return e.split(v).map((e, t) => t % 2 == 1 ? e : e.replace(_, (e, t) => t + n)).join("");
173
+ }, ie = (e, t) => {
174
+ let n = t && ee.test(t) ? t : te;
175
+ return e.split(y).map((e, t) => t % 2 == 1 ? e : e.replace(v, (e, t) => t + n)).join("");
176
176
  };
177
- function oe(e) {
177
+ function ae(e) {
178
178
  return `<!doctype html>
179
179
  <html lang="en">
180
180
  <head>
181
181
  <meta charset="utf-8">
182
182
  <meta http-equiv="Content-Security-Policy" content="${d}">
183
- <style id="slide-base">${ee}</style>
183
+ <style id="slide-base">${g}</style>
184
184
  <script>${u}<\/script>
185
185
  <script defer src="${i}" integrity="${a}" crossorigin="anonymous"><\/script>
186
186
  </head>
@@ -191,7 +191,7 @@ ${m(e)}
191
191
  }
192
192
  //#endregion
193
193
  //#region src/core/chartSlide.ts
194
- var b = [
194
+ var x = [
195
195
  "bar",
196
196
  "line",
197
197
  "pie",
@@ -200,9 +200,9 @@ var b = [
200
200
  "polarArea",
201
201
  "scatter",
202
202
  "bubble"
203
- ], x = "https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js", se = "sha384-jb8JQMbMoBUzgWatfe6COACi2ljcDdZQ2OxczGA3bGNeWe+6DChMTBJemed7ZnvJ", ce = "\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})();", le = [
203
+ ], oe = "https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js", se = "sha384-jb8JQMbMoBUzgWatfe6COACi2ljcDdZQ2OxczGA3bGNeWe+6DChMTBJemed7ZnvJ", ce = "\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})();", le = [
204
204
  "default-src 'none'",
205
- `script-src 'sha256-TfZZxJX+yWgzYLy7zqsMa85OJEaC+zNLIpKLDZVnUqA=' ${x}`,
205
+ `script-src 'sha256-TfZZxJX+yWgzYLy7zqsMa85OJEaC+zNLIpKLDZVnUqA=' ${oe}`,
206
206
  "style-src 'unsafe-inline'",
207
207
  "img-src data: blob:",
208
208
  "connect-src 'none'",
@@ -224,7 +224,7 @@ function fe(e, t) {
224
224
  <meta http-equiv="Content-Security-Policy" content="${le}">
225
225
  <style>${ue}</style>
226
226
  <script>${ce}<\/script>
227
- <script defer src="${x}" integrity="${se}" crossorigin="anonymous"><\/script>
227
+ <script defer src="${oe}" integrity="${se}" crossorigin="anonymous"><\/script>
228
228
  <script type="application/json" id="chart-config">${de(t)}<\/script>
229
229
  </head>
230
230
  <body>
@@ -236,53 +236,54 @@ ${e ? `<h1>${p(e)}</h1>` : ""}
236
236
  }
237
237
  //#endregion
238
238
  //#region src/core/definitions.ts
239
- var S = "presentSlide", pe = "defineStoryboard", C = "presentPanel", me = 4, he = 12, ge = 3, w = /^[0-9a-f]{12}$/, T = (e) => typeof e == "object" && !!e && !Array.isArray(e), E = (e) => typeof e == "string" ? e.trim() : "", D = (e, t) => e.toLowerCase() === t.toLowerCase(), O = (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", ve = `presentSlide's slide is too long: keep its html, markdown or chart under ${r} characters`, ye = `presentSlide's chart must be a Chart.js configuration: an object with type (${b.join(", ")}), data ({ labels, datasets }) and optionally options`;
240
- function be(e) {
239
+ var pe = "presentSlide", me = "defineStoryboard", he = "presentPanel", ge = 4, _e = 12, ve = 3, S = /^[0-9a-f]{12}$/, C = (e) => typeof e == "object" && !!e && !Array.isArray(e), w = (e) => typeof e == "string" ? e.trim() : "", T = (e, t) => e.toLowerCase() === t.toLowerCase(), E = (e) => typeof e == "number" && Number.isInteger(e), D = "presentSlide needs slide and totalSlides (whole numbers, slide from 1 to totalSlides), and one of imagePrompt, imageUrl, html, markdown or chart", O = `presentSlide's slide is too long: keep its html, markdown or chart under ${r} characters`, k = `presentSlide's chart must be a Chart.js configuration: an object with type (${x.join(", ")}), data ({ labels, datasets }) and optionally options`;
240
+ function ye(e) {
241
241
  let t = e;
242
242
  if (typeof t == "string") try {
243
243
  t = JSON.parse(t);
244
244
  } catch {
245
245
  return null;
246
246
  }
247
- if (!T(t) || !T(t.data)) return null;
247
+ if (!C(t) || !C(t.data)) return null;
248
248
  let n = t.type;
249
- return !b.some((e) => e === n) || t.options !== void 0 && !T(t.options) ? null : t;
249
+ return !x.some((e) => e === n) || t.options !== void 0 && !C(t.options) ? null : t;
250
250
  }
251
- function xe(e) {
252
- let { slide: t, totalSlides: n, title: r, imagePrompt: i } = e, a = E(e.html), o = a ? "" : E(e.markdown), s = !a && !o && e.chart !== void 0 && e.chart !== null;
253
- if (!O(t) || !O(n) || t < 1 || n < t || !a && !o && !s && !E(i)) return _e;
254
- let c = s ? be(e.chart) : null;
255
- if (s && !c) return ye;
256
- if (Math.max(a.length, o.length, c ? JSON.stringify(c).length : 0) > 6e4) return ve;
257
- let l = !a && !o && !c, u = !!a && y(a);
251
+ function A(e) {
252
+ let { slide: t, totalSlides: n, title: r, imagePrompt: i } = e, a = w(e.imageUrl), o = w(e.html), s = o ? "" : w(e.markdown), c = !o && !s && e.chart !== void 0 && e.chart !== null;
253
+ if (!E(t) || !E(n) || t < 1 || n < t || !o && !s && !c && !w(i) && !a) return D;
254
+ let l = c ? ye(e.chart) : null;
255
+ if (c && !l) return k;
256
+ if (Math.max(o.length, s.length, l ? JSON.stringify(l).length : 0) > 6e4) return O;
257
+ let u = !o && !s && !l, d = !!o && b(o), f = u || d || !!s;
258
258
  return {
259
259
  slide: t,
260
260
  totalSlides: n,
261
261
  title: typeof r == "string" ? r : "",
262
- imagePrompt: l ? String(i) : u || o ? E(i) : "",
263
- ...a && { html: a },
264
- ...o && { markdown: o },
265
- ...c && { chart: c },
262
+ imagePrompt: u ? typeof i == "string" ? i : "" : f ? w(i) : "",
263
+ ...f && a && { imageUrl: a },
264
+ ...o && { html: o },
265
+ ...s && { markdown: s },
266
+ ...l && { chart: l },
266
267
  mode: e.mode === "steps" ? "steps" : "presentation"
267
268
  };
268
269
  }
269
- var Se = "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.", k = ({ slide: e, totalSlides: t, title: n, mode: r }) => {
270
+ 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 }) => {
270
271
  let i = n ? ` ("${n}")` : "";
271
272
  if (r === "steps") {
272
273
  let n = `Step ${e} of ${t}${i}`;
273
274
  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.`;
274
275
  }
275
276
  let a = `Slide ${e} of ${t}${i}`;
276
- return e < t ? `${a} is now on the screen. Explain it: ${Se} 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: ${Se} Then wrap up the slideshow.`;
277
- }, Ce = [
278
- `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").`,
277
+ 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.`;
278
+ }, be = [
279
+ `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 picture on the slide (a photo, a scene, an object beside the text), give imagePrompt (a generated picture) or imageUrl (a picture from the web) too and put <img src="${_}" alt="..." class="..."> where it goes, sized by its classes (for example class="w-1/2 h-full object-cover rounded-2xl").`,
279
280
  "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).",
280
281
  "CSS animations, transitions and scripts don't play: animate only with data-animation. A <style> for layout is allowed (and Google Fonts by @import)."
281
- ].join(" "), we = `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}) on a line of its own: the slide is then two columns, the text on the left and the picture on the right. Without imagePrompt, the alt text is what is drawn.`, Te = `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.`, Ee = "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.", A = {
282
+ ].join(" "), xe = `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 \\$, and & % # inside \\text{} as \\& \\% \\#. For one picture on the slide, give imagePrompt (a generated picture) or imageUrl (a picture from the web) too and put ![what it shows](${_}) on a line of its own: the slide is then two columns, the text on the left and the picture on the right. Without imagePrompt, the alt text is what is drawn.`, Se = `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 ${x.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 picture on it: imagePrompt for the picture, and {{image}} where it goes. When the slide is about a real, particular thing (a person, a building, a product, an artwork) and you have the address of a picture of it (an image file, from a search or the user), give that as imageUrl instead of imagePrompt: it is shown as it is. 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 = {
282
283
  type: "function",
283
- name: S,
284
- prompt: Ee,
285
- 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.",
284
+ name: pe,
285
+ prompt: N,
286
+ description: "Show one slide of a slideshow, full screen: a picture generated from imagePrompt or from the web (imageUrl), a chart (chart), a slide written in Markdown with TeX math (markdown), or a slide written in HTML (html). Give one of them; an HTML or Markdown slide can also hold one picture (imagePrompt or imageUrl, 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.",
286
287
  parameters: {
287
288
  type: "object",
288
289
  properties: {
@@ -302,17 +303,21 @@ var Se = "teach its subject as a presenter speaking to the audience, and cover e
302
303
  type: "string",
303
304
  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}}."
304
305
  },
306
+ imageUrl: {
307
+ type: "string",
308
+ description: "A picture from the web, shown instead of a generated one: the https address of an image file (PNG, JPEG, GIF or WebP) of a real, particular thing, from a search or the user. Never an address you made up, or a web page's. With imagePrompt too, the picture is drawn from imagePrompt if the address can't be fetched. With html or markdown, it is the one picture placed where the slide has {{image}}."
309
+ },
305
310
  html: {
306
311
  type: "string",
307
- description: Ce
312
+ description: be
308
313
  },
309
314
  markdown: {
310
315
  type: "string",
311
- description: we
316
+ description: xe
312
317
  },
313
318
  chart: {
314
319
  type: "string",
315
- description: Te
320
+ description: Se
316
321
  },
317
322
  mode: {
318
323
  type: "string",
@@ -327,49 +332,49 @@ var Se = "teach its subject as a presenter speaking to the audience, and cover e
327
332
  ]
328
333
  }
329
334
  };
330
- function j(e) {
335
+ function F(e) {
331
336
  let { totalPanels: t } = e;
332
- if (!O(t) || t < 1 || t > 12) return "totalPanels must be a whole number from 1 to 12";
337
+ if (!E(t) || t < 1 || t > 12) return "totalPanels must be a whole number from 1 to 12";
333
338
  let n = [];
334
339
  for (let t of Array.isArray(e.characters) ? e.characters : []) {
335
- let e = T(t) ? E(t.name) : "", r = T(t) ? E(t.description) : "";
340
+ let e = C(t) ? w(t.name) : "", r = C(t) ? w(t.description) : "";
336
341
  if (!e || !r) return "every character needs a name and a description";
337
- if (n.some((t) => D(t.name, e))) return `two characters are named ${e}`;
342
+ if (n.some((t) => T(t.name, e))) return `two characters are named ${e}`;
338
343
  n.push({
339
344
  name: e,
340
345
  description: r
341
346
  });
342
347
  }
343
348
  return n.length < 1 || n.length > 4 ? "a storyboard has 1 to 4 characters" : {
344
- title: E(e.title),
345
- style: E(e.style),
349
+ title: w(e.title),
350
+ style: w(e.style),
346
351
  totalPanels: t,
347
352
  characters: n,
348
353
  interactive: e.interactive === !0
349
354
  };
350
355
  }
351
- 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";
352
- function P(e) {
353
- let { panel: t } = e, n = E(e.storyboardId), r = E(e.imagePrompt);
354
- if (!n || !r || !O(t) || t < 1) return null;
355
- let i = (e) => (Array.isArray(e) ? e : []).map(E).filter(Boolean);
356
+ 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";
357
+ function R(e) {
358
+ let { panel: t } = e, n = w(e.storyboardId), r = w(e.imagePrompt);
359
+ if (!n || !r || !E(t) || t < 1) return null;
360
+ let i = (e) => (Array.isArray(e) ? e : []).map(w).filter(Boolean);
356
361
  return {
357
362
  storyboardId: n,
358
363
  panel: t,
359
364
  characters: i(e.characters),
360
365
  imagePrompt: r,
361
- caption: E(e.caption),
366
+ caption: w(e.caption),
362
367
  choices: i(e.choices).slice(0, 3)
363
368
  };
364
369
  }
365
- function F(e, t, n) {
370
+ function z(e, t, n) {
366
371
  let { id: r, totalPanels: i } = e;
367
372
  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.`;
368
373
  }
369
- var I = "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.", L = {
374
+ 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.", Ce = {
370
375
  type: "function",
371
- name: pe,
372
- prompt: I,
376
+ name: me,
377
+ prompt: B,
373
378
  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.",
374
379
  parameters: {
375
380
  type: "object",
@@ -416,9 +421,9 @@ var I = "When the user asks for a story, a picture book, a comic or a storyboard
416
421
  "characters"
417
422
  ]
418
423
  }
419
- }, R = {
424
+ }, we = {
420
425
  type: "function",
421
- name: C,
426
+ name: he,
422
427
  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.",
423
428
  parameters: {
424
429
  type: "object",
@@ -457,34 +462,34 @@ var I = "When the user asks for a story, a picture book, a comic or a storyboard
457
462
  "imagePrompt"
458
463
  ]
459
464
  }
460
- }, z = (e) => typeof e == "object" && !!e && !Array.isArray(e), De = (e) => z(e) && typeof e.message == "string";
461
- function B(e) {
462
- let t = z(e?.data) ? e.data : {};
465
+ }, V = (e) => typeof e == "object" && !!e && !Array.isArray(e), Te = (e) => V(e) && typeof e.message == "string";
466
+ function H(e) {
467
+ let t = V(e?.data) ? e.data : {};
463
468
  return {
464
469
  ...typeof t.imageData == "string" && { imageData: t.imageData },
465
470
  ...typeof t.imagePath == "string" && { imagePath: t.imagePath }
466
471
  };
467
472
  }
468
- function V(e) {
469
- let t = z(e?.data) ? e.data : {};
473
+ function U(e) {
474
+ let t = V(e?.data) ? e.data : {};
470
475
  return typeof t.html == "string" ? t.html : "";
471
476
  }
472
- function H(e) {
473
- let t = z(e?.data) ? e.data : {};
474
- return z(t.chart) ? JSON.stringify(t.chart) : "";
477
+ function W(e) {
478
+ let t = V(e?.data) ? e.data : {};
479
+ return V(t.chart) ? JSON.stringify(t.chart) : "";
475
480
  }
476
- var Oe = (e) => !!B(e).imageData || !!V(e) || !!H(e);
477
- function ke(e, t) {
478
- let n = B(e), r = B(t);
481
+ var Ee = (e) => !!H(e).imageData || !!U(e) || !!W(e);
482
+ function De(e, t) {
483
+ let n = H(e), r = H(t);
479
484
  if (n.imagePath && r.imagePath) return n.imagePath === r.imagePath;
480
485
  if (n.imageData) return n.imageData === r.imageData;
481
- let i = V(e);
482
- if (i) return i === V(t);
483
- let a = H(e);
484
- return !!a && a === H(t);
486
+ let i = U(e);
487
+ if (i) return i === U(t);
488
+ let a = W(e);
489
+ return !!a && a === W(t);
485
490
  }
486
- var U = (e, t) => e.userSpokeAt === void 0 || e.userSpokeAt > t, W = () => crypto.randomUUID().replace(/-/g, "").slice(0, 12), Ae = "artifacts/";
487
- async function G(e, t) {
491
+ var Oe = (e, t) => e.userSpokeAt === void 0 || e.userSpokeAt > t, ke = () => crypto.randomUUID().replace(/-/g, "").slice(0, 12), Ae = "artifacts/";
492
+ async function je(e, t) {
488
493
  let n = e.files?.artifacts;
489
494
  if (!e.app?.editImages || !n) return [];
490
495
  let r = [];
@@ -493,24 +498,24 @@ async function G(e, t) {
493
498
  } catch {}
494
499
  return r;
495
500
  }
496
- async function K(e, t, n = []) {
501
+ async function G(e, t, n = []) {
497
502
  let r = e.app, i = r?.editImages, a = r?.generateImage;
498
503
  try {
499
504
  let e;
500
505
  if (n.length && i) e = await i(t, [...n]);
501
506
  else if (a) e = await a(t);
502
507
  else return { message: "image generation isn't available" };
503
- return De(e) ? e : { message: "image generation returned an unrecognized result" };
508
+ return Te(e) ? e : { message: "image generation returned an unrecognized result" };
504
509
  } catch (e) {
505
510
  return { message: `image generation failed: ${e instanceof Error ? e.message : String(e)}` };
506
511
  }
507
512
  }
508
- var je = 50;
509
- function q(e) {
513
+ var Me = 50;
514
+ function Ne(e) {
510
515
  let t = /* @__PURE__ */ new Map();
511
516
  return (n) => {
512
517
  let r = n.conversationId ?? "", i = t.get(r);
513
- if (i === void 0 ? i = e() : t.delete(r), t.set(r, i), t.size > je) {
518
+ if (i === void 0 ? i = e() : t.delete(r), t.set(r, i), t.size > Me) {
514
519
  let e = t.keys().next().value;
515
520
  e !== void 0 && t.delete(e);
516
521
  }
@@ -519,45 +524,45 @@ function q(e) {
519
524
  }
520
525
  //#endregion
521
526
  //#region src/core/markdownSlide.ts
522
- var J = "slide-md", Me = "slide-md-split", Y = "slide-md-text", Ne = "slide-md-picture", Pe = .8, Fe = `
523
- .${J} { 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; }
524
- .${J} > * { margin: 0; }
525
- .${J} h1 { font-size: 1.9em; font-weight: 800; color: #1e3a8a; line-height: 1.15; }
526
- .${J} h2 { font-size: 1.5em; font-weight: 700; color: #1e40af; line-height: 1.2; }
527
- .${J} h3 { font-size: 1.2em; font-weight: 700; color: #334155; }
528
- .${J} ul, .${J} ol { padding-left: 1.3em; display: flex; flex-direction: column; gap: 0.3em; }
529
- .${J} ul { list-style: disc; }
530
- .${J} ol { list-style: decimal; }
531
- .${J} li > ul, .${J} li > ol { margin-top: 0.3em; font-size: 0.9em; }
532
- .${J} li::marker { color: #2563eb; }
533
- .${J} strong { font-weight: 700; color: #1e3a8a; }
534
- .${J} em { font-style: italic; }
535
- .${J} a { color: #2563eb; text-decoration: underline; }
536
- .${J} code { font-family: ui-monospace, monospace; font-size: 0.85em; background: #f1f5f9; border-radius: 0.2em; padding: 0.05em 0.3em; }
537
- .${J} pre { background: #0f172a; color: #e2e8f0; border-radius: 0.4em; padding: 0.6em 0.8em; font-size: 0.75em; overflow: hidden; }
538
- .${J} pre code { background: none; padding: 0; color: inherit; }
539
- .${J} blockquote { border-left: 0.2em solid #93c5fd; padding-left: 0.8em; color: #475569; font-style: italic; }
540
- .${J} table { border-collapse: collapse; font-size: 0.85em; align-self: flex-start; }
541
- .${J} th, .${J} td { border: 1px solid #cbd5e1; padding: 0.25em 0.7em; text-align: left; }
542
- .${J} th { background: #eff6ff; font-weight: 700; }
543
- .${J} hr { border: 0; border-top: 2px solid #e2e8f0; }
544
- .${J} img { max-width: 100%; max-height: 60%; }
545
- .${J}.${Me} { flex-direction: row; align-items: center; gap: 48px; }
546
- .${J} .${Y} { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; justify-content: center; gap: 0.5em; }
547
- .${J} .${Y} > * { margin: 0; }
548
- .${J} .${Ne} { 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); }
549
- .${J} .math-display { display: block; text-align: center; font-size: 1.15em; }
550
- .${J} math { font-family: "Latin Modern Math", "STIX Two Math", "Cambria Math", math; }
551
- .${J} mtd { padding: 0.1em 0.4em; }
552
- .${J} mtd:first-child { padding-left: 0; }
553
- .${J} mtd:last-child { padding-right: 0; }
554
- .${J} .math-error { color: #b91c1c; font-family: ui-monospace, monospace; }`;
555
- function Ie(e) {
527
+ var K = "slide-md", Pe = "slide-md-split", q = "slide-md-text", Fe = "slide-md-picture", Ie = .8, Le = `
528
+ .${K} { 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; }
529
+ .${K} > * { margin: 0; }
530
+ .${K} h1 { font-size: 1.9em; font-weight: 800; color: #1e3a8a; line-height: 1.15; }
531
+ .${K} h2 { font-size: 1.5em; font-weight: 700; color: #1e40af; line-height: 1.2; }
532
+ .${K} h3 { font-size: 1.2em; font-weight: 700; color: #334155; }
533
+ .${K} ul, .${K} ol { padding-left: 1.3em; display: flex; flex-direction: column; gap: 0.3em; }
534
+ .${K} ul { list-style: disc; }
535
+ .${K} ol { list-style: decimal; }
536
+ .${K} li > ul, .${K} li > ol { margin-top: 0.3em; font-size: 0.9em; }
537
+ .${K} li::marker { color: #2563eb; }
538
+ .${K} strong { font-weight: 700; color: #1e3a8a; }
539
+ .${K} em { font-style: italic; }
540
+ .${K} a { color: #2563eb; text-decoration: underline; }
541
+ .${K} code { font-family: ui-monospace, monospace; font-size: 0.85em; background: #f1f5f9; border-radius: 0.2em; padding: 0.05em 0.3em; }
542
+ .${K} pre { background: #0f172a; color: #e2e8f0; border-radius: 0.4em; padding: 0.6em 0.8em; font-size: 0.75em; overflow: hidden; }
543
+ .${K} pre code { background: none; padding: 0; color: inherit; }
544
+ .${K} blockquote { border-left: 0.2em solid #93c5fd; padding-left: 0.8em; color: #475569; font-style: italic; }
545
+ .${K} table { border-collapse: collapse; font-size: 0.85em; align-self: flex-start; }
546
+ .${K} th, .${K} td { border: 1px solid #cbd5e1; padding: 0.25em 0.7em; text-align: left; }
547
+ .${K} th { background: #eff6ff; font-weight: 700; }
548
+ .${K} hr { border: 0; border-top: 2px solid #e2e8f0; }
549
+ .${K} img { max-width: 100%; max-height: 60%; }
550
+ .${K}.${Pe} { flex-direction: row; align-items: center; gap: 48px; }
551
+ .${K} .${q} { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; justify-content: center; gap: 0.5em; }
552
+ .${K} .${q} > * { margin: 0; }
553
+ .${K} .${Fe} { 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); }
554
+ .${K} .math-display { display: block; text-align: center; font-size: 1.15em; }
555
+ .${K} math { font-family: "Latin Modern Math", "STIX Two Math", "Cambria Math", math; }
556
+ .${K} mtd { padding: 0.1em 0.4em; }
557
+ .${K} mtd:first-child { padding-left: 0; }
558
+ .${K} mtd:last-child { padding-right: 0; }
559
+ .${K} .math-error { color: #b91c1c; font-family: ui-monospace, monospace; }`;
560
+ function J(e) {
556
561
  let t = e.split("\n").filter((e) => e.trim()).length, n = e.length;
557
562
  return t <= 5 && n <= 250 ? 40 : t <= 8 && n <= 450 ? 34 : t <= 12 && n <= 700 ? 28 : 24;
558
563
  }
559
- var Le = /^[ \t]*(?:\$\$([\s\S]+?)\$\$|\\\[([\s\S]+?)\\\])[ \t]*(?:\n|$)/, Re = /^(?:\$\$(.+?)\$\$|\$(?!\s)((?:\\.|[^\\$\n])+?)(?<!\s)\$(?!\d)|\\\((.+?)\\\))/;
560
- function ze(e) {
564
+ var Re = /^[ \t]*(?:\$\$([\s\S]+?)\$\$|\\\[([\s\S]+?)\\\])[ \t]*(?:\n|$)/, ze = /^(?:\$\$(.+?)\$\$|\$(?!\s)((?:\\.|[^\\$\n])+?)(?<!\s)\$(?!\d)|\\\((.+?)\\\))/;
565
+ function Be(e) {
561
566
  return [{
562
567
  name: "blockMath",
563
568
  level: "block",
@@ -566,7 +571,7 @@ function ze(e) {
566
571
  return t ? t.index + (t[1] ?? "").length : void 0;
567
572
  },
568
573
  tokenizer(e) {
569
- let t = Le.exec(e);
574
+ let t = Re.exec(e);
570
575
  if (t) return {
571
576
  type: "blockMath",
572
577
  raw: t[0],
@@ -579,7 +584,7 @@ function ze(e) {
579
584
  level: "inline",
580
585
  start: (e) => e.match(/(?<!\\)\$|\\\(/)?.index,
581
586
  tokenizer(e) {
582
- let t = Re.exec(e);
587
+ let t = ze.exec(e);
583
588
  if (t) return {
584
589
  type: "inlineMath",
585
590
  raw: t[0],
@@ -590,11 +595,21 @@ function ze(e) {
590
595
  renderer: (t) => e(String(t.text), t.display === !0)
591
596
  }];
592
597
  }
593
- var Be = /(<\/mi>|<\/mn>|<\/mrow>|<mo[^>]*>[)\]]<\/mo>)?(<mi(?: mathvariant="normal")?>[A-Za-z]{2,}<\/mi>)<mo>\u2061<\/mo>/g, Ve = "<mspace width=\"0.1667em\"></mspace>", He = (e) => e.replace(Be, (e, t, n) => `${t ? t + Ve : ""}${n}<mo lspace="0" rspace="0.1667em">\u2061</mo>`);
594
- async function Ue(e) {
598
+ var Ve = /(<\/mi>|<\/mn>|<\/mrow>|<mo[^>]*>[)\]]<\/mo>)?(<mi(?: mathvariant="normal")?>[A-Za-z]{2,}<\/mi>)<mo>\u2061<\/mo>/g, He = "<mspace width=\"0.1667em\"></mspace>", Ue = (e) => e.replace(Ve, (e, t, n) => `${t ? t + He : ""}${n}<mo lspace="0" rspace="0.1667em">\u2061</mo>`), We = /\\(?:text(?:bf|it|rm|sf|tt|normal)?|mbox)\s*\{/g, Ge = (e) => {
599
+ let t = "", n = 0;
600
+ for (let r of e.matchAll(We)) {
601
+ let i = r.index + r[0].length;
602
+ if (i <= n) continue;
603
+ let a = 1, o = i;
604
+ for (; o < e.length && a > 0; o++) e[o] === "\\" ? o++ : e[o] === "{" ? a++ : e[o] === "}" && a--;
605
+ t += e.slice(n, i) + e.slice(i, o).replace(/(?<!\\)((?:\\\\)*)([&%#])/g, "$1\\$2"), n = o;
606
+ }
607
+ return t + e.slice(n);
608
+ };
609
+ async function Ke(e) {
595
610
  let [{ Marked: t }, { default: n }] = await Promise.all([import("marked"), import("katex")]), r = (e, t) => {
596
611
  try {
597
- return He(n.renderToString(e, {
612
+ return Ue(n.renderToString(Ge(e), {
598
613
  output: "mathml",
599
614
  displayMode: t,
600
615
  throwOnError: !0
@@ -606,42 +621,42 @@ async function Ue(e) {
606
621
  gfm: !0,
607
622
  breaks: !1
608
623
  });
609
- i.use({ extensions: ze(r) });
624
+ i.use({ extensions: Be(r) });
610
625
  let a = i.lexer(e), o = a.findIndex((e) => {
611
626
  if (e.type !== "paragraph" || e.tokens?.length !== 1) return !1;
612
627
  let t = e.tokens[0];
613
- return t?.type === "image" ? t.href.trim() === g : t?.type === "text" && t.text.trim() === "{{image}}";
628
+ return t?.type === "image" ? t.href.trim() === _ : t?.type === "text" && t.text.trim() === "{{image}}";
614
629
  });
615
630
  if (o >= 0) {
616
631
  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 ?? "", "");
617
- return `<style>${Fe}</style>
618
- <div class="${J} ${Me}" data-fit style="font-size: ${Math.round(Ie(c) * Pe)}px">
619
- <div class="${Y}">
632
+ return `<style>${Le}</style>
633
+ <div class="${K} ${Pe}" data-fit style="font-size: ${Math.round(J(c) * Ie)}px">
634
+ <div class="${q}">
620
635
  ${s}</div>
621
- <img class="${Ne}" src="${g}" alt="${p(r)}">
636
+ <img class="${Fe}" src="${_}" alt="${p(r)}">
622
637
  </div>`;
623
638
  }
624
639
  let s = await i.parse(e);
625
- return `<style>${Fe}</style>
626
- <div class="${J}" data-fit style="font-size: ${Ie(e)}px">
640
+ return `<style>${Le}</style>
641
+ <div class="${K}" data-fit style="font-size: ${J(e)}px">
627
642
  ${s}</div>`;
628
643
  }
629
644
  //#endregion
630
645
  //#region src/core/records.ts
631
- var We = "slideshows", X = "storyboards", Ge = {}, Ke = /* @__PURE__ */ new WeakMap(), qe = /* @__PURE__ */ new WeakMap();
632
- function Je(e) {
633
- let t = Ke.get(e);
634
- return t || Ke.set(e, t = /* @__PURE__ */ new Map()), t;
646
+ var qe = "slideshows", Y = "storyboards", Je = {}, Ye = /* @__PURE__ */ new WeakMap(), Xe = /* @__PURE__ */ new WeakMap();
647
+ function Ze(e) {
648
+ let t = Ye.get(e);
649
+ return t || Ye.set(e, t = /* @__PURE__ */ new Map()), t;
635
650
  }
636
- function Ye(t, n) {
637
- let r = qe.get(t);
638
- r || qe.set(t, r = /* @__PURE__ */ new Map());
651
+ function Qe(t, n) {
652
+ let r = Xe.get(t);
653
+ r || Xe.set(t, r = /* @__PURE__ */ new Map());
639
654
  let i = r.get(n);
640
655
  return i || r.set(n, i = e()), i;
641
656
  }
642
- var Xe = (e, t) => `${e}/${t}.json`;
643
- async function Ze(e, t) {
644
- let n = Je(e ?? Ge), r = n.get(t);
657
+ var $e = (e, t) => `${e}/${t}.json`;
658
+ async function et(e, t) {
659
+ let n = Ze(e ?? Je), r = n.get(t);
645
660
  if (r) return r;
646
661
  if (!e) return null;
647
662
  try {
@@ -651,14 +666,14 @@ async function Ze(e, t) {
651
666
  return null;
652
667
  }
653
668
  }
654
- async function Qe(e, t, n) {
655
- return w.test(n) ? Ze(e, Xe(t, n)) : null;
669
+ async function tt(e, t, n) {
670
+ return S.test(n) ? et(e, $e(t, n)) : null;
656
671
  }
657
- async function Z(e, t, n, r) {
658
- let i = Xe(t, n), a = e ?? Ge;
659
- return Ye(a, i)(async () => {
660
- let t = r(await Ze(e, i));
661
- if (Je(a).set(i, t), !e) return !1;
672
+ async function X(e, t, n, r) {
673
+ let i = $e(t, n), a = e ?? Je;
674
+ return Qe(a, i)(async () => {
675
+ let t = r(await et(e, i));
676
+ if (Ze(a).set(i, t), !e) return !1;
662
677
  try {
663
678
  return await e.write(i, JSON.stringify(t, null, 2)), !0;
664
679
  } catch (e) {
@@ -666,12 +681,12 @@ async function Z(e, t, n, r) {
666
681
  }
667
682
  });
668
683
  }
669
- var Q = (e) => `the ${e} could not be saved, so it lasts only until the app or server restarts`, $e = 6e4;
670
- function et() {
684
+ var Z = (e) => `the ${e} could not be saved, so it lasts only until the app or server restarts`, nt = 6e4;
685
+ function rt() {
671
686
  let e = /* @__PURE__ */ new Map();
672
687
  return { claim: (t) => {
673
688
  let n = Date.now();
674
- for (let [t, r] of e) n - r.at > $e && e.delete(t);
689
+ for (let [t, r] of e) n - r.at > nt && e.delete(t);
675
690
  let r = e.get(t);
676
691
  if (r) return { earlier: r.shown };
677
692
  let i = () => void 0, a = new Promise((e) => i = e);
@@ -684,8 +699,136 @@ function et() {
684
699
  } };
685
700
  }
686
701
  //#endregion
702
+ //#region src/core/webImage.ts
703
+ var it = 1e4, at = 5242880, ot = 3, st = "images", ct = "artifacts/";
704
+ function lt(e) {
705
+ if (e.protocol !== "https:") return "only https URLs are fetched";
706
+ if (e.username || e.password) return "a URL with a password isn't fetched";
707
+ let t = e.hostname.toLowerCase().replace(/\.$/, "");
708
+ return t.startsWith("[") || /^\d+\.\d+\.\d+\.\d+$/.test(t) ? "a URL with an IP address isn't fetched" : !t.includes(".") || /\.(localhost|local|internal|lan|home\.arpa)$/.test(t) ? "a URL on a local network isn't fetched" : null;
709
+ }
710
+ var Q = (e, t, n = 0) => t.every((t, r) => e[n + r] === t);
711
+ function ut(e) {
712
+ return Q(e, [
713
+ 137,
714
+ 80,
715
+ 78,
716
+ 71,
717
+ 13,
718
+ 10,
719
+ 26,
720
+ 10
721
+ ]) ? {
722
+ mime: "image/png",
723
+ extension: "png"
724
+ } : Q(e, [
725
+ 255,
726
+ 216,
727
+ 255
728
+ ]) ? {
729
+ mime: "image/jpeg",
730
+ extension: "jpg"
731
+ } : Q(e, [
732
+ 71,
733
+ 73,
734
+ 70,
735
+ 56
736
+ ]) ? {
737
+ mime: "image/gif",
738
+ extension: "gif"
739
+ } : Q(e, [
740
+ 82,
741
+ 73,
742
+ 70,
743
+ 70
744
+ ]) && Q(e, [
745
+ 87,
746
+ 69,
747
+ 66,
748
+ 80
749
+ ], 8) ? {
750
+ mime: "image/webp",
751
+ extension: "webp"
752
+ } : null;
753
+ }
754
+ function dt(e) {
755
+ let t = "", n = 32768;
756
+ for (let r = 0; r < e.length; r += n) t += String.fromCharCode(...e.subarray(r, r + n));
757
+ return btoa(t);
758
+ }
759
+ var $ = (e) => e.body?.cancel().catch(() => void 0) ?? Promise.resolve();
760
+ async function ft(e) {
761
+ if (Number(e.headers.get("content-length")) > 5242880) return await $(e), null;
762
+ if (!e.body) {
763
+ let t = new Uint8Array(await e.arrayBuffer());
764
+ return t.length > 5242880 ? null : t;
765
+ }
766
+ let t = e.body.getReader(), n = [], r = 0;
767
+ for (;;) {
768
+ let { done: e, value: i } = await t.read();
769
+ if (e) break;
770
+ if (r += i.length, r > 5242880) return await t.cancel(), null;
771
+ n.push(i);
772
+ }
773
+ let i = new Uint8Array(r), a = 0;
774
+ for (let e of n) i.set(e, a), a += e.length;
775
+ return i;
776
+ }
777
+ async function pt(e, t) {
778
+ let n;
779
+ try {
780
+ n = new URL(e);
781
+ } catch {
782
+ return "it isn't a URL";
783
+ }
784
+ for (let e = 0;; e++) {
785
+ let r = lt(n);
786
+ if (r) return r;
787
+ let i = await fetch(n, {
788
+ redirect: "manual",
789
+ signal: t,
790
+ credentials: "omit",
791
+ referrerPolicy: "no-referrer"
792
+ });
793
+ if (i.type === "opaqueredirect") return fetch(n, {
794
+ signal: t,
795
+ credentials: "omit",
796
+ referrerPolicy: "no-referrer"
797
+ });
798
+ let a = i.headers.get("location");
799
+ if (i.status < 300 || i.status >= 400 || !a) return i;
800
+ if (await $(i), e >= ot) return "it redirects too many times";
801
+ n = new URL(a, n);
802
+ }
803
+ }
804
+ async function mt(e, t) {
805
+ let n;
806
+ try {
807
+ let t = await pt(e, AbortSignal.timeout(it));
808
+ if (typeof t == "string") return { error: t };
809
+ if (!t.ok) return await $(t), { error: `the site answered ${t.status}` };
810
+ n = await ft(t);
811
+ } catch (e) {
812
+ return { error: `it couldn't be fetched (${e instanceof Error ? e.message : String(e)})` };
813
+ }
814
+ if (!n) return { error: `it is larger than ${at / 1024 / 1024} MB` };
815
+ let r = ut(n);
816
+ if (!r) return { error: "it isn't a PNG, JPEG, GIF or WebP picture" };
817
+ let i = `data:${r.mime};base64,${dt(n)}`;
818
+ if (!t) return { imageData: i };
819
+ let a = /* @__PURE__ */ new Date(), o = String(a.getUTCMonth() + 1).padStart(2, "0"), s = crypto.randomUUID().replace(/-/g, "").slice(0, 16), c = `${st}/${a.getUTCFullYear()}/${o}/${s}.${r.extension}`;
820
+ try {
821
+ return await t.write(c, n), {
822
+ imageData: i,
823
+ imagePath: `${ct}${c}`
824
+ };
825
+ } catch {
826
+ return { imageData: i };
827
+ }
828
+ }
829
+ //#endregion
687
830
  //#region src/core/presentSlide.ts
688
- function tt({ slide: e, totalSlides: t, mode: n }) {
831
+ function ht({ slide: e, totalSlides: t, mode: n }) {
689
832
  return n === "steps" ? {
690
833
  step: e,
691
834
  total: t,
@@ -703,7 +846,7 @@ function tt({ slide: e, totalSlides: t, mode: n }) {
703
846
  nextCall: `call presentSlide for slide ${e + 1} of ${t}`
704
847
  };
705
848
  }
706
- var nt = (e, { slide: t, totalSlides: n, title: r, imagePrompt: i, html: a, markdown: o, chart: s }) => JSON.stringify([
849
+ var gt = (e, { slide: t, totalSlides: n, title: r, imagePrompt: i, imageUrl: a, html: o, markdown: s, chart: c }) => JSON.stringify([
707
850
  e,
708
851
  t,
709
852
  n,
@@ -711,20 +854,21 @@ var nt = (e, { slide: t, totalSlides: n, title: r, imagePrompt: i, html: a, mark
711
854
  i,
712
855
  a,
713
856
  o,
714
- s
715
- ]), rt = q(() => ({
857
+ s,
858
+ c
859
+ ]), _t = Ne(() => ({
716
860
  latest: {
717
861
  presentation: null,
718
862
  steps: null
719
863
  },
720
864
  lastShown: null,
721
- repeats: et()
865
+ repeats: rt()
722
866
  }));
723
- function it(e, t) {
867
+ function vt(e, t) {
724
868
  let n = e.latest[t.mode], r = n?.totalSlides === t.totalSlides && (t.slide !== 1 || n.firstTitle === t.title);
725
869
  if (n && r) return n;
726
870
  let i = {
727
- id: W(),
871
+ id: ke(),
728
872
  mode: t.mode,
729
873
  totalSlides: t.totalSlides,
730
874
  firstTitle: t.slide === 1 ? t.title : "",
@@ -734,85 +878,118 @@ function it(e, t) {
734
878
  };
735
879
  return e.latest[t.mode] = i, i;
736
880
  }
737
- function at(e, t, n, r) {
881
+ function yt(e, t, n, r) {
738
882
  t.current = n.slide, t.shownAt = Date.now(), e.lastShown = t;
739
883
  let i = n.mode === "steps" ? "step" : "slide", { uuid: a, ...o } = r;
740
884
  return {
741
885
  ...o,
742
886
  message: `${i} ${n.slide} of ${n.totalSlides} is on the screen again, as it was`,
743
- instructions: k(n),
887
+ instructions: M(n),
744
888
  instructionsRequired: !0,
745
- sequence: tt(n)
889
+ sequence: ht(n)
746
890
  };
747
891
  }
748
- function ot(e, t) {
892
+ function bt(e, t) {
749
893
  if (e.mode !== "steps") return e.title ? `A presentation slide titled "${e.title}". ${e.imagePrompt}` : e.imagePrompt;
750
894
  let n = e.title ? `, "${e.title}"` : "";
751
895
  return [
752
896
  `An instructional illustration of step ${e.slide} of ${e.totalSlides}${n}. ${e.imagePrompt}`,
753
- t ? st : "",
897
+ t ? xt : "",
754
898
  "Show the action clearly, with little or no text."
755
899
  ].filter(Boolean).join(" ");
756
900
  }
757
- var st = "The reference image is the previous step: keep the same objects, hands, tools and setting, and show what this step changes.";
758
- async function ct(e, t, n) {
901
+ var xt = "The reference image is the previous step: keep the same objects, hands, tools and setting, and show what this step changes.";
902
+ async function St(e, t, n) {
759
903
  if (n.mode !== "steps") return [];
760
- let r = B(t.slides.get(n.slide - 1)).imagePath;
761
- return r ? await G(e, [r]) : [];
904
+ let r = H(t.slides.get(n.slide - 1)).imagePath;
905
+ return r ? await je(e, [r]) : [];
762
906
  }
763
- var lt = (e, t) => [
907
+ var Ct = (e, t) => [
764
908
  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}`,
765
- t ? st : "",
909
+ t ? xt : "",
766
910
  e.markdown ? "Keep the subject in the middle: the picture is cropped to a tall frame." : "",
767
911
  "No text, letters or numbers in the picture."
768
912
  ].filter(Boolean).join(" ");
769
- async function ut(e, t, n) {
913
+ async function wt(e, t) {
914
+ let n = await mt(t, e.files?.artifacts);
915
+ return "error" in n && console.info(`[sequence] picture at ${t} not shown: ${n.error}`), n;
916
+ }
917
+ async function Tt(e, t, n) {
770
918
  if (n.chart) return {
771
919
  chart: n.chart,
772
920
  prompt: ""
773
921
  };
774
922
  if (n.html || n.markdown) {
775
923
  let r = n.html ? { html: n.html } : {
776
- html: await Ue(n.markdown ?? ""),
924
+ html: await Ke(n.markdown ?? ""),
777
925
  markdown: n.markdown ?? ""
778
926
  };
779
- if (!y(r.html)) return {
927
+ if (!b(r.html)) return {
780
928
  ...r,
781
929
  prompt: ""
782
930
  };
783
- let i = n.imagePrompt || ie(r.html) || n.title, a = {
931
+ let i = n.imagePrompt || re(r.html) || n.title, a;
932
+ if (n.imageUrl) {
933
+ let t = await wt(e, n.imageUrl);
934
+ if (!("error" in t)) return {
935
+ ...r,
936
+ ...t,
937
+ imageUrl: n.imageUrl,
938
+ prompt: i,
939
+ imagePrompt: i
940
+ };
941
+ a = t.error;
942
+ }
943
+ let o = {
784
944
  ...n,
785
945
  imagePrompt: i
786
- }, o = await ct(e, t, a), s = lt(a, o.length > 0), c = await K(e, s, o), { imageData: l, imagePath: u } = B(c);
787
- return l ? {
946
+ }, s = await St(e, t, o), c = Ct(o, s.length > 0), l = await G(e, c, s), { imageData: u, imagePath: d } = H(l), f = a !== void 0 && { urlFailed: a };
947
+ return u ? {
788
948
  ...r,
789
- imageData: l,
790
- ...u && { imagePath: u },
791
- prompt: s,
792
- imagePrompt: i
949
+ imageData: u,
950
+ ...d && { imagePath: d },
951
+ prompt: c,
952
+ imagePrompt: i,
953
+ ...f
793
954
  } : {
794
955
  ...r,
795
- prompt: s,
956
+ prompt: c,
796
957
  imagePrompt: i,
797
- pictureFailed: c.message
958
+ pictureFailed: l.message,
959
+ ...f
798
960
  };
799
961
  }
800
- let r = await ct(e, t, n), i = ot(n, r.length > 0), a = await K(e, i, r), { imageData: o, imagePath: s } = B(a);
801
- return o ? {
802
- imageData: o,
803
- ...s && { imagePath: s },
804
- prompt: i
962
+ let r;
963
+ if (n.imageUrl) {
964
+ let t = await wt(e, n.imageUrl);
965
+ if (!("error" in t)) return {
966
+ ...t,
967
+ imageUrl: n.imageUrl,
968
+ prompt: n.imagePrompt || n.title
969
+ };
970
+ if (!n.imagePrompt) return { failed: {
971
+ message: `the picture at ${n.imageUrl} couldn't be shown: ${t.error}. Call presentSlide again with another imageUrl (an image file's address), or with imagePrompt to draw it.`,
972
+ sequence: null
973
+ } };
974
+ r = t.error;
975
+ }
976
+ let i = await St(e, t, n), a = bt(n, i.length > 0), o = await G(e, a, i), { imageData: s, imagePath: c } = H(o);
977
+ return s ? {
978
+ imageData: s,
979
+ ...c && { imagePath: c },
980
+ prompt: a,
981
+ ...r !== void 0 && { urlFailed: r }
805
982
  } : { failed: {
806
- ...a,
983
+ ...o,
807
984
  sequence: null
808
985
  } };
809
986
  }
810
- async function dt(e, t, n) {
811
- let r = await ut(e, t, n);
987
+ async function Et(e, t, n) {
988
+ let r = await Tt(e, t, n);
812
989
  if ("failed" in r) return r.failed;
813
- let { imageData: i, imagePath: a, html: o, markdown: s, chart: c, prompt: l, pictureFailed: u } = r, d = t.id, f = await Z(e.files?.artifacts, We, d, (e) => {
990
+ let { imageData: i, imagePath: a, imageUrl: o, html: s, markdown: c, chart: l, prompt: u, pictureFailed: d, urlFailed: f } = r, p = t.id, m = await X(e.files?.artifacts, qe, p, (e) => {
814
991
  let t = e ?? {
815
- id: d,
992
+ id: p,
816
993
  title: "",
817
994
  mode: n.mode,
818
995
  totalSlides: n.totalSlides,
@@ -820,47 +997,51 @@ async function dt(e, t, n) {
820
997
  };
821
998
  return n.slide === 1 && (t.title = n.title), t.slides[String(n.slide)] = {
822
999
  title: n.title,
823
- imagePrompt: o ? r.imagePrompt ?? "" : n.imagePrompt,
1000
+ imagePrompt: s ? r.imagePrompt ?? "" : n.imagePrompt,
824
1001
  ...a && { imagePath: a },
825
- ...o && { html: o },
826
- ...s && { markdown: s },
827
- ...c && { chart: c }
1002
+ ...o && { imageUrl: o },
1003
+ ...s && { html: s },
1004
+ ...c && { markdown: c },
1005
+ ...l && { chart: l }
828
1006
  }, t;
829
- }), p = {
1007
+ }), h = {
830
1008
  ...i && { imageData: i },
831
1009
  ...a && { imagePath: a },
832
- ...o && { html: o },
833
- ...s && { markdown: s },
834
- ...c && { chart: c },
835
- prompt: l,
836
- slideshowId: d,
1010
+ ...o && { imageUrl: o },
1011
+ ...s && { html: s },
1012
+ ...c && { markdown: c },
1013
+ ...l && { chart: l },
1014
+ prompt: u,
1015
+ slideshowId: p,
837
1016
  slide: n.slide,
838
1017
  totalSlides: n.totalSlides,
839
1018
  title: n.title,
840
1019
  mode: n.mode
841
- }, m = n.mode === "steps" ? "step" : "slide";
1020
+ }, g = n.mode === "steps" ? "step" : "slide";
842
1021
  return {
843
- data: p,
1022
+ data: h,
844
1023
  title: n.title || `Slide ${n.slide}`,
845
1024
  message: [
846
- `${m} ${n.slide} of ${n.totalSlides} of slideshow "${d}" is on the screen`,
1025
+ `${g} ${n.slide} of ${n.totalSlides} of slideshow "${p}" is on the screen`,
1026
+ o ? `its picture is from ${o}` : "",
847
1027
  a ? `saved to ${a}` : "",
848
- u ? `its picture couldn't be drawn (${u}), so the slide is shown without it` : "",
849
- f ? "" : Q("slideshow")
1028
+ f === void 0 ? "" : `the picture at ${n.imageUrl} couldn't be shown (${f}), so it was drawn instead`,
1029
+ d ? `its picture couldn't be drawn (${d}), so the slide is shown without it` : "",
1030
+ m ? "" : Z("slideshow")
850
1031
  ].filter(Boolean).join("; "),
851
- instructions: k(n),
1032
+ instructions: M(n),
852
1033
  instructionsRequired: !0,
853
- sequence: tt(n)
1034
+ sequence: ht(n)
854
1035
  };
855
1036
  }
856
- async function $(e, t) {
857
- let n = xe(t);
1037
+ async function Dt(e, t) {
1038
+ let n = A(t);
858
1039
  if (typeof n == "string") return {
859
1040
  message: n,
860
1041
  sequence: null
861
1042
  };
862
- let r = rt(e), i = it(r, n), a = n.mode === "steps";
863
- if (a && n.slide > i.current && i.current > 0 && !U(e, i.shownAt)) {
1043
+ let r = _t(e), i = vt(r, n), a = n.mode === "steps";
1044
+ if (a && n.slide > i.current && i.current > 0 && !Oe(e, i.shownAt)) {
864
1045
  console.info(`[sequence] holding step ${n.slide} for the user`);
865
1046
  let e = i.shownAt === Infinity ? "is still being drawn" : "is still on the screen";
866
1047
  return {
@@ -869,15 +1050,15 @@ async function $(e, t) {
869
1050
  };
870
1051
  }
871
1052
  let o = a ? i.slides.get(n.slide) : void 0;
872
- if (o) return ke(e.currentResult, o) ? {
1053
+ if (o) return De(e.currentResult, o) ? {
873
1054
  message: `step ${n.slide} of ${n.totalSlides} is already on the screen`,
874
1055
  cancelled: !0
875
- } : at(r, i, n, o);
876
- let s = r.repeats.claim(nt(i.id, n));
1056
+ } : yt(r, i, n, o);
1057
+ let s = r.repeats.claim(gt(i.id, n));
877
1058
  if ("earlier" in s) {
878
- if (!await s.earlier) return $(e, t);
1059
+ if (!await s.earlier) return Dt(e, t);
879
1060
  let a = i.slides.get(n.slide);
880
- return a && r.lastShown !== i ? at(r, i, n, a) : {
1061
+ return a && r.lastShown !== i ? yt(r, i, n, a) : {
881
1062
  message: `slide ${n.slide} of ${n.totalSlides} is already on the screen`,
882
1063
  cancelled: !0
883
1064
  };
@@ -889,22 +1070,22 @@ async function $(e, t) {
889
1070
  i.current = n.slide, i.shownAt = Infinity;
890
1071
  let u = !1;
891
1072
  try {
892
- let t = await dt(e, i, n);
893
- return u = Oe(t), u && (i.slides.set(n.slide, t), i.current = n.slide, i.shownAt = Date.now(), r.lastShown = i), t;
1073
+ let t = await Et(e, i, n);
1074
+ return u = Ee(t), u && (i.slides.set(n.slide, t), i.current = n.slide, i.shownAt = Date.now(), r.lastShown = i), t;
894
1075
  } finally {
895
1076
  c(u), !u && i.current === n.slide && (i.current = l.current, i.shownAt = l.shownAt);
896
1077
  }
897
1078
  }
898
1079
  //#endregion
899
1080
  //#region src/core/storyboard.ts
900
- var ft = ({ id: e, title: t, totalPanels: n }) => ({
1081
+ var Ot = ({ id: e, title: t, totalPanels: n }) => ({
901
1082
  step: 0,
902
1083
  total: n,
903
1084
  kind: "story",
904
1085
  label: `The cast of "${t}"`,
905
1086
  onShown: "introduce the characters",
906
1087
  nextCall: `call presentPanel for panel 1 of ${n} with storyboardId "${e}"`
907
- }), pt = ({ id: e, totalPanels: t }, n, r) => ({
1088
+ }), kt = ({ id: e, totalPanels: t }, n, r) => ({
908
1089
  step: n,
909
1090
  total: t,
910
1091
  kind: "story",
@@ -912,21 +1093,21 @@ var ft = ({ id: e, title: t, totalPanels: n }) => ({
912
1093
  onShown: "tell that part of the story",
913
1094
  nextCall: `call presentPanel for panel ${n + 1} of ${t} with storyboardId "${e}"`,
914
1095
  ...r.length > 0 && { waitsForUser: !0 }
915
- }), mt = (e, t) => e ? `${e}. ${t}` : t, ht = (e, { name: t, description: n }) => mt(e, `Character reference sheet of ${t}: ${n}. Full body, front, side and back views, on a plain white background. No text or labels.`);
916
- async function gt(e, t) {
917
- let n = j(t);
1096
+ }), At = (e, t) => e ? `${e}. ${t}` : t, jt = (e, { name: t, description: n }) => At(e, `Character reference sheet of ${t}: ${n}. Full body, front, side and back views, on a plain white background. No text or labels.`);
1097
+ async function Mt(e, t) {
1098
+ let n = F(t);
918
1099
  if (typeof n == "string") return {
919
1100
  message: n,
920
1101
  sequence: null
921
1102
  };
922
- let r = await Promise.all(n.characters.map((t) => K(e, ht(n.style, t)))), i = r.map(B), a = r.find((e, t) => !i[t]?.imageData);
1103
+ let r = await Promise.all(n.characters.map((t) => G(e, jt(n.style, t)))), i = r.map(H), a = r.find((e, t) => !i[t]?.imageData);
923
1104
  if (i.every(({ imageData: e }) => !e) && a) return {
924
1105
  ...a,
925
1106
  message: `the character sheets couldn't be made: ${a.message}`,
926
1107
  sequence: null
927
1108
  };
928
1109
  let o = {
929
- id: W(),
1110
+ id: ke(),
930
1111
  ...n,
931
1112
  characters: n.characters.map((e, t) => {
932
1113
  let n = i[t]?.imagePath;
@@ -936,7 +1117,7 @@ async function gt(e, t) {
936
1117
  };
937
1118
  }),
938
1119
  panels: {}
939
- }, 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;
1120
+ }, s = await X(e.files?.artifacts, Y, 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;
940
1121
  return {
941
1122
  data: {
942
1123
  storyboardId: o.id,
@@ -957,39 +1138,39 @@ async function gt(e, t) {
957
1138
  `storyboard "${o.id}" is ready with ${o.totalPanels} panels; the cast is on the screen`,
958
1139
  c.length ? `character sheets saved to ${c.join(", ")}` : "",
959
1140
  l.length ? `no sheet for ${l.join("; ")}: they will be drawn from their description` : "",
960
- s ? "" : Q("storyboard")
1141
+ s ? "" : Z("storyboard")
961
1142
  ].filter(Boolean).join("; "),
962
- instructions: M(o),
1143
+ instructions: I(o),
963
1144
  instructionsRequired: !0,
964
- sequence: ft(o)
1145
+ sequence: Ot(o)
965
1146
  };
966
1147
  }
967
- function _t(e, t, n) {
968
- let r = [mt(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}`);
1148
+ function Nt(e, t, n) {
1149
+ let r = [At(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}`);
969
1150
  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(" ");
970
1151
  }
971
- async function vt(e, t, n) {
1152
+ async function Pt(e, t, n) {
972
1153
  let r = [], i = [];
973
1154
  for (let a of n.characters) {
974
- let n = t.characters.find((e) => D(e.name, a));
1155
+ let n = t.characters.find((e) => T(e.name, a));
975
1156
  if (!n) r.push(a);
976
1157
  else if (!i.some((e) => e.character === n)) {
977
- let [t] = n.imagePath ? await G(e, [n.imagePath]) : [];
1158
+ let [t] = n.imagePath ? await je(e, [n.imagePath]) : [];
978
1159
  i.push({
979
1160
  character: n,
980
1161
  sheet: t ?? null
981
1162
  });
982
1163
  }
983
1164
  }
984
- let a = i.map(({ sheet: e }) => e).filter((e) => !!e), o = _t(t, n, i.map(({ character: e, sheet: t }) => ({
1165
+ let a = i.map(({ sheet: e }) => e).filter((e) => !!e), o = Nt(t, n, i.map(({ character: e, sheet: t }) => ({
985
1166
  character: e,
986
1167
  hasSheet: !!t
987
- }))), s = await K(e, o, a), { imageData: c, imagePath: l } = B(s);
1168
+ }))), s = await G(e, o, a), { imageData: c, imagePath: l } = H(s);
988
1169
  if (!c) return {
989
1170
  ...s,
990
1171
  sequence: null
991
1172
  };
992
- let u = n.panel < t.totalPanels && n.choices.length >= 2 ? n.choices : [], d = await Z(e.files?.artifacts, X, t.id, (e) => {
1173
+ let u = n.panel < t.totalPanels && n.choices.length >= 2 ? n.choices : [], d = await X(e.files?.artifacts, Y, t.id, (e) => {
993
1174
  let r = e ?? t;
994
1175
  return u.length && (r.interactive = !0), r.panels[String(n.panel)] = {
995
1176
  caption: n.caption,
@@ -1015,25 +1196,25 @@ async function vt(e, t, n) {
1015
1196
  `panel ${n.panel} of ${t.totalPanels} is on the screen`,
1016
1197
  l ? `saved to ${l}` : "",
1017
1198
  r.length ? `not in the cast, so drawn from the prompt alone: ${r.join(", ")}` : "",
1018
- d ? "" : Q("storyboard")
1199
+ d ? "" : Z("storyboard")
1019
1200
  ].filter(Boolean).join("; "),
1020
- instructions: F(t, n.panel, u),
1201
+ instructions: z(t, n.panel, u),
1021
1202
  instructionsRequired: !0,
1022
- sequence: pt(t, n.panel, u)
1203
+ sequence: kt(t, n.panel, u)
1023
1204
  };
1024
1205
  }
1025
- var yt = q(() => ({
1026
- repeats: et(),
1206
+ var Ft = Ne(() => ({
1207
+ repeats: rt(),
1027
1208
  awaitingChoice: /* @__PURE__ */ new Map()
1028
1209
  }));
1029
- async function bt(e, t) {
1030
- let n = P(t);
1210
+ async function It(e, t) {
1211
+ let n = R(t);
1031
1212
  if (!n) return {
1032
- message: N,
1213
+ message: L,
1033
1214
  sequence: null
1034
1215
  };
1035
- let { storyboardId: r, panel: i } = n, { repeats: a, awaitingChoice: o } = yt(e), s = o.get(r);
1036
- if (s && i > s.panel && !U(e, s.shownAt)) return console.info(`[sequence] holding panel ${i} for the user`), {
1216
+ let { storyboardId: r, panel: i } = n, { repeats: a, awaitingChoice: o } = Ft(e), s = o.get(r);
1217
+ if (s && i > s.panel && !Oe(e, s.shownAt)) return console.info(`[sequence] holding panel ${i} for the user`), {
1037
1218
  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.`,
1038
1219
  cancelled: !0
1039
1220
  };
@@ -1041,7 +1222,7 @@ async function bt(e, t) {
1041
1222
  if ("earlier" in c) return await c.earlier ? {
1042
1223
  message: `panel ${i} is already on the screen`,
1043
1224
  cancelled: !0
1044
- } : bt(e, t);
1225
+ } : It(e, t);
1045
1226
  let { settle: l } = c, u = {
1046
1227
  panel: i,
1047
1228
  shownAt: Infinity
@@ -1049,7 +1230,7 @@ async function bt(e, t) {
1049
1230
  o.set(r, u);
1050
1231
  let f = () => o.get(r) === u, p = !1;
1051
1232
  try {
1052
- let t = await Qe(e.files?.artifacts, X, r);
1233
+ let t = await tt(e.files?.artifacts, Y, r);
1053
1234
  if (!t) return {
1054
1235
  message: `there is no storyboard "${r}"; call defineStoryboard first`,
1055
1236
  sequence: null
@@ -1058,8 +1239,8 @@ async function bt(e, t) {
1058
1239
  message: `storyboard "${t.id}" has ${t.totalPanels} panels`,
1059
1240
  sequence: null
1060
1241
  };
1061
- let a = await vt(e, t, n);
1062
- p = !!B(a).imageData;
1242
+ let a = await Pt(e, t, n);
1243
+ p = !!H(a).imageData;
1063
1244
  let s = a.data;
1064
1245
  return p && f() && (s?.choices?.length ? o.set(r, {
1065
1246
  panel: i,
@@ -1071,21 +1252,21 @@ async function bt(e, t) {
1071
1252
  }
1072
1253
  //#endregion
1073
1254
  //#region src/core/index.ts
1074
- var xt = {
1075
- toolDefinition: A,
1255
+ var Lt = {
1256
+ toolDefinition: P,
1076
1257
  generatingMessage: "Making the slide...",
1077
1258
  isEnabled: () => !0,
1078
- execute: (e, t) => $(e, t)
1079
- }, St = {
1080
- toolDefinition: L,
1259
+ execute: (e, t) => Dt(e, t)
1260
+ }, Rt = {
1261
+ toolDefinition: Ce,
1081
1262
  generatingMessage: "Drawing the characters...",
1082
1263
  isEnabled: () => !0,
1083
- execute: (e, t) => gt(e, t)
1084
- }, Ct = {
1085
- toolDefinition: R,
1264
+ execute: (e, t) => Mt(e, t)
1265
+ }, zt = {
1266
+ toolDefinition: we,
1086
1267
  generatingMessage: "Drawing the panel...",
1087
1268
  isEnabled: () => !0,
1088
- execute: (e, t) => bt(e, t)
1269
+ execute: (e, t) => It(e, t)
1089
1270
  };
1090
1271
  //#endregion
1091
- export { k as A, t as B, I as C, xe as D, P as E, s as F, oe as H, h as I, l as L, fe as M, r as N, j as O, o as P, n as R, ve as S, F as T, ae as U, y as V, A as _, X as a, _e as b, pe as c, ge as d, he as f, S as g, R as h, We as i, b as j, D as k, L as l, C as m, Ct as n, Qe as o, N as p, xt as r, Ue as s, St as t, me as u, Ee as v, M as w, ye as x, w as y, g as z };
1272
+ export { M as A, t as B, B as C, A as D, R as E, s as F, ae as H, h as I, l as L, fe as M, r as N, F as O, o as P, n as R, O as S, z as T, ie as U, b as V, P as _, Y as a, D as b, me as c, ve as d, _e as f, pe as g, we as h, qe as i, x as j, T as k, Ce as l, he as m, zt as n, tt as o, L as p, Lt as r, Ke as s, Rt as t, ge as u, N as v, I as w, k as x, S as y, _ as z };