@gui-chat-plugin/sequence 0.5.4 → 0.6.1

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}) on a line of its own: the slide is then two columns, the text on the left and the picture on the right.`, 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,42 @@ 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) => {
598
+ if (e.type !== "paragraph" || e.tokens?.length !== 1) return !1;
599
+ let t = e.tokens[0];
600
+ return t?.type === "image" ? t.href.trim() === g : t?.type === "text" && t.text.trim() === "{{image}}";
601
+ });
602
+ if (o >= 0) {
603
+ 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 ?? "", "");
604
+ return `<style>${Ne}</style>
605
+ <div class="${Y} ${Ae}" data-fit style="font-size: ${Math.round(Pe(c) * Me)}px">
606
+ <div class="${X}">
607
+ ${s}</div>
608
+ <img class="${je}" src="${g}" alt="${p(r)}">
609
+ </div>`;
610
+ }
611
+ let s = await i.parse(e);
612
+ return `<style>${Ne}</style>
613
+ <div class="${Y}" data-fit style="font-size: ${Pe(e)}px">
614
+ ${s}</div>`;
591
615
  }
592
616
  //#endregion
593
617
  //#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;
618
+ var He = "slideshows", Z = "storyboards", Ue = {}, We = /* @__PURE__ */ new WeakMap(), Ge = /* @__PURE__ */ new WeakMap();
619
+ function Ke(e) {
620
+ let t = We.get(e);
621
+ return t || We.set(e, t = /* @__PURE__ */ new Map()), t;
598
622
  }
599
- function Ie(t, n) {
600
- let r = Pe.get(t);
601
- r || Pe.set(t, r = /* @__PURE__ */ new Map());
623
+ function qe(t, n) {
624
+ let r = Ge.get(t);
625
+ r || Ge.set(t, r = /* @__PURE__ */ new Map());
602
626
  let i = r.get(n);
603
627
  return i || r.set(n, i = e()), i;
604
628
  }
605
- var Le = (e, t) => `${e}/${t}.json`;
606
- async function Re(e, t) {
607
- let n = Fe(e ?? Me), r = n.get(t);
629
+ var Je = (e, t) => `${e}/${t}.json`;
630
+ async function Ye(e, t) {
631
+ let n = Ke(e ?? Ue), r = n.get(t);
608
632
  if (r) return r;
609
633
  if (!e) return null;
610
634
  try {
@@ -614,14 +638,14 @@ async function Re(e, t) {
614
638
  return null;
615
639
  }
616
640
  }
617
- async function ze(e, t, n) {
618
- return v.test(n) ? Re(e, Le(t, n)) : null;
641
+ async function Xe(e, t, n) {
642
+ return x.test(n) ? Ye(e, Je(t, n)) : null;
619
643
  }
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;
644
+ async function Q(e, t, n, r) {
645
+ let i = Je(t, n), a = e ?? Ue;
646
+ return qe(a, i)(async () => {
647
+ let t = r(await Ye(e, i));
648
+ if (Ke(a).set(i, t), !e) return !1;
625
649
  try {
626
650
  return await e.write(i, JSON.stringify(t, null, 2)), !0;
627
651
  } catch (e) {
@@ -629,12 +653,12 @@ async function Z(e, t, n, r) {
629
653
  }
630
654
  });
631
655
  }
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() {
656
+ var $ = (e) => `the ${e} could not be saved, so it lasts only until the app or server restarts`, Ze = 6e4;
657
+ function Qe() {
634
658
  let e = /* @__PURE__ */ new Map();
635
659
  return { claim: (t) => {
636
660
  let n = Date.now();
637
- for (let [t, r] of e) n - r.at > Be && e.delete(t);
661
+ for (let [t, r] of e) n - r.at > Ze && e.delete(t);
638
662
  let r = e.get(t);
639
663
  if (r) return { earlier: r.shown };
640
664
  let i = () => void 0, a = new Promise((e) => i = e);
@@ -648,7 +672,7 @@ function Ve() {
648
672
  }
649
673
  //#endregion
650
674
  //#region src/core/presentSlide.ts
651
- function He({ slide: e, totalSlides: t, mode: n }) {
675
+ function $e({ slide: e, totalSlides: t, mode: n }) {
652
676
  return n === "steps" ? {
653
677
  step: e,
654
678
  total: t,
@@ -666,7 +690,7 @@ function He({ slide: e, totalSlides: t, mode: n }) {
666
690
  nextCall: `call presentSlide for slide ${e + 1} of ${t}`
667
691
  };
668
692
  }
669
- var Ue = (e, { slide: t, totalSlides: n, title: r, imagePrompt: i, html: a, markdown: o, chart: s }) => JSON.stringify([
693
+ var et = (e, { slide: t, totalSlides: n, title: r, imagePrompt: i, html: a, markdown: o, chart: s }) => JSON.stringify([
670
694
  e,
671
695
  t,
672
696
  n,
@@ -675,19 +699,19 @@ var Ue = (e, { slide: t, totalSlides: n, title: r, imagePrompt: i, html: a, mark
675
699
  a,
676
700
  o,
677
701
  s
678
- ]), We = K(() => ({
702
+ ]), tt = ke(() => ({
679
703
  latest: {
680
704
  presentation: null,
681
705
  steps: null
682
706
  },
683
707
  lastShown: null,
684
- repeats: Ve()
708
+ repeats: Qe()
685
709
  }));
686
- function Ge(e, t) {
710
+ function nt(e, t) {
687
711
  let n = e.latest[t.mode], r = n?.totalSlides === t.totalSlides && (t.slide !== 1 || n.firstTitle === t.title);
688
712
  if (n && r) return n;
689
713
  let i = {
690
- id: U(),
714
+ id: Te(),
691
715
  mode: t.mode,
692
716
  totalSlides: t.totalSlides,
693
717
  firstTitle: t.slide === 1 ? t.title : "",
@@ -697,56 +721,84 @@ function Ge(e, t) {
697
721
  };
698
722
  return e.latest[t.mode] = i, i;
699
723
  }
700
- function Ke(e, t, n, r) {
724
+ function rt(e, t, n, r) {
701
725
  t.current = n.slide, t.shownAt = Date.now(), e.lastShown = t;
702
726
  let i = n.mode === "steps" ? "step" : "slide", { uuid: a, ...o } = r;
703
727
  return {
704
728
  ...o,
705
729
  message: `${i} ${n.slide} of ${n.totalSlides} is on the screen again, as it was`,
706
- instructions: O(n),
730
+ instructions: M(n),
707
731
  instructionsRequired: !0,
708
- sequence: He(n)
732
+ sequence: $e(n)
709
733
  };
710
734
  }
711
- function qe(e, t) {
735
+ function it(e, t) {
712
736
  if (e.mode !== "steps") return e.title ? `A presentation slide titled "${e.title}". ${e.imagePrompt}` : e.imagePrompt;
713
737
  let n = e.title ? `, "${e.title}"` : "";
714
738
  return [
715
739
  `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." : "",
