@web-ppt/viewer-core 0.5.0-beta.2 → 0.5.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.
@@ -1,152 +1,609 @@
1
- import { transitionPreferredDirection as E, hiddenBefore as Y, staticHidden as k, groupSteps as z, slideText as L, renderSlideToSvg as S, slideToPng as X } from "@web-ppt/core";
2
- import { groupSteps as et, hiddenBefore as st, staticHidden as it } from "@web-ppt/core";
3
- const p = 1.15;
4
- function D(i) {
5
- switch (i) {
1
+ import { transitionPreferredDirection as rt, hiddenBefore as st, staticHidden as tt, groupSteps as ot, slideText as at, renderSlideToSvg as G, invalidateTextMeasureCaches as ct, slideToPng as lt } from "@web-ppt/core";
2
+ import { groupSteps as It, hiddenBefore as Ft, staticHidden as _t } from "@web-ppt/core";
3
+ const z = 6;
4
+ function d(n) {
5
+ return `${Math.round(n * 1e3) / 1e3}%`;
6
+ }
7
+ function W(n, t) {
8
+ const e = n === "vert", r = [];
9
+ for (let s = 0; s < z; s++) {
10
+ const i = s / z * 100, o = (s + 1) / z * 100, c = t ? o : i;
11
+ r.push(e ? g(i, 0, c, 100) : g(0, i, 100, c));
12
+ }
13
+ return A(r);
14
+ }
15
+ const K = [
16
+ "linear-gradient(#000,#000)",
17
+ "linear-gradient(#000,#000)",
18
+ "linear-gradient(#000,#000)",
19
+ "linear-gradient(#000,#000)"
20
+ ].join(", "), et = { l: 0, t: 0, w: 100, h: 100 };
21
+ function nt(n) {
22
+ return n.l === 0 && n.t === 0 && n.w === 100 && n.h === 100;
23
+ }
24
+ function L(n, t = et) {
25
+ if (nt(t)) {
26
+ const c = n ? 50 : 0, l = `100% ${c}%, 100% ${c}%, ${c}% 100%, ${c}% 100%`;
27
+ return {
28
+ opacity: 1,
29
+ maskImage: K,
30
+ maskRepeat: "no-repeat",
31
+ maskPosition: "center top, center bottom, left center, right center",
32
+ maskSize: l,
33
+ maskOrigin: "fill-box",
34
+ maskClip: "fill-box"
35
+ };
36
+ }
37
+ const e = n ? 0.501 : 0, r = t.h * e, s = t.w * e, i = 100 - (t.t + t.h), o = 100 - (t.l + t.w);
38
+ return {
39
+ opacity: 1,
40
+ maskImage: K,
41
+ maskRepeat: "no-repeat",
42
+ // 位置在两帧里不变,只让尺寸插值。底边和右边钉在墨迹框上,条带向中心长。
43
+ maskPosition: [
44
+ `left ${d(t.l)} top ${d(t.t)}`,
45
+ `left ${d(t.l)} bottom ${d(i)}`,
46
+ `left ${d(t.l)} top ${d(t.t)}`,
47
+ `right ${d(o)} top ${d(t.t)}`
48
+ ].join(", "),
49
+ maskSize: [
50
+ `${d(t.w)} ${d(r)}`,
51
+ `${d(t.w)} ${d(r)}`,
52
+ `${d(s)} ${d(t.h)}`,
53
+ `${d(s)} ${d(t.h)}`
54
+ ].join(", "),
55
+ maskOrigin: "fill-box",
56
+ maskClip: "fill-box"
57
+ };
58
+ }
59
+ function Y(n, t = et) {
60
+ if (nt(t))
61
+ return n ? "inset(0% 0% 0% 0%) fill-box" : "inset(50% 50% 50% 50%) fill-box";
62
+ const e = n ? t.t : t.t + t.h / 2, r = n ? t.l : t.l + t.w / 2, s = n ? 100 - (t.t + t.h) : 100 - (t.t + t.h / 2), i = n ? 100 - (t.l + t.w) : 100 - (t.l + t.w / 2);
63
+ return `inset(${d(e)} ${d(i)} ${d(s)} ${d(r)}) fill-box`;
64
+ }
65
+ function A(n, t = []) {
66
+ return {
67
+ opacity: 1,
68
+ maskImage: n.map(() => "linear-gradient(#000,#000)").join(", "),
69
+ maskRepeat: "no-repeat",
70
+ maskPosition: n.map((e, r) => {
71
+ var s, i;
72
+ return `${((s = t[r]) == null ? void 0 : s.x) === "right" ? `right ${d(100 - e[2][0])}` : `left ${d(e[0][0])}`} ${((i = t[r]) == null ? void 0 : i.y) === "bottom" ? `bottom ${d(100 - e[2][1])}` : `top ${d(e[0][1])}`}`;
73
+ }).join(", "),
74
+ maskSize: n.map((e) => `${d(e[2][0] - e[0][0])} ${d(e[2][1] - e[0][1])}`).join(", "),
75
+ maskOrigin: "fill-box",
76
+ maskClip: "fill-box"
77
+ };
78
+ }
79
+ function R(n, t = !1) {
80
+ const e = (i) => Math.round(i * 1e3) / 1e3, r = n.map((i) => `M${e(i[0][0])} ${e(i[0][1])} ` + i.slice(1).map(([o, c]) => `L${e(o)} ${e(c)}`).join(" ") + " Z").join(" "), s = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="none"><path fill="#000" fill-rule="${t ? "evenodd" : "nonzero"}" d="${r}"/></svg>`;
81
+ return {
82
+ opacity: 1,
83
+ maskImage: `url("data:image/svg+xml,${encodeURIComponent(s)}")`,
84
+ maskRepeat: "no-repeat",
85
+ maskPosition: "center",
86
+ maskSize: "100% 100%",
87
+ maskOrigin: "fill-box",
88
+ maskClip: "fill-box"
89
+ };
90
+ }
91
+ function g(n, t, e, r) {
92
+ return [[n, t], [e, t], [e, r], [n, r]];
93
+ }
94
+ function Z(n, t) {
95
+ const e = (n == null ? void 0 : n.endsWith("vert")) ?? !0, r = (n == null ? void 0 : n.startsWith("in")) ?? !1, s = t ? 50 : 0;
96
+ return A(e ? r ? [g(0, 0, s, 100), g(100 - s, 0, 100, 100)] : [g(50 - s, 0, 50, 100), g(50, 0, 50 + s, 100)] : r ? [g(0, 0, 100, s), g(0, 100 - s, 100, 100)] : [g(0, 50 - s, 100, 50), g(0, 50, 100, 50 + s)]);
97
+ }
98
+ function U(n, t) {
99
+ const e = [];
100
+ for (let r = 0; r < 6; r++) for (let s = 0; s < 8; s++) {
101
+ const i = s * 12.5, o = r * (100 / 6), c = i + 12.5, l = o + 100 / 6, h = (r + s) % 2 === 1;
102
+ n === "down" ? e.push(g(
103
+ i,
104
+ h ? l - (t ? l - o : 0) : o,
105
+ c,
106
+ h ? l : o + (t ? l - o : 0)
107
+ )) : e.push(g(
108
+ h ? c - (t ? c - i : 0) : i,
109
+ o,
110
+ h ? c : i + (t ? c - i : 0),
111
+ l
112
+ ));
113
+ }
114
+ return A(e);
115
+ }
116
+ function N(n, t) {
117
+ const e = n === "vert", r = 128, s = typeof t == "boolean" ? Number(t) : t, i = [];
118
+ for (let o = 0; o < r; o++) {
119
+ const c = o * 100 / r, l = (o + 1) * 100 / r, h = o * 73 % r, u = Math.min(1, Math.max(0, s * r - h)) * (l - c);
120
+ i.push(e ? g(c, 0, c + u, 100) : g(0, c, 100, c + u));
121
+ }
122
+ return A(i);
123
+ }
124
+ function D(n, t) {
125
+ const e = (n == null ? void 0 : n.startsWith("l")) ?? !1, r = (n == null ? void 0 : n.endsWith("u")) ?? !1, s = typeof t == "boolean" ? Number(t) : t, i = 8, o = [];
126
+ for (let c = 0; c < i; c++) {
127
+ const l = c * 100 / i, h = (c + 1) * 100 / i, u = (r ? i - c - 1 : c) / (2 * i), f = Math.min(1, Math.max(0, (s - u) / (1 - (i - 1) / (2 * i)))) * 100;
128
+ o.push(e ? g(100 - f, l, 100, h) : g(0, l, f, h));
129
+ }
130
+ return A(o, e ? o.map(() => ({ x: "right" })) : []);
131
+ }
132
+ function ht(n, t) {
133
+ if (n === "circle") return Array.from({ length: 40 }, (r, s) => {
134
+ const i = s * Math.PI / 20 - Math.PI / 2;
135
+ return [50 + t * Math.cos(i), 50 + t * Math.sin(i)];
136
+ });
137
+ if (n === "diamond") return [
138
+ [50, 50 - t],
139
+ [50 + t, 50],
140
+ [50, 50 + t],
141
+ [50 - t, 50]
142
+ ];
143
+ const e = t / 3;
144
+ return [
145
+ [50 - e, 50 - t],
146
+ [50 + e, 50 - t],
147
+ [50 + e, 50 - e],
148
+ [50 + t, 50 - e],
149
+ [50 + t, 50 + e],
150
+ [50 + e, 50 + e],
151
+ [50 + e, 50 + t],
152
+ [50 - e, 50 + t],
153
+ [50 - e, 50 + e],
154
+ [50 - t, 50 + e],
155
+ [50 - t, 50 - e],
156
+ [50 - e, 50 - e]
157
+ ];
158
+ }
159
+ function O(n, t, e) {
160
+ const r = typeof e == "boolean" ? Number(e) : e;
161
+ if (n === "plus" && t === "in") {
162
+ const c = r * 50;
163
+ return A([
164
+ g(0, 0, c, c),
165
+ g(100 - c, 0, 100, c),
166
+ g(0, 100 - c, c, 100),
167
+ g(100 - c, 100 - c, 100, 100)
168
+ ], [{}, { x: "right" }, { y: "bottom" }, { x: "right", y: "bottom" }]);
169
+ }
170
+ const s = n === "circle" ? 72 : n === "diamond" ? 101 : 151, i = (t === "in" ? 1 - r : r) * s, o = ht(n, i);
171
+ return t === "in" ? R([g(0, 0, 100, 100), o], !0) : R([o]);
172
+ }
173
+ function j(n, t) {
174
+ const e = [1, 2, 3, 4, 8].includes(Number(n)) ? Number(n) : 1, r = typeof t == "boolean" ? Number(t) : t, s = [];
175
+ for (let i = 0; i < e; i++) {
176
+ const o = -Math.PI / 2 + i * 2 * Math.PI / e, c = r * 2 * Math.PI / e, l = [[50, 50]];
177
+ for (let h = 0; h <= 16; h++) {
178
+ const u = o + c * h / 16;
179
+ l.push([50 + 200 * Math.cos(u), 50 + 200 * Math.sin(u)]);
180
+ }
181
+ s.push(l);
182
+ }
183
+ return R(s);
184
+ }
185
+ function I(n, t) {
186
+ const e = typeof n == "boolean" ? Number(n) : n, r = [];
187
+ for (let s = 0; s < 8; s++) for (let i = 0; i < 10; i++) {
188
+ const o = i * 10, c = s * 12.5, l = (i + 1) * 10, h = (s + 1) * 12.5;
189
+ let u = Math.imul(s * 10 + i + t * 101, 73244475);
190
+ u = Math.imul(u ^ u >>> 16, 73244475), u = (u ^ u >>> 16) >>> 0;
191
+ const a = u % 17 / 17, f = o + (l - o) * a, m = c + (h - c) * (1 - a), v = (u >>> 8) % 8, b = Math.min(1, Math.max(0, e * 8 - v));
192
+ r.push(g(
193
+ f + (o - f) * b,
194
+ m + (c - m) * b,
195
+ f + (l - f) * b,
196
+ m + (h - m) * b
197
+ ));
198
+ }
199
+ return A(r);
200
+ }
201
+ const ut = 2147483647;
202
+ function ft(n, t, e) {
203
+ const r = n.querySelector("audio,video");
204
+ if (!r) return null;
205
+ if (!Number.isFinite(e) || e < 0)
206
+ throw new Error(`媒体调用的起始时间无效:${e}ms`);
207
+ let s = null, i = e, o = !1, c = !1, l, h;
208
+ const u = new Promise((v, b) => {
209
+ l = v, h = b;
210
+ }), a = () => {
211
+ c = !0, Promise.resolve(r.play()).then(l, h);
212
+ }, f = () => {
213
+ if (s = null, !o)
214
+ try {
215
+ switch (t.action) {
216
+ case "play":
217
+ t.fromSeconds !== void 0 && (r.currentTime = t.fromSeconds), a();
218
+ return;
219
+ case "resume":
220
+ a();
221
+ return;
222
+ case "pause":
223
+ r.pause();
224
+ break;
225
+ case "stop":
226
+ r.pause(), r.currentTime = 0;
227
+ break;
228
+ case "togglePause":
229
+ if (r.paused) {
230
+ a();
231
+ return;
232
+ }
233
+ r.pause();
234
+ break;
235
+ }
236
+ l();
237
+ } catch (v) {
238
+ h(v);
239
+ }
240
+ }, m = () => {
241
+ if (i === 0) {
242
+ f();
243
+ return;
244
+ }
245
+ const v = Math.min(i, ut);
246
+ s = setTimeout(() => {
247
+ i -= v, m();
248
+ }, v);
249
+ };
250
+ return m(), {
251
+ finished: u,
252
+ cancel: () => {
253
+ o = !0, s !== null && clearTimeout(s), c && r.pause(), l();
254
+ }
255
+ };
256
+ }
257
+ const x = 1.15;
258
+ function pt(n) {
259
+ switch (n) {
6
260
  case "l":
7
- return [-100 * p, 0];
261
+ return [-100 * x, 0];
8
262
  case "r":
9
- return [100 * p, 0];
263
+ return [100 * x, 0];
10
264
  case "u":
11
- return [0, -100 * p];
265
+ return [0, -100 * x];
12
266
  case "d":
13
- return [0, 100 * p];
267
+ return [0, 100 * x];
14
268
  case "lu":
15
- return [-100 * p, -100 * p];
269
+ return [-100 * x, -100 * x];
16
270
  case "ru":
17
- return [100 * p, -100 * p];
271
+ return [100 * x, -100 * x];
18
272
  case "ld":
19
- return [-100 * p, 100 * p];
273
+ return [-100 * x, 100 * x];
20
274
  case "rd":
21
- return [100 * p, 100 * p];
275
+ return [100 * x, 100 * x];
22
276
  default:
23
- return [0, 100 * p];
277
+ return [0, 100 * x];
278
+ }
279
+ }
280
+ function dt(n, t, e) {
281
+ const r = n.querySelector("svg");
282
+ if (!r || typeof r.getBoundingClientRect != "function" || typeof t.getBoundingClientRect != "function") return null;
283
+ const s = r.getBoundingClientRect(), i = t.getBoundingClientRect();
284
+ if (s.width < 1 || s.height < 1 || i.width < 1 || i.height < 1) return null;
285
+ const o = (s.left - i.right - 4) / i.width * 100, c = (s.right - i.left + 4) / i.width * 100, l = (s.top - i.bottom - 4) / i.height * 100, h = (s.bottom - i.top + 4) / i.height * 100, u = e != null && e.includes("l") ? o : e != null && e.includes("r") ? c : 0, a = e != null && e.includes("u") ? l : e != null && e.includes("d") || !e ? h : 0;
286
+ return `translate(${u}%, ${a}%)`;
287
+ }
288
+ function k(n, t) {
289
+ return n === t ? `scale(${n})` : `scale(${n}, ${t})`;
290
+ }
291
+ const mt = ["maskImage", "maskRepeat", "maskPosition", "maskSize"];
292
+ function yt(n) {
293
+ var a, f;
294
+ const t = (a = n.getBoundingClientRect) == null ? void 0 : a.call(n), e = (f = n.ownerDocument) == null ? void 0 : f.createRange;
295
+ if (!t || t.width < 1 || t.height < 1 || typeof e != "function") return null;
296
+ const r = e.call(n.ownerDocument);
297
+ r.selectNodeContents(n);
298
+ const s = r.getBoundingClientRect();
299
+ if (s.width < 1 || s.height < 1) return null;
300
+ const i = Math.min(100, Math.max(0, (s.left - t.left) / t.width * 100)), o = Math.min(100, Math.max(0, (s.top - t.top) / t.height * 100)), c = Math.min(100, Math.max(i, (s.right - t.left) / t.width * 100)), l = Math.min(100, Math.max(o, (s.bottom - t.top) / t.height * 100)), h = c - i, u = l - o;
301
+ return h < 1 || u < 1 ? null : { l: i, t: o, w: h, h: u };
302
+ }
303
+ function gt(n, t) {
304
+ if (!t || typeof n.querySelectorAll != "function") return [];
305
+ const e = [];
306
+ for (const s of n.querySelectorAll("[data-p]")) {
307
+ const i = Number(s.getAttribute("data-p"));
308
+ Number.isInteger(i) && i >= t.start && i <= t.end && e.push(s);
309
+ }
310
+ if (e.length) return e;
311
+ const r = [];
312
+ for (const s of n.querySelectorAll("foreignObject > :first-child")) {
313
+ const i = [...s.children].filter((o) => o.localName === "div");
314
+ for (let o = t.start; o <= t.end && o < i.length; o++)
315
+ r.push(i[o]);
316
+ }
317
+ return r;
318
+ }
319
+ function vt(n, t, e) {
320
+ if (n.kind !== "emphasis" && n.kind !== "motion" && n.effect === "zoom" && (n.dir === "in" || n.dir === "out")) {
321
+ const r = yt(t);
322
+ if (r) {
323
+ const s = n.dir === "in" ? {
324
+ from: L(!1, r),
325
+ to: L(!0, r)
326
+ } : {
327
+ from: { opacity: 1, clipPath: Y(!1, r) },
328
+ to: { opacity: 1, clipPath: Y(!0, r) }
329
+ }, i = n.kind === "exit" ? [s.to, s.from] : [s.from, s.to];
330
+ return F(i);
331
+ }
24
332
  }
333
+ return F(e);
25
334
  }
26
- function d(i, e) {
27
- const t = e ? 100 : 0;
28
- switch (i) {
335
+ function F(n) {
336
+ const t = (e) => e.clipPath !== void 0 || e.maskSize !== void 0;
337
+ return n.some(t) ? n.map((e) => {
338
+ const r = {};
339
+ e.clipPath !== void 0 && (r.clipPath = String(e.clipPath).replace(/ fill-box/g, ""));
340
+ for (const s of mt) e[s] !== void 0 && (r[s] = e[s]);
341
+ return e.maskSize !== void 0 && (r.maskOrigin = "border-box", r.maskClip = "border-box"), e.offset !== void 0 && (r.offset = e.offset), r;
342
+ }) : null;
343
+ }
344
+ function $(n, t) {
345
+ const e = t ? 100 : 0;
346
+ switch (n) {
29
347
  case "l":
30
- return `inset(0 ${t}% 0 0)`;
348
+ return `inset(0 ${e}% 0 0)`;
31
349
  case "r":
32
- return `inset(0 0 0 ${t}%)`;
350
+ return `inset(0 0 0 ${e}%)`;
33
351
  case "u":
34
- return `inset(0 0 ${t}% 0)`;
352
+ return `inset(0 0 ${e}% 0)`;
35
353
  case "horz":
36
- return `inset(0 ${t / 2}% 0 ${t / 2}%)`;
354
+ return `inset(0 ${e / 2}% 0 ${e / 2}%)`;
37
355
  case "vert":
38
- return `inset(${t / 2}% 0 ${t / 2}% 0)`;
356
+ return `inset(${e / 2}% 0 ${e / 2}% 0)`;
39
357
  default:
40
- return `inset(${t}% 0 0 0)`;
358
+ return `inset(${e}% 0 0 0)`;
41
359
  }
42
360
  }
43
- function T(i) {
44
- switch (i.effect) {
361
+ const xt = {
362
+ d: { origin: "center bottom", axis: "scaleY" },
363
+ u: { origin: "center top", axis: "scaleY" },
364
+ l: { origin: "left center", axis: "scaleX" },
365
+ r: { origin: "right center", axis: "scaleX" },
366
+ lu: { origin: "left top", axis: "scale" },
367
+ ru: { origin: "right top", axis: "scale" },
368
+ ld: { origin: "left bottom", axis: "scale" },
369
+ rd: { origin: "right bottom", axis: "scale" }
370
+ };
371
+ function bt(n) {
372
+ return (n ? xt[n] : void 0) ?? { origin: "center", axis: "scaleX" };
373
+ }
374
+ function _(n, t) {
375
+ const e = Math.round(Math.sin(2.5 * Math.PI * t) * 1e4) / 1e4;
376
+ return {
377
+ opacity: t,
378
+ transform: n === "horz" ? `scaleY(${e})` : `scaleX(${e})`
379
+ };
380
+ }
381
+ function q(n) {
382
+ var t, e, r, s, i, o, c, l, h, u;
383
+ switch (n.effect) {
45
384
  case "appear":
46
385
  return { from: { opacity: 0 }, to: { opacity: 1 } };
47
386
  case "fly": {
48
- const [e, t] = D(i.dir);
387
+ const [a, f] = pt(n.dir);
49
388
  return {
50
- from: { opacity: 0, transform: `translate(${e}%, ${t}%)` },
389
+ from: { opacity: 0, transform: `translate(${a}%, ${f}%)` },
51
390
  to: { opacity: 1, transform: "translate(0, 0)" }
52
391
  };
53
392
  }
54
393
  case "zoom":
55
- return {
56
- from: { opacity: 0, transform: i.dir === "out" ? "scale(1.6)" : "scale(0.1)" },
57
- to: { opacity: 1, transform: "scale(1)" }
394
+ return n.dir === "in" ? { from: L(!1), to: L(!0) } : n.dir === "out" ? {
395
+ from: { opacity: 1, clipPath: Y(!1) },
396
+ to: { opacity: 1, clipPath: Y(!0) }
397
+ } : {
398
+ from: { opacity: 0, transform: k(((t = n.scale) == null ? void 0 : t.fromX) ?? 0, ((e = n.scale) == null ? void 0 : e.fromY) ?? 0) },
399
+ to: { opacity: 1, transform: k(((r = n.scale) == null ? void 0 : r.toX) ?? 1, ((s = n.scale) == null ? void 0 : s.toY) ?? 1) }
58
400
  };
59
401
  case "grow":
60
- return { from: { opacity: 0, transform: "scale(0.2) rotate(-90deg)" }, to: { opacity: 1, transform: "scale(1) rotate(0)" } };
402
+ return {
403
+ from: { opacity: 1, transform: `${k(((i = n.scale) == null ? void 0 : i.fromX) ?? 0, ((o = n.scale) == null ? void 0 : o.fromY) ?? 0)} rotate(${((c = n.rotation) == null ? void 0 : c.from) ?? 0}deg)` },
404
+ to: { opacity: 1, transform: `${k(((l = n.scale) == null ? void 0 : l.toX) ?? 1, ((h = n.scale) == null ? void 0 : h.toY) ?? 1)} rotate(${((u = n.rotation) == null ? void 0 : u.to) ?? 90}deg)` }
405
+ };
61
406
  case "spin":
62
407
  return { from: { opacity: 0, transform: "rotate(-180deg) scale(0.4)" }, to: { opacity: 1, transform: "rotate(0) scale(1)" } };
63
408
  case "swivel":
64
- return { from: { opacity: 0, transform: "rotateY(90deg)" }, to: { opacity: 1, transform: "rotateY(0)" } };
409
+ return { from: _(n.dir, 0), to: _(n.dir, 1) };
65
410
  case "float":
66
411
  return { from: { opacity: 0, transform: "translateY(30%)" }, to: { opacity: 1, transform: "translateY(0)" } };
67
412
  case "bounce":
68
413
  return { from: { opacity: 0, transform: "translateY(-60%)" }, to: { opacity: 1, transform: "translateY(0)" } };
69
- case "stretch":
70
- return { from: { opacity: 0, transform: "scaleX(0.05)" }, to: { opacity: 1, transform: "scaleX(1)" } };
71
- case "wipe":
414
+ case "stretch": {
415
+ if (n.scale)
416
+ return {
417
+ from: { opacity: 0, transform: k(n.scale.fromX, n.scale.fromY) },
418
+ to: { opacity: 1, transform: k(n.scale.toX, n.scale.toY) }
419
+ };
420
+ const { origin: a, axis: f } = bt(n.dir);
421
+ return {
422
+ from: { opacity: 1, transform: `${f}(0)`, transformOrigin: a },
423
+ to: { opacity: 1, transform: `${f}(1)`, transformOrigin: a }
424
+ };
425
+ }
72
426
  case "blinds":
427
+ return {
428
+ from: W(n.dir, !1),
429
+ to: W(n.dir, !0)
430
+ };
431
+ case "checkerboard":
432
+ return {
433
+ from: U(n.dir, !1),
434
+ to: U(n.dir, !0)
435
+ };
436
+ case "randomBar":
437
+ return {
438
+ from: N(n.dir, !1),
439
+ to: N(n.dir, !0)
440
+ };
441
+ case "strips":
442
+ return {
443
+ from: D(n.dir, !1),
444
+ to: D(n.dir, !0)
445
+ };
446
+ case "circle":
447
+ case "diamond":
448
+ case "plus":
449
+ return {
450
+ from: O(n.effect, n.dir, !1),
451
+ to: O(n.effect, n.dir, !0)
452
+ };
453
+ case "wipe":
454
+ return {
455
+ from: { opacity: 1, clipPath: $(n.dir, !0) },
456
+ to: { opacity: 1, clipPath: $(n.dir, !1) }
457
+ };
73
458
  case "split":
459
+ return {
460
+ from: Z(n.dir, !1),
461
+ to: Z(n.dir, !0)
462
+ };
74
463
  case "wheel":
75
464
  return {
76
- from: { opacity: 1, clipPath: d(i.dir, !0) },
77
- to: { opacity: 1, clipPath: d(i.dir, !1) }
465
+ from: j(n.dir, !1),
466
+ to: j(n.dir, !0)
78
467
  };
79
468
  case "dissolve":
80
- case "fade":
469
+ return {
470
+ from: I(!1, n.target),
471
+ to: I(!0, n.target)
472
+ };
81
473
  case "random":
474
+ return q({ ...n, effect: ["fly", "wipe", "zoom"][n.target % 3], dir: "d" });
475
+ case "fade":
82
476
  default:
83
477
  return { from: { opacity: 0 }, to: { opacity: 1 } };
84
478
  }
85
479
  }
86
- function N(i) {
87
- const e = T({ ...i });
88
- return { from: e.to, to: e.from };
480
+ function wt(n) {
481
+ const t = q({ ...n, kind: "entrance" });
482
+ return { from: t.to, to: t.from };
89
483
  }
90
- function V(i) {
91
- switch (i.effect) {
484
+ function kt(n) {
485
+ var t, e, r, s;
486
+ switch (n.effect) {
92
487
  case "spin":
93
488
  return { from: { transform: "rotate(0)" }, to: { transform: "rotate(360deg)" } };
94
489
  case "grow":
95
- return { from: { transform: "scale(1)" }, to: { transform: "scale(1.25)" } };
490
+ return {
491
+ from: { transform: k(((t = n.scale) == null ? void 0 : t.fromX) ?? 1, ((e = n.scale) == null ? void 0 : e.fromY) ?? 1) },
492
+ to: { transform: k(((r = n.scale) == null ? void 0 : r.toX) ?? 1.25, ((s = n.scale) == null ? void 0 : s.toY) ?? 1.25) }
493
+ };
96
494
  default:
97
- return { from: { opacity: 1 }, to: { opacity: 0.35 } };
98
- }
99
- }
100
- function F(i) {
101
- return i.kind === "exit" ? N(i) : i.kind === "emphasis" ? V(i) : i.kind === "motion" ? { from: { opacity: 1 }, to: { opacity: 1 } } : T(i);
102
- }
103
- function q(i, e) {
104
- var s, r, c;
105
- const t = [];
106
- let n = 0, o = 0;
107
- for (const a of e) {
108
- const l = a.trigger === "afterPrev" ? o + a.delayMs : a.trigger === "withPrev" ? n + a.delayMs : a.delayMs;
109
- n = l, o = l + a.durationMs;
110
- const h = i.querySelector(`[data-el="${a.target}"]`);
111
- if (!h) continue;
112
- const { from: b, to: g } = F(a);
113
- h.style.visibility = "visible", a.kind === "entrance" && (h.style.opacity = "");
114
- const f = (s = a.motionPath) == null ? void 0 : s.reduce((u, [m, w], A, P) => (A === 0 ? u.push(0) : u.push(u[A - 1] + Math.hypot(m - P[A - 1][0], w - P[A - 1][1])), u), []), x = (f == null ? void 0 : f[f.length - 1]) ?? 0, $ = (r = a.motionPath) != null && r.length ? a.motionPath.map(([u, m], w) => ({
115
- transform: `translate(${u}px, ${m}px)`,
116
- offset: x > 0 ? f[w] / x : w / (a.motionPath.length - 1)
117
- })) : [b, g];
495
+ return { from: { opacity: 1 }, to: { opacity: 0.5 } };
496
+ }
497
+ }
498
+ function B(n) {
499
+ return n.kind === "exit" ? wt(n) : n.kind === "emphasis" ? kt(n) : n.kind === "motion" ? { from: { opacity: 1 }, to: { opacity: 1 } } : q(n);
500
+ }
501
+ function $t(n, t) {
502
+ var l, h, u;
503
+ const e = [], r = [], s = [];
504
+ let i = !1, o = 0, c = 0;
505
+ for (const a of t) {
506
+ const f = a.trigger === "afterPrev" ? c + a.delayMs : a.trigger === "withPrev" ? o + a.delayMs : a.delayMs;
507
+ o = f, c = f + a.durationMs;
508
+ const m = n.querySelector(`[data-el="${a.target}"]`);
509
+ if (!m) continue;
510
+ if (a.mediaCommand) {
511
+ const y = ft(m, a.mediaCommand, f);
512
+ y && s.push(y);
513
+ continue;
514
+ }
515
+ a.kind === "exit" && r.push(m);
516
+ const { from: v, to: b } = B(a);
517
+ if (m.style.visibility = "visible", a.kind === "entrance" && (m.style.opacity = ""), a.effect === "fly" && (a.kind === "entrance" || a.kind === "exit")) {
518
+ const y = dt(n, m, a.dir);
519
+ y && (a.kind === "entrance" ? v.transform = y : b.transform = y);
520
+ }
521
+ const S = (l = a.motionPath) == null ? void 0 : l.reduce((y, [p, P], w, T) => (w === 0 ? y.push(0) : y.push(y[w - 1] + Math.hypot(p - T[w - 1][0], P - T[w - 1][1])), y), []), V = (S == null ? void 0 : S[S.length - 1]) ?? 0, M = (h = a.motionPath) != null && h.length ? a.motionPath.map(([y, p], P) => ({
522
+ transform: `translate(${y}px, ${p}px)`,
523
+ offset: V > 0 ? S[P] / V : P / (a.motionPath.length - 1)
524
+ })) : a.effect === "randomBar" ? Array.from({ length: 13 }, (y, p) => ({
525
+ ...N(a.dir, a.kind === "exit" ? 1 - p / 12 : p / 12),
526
+ offset: p / 12
527
+ })) : a.effect === "strips" ? Array.from({ length: 21 }, (y, p) => ({
528
+ ...D(a.dir, a.kind === "exit" ? 1 - p / 20 : p / 20),
529
+ offset: p / 20
530
+ })) : a.effect === "wheel" ? Array.from({ length: 73 }, (y, p) => ({
531
+ ...j(a.dir, a.kind === "exit" ? 1 - p / 72 : p / 72),
532
+ offset: p / 72
533
+ })) : a.effect === "circle" || a.effect === "diamond" || a.effect === "plus" && a.dir !== "in" ? Array.from({ length: 37 }, (y, p) => ({
534
+ ...O(
535
+ a.effect,
536
+ a.dir,
537
+ a.kind === "exit" ? 1 - p / 36 : p / 36
538
+ ),
539
+ offset: p / 36
540
+ })) : a.effect === "dissolve" ? Array.from({ length: 9 }, (y, p) => ({
541
+ ...I(a.kind === "exit" ? 1 - p / 8 : p / 8, a.target),
542
+ offset: p / 8
543
+ })) : a.effect === "swivel" && (a.kind === "entrance" || a.kind === "exit") ? Array.from({ length: 41 }, (y, p) => ({
544
+ ..._(a.dir, a.kind === "exit" ? 1 - p / 40 : p / 40),
545
+ offset: p / 40
546
+ })) : a.effect === "bounce" && a.kind === "entrance" ? [
547
+ { opacity: 0, transform: "translateY(-60%)", offset: 0 },
548
+ { opacity: 1, transform: "translateY(10%)", offset: 0.5 },
549
+ { opacity: 1, transform: "translateY(-8%)", offset: 0.7 },
550
+ { opacity: 1, transform: "translateY(3%)", offset: 0.85 },
551
+ { opacity: 1, transform: "translateY(0)", offset: 1 }
552
+ ] : [v, b];
118
553
  try {
119
- const u = (c = a.motionPath) != null && c.length ? "linear" : a.effect === "appear" && a.kind === "entrance" ? "steps(1, start)" : a.effect === "appear" && a.kind === "exit" ? "steps(1, end)" : "cubic-bezier(0.25, 0.46, 0.45, 0.94)", m = h.animate($, {
554
+ const y = (u = a.motionPath) != null && u.length || a.effect === "randomBar" || a.effect === "strips" || a.effect === "wheel" || a.effect === "circle" || a.effect === "diamond" || a.effect === "plus" || a.effect === "dissolve" || a.effect === "bounce" || a.effect === "swivel" ? "linear" : a.effect === "appear" && a.kind === "entrance" ? "steps(1, start)" : a.effect === "appear" && a.kind === "exit" ? "steps(1, end)" : "cubic-bezier(0.25, 0.46, 0.45, 0.94)", p = m.animate(M, {
120
555
  duration: a.durationMs,
121
- delay: l,
556
+ delay: f,
122
557
  // 路径动画在 PowerPoint 里是匀速,不能套入场用的缓动
123
- easing: u,
558
+ easing: y,
124
559
  fill: "both"
125
560
  });
126
- a.kind === "exit" && m.finished.then(() => {
127
- h.style.visibility = "hidden";
561
+ a.kind === "exit" && p.finished.then(() => {
562
+ i || (m.style.visibility = "hidden");
128
563
  }).catch(() => {
129
- }), t.push(m);
564
+ }), e.push(p);
565
+ const P = F(M);
566
+ if (!P || typeof m.querySelectorAll != "function") continue;
567
+ const w = gt(m, a.paragraphRange), T = w.length ? w : m.querySelectorAll("foreignObject > :first-child");
568
+ for (const X of T) {
569
+ if (!(X instanceof HTMLElement)) continue;
570
+ const H = w.length ? vt(a, X, M) : P;
571
+ H && e.push(X.animate(H, {
572
+ duration: a.durationMs,
573
+ delay: f,
574
+ easing: y,
575
+ fill: "both"
576
+ }));
577
+ }
130
578
  } catch {
131
- Object.assign(h.style, $[$.length - 1] ?? g);
579
+ Object.assign(m.style, M[M.length - 1] ?? b), a.kind === "exit" && (m.style.visibility = "hidden");
132
580
  }
133
581
  }
134
582
  return {
135
- animations: t,
136
- cancel: () => t.forEach((a) => {
137
- try {
138
- a.finish();
139
- } catch {
140
- }
141
- }),
142
- finished: Promise.all(t.map((a) => a.finished.catch(() => {
143
- }))).then(() => {
583
+ animations: e,
584
+ cancel: () => {
585
+ i = !0, e.forEach((a) => {
586
+ try {
587
+ a.finish();
588
+ } catch {
589
+ }
590
+ }), s.forEach((a) => a.cancel());
591
+ for (const a of r) a.style.visibility = "hidden";
592
+ },
593
+ // 等全部视觉与媒体调用落定后再报告:媒体失败不能让批次提前收尾、截断仍在播的视觉动画。
594
+ finished: Promise.all([
595
+ Promise.all(e.map((a) => a.finished.catch(() => {
596
+ }))),
597
+ Promise.allSettled(s.map((a) => a.finished))
598
+ ]).then(([, a]) => {
599
+ const f = a.find((m) => m.status === "rejected");
600
+ if (f) throw f.reason;
144
601
  })
145
602
  };
146
603
  }
147
- function M(i, e) {
148
- const t = i.dir ?? E(i.type) ?? "", n = (s, r) => `translate(${s}, ${r})`, o = () => {
149
- const s = {
604
+ function J(n, t) {
605
+ const e = n.dir ?? rt(n.type) ?? "", r = (i, o) => `translate(${i}, ${o})`, s = () => {
606
+ const i = {
150
607
  l: ["-100%", "0"],
151
608
  r: ["100%", "0"],
152
609
  u: ["0", "-100%"],
@@ -156,11 +613,16 @@ function M(i, e) {
156
613
  ru: ["100%", "-100%"],
157
614
  rd: ["100%", "100%"]
158
615
  };
159
- return s[t] ?? s.d;
616
+ return i[e] ?? i.d;
160
617
  };
161
- switch (i.type) {
618
+ switch (n.type) {
162
619
  case "cut":
163
- return e ? [{ opacity: 1 }, { opacity: 1 }] : [
620
+ return t ? [
621
+ { opacity: 0, offset: 0 },
622
+ { opacity: 0, offset: 0.49 },
623
+ { opacity: 1, offset: 0.5 },
624
+ { opacity: 1, offset: 1 }
625
+ ] : [
164
626
  { opacity: 1, offset: 0 },
165
627
  { opacity: 1, offset: 0.49 },
166
628
  { opacity: 0, offset: 0.5 },
@@ -168,229 +630,229 @@ function M(i, e) {
168
630
  ];
169
631
  case "push":
170
632
  case "pull": {
171
- const [s, r] = o(), c = i.type === "pull" ? -1 : 1, a = (l) => l === "0" ? "0" : `${-parseFloat(l) * c}%`;
172
- return e ? [{ transform: n(c > 0 ? s : a(s), c > 0 ? r : a(r)) }, { transform: "translate(0,0)" }] : [{ transform: "translate(0,0)" }, { transform: n(a(s), a(r)) }];
633
+ const [i, o] = s(), c = n.type === "pull" ? -1 : 1, l = (h) => h === "0" ? "0" : `${-parseFloat(h) * c}%`;
634
+ return t ? [{ transform: r(c > 0 ? i : l(i), c > 0 ? o : l(o)) }, { transform: "translate(0,0)" }] : [{ transform: "translate(0,0)" }, { transform: r(l(i), l(o)) }];
173
635
  }
174
636
  case "cover": {
175
- const [s, r] = o();
176
- return e ? [{ transform: n(s, r) }, { transform: "translate(0,0)" }] : [{ opacity: 1 }, { opacity: 1 }];
637
+ const [i, o] = s();
638
+ return t ? [{ transform: r(i, o) }, { transform: "translate(0,0)" }] : [{ opacity: 1 }, { opacity: 1 }];
177
639
  }
178
640
  case "wipe": {
179
- const s = d(t || "d", !0), r = d(t || "d", !1);
180
- return e ? [{ clipPath: s }, { clipPath: r }] : [{ opacity: 1 }, { opacity: 1 }];
641
+ const i = $(e || "d", !0), o = $(e || "d", !1);
642
+ return t ? [{ clipPath: i }, { clipPath: o }] : [{ opacity: 1 }, { opacity: 1 }];
181
643
  }
182
644
  case "split": {
183
- const s = t.startsWith("vert"), r = t.endsWith("out"), c = s ? "inset(0 50% 0 50%)" : "inset(50% 0 50% 0)", a = "inset(0 0 0 0)";
184
- return e ? r ? [{ clipPath: c }, { clipPath: a }] : [{ clipPath: a }, { clipPath: a }] : [{ clipPath: a }, { clipPath: c }];
645
+ const i = e.startsWith("vert"), o = e.endsWith("out"), c = i ? "inset(0 50% 0 50%)" : "inset(50% 0 50% 0)", l = "inset(0 0 0 0)";
646
+ return t ? o ? [{ clipPath: c }, { clipPath: l }] : [{ clipPath: l }, { clipPath: l }] : [{ clipPath: l }, { clipPath: c }];
185
647
  }
186
648
  case "zoom":
187
- return e ? [{ opacity: 0, transform: t === "out" ? "scale(1.4)" : "scale(0.6)" }, { opacity: 1, transform: "scale(1)" }] : [{ opacity: 1 }, { opacity: 0 }];
649
+ return t ? [{ opacity: 0, transform: e === "out" ? "scale(1.4)" : "scale(0.6)" }, { opacity: 1, transform: "scale(1)" }] : [{ opacity: 1 }, { opacity: 0 }];
188
650
  case "wheel":
189
651
  case "circle":
190
652
  case "diamond":
191
653
  case "plus":
192
654
  case "wedge":
193
- return e ? [{ opacity: 0, transform: "scale(0.7)" }, { opacity: 1, transform: "scale(1)" }] : [{ opacity: 1 }, { opacity: 0 }];
655
+ return t ? [{ opacity: 0, transform: "scale(0.7)" }, { opacity: 1, transform: "scale(1)" }] : [{ opacity: 1 }, { opacity: 0 }];
194
656
  case "ripple": {
195
- const s = {
657
+ const i = {
196
658
  lu: "0% 0%",
197
659
  ld: "0% 100%",
198
660
  ru: "100% 0%",
199
661
  rd: "100% 100%",
200
662
  center: "50% 50%"
201
- }, r = s[t] ?? s.center;
202
- return e ? [{ clipPath: `circle(0% at ${r})` }, { clipPath: `circle(145% at ${r})` }] : [{ opacity: 1 }, { opacity: 1 }];
663
+ }, o = i[e] ?? i.center;
664
+ return t ? [{ clipPath: `circle(0% at ${o})` }, { clipPath: `circle(145% at ${o})` }] : [{ opacity: 1 }, { opacity: 1 }];
203
665
  }
204
666
  case "vortex": {
205
- const [s, r] = o(), c = t === "r" || t === "d" ? 180 : -180;
206
- return e ? [{ opacity: 0, transformOrigin: `${s === "0" ? "50%" : s.startsWith("-") ? "0%" : "100%"} ${r === "0" ? "50%" : r.startsWith("-") ? "0%" : "100%"}`, transform: `scale(0.2) rotate(${c}deg)` }, { opacity: 1, transform: "none" }] : [{ opacity: 1 }, { opacity: 0 }];
667
+ const [i, o] = s(), c = e === "r" || e === "d" ? 180 : -180;
668
+ return t ? [{ opacity: 0, transformOrigin: `${i === "0" ? "50%" : i.startsWith("-") ? "0%" : "100%"} ${o === "0" ? "50%" : o.startsWith("-") ? "0%" : "100%"}`, transform: `scale(0.2) rotate(${c}deg)` }, { opacity: 1, transform: "none" }] : [{ opacity: 1 }, { opacity: 0 }];
207
669
  }
208
670
  case "honeycomb":
209
- return e ? [{ opacity: 0, transform: "scale(0.85) rotate(-6deg)" }, { opacity: 1, transform: "none" }] : [{ opacity: 1, transform: "none" }, { opacity: 0, transform: "scale(1.1)" }];
671
+ return t ? [{ opacity: 0, transform: "scale(0.85) rotate(-6deg)" }, { opacity: 1, transform: "none" }] : [{ opacity: 1, transform: "none" }, { opacity: 0, transform: "scale(1.1)" }];
210
672
  case "glitter":
211
- return e ? [{ opacity: 0, clipPath: d(t || "l", !0) }, { opacity: 1, clipPath: d(t || "l", !1) }] : [{ opacity: 1 }, { opacity: 0 }];
673
+ return t ? [{ opacity: 0, clipPath: $(e || "l", !0) }, { opacity: 1, clipPath: $(e || "l", !1) }] : [{ opacity: 1 }, { opacity: 0 }];
212
674
  case "shred": {
213
- const s = t === "out";
214
- return e ? [{ opacity: 0, transform: s ? "scale(1.35) rotate(5deg)" : "scale(0.72) rotate(-5deg)" }, { opacity: 1, transform: "none" }] : [{ opacity: 1, transform: "none" }, { opacity: 0, transform: s ? "scaleY(0.72)" : "scaleY(1.2)" }];
675
+ const i = e === "out";
676
+ return t ? [{ opacity: 0, transform: i ? "scale(1.35) rotate(5deg)" : "scale(0.72) rotate(-5deg)" }, { opacity: 1, transform: "none" }] : [{ opacity: 1, transform: "none" }, { opacity: 0, transform: i ? "scaleY(0.72)" : "scaleY(1.2)" }];
215
677
  }
216
678
  case "flash":
217
- return e ? [{ opacity: 0, filter: "brightness(3)" }, { opacity: 1, filter: "brightness(1)" }] : [{ opacity: 1, filter: "brightness(1)" }, { opacity: 0, filter: "brightness(3)" }];
679
+ return t ? [{ opacity: 0, filter: "brightness(3)" }, { opacity: 1, filter: "brightness(1)" }] : [{ opacity: 1, filter: "brightness(1)" }, { opacity: 0, filter: "brightness(3)" }];
218
680
  case "reveal": {
219
- const [s, r] = o();
220
- return e ? [{ opacity: 0, transform: n(s, r) }, { opacity: 1, transform: "translate(0,0)" }] : [{ opacity: 1 }, { opacity: 0 }];
681
+ const [i, o] = s();
682
+ return t ? [{ opacity: 0, transform: r(i, o) }, { opacity: 1, transform: "translate(0,0)" }] : [{ opacity: 1 }, { opacity: 0 }];
221
683
  }
222
684
  case "wheelReverse":
223
- return e ? [{ opacity: 0, transform: "scale(1.3) rotate(20deg)" }, { opacity: 1, transform: "none" }] : [{ opacity: 1 }, { opacity: 0 }];
685
+ return t ? [{ opacity: 0, transform: "scale(1.3) rotate(20deg)" }, { opacity: 1, transform: "none" }] : [{ opacity: 1 }, { opacity: 0 }];
224
686
  case "doors":
225
- return e ? [{ clipPath: t === "horz" ? "inset(50% 0 50% 0)" : "inset(0 50% 0 50%)" }, { clipPath: "inset(0 0 0 0)" }] : [{ opacity: 1 }, { opacity: 1 }];
687
+ return t ? [{ clipPath: e === "horz" ? "inset(50% 0 50% 0)" : "inset(0 50% 0 50%)" }, { clipPath: "inset(0 0 0 0)" }] : [{ opacity: 1 }, { opacity: 1 }];
226
688
  case "window":
227
- return e ? [{ clipPath: t === "horz" ? "inset(0 50% 0 50%)" : "inset(50% 0 50% 0)" }, { clipPath: "inset(0 0 0 0)" }] : [{ opacity: 1 }, { opacity: 1 }];
689
+ return t ? [{ clipPath: e === "horz" ? "inset(0 50% 0 50%)" : "inset(50% 0 50% 0)" }, { clipPath: "inset(0 0 0 0)" }] : [{ opacity: 1 }, { opacity: 1 }];
228
690
  case "switch":
229
691
  case "flip": {
230
- const s = (i.type === "flip" ? -1 : 1) * (t === "r" ? -1 : 1);
231
- return e ? [
232
- { opacity: 0, transform: `perspective(1400px) rotateY(${s * -80}deg)` },
692
+ const i = (n.type === "flip" ? -1 : 1) * (e === "r" ? -1 : 1);
693
+ return t ? [
694
+ { opacity: 0, transform: `perspective(1400px) rotateY(${i * -80}deg)` },
233
695
  { opacity: 1, transform: "perspective(1400px) rotateY(0)" }
234
696
  ] : [
235
697
  { opacity: 1, transform: "perspective(1400px) rotateY(0)" },
236
- { opacity: 0, transform: `perspective(1400px) rotateY(${s * 80}deg)` }
698
+ { opacity: 0, transform: `perspective(1400px) rotateY(${i * 80}deg)` }
237
699
  ];
238
700
  }
239
701
  case "prism": {
240
- const s = t === "u" || t === "d", r = t === "r" || t === "d" ? -1 : 1, c = (a) => s ? `rotateX(${a}deg)` : `rotateY(${a}deg)`;
241
- return e ? [
242
- { opacity: 0, transform: `perspective(1400px) ${c(r * -70)}` },
702
+ const i = e === "u" || e === "d", o = e === "r" || e === "d" ? -1 : 1, c = (l) => i ? `rotateX(${l}deg)` : `rotateY(${l}deg)`;
703
+ return t ? [
704
+ { opacity: 0, transform: `perspective(1400px) ${c(o * -70)}` },
243
705
  { opacity: 1, transform: `perspective(1400px) ${c(0)}` }
244
706
  ] : [
245
707
  { opacity: 1, transform: `perspective(1400px) ${c(0)}` },
246
- { opacity: 0, transform: `perspective(1400px) ${c(r * 70)}` }
708
+ { opacity: 0, transform: `perspective(1400px) ${c(o * 70)}` }
247
709
  ];
248
710
  }
249
711
  case "ferris": {
250
- const s = t === "r" ? -1 : 1;
251
- return e ? [
252
- { opacity: 0, transform: `perspective(1400px) rotateX(${s * 70}deg)` },
712
+ const i = e === "r" ? -1 : 1;
713
+ return t ? [
714
+ { opacity: 0, transform: `perspective(1400px) rotateX(${i * 70}deg)` },
253
715
  { opacity: 1, transform: "perspective(1400px) rotateX(0)" }
254
716
  ] : [
255
717
  { opacity: 1, transform: "perspective(1400px) rotateX(0)" },
256
- { opacity: 0, transform: `perspective(1400px) rotateX(${s * -70}deg)` }
718
+ { opacity: 0, transform: `perspective(1400px) rotateX(${i * -70}deg)` }
257
719
  ];
258
720
  }
259
721
  case "gallery":
260
722
  case "conveyor": {
261
- const s = i.type === "conveyor" ? 25 : 12, r = t.includes("l") ? "-100%" : "100%", c = t.includes("l") ? "100%" : "-100%";
262
- return e ? [
263
- { transform: `perspective(1600px) translateX(${r}) rotateY(${s}deg)` },
723
+ const i = n.type === "conveyor" ? 25 : 12, o = e.includes("l") ? "-100%" : "100%", c = e.includes("l") ? "100%" : "-100%";
724
+ return t ? [
725
+ { transform: `perspective(1600px) translateX(${o}) rotateY(${i}deg)` },
264
726
  { transform: "perspective(1600px) translateX(0) rotateY(0)" }
265
727
  ] : [
266
728
  { transform: "perspective(1600px) translateX(0) rotateY(0)" },
267
- { transform: `perspective(1600px) translateX(${c}) rotateY(${-s}deg)` }
729
+ { transform: `perspective(1600px) translateX(${c}) rotateY(${-i}deg)` }
268
730
  ];
269
731
  }
270
732
  case "pan": {
271
- const [s, r] = o(), c = (a) => a === "0" ? "0" : `${-parseFloat(a)}%`;
272
- return e ? [{ transform: n(s, r) }, { transform: "translate(0,0)" }] : [{ transform: "translate(0,0)" }, { transform: n(c(s), c(r)) }];
733
+ const [i, o] = s(), c = (l) => l === "0" ? "0" : `${-parseFloat(l)}%`;
734
+ return t ? [{ transform: r(i, o) }, { transform: "translate(0,0)" }] : [{ transform: "translate(0,0)" }, { transform: r(c(i), c(o)) }];
273
735
  }
274
736
  case "flythrough":
275
- return e ? [{ opacity: 0, transform: `perspective(1000px) scale(${t === "out" ? 2.2 : 0.15})` }, { opacity: 1, transform: "none" }] : [{ opacity: 1, transform: "none" }, { opacity: 0, transform: `perspective(1000px) scale(${t === "out" ? 0.15 : 2.2})` }];
737
+ return t ? [{ opacity: 0, transform: `perspective(1000px) scale(${e === "out" ? 2.2 : 0.15})` }, { opacity: 1, transform: "none" }] : [{ opacity: 1, transform: "none" }, { opacity: 0, transform: `perspective(1000px) scale(${e === "out" ? 0.15 : 2.2})` }];
276
738
  case "warp": {
277
- const s = t === "out";
278
- return e ? [{ opacity: 0, transform: s ? "skewX(-18deg) scale(1.35)" : "skewX(18deg) scale(0.65)" }, { opacity: 1, transform: "none" }] : [{ opacity: 1, transform: "none" }, { opacity: 0, transform: s ? "skewX(18deg) scale(0.65)" : "skewX(-18deg) scale(1.35)" }];
739
+ const i = e === "out";
740
+ return t ? [{ opacity: 0, transform: i ? "skewX(-18deg) scale(1.35)" : "skewX(18deg) scale(0.65)" }, { opacity: 1, transform: "none" }] : [{ opacity: 1, transform: "none" }, { opacity: 0, transform: i ? "skewX(18deg) scale(0.65)" : "skewX(-18deg) scale(1.35)" }];
279
741
  }
280
742
  case "blinds":
281
743
  case "checker":
282
744
  case "randomBar": {
283
- const s = d(t, !0);
284
- return e ? [{ opacity: 0.2, clipPath: s }, { opacity: 1, clipPath: d(t, !1) }] : [{ opacity: 1 }, { opacity: 0 }];
745
+ const i = $(e, !0);
746
+ return t ? [{ opacity: 0.2, clipPath: i }, { opacity: 1, clipPath: $(e, !1) }] : [{ opacity: 1 }, { opacity: 0 }];
285
747
  }
286
748
  case "comb":
287
- return e ? [{ opacity: 0, transform: t === "vert" ? "translateY(-100%)" : "translateX(-100%)" }, { opacity: 1, transform: "translate(0,0)" }] : [{ opacity: 1 }, { opacity: 0 }];
749
+ return t ? [{ opacity: 0, transform: e === "vert" ? "translateY(-100%)" : "translateX(-100%)" }, { opacity: 1, transform: "translate(0,0)" }] : [{ opacity: 1 }, { opacity: 0 }];
288
750
  case "strips": {
289
- const s = {
751
+ const i = {
290
752
  lu: "0% 0%",
291
753
  ld: "0% 100%",
292
754
  ru: "100% 0%",
293
755
  rd: "100% 100%"
294
- }, r = s[t] ?? s.rd;
295
- return e ? [{ opacity: 0, clipPath: `circle(0% at ${r})` }, { opacity: 1, clipPath: `circle(145% at ${r})` }] : [{ opacity: 1 }, { opacity: 0 }];
756
+ }, o = i[e] ?? i.rd;
757
+ return t ? [{ opacity: 0, clipPath: `circle(0% at ${o})` }, { opacity: 1, clipPath: `circle(145% at ${o})` }] : [{ opacity: 1 }, { opacity: 0 }];
296
758
  }
297
759
  case "newsflash":
298
760
  case "dissolve":
299
761
  case "fade":
300
762
  case "morph":
301
763
  default:
302
- return e ? [{ opacity: 0 }, { opacity: 1 }] : [{ opacity: 1 }, { opacity: 0 }];
764
+ return t ? [{ opacity: 0 }, { opacity: 1 }] : [{ opacity: 1 }, { opacity: 0 }];
303
765
  }
304
766
  }
305
- function H(i, e) {
306
- const t = Promise.all(i.map((n) => n.catch(() => {
767
+ function At(n, t) {
768
+ const e = Promise.all(n.map((r) => r.catch(() => {
307
769
  }))).then(() => {
308
770
  });
309
- return typeof setTimeout != "function" ? t : Promise.race([t, new Promise((n) => setTimeout(n, e + 250))]);
771
+ return typeof setTimeout != "function" ? e : Promise.race([e, new Promise((r) => setTimeout(r, t + 250))]);
310
772
  }
311
- function O(i, e) {
312
- const t = /* @__PURE__ */ new Map();
313
- i.querySelectorAll("[data-el]").forEach((o) => {
314
- const s = o.getBoundingClientRect();
315
- (s.width > 0 || s.height > 0) && t.set(o.getAttribute("data-el") ?? "", s);
773
+ function Pt(n, t) {
774
+ const e = /* @__PURE__ */ new Map();
775
+ n.querySelectorAll("[data-el]").forEach((s) => {
776
+ const i = s.getBoundingClientRect();
777
+ (i.width > 0 || i.height > 0) && e.set(s.getAttribute("data-el") ?? "", i);
316
778
  });
317
- const n = [];
318
- return e.querySelectorAll("[data-el]").forEach((o) => {
319
- const s = t.get(o.getAttribute("data-el") ?? "");
320
- if (!s) return;
321
- const r = o.getBoundingClientRect();
322
- r.width <= 0 && r.height <= 0 || n.push({ node: o, from: s, to: r });
323
- }), n;
324
- }
325
- function v(i, e, t) {
326
- let n = !1;
327
- const o = () => {
328
- if (!n) {
329
- n = !0;
330
- for (const r of i)
779
+ const r = [];
780
+ return t.querySelectorAll("[data-el]").forEach((s) => {
781
+ const i = e.get(s.getAttribute("data-el") ?? "");
782
+ if (!i) return;
783
+ const o = s.getBoundingClientRect();
784
+ o.width <= 0 && o.height <= 0 || r.push({ node: s, from: i, to: o });
785
+ }), r;
786
+ }
787
+ function E(n, t, e) {
788
+ let r = !1;
789
+ const s = () => {
790
+ if (!r) {
791
+ r = !0;
792
+ for (const o of n)
331
793
  try {
332
- r.cancel();
794
+ o.cancel();
333
795
  } catch {
334
796
  }
335
- e == null || e.remove();
797
+ t == null || t.remove();
336
798
  }
337
- }, s = H(i.map((r) => r.finished), t).then(o);
338
- return { animations: i, finished: s, cancel: o };
799
+ }, i = At(n.map((o) => o.finished), e).then(s);
800
+ return { animations: n, finished: i, cancel: s };
339
801
  }
340
- function j(i, e, t) {
341
- if (!i) return v([], null, t.durationMs);
342
- const n = { duration: t.durationMs, easing: "ease-in-out", fill: "both" }, o = O(i, e), s = new Set(o.map((a) => a.node.getAttribute("data-el"))), r = [], c = (a, l) => {
802
+ function St(n, t, e) {
803
+ if (!n) return E([], null, e.durationMs);
804
+ const r = { duration: e.durationMs, easing: "ease-in-out", fill: "both" }, s = Pt(n, t), i = new Set(s.map((l) => l.node.getAttribute("data-el"))), o = [], c = (l, h) => {
343
805
  try {
344
- r.push(a.animate(l, n));
806
+ o.push(l.animate(h, r));
345
807
  } catch {
346
808
  }
347
809
  };
348
- for (const { node: a, from: l, to: h } of o) {
349
- const b = l.left - h.left, g = l.top - h.top, f = h.width > 0 ? l.width / h.width : 1, x = h.height > 0 ? l.height / h.height : 1;
350
- c(a, [
351
- { transformOrigin: "left top", transform: `translate(${b}px, ${g}px) scale(${f}, ${x})` },
810
+ for (const { node: l, from: h, to: u } of s) {
811
+ const a = h.left - u.left, f = h.top - u.top, m = u.width > 0 ? h.width / u.width : 1, v = u.height > 0 ? h.height / u.height : 1;
812
+ c(l, [
813
+ { transformOrigin: "left top", transform: `translate(${a}px, ${f}px) scale(${m}, ${v})` },
352
814
  { transformOrigin: "left top", transform: "none" }
353
815
  ]);
354
816
  }
355
- return i.querySelectorAll("[data-el]").forEach((a) => {
356
- const l = s.has(a.getAttribute("data-el"));
357
- c(a, l ? [{ opacity: 0 }, { opacity: 0 }] : [{ opacity: 1 }, { opacity: 0 }]);
358
- }), e.querySelectorAll("[data-el]").forEach((a) => {
359
- s.has(a.getAttribute("data-el")) || c(a, [{ opacity: 0 }, { opacity: 1 }]);
360
- }), v(r, i, t.durationMs);
361
- }
362
- function B(i, e, t) {
363
- if (!t || t.type === "none")
364
- return i == null || i.remove(), v([], null, 0);
365
- if (t.type === "morph" && i) return j(i, e, t);
366
- const n = { duration: t.durationMs, easing: "ease-in-out", fill: "both" }, o = [];
817
+ return n.querySelectorAll("[data-el]").forEach((l) => {
818
+ const h = i.has(l.getAttribute("data-el"));
819
+ c(l, h ? [{ opacity: 0 }, { opacity: 0 }] : [{ opacity: 1 }, { opacity: 0 }]);
820
+ }), t.querySelectorAll("[data-el]").forEach((l) => {
821
+ i.has(l.getAttribute("data-el")) || c(l, [{ opacity: 0 }, { opacity: 1 }]);
822
+ }), E(o, n, e.durationMs);
823
+ }
824
+ function it(n, t, e) {
825
+ if (!e || e.type === "none")
826
+ return n == null || n.remove(), E([], null, 0);
827
+ if (e.type === "morph" && n) return St(n, t, e);
828
+ const r = { duration: e.durationMs, easing: "ease-in-out", fill: "both" }, s = [];
367
829
  try {
368
- o.push(e.animate(M(t, !0), n)), i && o.push(i.animate(M(t, !1), n));
830
+ s.push(t.animate(J(e, !0), r)), n && s.push(n.animate(J(e, !1), r));
369
831
  } catch {
370
- for (const s of o) {
371
- s.finished.catch(() => {
832
+ for (const i of s) {
833
+ i.finished.catch(() => {
372
834
  });
373
835
  try {
374
- s.cancel();
836
+ i.cancel();
375
837
  } catch {
376
838
  }
377
839
  }
378
- return i == null || i.remove(), v([], null, 0);
840
+ return n == null || n.remove(), E([], null, 0);
379
841
  }
380
- return v(o, i, t.durationMs);
842
+ return E(s, n, e.durationMs);
381
843
  }
382
- function W(i, e, t) {
383
- return B(i, e, t).finished;
844
+ function Rt(n, t, e) {
845
+ return it(n, t, e).finished;
384
846
  }
385
- function Z(i) {
386
- var t;
387
- const e = (t = i.transition) == null ? void 0 : t.advanceAfterMs;
388
- return e !== void 0 && e >= 0 ? e : null;
847
+ function Mt(n) {
848
+ var e;
849
+ const t = (e = n.transition) == null ? void 0 : e.advanceAfterMs;
850
+ return t !== void 0 && t >= 0 ? t : null;
389
851
  }
390
- const R = 2147483647;
391
- class _ {
392
- constructor(e, t = {}) {
393
- this.presentation = e, this.options = t, this.idx = 0, this.zoomValue = 1, this.groups = [], this.cursor = 0, this.listeners = /* @__PURE__ */ new Set(), this.autoTimer = null, this.textCache = /* @__PURE__ */ new Map(), this.idx = this.clamp(t.index ?? 0), this.loadAnimations();
852
+ const Ct = 2147483647;
853
+ class Et {
854
+ constructor(t, e = {}) {
855
+ this.presentation = t, this.options = e, this.idx = 0, this.zoomValue = 1, this.groups = [], this.cursor = 0, this.listeners = /* @__PURE__ */ new Set(), this.autoTimer = null, this.textCache = /* @__PURE__ */ new Map(), this.idx = this.clamp(e.index ?? 0), this.loadAnimations();
394
856
  }
395
857
  // ---------------- 只读状态 ----------------
396
858
  get index() {
@@ -417,6 +879,12 @@ class _ {
417
879
  get hasPendingAnimation() {
418
880
  return this.animate && this.cursor < this.groups.length;
419
881
  }
882
+ /** 光标之前已经结束的步骤。终态样式按这个顺序覆盖。 */
883
+ get completedSteps() {
884
+ const t = [];
885
+ for (let e = 0; e < this.cursor && e < this.groups.length; e++) t.push(...this.groups[e]);
886
+ return t;
887
+ }
420
888
  /**
421
889
  * 当前应当隐藏的元素 id —— UI 据此设置可见性。
422
890
  *
@@ -424,64 +892,83 @@ class _ {
424
892
  * 一起画出来就是几帧叠在一起(见 core 的 staticHidden)。
425
893
  */
426
894
  get hiddenElementIds() {
427
- return this.animate ? Y(this.groups, this.cursor) : k(this.slide);
895
+ return this.animate ? st(this.groups, this.cursor) : tt(this.slide);
428
896
  }
429
897
  /** 本页的自动换片延迟(毫秒),未配置则为 null */
430
898
  get autoAdvanceDelay() {
431
- return this.options.autoAdvance ? Z(this.slide) : null;
899
+ return this.options.autoAdvance ? Mt(this.slide) : null;
432
900
  }
433
901
  // ---------------- 订阅 ----------------
434
- subscribe(e) {
435
- return this.listeners.add(e), () => this.listeners.delete(e);
902
+ subscribe(t) {
903
+ return this.listeners.add(t), () => this.listeners.delete(t);
436
904
  }
437
- emit(e) {
438
- for (const t of this.listeners) t(e);
905
+ emit(t) {
906
+ for (const e of this.listeners) e(t);
439
907
  }
440
908
  // ---------------- 导航 ----------------
441
- clamp(e) {
442
- return Math.max(0, Math.min(this.count - 1, e));
909
+ clamp(t) {
910
+ return Math.max(0, Math.min(this.count - 1, t));
443
911
  }
444
- visible(e) {
445
- var t;
446
- return !this.options.skipHidden || !((t = this.presentation.slides[e]) != null && t.hidden);
912
+ visible(t) {
913
+ var e;
914
+ return !this.options.skipHidden || !((e = this.presentation.slides[t]) != null && e.hidden);
447
915
  }
448
916
  /**
449
917
  * 跳转到指定页。返回是否真的换了页。
450
918
  * 前进时带上目标页的切换效果;回退不播切换,避免观感错乱。
451
919
  */
452
- goTo(e, t = "forward") {
453
- const n = this.clamp(e);
454
- if (n === this.idx) return !1;
455
- const o = this.idx;
456
- return this.idx = n, this.loadAnimations(), this.emit({
920
+ goTo(t, e = "forward") {
921
+ const r = this.clamp(t);
922
+ if (r === this.idx) return !1;
923
+ const s = this.idx;
924
+ return this.idx = r, this.loadAnimations(), this.emit({
457
925
  type: "slide",
458
- index: n,
459
- previous: o,
460
- transition: t === "forward" && this.animate ? this.slide.transition : void 0
926
+ index: r,
927
+ previous: s,
928
+ transition: e === "forward" && this.animate ? this.slide.transition : void 0
461
929
  }), !0;
462
930
  }
463
931
  /** 有待播动画时先播动画,否则翻页 */
464
932
  next() {
465
933
  if (this.playNextAnimation()) return;
466
- let e = this.idx + 1;
467
- for (; e < this.count && !this.visible(e); ) e++;
468
- e < this.count && this.goTo(e);
934
+ let t = this.idx + 1;
935
+ for (; t < this.count && !this.visible(t); ) t++;
936
+ t < this.count && this.goTo(t);
469
937
  }
938
+ /**
939
+ * 放映时先退回一批已经播过的点击;本页还在开头,才去上一张可见页。
940
+ *
941
+ * 上一页要落在终态,否则入场又藏起来,没法继续往回退。
942
+ * 光标必须在发出 slide 之前拨到末批,不然会先画出开头那一帧。
943
+ * 浏览关掉动画时批次表是空的,这里仍是整页回退。
944
+ */
470
945
  prev() {
471
- let e = this.idx - 1;
472
- for (; e >= 0 && !this.visible(e); ) e--;
473
- e >= 0 && this.goTo(e, "backward");
946
+ if (this.animate && this.cursor > 0) {
947
+ this.cursor--, this.emit({
948
+ type: "animation",
949
+ done: this.cursor,
950
+ total: this.groups.length,
951
+ group: null,
952
+ settle: !0
953
+ });
954
+ return;
955
+ }
956
+ let t = this.idx - 1;
957
+ for (; t >= 0 && !this.visible(t); ) t--;
958
+ if (t < 0) return;
959
+ const e = this.idx;
960
+ this.idx = t, this.loadAnimations(), this.animate && (this.cursor = this.groups.length), this.emit({ type: "slide", index: this.idx, previous: e });
474
961
  }
475
- setZoom(e) {
476
- const t = Math.max(0.1, Math.min(8, e));
477
- t !== this.zoomValue && (this.zoomValue = t, this.emit({ type: "zoom", zoom: t }));
962
+ setZoom(t) {
963
+ const e = Math.max(0.1, Math.min(8, t));
964
+ e !== this.zoomValue && (this.zoomValue = e, this.emit({ type: "zoom", zoom: e }));
478
965
  }
479
- setAnimate(e) {
480
- this.options.animate !== e && (this.options = { ...this.options, animate: e }, this.loadAnimations(), this.emit({ type: "animation", done: this.cursor, total: this.groups.length, group: null }));
966
+ setAnimate(t) {
967
+ this.options.animate !== t && (this.options = { ...this.options, animate: t }, this.loadAnimations(), this.emit({ type: "animation", done: this.cursor, total: this.groups.length, group: null }));
481
968
  }
482
969
  // ---------------- 动画 ----------------
483
970
  loadAnimations() {
484
- this.groups = this.animate ? z(this.slide.animations) : [], this.cursor = 0;
971
+ this.groups = this.animate ? ot(this.slide.animations) : [], this.cursor = 0;
485
972
  }
486
973
  /**
487
974
  * 推进一批动画。返回应播放的这一批;没有待播批次时返回 null。
@@ -489,8 +976,8 @@ class _ {
489
976
  */
490
977
  playNextAnimation() {
491
978
  if (!this.hasPendingAnimation) return null;
492
- const e = this.groups[this.cursor];
493
- return this.cursor++, this.emit({ type: "animation", done: this.cursor, total: this.groups.length, group: e }), e;
979
+ const t = this.groups[this.cursor];
980
+ return this.cursor++, this.emit({ type: "animation", done: this.cursor, total: this.groups.length, group: t }), t;
494
981
  }
495
982
  /** 直接跳到本页动画终态 */
496
983
  finishAnimations() {
@@ -500,86 +987,109 @@ class _ {
500
987
  /** 启动自动换片计时;返回取消函数。由 UI 层在每次换页后调用。 */
501
988
  scheduleAutoAdvance() {
502
989
  this.cancelAutoAdvance();
503
- const e = this.autoAdvanceDelay;
504
- if (e === null) return () => {
990
+ const t = this.autoAdvanceDelay;
991
+ if (t === null) return () => {
505
992
  };
506
- let t = e;
507
- const n = () => {
508
- const o = Math.min(t, R);
993
+ let e = t;
994
+ const r = () => {
995
+ const s = Math.min(e, Ct);
509
996
  this.autoTimer = setTimeout(() => {
510
- this.autoTimer = null, t -= o, t > 0 ? n() : this.next();
511
- }, o);
997
+ this.autoTimer = null, e -= s, e > 0 ? r() : this.next();
998
+ }, s);
512
999
  };
513
- return n(), () => this.cancelAutoAdvance();
1000
+ return r(), () => this.cancelAutoAdvance();
514
1001
  }
515
1002
  cancelAutoAdvance() {
516
1003
  this.autoTimer !== null && (clearTimeout(this.autoTimer), this.autoTimer = null);
517
1004
  }
518
1005
  // ---------------- 文本 / 搜索 ----------------
519
- text(e) {
520
- let t = this.textCache.get(e);
521
- return t === void 0 && (t = L(this.presentation.slides[e]), this.textCache.set(e, t)), t;
1006
+ text(t) {
1007
+ let e = this.textCache.get(t);
1008
+ return e === void 0 && (e = at(this.presentation.slides[t]), this.textCache.set(t, e)), e;
522
1009
  }
523
1010
  /** 全文搜索,返回命中的页索引 */
524
- search(e) {
525
- const t = e.trim().toLowerCase();
526
- if (!t) return [];
527
- const n = [];
528
- for (let o = 0; o < this.count; o++)
529
- this.text(o).toLowerCase().includes(t) && n.push(o);
530
- return n;
1011
+ search(t) {
1012
+ const e = t.trim().toLowerCase();
1013
+ if (!e) return [];
1014
+ const r = [];
1015
+ for (let s = 0; s < this.count; s++)
1016
+ this.text(s).toLowerCase().includes(e) && r.push(s);
1017
+ return r;
531
1018
  }
532
1019
  /** 解析绝对或相对内部跳转;相对动作保留到点击时,页序变化后仍指向正确目标。 */
533
- resolveLink(e) {
534
- if (!e.startsWith("slide:")) return null;
535
- const t = e.slice(6), n = t === "next" ? this.idx + 2 : t === "previous" ? this.idx : t === "first" ? 1 : t === "last" ? this.count : Number(t);
536
- return Number.isFinite(n) ? this.clamp(n - 1) : null;
1020
+ resolveLink(t) {
1021
+ if (!t.startsWith("slide:")) return null;
1022
+ const e = t.slice(6), r = e === "next" ? this.idx + 2 : e === "previous" ? this.idx : e === "first" ? 1 : e === "last" ? this.count : Number(e);
1023
+ return Number.isFinite(r) ? this.clamp(r - 1) : null;
537
1024
  }
538
1025
  destroy() {
539
1026
  this.cancelAutoAdvance(), this.listeners.clear(), this.textCache.clear();
540
1027
  }
541
1028
  }
542
- const C = "http://www.w3.org/2000/svg", I = "http://www.w3.org/1999/xhtml";
543
- let y = null;
544
- function J() {
545
- y = null;
546
- }
547
- function K(i) {
548
- if (y !== null) return y;
549
- const e = i.body ?? i.documentElement;
550
- if (!e) return !0;
551
- const t = i.createElementNS(C, "svg");
552
- t.setAttribute("viewBox", "0 0 100 100"), t.setAttribute("width", "200"), t.setAttribute("height", "200"), t.setAttribute("style", "position:absolute;left:-9999px;top:-9999px;pointer-events:none");
553
- const n = i.createElementNS(C, "foreignObject");
554
- n.setAttribute("width", "100"), n.setAttribute("height", "100");
555
- const o = i.createElementNS(I, "div");
556
- o.setAttribute("style", "width:100px;height:100px"), n.appendChild(o), t.appendChild(n), e.appendChild(t);
557
- const s = o.getBoundingClientRect().width;
558
- return t.remove(), y = s === 0 || s > 150, y;
559
- }
560
- class Q {
561
- constructor(e, t, n = {}) {
562
- this.container = e, this.presentation = t, this.svgCache = /* @__PURE__ */ new Map(), this.playing = null, this.cancelAuto = null, this.onChange = null, this.onAnimStep = null, this.onLinkClick = null, this.handleClick = (s) => {
563
- const r = s.target, c = r == null ? void 0 : r.closest("[data-slide]");
1029
+ const Q = "http://www.w3.org/2000/svg", Tt = "http://www.w3.org/1999/xhtml";
1030
+ let C = null;
1031
+ function Nt() {
1032
+ C = null;
1033
+ }
1034
+ function Lt(n) {
1035
+ if (C !== null) return C;
1036
+ const t = n.body ?? n.documentElement;
1037
+ if (!t) return !0;
1038
+ const e = n.createElementNS(Q, "svg");
1039
+ e.setAttribute("viewBox", "0 0 100 100"), e.setAttribute("width", "200"), e.setAttribute("height", "200"), e.setAttribute("style", "position:absolute;left:-9999px;top:-9999px;pointer-events:none");
1040
+ const r = n.createElementNS(Q, "foreignObject");
1041
+ r.setAttribute("width", "100"), r.setAttribute("height", "100");
1042
+ const s = n.createElementNS(Tt, "div");
1043
+ s.setAttribute("style", "width:100px;height:100px"), r.appendChild(s), e.appendChild(r), t.appendChild(e);
1044
+ const i = s.getBoundingClientRect().width;
1045
+ return e.remove(), C = i === 0 || i > 150, C;
1046
+ }
1047
+ const Yt = /* @__PURE__ */ new Set(["offset", "easing", "composite"]);
1048
+ function Xt(n) {
1049
+ if (n.mediaCommand) return null;
1050
+ if (n.kind === "entrance")
1051
+ return n.effect === "grow" && n.rotation ? { transform: String(B(n).to.transform) } : null;
1052
+ if (n.kind === "exit") return null;
1053
+ if (n.kind === "motion") {
1054
+ const e = n.motionPath;
1055
+ if (!(e != null && e.length)) return null;
1056
+ const [r, s] = e[e.length - 1];
1057
+ return { transform: `translate(${r}px, ${s}px)` };
1058
+ }
1059
+ const t = {};
1060
+ for (const [e, r] of Object.entries(B(n).to))
1061
+ Yt.has(e) || r == null || typeof r == "object" || (t[e] = String(r));
1062
+ return Object.keys(t).length ? t : null;
1063
+ }
1064
+ class Dt {
1065
+ constructor(t, e, r = {}) {
1066
+ this.container = t, this.presentation = e, this.svgCache = /* @__PURE__ */ new Map(), this.playing = null, this.playingGroup = null, this.transition = null, this.currentLayer = null, this.cancelAuto = null, this.onChange = null, this.onAnimStep = null, this.onLinkClick = null, this.handleClick = (i) => {
1067
+ var a;
1068
+ const o = i.target, c = (a = o == null ? void 0 : o.closest("[data-media-toggle]")) == null ? void 0 : a.querySelector("audio");
564
1069
  if (c) {
565
- s.preventDefault();
566
- const h = this.state.resolveLink(`slide:${c.getAttribute("data-slide") ?? ""}`);
567
- h !== null && this.goTo(h);
1070
+ i.preventDefault(), c.paused ? Promise.resolve(c.play()).catch((f) => this.reportPlaybackError(f)) : c.pause();
1071
+ return;
1072
+ }
1073
+ const l = o == null ? void 0 : o.closest("[data-slide]");
1074
+ if (l) {
1075
+ i.preventDefault();
1076
+ const f = this.state.resolveLink(`slide:${l.getAttribute("data-slide") ?? ""}`);
1077
+ f !== null && this.goTo(f);
568
1078
  return;
569
1079
  }
570
- const a = r == null ? void 0 : r.closest("a[href]"), l = a == null ? void 0 : a.getAttribute("href");
571
- l && this.onLinkClick && this.onLinkClick(l) === !0 && s.preventDefault();
572
- }, this.handleKeyDown = (s) => {
573
- if (s.key !== "Enter") return;
574
- const r = s.target, c = r == null ? void 0 : r.closest("[data-slide]");
1080
+ const h = o == null ? void 0 : o.closest("a[href]"), u = h == null ? void 0 : h.getAttribute("href");
1081
+ u && this.onLinkClick && this.onLinkClick(u) === !0 && i.preventDefault();
1082
+ }, this.handleKeyDown = (i) => {
1083
+ if (i.key !== "Enter") return;
1084
+ const o = i.target, c = o == null ? void 0 : o.closest("[data-slide]");
575
1085
  if (!c) return;
576
- const a = this.state.resolveLink(`slide:${c.getAttribute("data-slide") ?? ""}`);
577
- a !== null && (s.preventDefault(), this.goTo(a));
578
- }, this.media = n.media ?? "badge";
579
- const o = n.textMode ?? "auto";
580
- this.textMode = o !== "auto" ? o : K(e.ownerDocument) ? "html" : "svg", this.state = new _(t, n), this.unsubscribe = this.state.subscribe((s) => {
581
- var r, c;
582
- s.type === "slide" ? (this.paint(s.transition), (r = this.onChange) == null || r.call(this, s.index)) : s.type === "animation" ? (s.group ? this.play(s.group) : this.applyVisibility(), (c = this.onAnimStep) == null || c.call(this, s.done, s.total)) : s.type === "zoom" && this.applyZoom();
1086
+ const l = this.state.resolveLink(`slide:${c.getAttribute("data-slide") ?? ""}`);
1087
+ l !== null && (i.preventDefault(), this.goTo(l));
1088
+ }, this.media = r.media ?? "badge";
1089
+ const s = r.textMode ?? "auto";
1090
+ this.textMode = s !== "auto" ? s : Lt(t.ownerDocument) ? "html" : "svg", this.state = new Et(e, r), this.unsubscribe = this.state.subscribe((i) => {
1091
+ var o, c;
1092
+ i.type === "slide" ? (this.paint(i.transition), (o = this.onChange) == null || o.call(this, i.index)) : i.type === "animation" ? (i.group ? this.play(i.group) : i.settle ? this.paint() : (this.releasePlayback(!0), this.applyVisibility(), this.applySettled()), i.settle || (c = this.onAnimStep) == null || c.call(this, i.done, i.total)) : i.type === "zoom" && this.applyZoom();
583
1093
  }), this.container.addEventListener("click", this.handleClick), this.container.addEventListener("keydown", this.handleKeyDown), this.paint();
584
1094
  }
585
1095
  // ---------------- 转发给状态机 ----------------
@@ -604,8 +1114,8 @@ class Q {
604
1114
  get hasPendingAnimation() {
605
1115
  return this.state.hasPendingAnimation;
606
1116
  }
607
- goTo(e, t = "forward") {
608
- this.state.goTo(e, t);
1117
+ goTo(t, e = "forward") {
1118
+ this.state.goTo(t, e);
609
1119
  }
610
1120
  next() {
611
1121
  this.state.next();
@@ -613,41 +1123,41 @@ class Q {
613
1123
  prev() {
614
1124
  this.state.prev();
615
1125
  }
616
- setZoom(e) {
617
- this.state.setZoom(e);
1126
+ setZoom(t) {
1127
+ this.state.setZoom(t);
618
1128
  }
619
1129
  finishAnimations() {
620
- this.state.finishAnimations();
1130
+ this.state.finishAnimations(), this.playing && (this.releasePlayback(!0), this.applyVisibility(), this.applySettled());
621
1131
  }
622
- search(e) {
623
- return this.state.search(e);
1132
+ search(t) {
1133
+ return this.state.search(t);
624
1134
  }
625
- text(e) {
626
- return this.state.text(e);
1135
+ text(t) {
1136
+ return this.state.text(t);
627
1137
  }
628
- setAnimate(e) {
629
- this.state.setAnimate(e), this.paint();
1138
+ setAnimate(t) {
1139
+ this.state.setAnimate(t), this.paint();
630
1140
  }
631
1141
  playNextAnimation() {
632
1142
  return this.state.playNextAnimation() !== null;
633
1143
  }
634
1144
  // ---------------- 渲染 ----------------
635
1145
  /** 带缓存的单页 SVG(主视图用) */
636
- slideSvg(e) {
637
- let t = this.svgCache.get(e);
638
- return t === void 0 && (t = S(this.presentation, this.presentation.slides[e], {
1146
+ slideSvg(t) {
1147
+ let e = this.svgCache.get(t);
1148
+ return e === void 0 && (e = G(this.presentation, this.presentation.slides[t], {
639
1149
  media: this.media,
640
1150
  textMode: this.textMode
641
- }), this.svgCache.set(e, t)), t;
1151
+ }), this.svgCache.set(t, e)), e;
642
1152
  }
643
1153
  /** 不走缓存,用于缩略图等需要独立 defs id 的场景 */
644
- renderSlide(e) {
645
- const t = this.presentation.slides[e];
646
- return S(this.presentation, t, {
1154
+ renderSlide(t) {
1155
+ const e = this.presentation.slides[t];
1156
+ return G(this.presentation, e, {
647
1157
  // 缩略图不嵌播放器:既没意义,还会为每个缩略图各建一个媒体元素
648
1158
  textMode: this.textMode,
649
1159
  // 缩略图是静态产物,没有后续的 applyVisibility,隐藏状态只能烘进 SVG
650
- hiddenElements: [...k(t)]
1160
+ hiddenElements: [...tt(e)]
651
1161
  });
652
1162
  }
653
1163
  /**
@@ -658,24 +1168,56 @@ class Q {
658
1168
  * `foreignObject` 路径由浏览器自己重排,重渲只是顺带把缓存换掉。
659
1169
  */
660
1170
  refresh() {
661
- this.svgCache.delete(this.index), this.paint();
662
- }
663
- exportPng(e = 2, t = this.index) {
664
- return X(this.presentation, this.presentation.slides[t], e);
1171
+ ct(), this.svgCache.delete(this.index), this.paint();
1172
+ }
1173
+ exportPng(t = 2, e = this.index) {
1174
+ return lt(this.presentation, this.presentation.slides[e], t);
1175
+ }
1176
+ paint(t) {
1177
+ var l, h, u, a;
1178
+ const e = t ? this.playingGroup : null, r = this.currentLayer;
1179
+ this.releasePlayback(!!e), e && r && this.applySettled(e, r, /* @__PURE__ */ new Set()), (l = this.transition) == null || l.cancel(), this.transition = null, (h = this.cancelAuto) == null || h.call(this);
1180
+ const s = this.container.ownerDocument.createElement("div");
1181
+ s.style.cssText = "position:absolute;inset:0;display:flex;align-items:center;justify-content:center", s.innerHTML = this.slideSvg(this.index);
1182
+ const i = ((u = this.currentLayer) == null ? void 0 : u.parentElement) === this.container ? this.currentLayer : this.container.firstElementChild, o = this.container.ownerDocument.defaultView;
1183
+ if ((!o || o.getComputedStyle(this.container).position === "static") && (this.container.style.position = "relative"), t && i) {
1184
+ this.container.appendChild(s), this.currentLayer = s;
1185
+ const f = it(i, s, t);
1186
+ this.transition = f, f.finished.then(() => {
1187
+ this.transition === f && (this.transition = null, this.startAutoAdvance());
1188
+ });
1189
+ } else
1190
+ this.container.innerHTML = "", this.container.appendChild(s), this.currentLayer = s, this.startAutoAdvance();
1191
+ const c = s.querySelector("svg");
1192
+ c && (c.style.display = "block", c.style.maxWidth = "none"), this.applyZoom(), this.applyVisibility(), this.applySettled(), (a = this.onAnimStep) == null || a.call(this, this.state.animationDone, this.state.animationTotal);
1193
+ }
1194
+ play(t) {
1195
+ this.releasePlayback(!0), this.applySettled(this.state.completedSteps.slice(0, -t.length));
1196
+ const e = this.currentLayer;
1197
+ if (!e) return;
1198
+ const r = $t(e, t);
1199
+ this.playing = r, this.playingGroup = t, this.applyVisibility();
1200
+ const s = () => {
1201
+ this.playing === r && (this.releasePlayback(!1), this.applyVisibility(), this.applySettled());
1202
+ };
1203
+ r.finished.then(s, (i) => {
1204
+ s(), this.reportPlaybackError(i);
1205
+ });
665
1206
  }
666
- paint(e) {
667
- var r, c, a;
668
- (r = this.playing) == null || r.cancel(), this.playing = null, (c = this.cancelAuto) == null || c.call(this);
669
- const t = document.createElement("div");
670
- t.style.cssText = "position:absolute;inset:0;display:flex;align-items:center;justify-content:center", t.innerHTML = this.slideSvg(this.index);
671
- const n = this.container.firstElementChild, o = this.container.ownerDocument.defaultView;
672
- (!o || o.getComputedStyle(this.container).position === "static") && (this.container.style.position = "relative"), e && n ? (this.container.appendChild(t), W(n, t, e).then(() => this.startAutoAdvance())) : (this.container.innerHTML = "", this.container.appendChild(t), this.startAutoAdvance());
673
- const s = t.querySelector("svg");
674
- s && (s.style.display = "block", s.style.maxWidth = "none"), this.applyZoom(), this.applyVisibility(), (a = this.onAnimStep) == null || a.call(this, this.state.animationDone, this.state.animationTotal);
1207
+ reportPlaybackError(t) {
1208
+ const e = this.container.ownerDocument.createEvent("CustomEvent");
1209
+ e.initCustomEvent("web-ppt-playback-error", !1, !1, t), this.container.dispatchEvent(e);
675
1210
  }
676
- play(e) {
677
- var t;
678
- (t = this.playing) == null || t.cancel(), this.playing = q(this.container, e), this.applyVisibility();
1211
+ releasePlayback(t) {
1212
+ const e = this.playing;
1213
+ if (e) {
1214
+ this.playing = null, this.playingGroup = null, t && e.cancel();
1215
+ for (const r of e.animations)
1216
+ try {
1217
+ r.cancel();
1218
+ } catch {
1219
+ }
1220
+ }
679
1221
  }
680
1222
  /**
681
1223
  * 按状态机给出的隐藏集合设置元素可见性。
@@ -683,39 +1225,56 @@ class Q {
683
1225
  * 不播动画时也要跑:静态画面取的是动画终态,退场元素同样得藏起来。
684
1226
  */
685
1227
  applyVisibility() {
686
- const e = this.state.hiddenElementIds;
687
- this.container.querySelectorAll("[data-el]").forEach((t) => {
688
- const n = Number(t.getAttribute("data-el"));
689
- t.style.visibility = e.has(n) ? "hidden" : "";
1228
+ var r, s;
1229
+ const t = this.state.hiddenElementIds, e = new Set((r = this.playingGroup) == null ? void 0 : r.filter((i) => i.kind === "exit").map((i) => i.target));
1230
+ (s = this.currentLayer) == null || s.querySelectorAll("[data-el]").forEach((i) => {
1231
+ const o = Number(i.getAttribute("data-el"));
1232
+ i.style.visibility = t.has(o) && !e.has(o) ? "hidden" : "";
690
1233
  });
691
1234
  }
1235
+ /**
1236
+ * 已播完的强调和路径不会写进隐藏集。重绘清掉 fill 之后,要把终态再铺回去。
1237
+ */
1238
+ applySettled(t = this.state.completedSteps, e = this.currentLayer, r = this.state.hiddenElementIds) {
1239
+ var s;
1240
+ for (const i of t) {
1241
+ const o = Xt(i);
1242
+ if (!o || r.has(i.target)) continue;
1243
+ const l = e == null ? void 0 : e.querySelector(`[data-el="${i.target}"]`);
1244
+ if ((s = l == null ? void 0 : l.style) != null && s.setProperty)
1245
+ for (const [h, u] of Object.entries(o))
1246
+ l.style.setProperty(h.replace(/[A-Z]/g, (a) => `-${a.toLowerCase()}`), u);
1247
+ }
1248
+ }
692
1249
  applyZoom() {
693
- const e = this.container.querySelector("svg");
694
- if (!e) return;
695
- const t = this.state.zoom;
696
- t === 1 ? (e.style.width = "100%", e.style.height = "100%") : (e.style.width = `${this.presentation.width * t}px`, e.style.height = `${this.presentation.height * t}px`);
1250
+ var r;
1251
+ const t = (r = this.currentLayer) == null ? void 0 : r.querySelector("svg");
1252
+ if (!t) return;
1253
+ const e = this.state.zoom;
1254
+ e === 1 ? (t.style.width = "100%", t.style.height = "100%") : (t.style.width = `${this.presentation.width * e}px`, t.style.height = `${this.presentation.height * e}px`);
697
1255
  }
698
1256
  startAutoAdvance() {
699
1257
  this.cancelAuto = this.state.scheduleAutoAdvance();
700
1258
  }
701
1259
  destroy() {
702
- var e, t;
703
- this.container.removeEventListener("click", this.handleClick), this.container.removeEventListener("keydown", this.handleKeyDown), this.unsubscribe(), (e = this.playing) == null || e.cancel(), (t = this.cancelAuto) == null || t.call(this), this.state.destroy(), this.container.innerHTML = "", this.svgCache.clear();
1260
+ var t, e;
1261
+ this.container.removeEventListener("click", this.handleClick), this.container.removeEventListener("keydown", this.handleKeyDown), this.unsubscribe(), this.releasePlayback(!1), (t = this.transition) == null || t.cancel(), this.transition = null, this.currentLayer = null, (e = this.cancelAuto) == null || e.call(this), this.state.destroy(), this.container.innerHTML = "", this.svgCache.clear();
704
1262
  }
705
1263
  }
706
1264
  export {
707
- _ as PresentationState,
708
- Q as Viewer,
709
- Z as autoAdvanceMs,
710
- K as foreignObjectScalesCorrectly,
711
- F as framesFor,
712
- et as groupSteps,
713
- st as hiddenBefore,
714
- O as morphPairs,
715
- q as playGroup,
716
- W as playTransition,
717
- B as playTransitionControlled,
718
- J as resetForeignObjectProbe,
719
- it as staticHidden,
720
- M as transitionFrames
1265
+ Et as PresentationState,
1266
+ Dt as Viewer,
1267
+ Mt as autoAdvanceMs,
1268
+ Lt as foreignObjectScalesCorrectly,
1269
+ B as framesFor,
1270
+ It as groupSteps,
1271
+ Ft as hiddenBefore,
1272
+ Pt as morphPairs,
1273
+ $t as playGroup,
1274
+ Rt as playTransition,
1275
+ it as playTransitionControlled,
1276
+ Nt as resetForeignObjectProbe,
1277
+ Xt as settledDeclaration,
1278
+ _t as staticHidden,
1279
+ J as transitionFrames
721
1280
  };