740
+ t ? at : "",
717
741
  "Show the action clearly, with little or no text."
718
742
  ].filter(Boolean).join(" ");
719
743
  }
720
- async function Je(e, t, n) {
721
- if (n.html) return {
722
- html: n.html,
723
- prompt: ""
724
- };
744
+ var at = "The reference image is the previous step: keep the same objects, hands, tools and setting, and show what this step changes.";
745
+ async function ot(e, t, n) {
746
+ if (n.mode !== "steps") return [];
747
+ let r = W(t.slides.get(n.slide - 1)).imagePath;
748
+ return r ? await De(e, [r]) : [];
749
+ }
750
+ var st = (e, t) => [
751
+ 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}`,
752
+ t ? at : "",
753
+ e.markdown ? "Keep the subject in the middle: the picture is cropped to a tall frame." : "",
754
+ "No text, letters or numbers in the picture."
755
+ ].filter(Boolean).join(" ");
756
+ async function ct(e, t, n) {
725
757
  if (n.chart) return {
726
758
  chart: n.chart,
727
759
  prompt: ""
728
760
  };
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
761
+ if (n.html || n.markdown) {
762
+ let r = n.html ? { html: n.html } : {
763
+ html: await Ve(n.markdown ?? ""),
764
+ markdown: n.markdown ?? ""
765
+ }, i = y(r.html);
766
+ if (i && !n.imagePrompt) return { failed: {
767
+ message: O,
768
+ sequence: null
769
+ } };
770
+ if (!i) return {
771
+ ...r,
772
+ prompt: ""
773
+ };
774
+ 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);
775
+ return c ? {
776
+ ...r,
777
+ imageData: c,
778
+ ...l && { imagePath: l },
779
+ prompt: o
780
+ } : {
781
+ ...r,
782
+ prompt: o,
783
+ pictureFailed: s.message
784
+ };
785
+ }
786
+ 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);
787
+ return o ? {
788
+ imageData: o,
789
+ ...s && { imagePath: s },
790
+ prompt: i
739
791
  } : { failed: {
740
- ...s,
792
+ ...a,
741
793
  sequence: null
742
794
  } };
743
795
  }
744
- async function Ye(e, t, n) {
745
- let r = await Je(e, t, n);
796
+ async function lt(e, t, n) {
797
+ let r = await ct(e, t, n);
746
798
  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) => {
799
+ 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
800
  let t = e ?? {
749
- id: u,
801
+ id: d,
750
802
  title: "",
751
803
  mode: n.mode,
752
804
  totalSlides: n.totalSlides,
@@ -754,46 +806,47 @@ async function Ye(e, t, n) {
754
806
  };
755
807
  return n.slide === 1 && (t.title = n.title), t.slides[String(n.slide)] = {
756
808
  title: n.title,
757
- imagePrompt: n.imagePrompt,
809
+ imagePrompt: o && !l ? "" : n.imagePrompt,
758
810
  ...a && { imagePath: a },
759
811
  ...o && { html: o },
760
812
  ...s && { markdown: s },
761
813
  ...c && { chart: c }
762
814
  }, t;
763
- }), f = {
815
+ }), p = {
764
816
  ...i && { imageData: i },
765
817
  ...a && { imagePath: a },
766
818
  ...o && { html: o },
767
819
  ...s && { markdown: s },
768
820
  ...c && { chart: c },
769
821
  prompt: l,
770
- slideshowId: u,
822
+ slideshowId: d,
771
823
  slide: n.slide,
772
824
  totalSlides: n.totalSlides,
773
825
  title: n.title,
774
826
  mode: n.mode
775
- }, p = n.mode === "steps" ? "step" : "slide";
827
+ }, m = n.mode === "steps" ? "step" : "slide";
776
828
  return {
777
- data: f,
829
+ data: p,
778
830
  title: n.title || `Slide ${n.slide}`,
779
831
  message: [
780
- `${p} ${n.slide} of ${n.totalSlides} of slideshow "${u}" is on the screen`,
832
+ `${m} ${n.slide} of ${n.totalSlides} of slideshow "${d}" is on the screen`,
781
833
  a ? `saved to ${a}` : "",
782
- d ? "" : Q("slideshow")
834
+ u ? `its picture couldn't be drawn (${u}), so the slide is shown without it` : "",
835
+ f ? "" : $("slideshow")
783
836
  ].filter(Boolean).join("; "),
784
- instructions: O(n),
837
+ instructions: M(n),
785
838
  instructionsRequired: !0,
786
- sequence: He(n)
839
+ sequence: $e(n)
787
840
  };
788
841
  }
789
- async function Xe(e, t) {
790
- let n = E(t);
842
+ async function ut(e, t) {
843
+ let n = A(t);
791
844
  if (typeof n == "string") return {
792
845
  message: n,
793
846
  sequence: null
794
847
  };
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)) {
848
+ let r = tt(e), i = nt(r, n), a = n.mode === "steps";
849
+ if (a && n.slide > i.current && i.current > 0 && !q(e, i.shownAt)) {
797
850
  console.info(`[sequence] holding step ${n.slide} for the user`);
798
851
  let e = i.shownAt === Infinity ? "is still being drawn" : "is still on the screen";
799
852
  return {
@@ -802,15 +855,15 @@ async function Xe(e, t) {
802
855
  };
803
856
  }
804
857
  let o = a ? i.slides.get(n.slide) : void 0;
805
- if (o) return xe(e.currentResult, o) ? {
858
+ if (o) return we(e.currentResult, o) ? {
806
859
  message: `step ${n.slide} of ${n.totalSlides} is already on the screen`,
807
860
  cancelled: !0
808
- } : Ke(r, i, n, o);
809
- let s = r.repeats.claim(Ue(i.id, n));
861
+ } : rt(r, i, n, o);
862
+ let s = r.repeats.claim(et(i.id, n));
810
863
  if ("earlier" in s) {
811
- if (!await s.earlier) return Xe(e, t);
864
+ if (!await s.earlier) return ut(e, t);
812
865
  let a = i.slides.get(n.slide);
813
- return a && r.lastShown !== i ? Ke(r, i, n, a) : {
866
+ return a && r.lastShown !== i ? rt(r, i, n, a) : {
814
867
  message: `slide ${n.slide} of ${n.totalSlides} is already on the screen`,
815
868
  cancelled: !0
816
869
  };
@@ -822,22 +875,22 @@ async function Xe(e, t) {
822
875
  i.current = n.slide, i.shownAt = Infinity;
823
876
  let u = !1;
824
877
  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;
878
+ let t = await lt(e, i, n);
879
+ return u = Ce(t), u && (i.slides.set(n.slide, t), i.current = n.slide, i.shownAt = Date.now(), r.lastShown = i), t;
827
880
  } finally {
828
881
  c(u), !u && i.current === n.slide && (i.current = l.current, i.shownAt = l.shownAt);
829
882
  }
830
883
  }
831
884
  //#endregion
832
885
  //#region src/core/storyboard.ts
833
- var Ze = ({ id: e, title: t, totalPanels: n }) => ({
886
+ var dt = ({ id: e, title: t, totalPanels: n }) => ({
834
887
  step: 0,
835
888
  total: n,
836
889
  kind: "story",
837
890
  label: `The cast of "${t}"`,
838
891
  onShown: "introduce the characters",
839
892
  nextCall: `call presentPanel for panel 1 of ${n} with storyboardId "${e}"`
840
- }), Qe = ({ id: e, totalPanels: t }, n, r) => ({
893
+ }), ft = ({ id: e, totalPanels: t }, n, r) => ({
841
894
  step: n,
842
895
  total: t,
843
896
  kind: "story",
@@ -845,21 +898,21 @@ var Ze = ({ id: e, title: t, totalPanels: n }) => ({
845
898
  onShown: "tell that part of the story",
846
899
  nextCall: `call presentPanel for panel ${n + 1} of ${t} with storyboardId "${e}"`,
847
900
  ...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);
901
+ }), 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.`);
902
+ async function ht(e, t) {
903
+ let n = F(t);
851
904
  if (typeof n == "string") return {
852
905
  message: n,
853
906
  sequence: null
854
907
  };
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);
908
+ 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
909
  if (i.every(({ imageData: e }) => !e) && a) return {
857
910
  ...a,
858
911
  message: `the character sheets couldn't be made: ${a.message}`,
859
912
  sequence: null
860
913
  };
861
914
  let o = {
862
- id: U(),
915
+ id: Te(),
863
916
  ...n,
864
917
  characters: n.characters.map((e, t) => {
865
918
  let n = i[t]?.imagePath;
@@ -869,7 +922,7 @@ async function tt(e, t) {
869
922
  };
870
923
  }),
871
924
  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;
925
+ }, 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
926
  return {
874
927
  data: {
875
928
  storyboardId: o.id,
@@ -890,39 +943,39 @@ async function tt(e, t) {
890
943
  `storyboard "${o.id}" is ready with ${o.totalPanels} panels; the cast is on the screen`,
891
944
  c.length ? `character sheets saved to ${c.join(", ")}` : "",
892
945
  l.length ? `no sheet for ${l.join("; ")}: they will be drawn from their description` : "",
893
- s ? "" : Q("storyboard")
946
+ s ? "" : $("storyboard")
894
947
  ].filter(Boolean).join("; "),
895
- instructions: M(o),
948
+ instructions: I(o),
896
949
  instructionsRequired: !0,
897
- sequence: Ze(o)
950
+ sequence: dt(o)
898
951
  };
899
952
  }
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}`);
953
+ function gt(e, t, n) {
954
+ 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
955
  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
956
  }
904
- async function rt(e, t, n) {
957
+ async function _t(e, t, n) {
905
958
  let r = [], i = [];
906
959
  for (let a of n.characters) {
907
- let n = t.characters.find((e) => x(e.name, a));
960
+ let n = t.characters.find((e) => w(e.name, a));
908
961
  if (!n) r.push(a);
909
962
  else if (!i.some((e) => e.character === n)) {
910
- let [t] = n.imagePath ? await W(e, [n.imagePath]) : [];
963
+ let [t] = n.imagePath ? await De(e, [n.imagePath]) : [];
911
964
  i.push({
912
965
  character: n,
913
966
  sheet: t ?? null
914
967
  });
915
968
  }
916
969
  }
917
- let a = i.map(({ sheet: e }) => e).filter((e) => !!e), o = nt(t, n, i.map(({ character: e, sheet: t }) => ({
970
+ let a = i.map(({ sheet: e }) => e).filter((e) => !!e), o = gt(t, n, i.map(({ character: e, sheet: t }) => ({
918
971
  character: e,
919
972
  hasSheet: !!t
920
- }))), s = await G(e, o, a), { imageData: c, imagePath: l } = z(s);
973
+ }))), s = await J(e, o, a), { imageData: c, imagePath: l } = W(s);
921
974
  if (!c) return {
922
975
  ...s,
923
976
  sequence: null
924
977
  };
925
- let u = n.panel < t.totalPanels && n.choices.length >= 2 ? n.choices : [], d = await Z(e.files?.artifacts, X, t.id, (e) => {
978
+ let u = n.panel < t.totalPanels && n.choices.length >= 2 ? n.choices : [], d = await Q(e.files?.artifacts, Z, t.id, (e) => {
926
979
  let r = e ?? t;
927
980
  return u.length && (r.interactive = !0), r.panels[String(n.panel)] = {
928
981
  caption: n.caption,
@@ -948,25 +1001,25 @@ async function rt(e, t, n) {
948
1001
  `panel ${n.panel} of ${t.totalPanels} is on the screen`,
949
1002
  l ? `saved to ${l}` : "",
950
1003
  r.length ? `not in the cast, so drawn from the prompt alone: ${r.join(", ")}` : "",
951
- d ? "" : Q("storyboard")
1004
+ d ? "" : $("storyboard")
952
1005
  ].filter(Boolean).join("; "),
953
- instructions: F(t, n.panel, u),
1006
+ instructions: z(t, n.panel, u),
954
1007
  instructionsRequired: !0,
955
- sequence: Qe(t, n.panel, u)
1008
+ sequence: ft(t, n.panel, u)
956
1009
  };
957
1010
  }
958
- var it = K(() => ({
959
- repeats: Ve(),
1011
+ var vt = ke(() => ({
1012
+ repeats: Qe(),
960
1013
  awaitingChoice: /* @__PURE__ */ new Map()
961
1014
  }));
962
- async function $(e, t) {
963
- let n = P(t);
1015
+ async function yt(e, t) {
1016
+ let n = R(t);
964
1017
  if (!n) return {
965
- message: N,
1018
+ message: L,
966
1019
  sequence: null
967
1020
  };
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`), {
1021
+ let { storyboardId: r, panel: i } = n, { repeats: a, awaitingChoice: o } = vt(e), s = o.get(r);
1022
+ if (s && i > s.panel && !q(e, s.shownAt)) return console.info(`[sequence] holding panel ${i} for the user`), {
970
1023
  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
1024
  cancelled: !0
972
1025
  };
@@ -974,7 +1027,7 @@ async function $(e, t) {
974
1027
  if ("earlier" in c) return await c.earlier ? {
975
1028
  message: `panel ${i} is already on the screen`,
976
1029
  cancelled: !0
977
- } : $(e, t);
1030
+ } : yt(e, t);
978
1031
  let { settle: l } = c, u = {
979
1032
  panel: i,
980
1033
  shownAt: Infinity
@@ -982,7 +1035,7 @@ async function $(e, t) {
982
1035
  o.set(r, u);
983
1036
  let f = () => o.get(r) === u, p = !1;
984
1037
  try {
985
- let t = await ze(e.files?.artifacts, X, r);
1038
+ let t = await Xe(e.files?.artifacts, Z, r);
986
1039
  if (!t) return {
987
1040
  message: `there is no storyboard "${r}"; call defineStoryboard first`,
988
1041
  sequence: null
@@ -991,8 +1044,8 @@ async function $(e, t) {
991
1044
  message: `storyboard "${t.id}" has ${t.totalPanels} panels`,
992
1045
  sequence: null
993
1046
  };
994
- let a = await rt(e, t, n);
995
- p = !!z(a).imageData;
1047
+ let a = await _t(e, t, n);
1048
+ p = !!W(a).imageData;
996
1049
  let s = a.data;
997
1050
  return p && f() && (s?.choices?.length ? o.set(r, {
998
1051
  panel: i,
@@ -1004,21 +1057,21 @@ async function $(e, t) {
1004
1057
  }
1005
1058
  //#endregion
1006
1059
  //#region src/core/index.ts
1007
- var at = {
1008
- toolDefinition: A,
1060
+ var bt = {
1061
+ toolDefinition: P,
1009
1062
  generatingMessage: "Making the slide...",
1010
1063
  isEnabled: () => !0,
1011
- execute: (e, t) => Xe(e, t)
1012
- }, ot = {
1013
- toolDefinition: I,
1064
+ execute: (e, t) => ut(e, t)
1065
+ }, xt = {
1066
+ toolDefinition: V,
1014
1067
  generatingMessage: "Drawing the characters...",
1015
1068
  isEnabled: () => !0,
1016
- execute: (e, t) => tt(e, t)
1017
- }, st = {
1018
- toolDefinition: L,
1069
+ execute: (e, t) => ht(e, t)
1070
+ }, St = {
1071
+ toolDefinition: H,
1019
1072
  generatingMessage: "Drawing the panel...",
1020
1073
  isEnabled: () => !0,
1021
- execute: (e, t) => $(e, t)
1074
+ execute: (e, t) => yt(e, t)
1022
1075
  };
1023
1076
  //#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 };
1077
+ 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 };