manim-web 0.10.0 → 0.12.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.
Files changed (69) hide show
  1. package/dist/GLTFLoader-CisHz7tR.js +1381 -0
  2. package/dist/GLTFLoader-DMbWuMln.js +1381 -0
  3. package/dist/OBJLoader-Clh2POv9.js +287 -0
  4. package/dist/OBJLoader-kkTsEhJf.js +287 -0
  5. package/dist/audio/Voiceover.d.ts +95 -0
  6. package/dist/audio/Voiceover.d.ts.map +1 -0
  7. package/dist/audio/VoiceoverScene.d.ts +28 -0
  8. package/dist/audio/VoiceoverScene.d.ts.map +1 -0
  9. package/dist/audio/bookmarks.d.ts +40 -0
  10. package/dist/audio/bookmarks.d.ts.map +1 -0
  11. package/dist/audio/speechSynthesizer.d.ts +95 -0
  12. package/dist/audio/speechSynthesizer.d.ts.map +1 -0
  13. package/dist/core/Mobject.d.ts +31 -0
  14. package/dist/core/Mobject.d.ts.map +1 -1
  15. package/dist/core/Scene.d.ts +9 -0
  16. package/dist/core/Scene.d.ts.map +1 -1
  17. package/dist/export/FrameExporter.d.ts +86 -0
  18. package/dist/export/FrameExporter.d.ts.map +1 -0
  19. package/dist/export/WebCodecsExporter.d.ts +108 -0
  20. package/dist/export/WebCodecsExporter.d.ts.map +1 -0
  21. package/dist/export/index.d.ts +2 -0
  22. package/dist/export/index.d.ts.map +1 -1
  23. package/dist/index.d.ts +12 -1
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +3 -2
  26. package/dist/integrations/react.js +17 -16
  27. package/dist/integrations/vue.js +16 -15
  28. package/dist/integrations/webcomponent.d.ts +65 -0
  29. package/dist/integrations/webcomponent.d.ts.map +1 -0
  30. package/dist/integrations/webcomponent.js +2 -0
  31. package/dist/interaction/MovablePoint.d.ts +127 -0
  32. package/dist/interaction/MovablePoint.d.ts.map +1 -0
  33. package/dist/interaction/Slider.d.ts +125 -0
  34. package/dist/interaction/Slider.d.ts.map +1 -0
  35. package/dist/interaction/index.d.ts +2 -0
  36. package/dist/interaction/index.d.ts.map +1 -1
  37. package/dist/manim-web.browser.js +10073 -20358
  38. package/dist/mobjects/svg/SVGMobject.d.ts +29 -0
  39. package/dist/mobjects/svg/SVGMobject.d.ts.map +1 -1
  40. package/dist/mobjects/svg/index.d.ts +3 -1
  41. package/dist/mobjects/svg/index.d.ts.map +1 -1
  42. package/dist/mobjects/svg/svgFill.d.ts +42 -0
  43. package/dist/mobjects/svg/svgFill.d.ts.map +1 -0
  44. package/dist/mobjects/svg/svgGradients.d.ts +68 -0
  45. package/dist/mobjects/svg/svgGradients.d.ts.map +1 -0
  46. package/dist/mobjects/svg/svgImage.d.ts +9 -0
  47. package/dist/mobjects/svg/svgImage.d.ts.map +1 -0
  48. package/dist/mobjects/svg/svgLoader.d.ts +35 -0
  49. package/dist/mobjects/svg/svgLoader.d.ts.map +1 -0
  50. package/dist/mobjects/svg/svgText.d.ts +15 -0
  51. package/dist/mobjects/svg/svgText.d.ts.map +1 -0
  52. package/dist/mobjects/three-d/ModelMobject.d.ts +122 -0
  53. package/dist/mobjects/three-d/ModelMobject.d.ts.map +1 -0
  54. package/dist/mobjects/video/VideoMobject.d.ts +126 -0
  55. package/dist/mobjects/video/VideoMobject.d.ts.map +1 -0
  56. package/dist/mobjects/video/index.d.ts +2 -0
  57. package/dist/mobjects/video/index.d.ts.map +1 -0
  58. package/dist/mp4-muxer-5DGKGEJk.js +900 -0
  59. package/dist/player/Player.d.ts +4 -0
  60. package/dist/player/Player.d.ts.map +1 -1
  61. package/dist/rendering/blendModes.d.ts +38 -0
  62. package/dist/rendering/blendModes.d.ts.map +1 -0
  63. package/dist/{src-D29Z9zIa.js → src-BQF5-SG7.js} +6853 -6218
  64. package/dist/three.core-1aHSpGwp.js +11626 -0
  65. package/dist/utils/ThemeManager.d.ts +79 -0
  66. package/dist/utils/ThemeManager.d.ts.map +1 -0
  67. package/dist/webcomponent-BS5WnkDO.js +707 -0
  68. package/dist/webm-muxer-BGY-Mgbp.js +857 -0
  69. package/package.json +9 -2
@@ -0,0 +1,707 @@
1
+ //#region src/utils/logger.ts
2
+ var e = {
3
+ debug: 0,
4
+ info: 1,
5
+ warn: 2,
6
+ error: 3
7
+ }, t = typeof process < "u" ? process.env?.LOG_LEVEL : void 0, n = t && Object.prototype.hasOwnProperty.call(e, t) ? t : "info";
8
+ function r(t) {
9
+ return e[t] >= e[n];
10
+ }
11
+ var i = "[REDACTED]", a = [
12
+ /Bearer\s+[A-Za-z0-9\-._~+/]+=*/gi,
13
+ /eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g,
14
+ /AKIA[0-9A-Z]{16}/g,
15
+ /gh[pousr]_[A-Za-z0-9_]{36,}/g,
16
+ /[sp]k_(live|test)_[A-Za-z0-9]{24,}/g,
17
+ /(?:api[_-]?key|api[_-]?secret|access[_-]?token|auth[_-]?token|secret[_-]?key|password)\s*[:=]\s*['"]?[A-Za-z0-9\-._~+/]{8,}['"]?/gi,
18
+ /[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/g
19
+ ], o = /pass(?:word|wd)|secret|token|authorization|api[_-]?key|access[_-]?key|private[_-]?key|credential/i;
20
+ function s(e) {
21
+ let t = e;
22
+ for (let e of a) e.lastIndex = 0, t = t.replace(e, i);
23
+ return t;
24
+ }
25
+ function c(e, t = /* @__PURE__ */ new WeakSet()) {
26
+ if (typeof e == "string") return s(e);
27
+ if (e instanceof Error) return s(e.stack ?? `${e.name}: ${e.message}`);
28
+ if (Array.isArray(e)) {
29
+ if (t.has(e)) return "[Circular]";
30
+ t.add(e);
31
+ try {
32
+ return e.map((e) => c(e, t));
33
+ } finally {
34
+ t.delete(e);
35
+ }
36
+ }
37
+ if (typeof e == "object" && e) {
38
+ if (t.has(e)) return "[Circular]";
39
+ t.add(e);
40
+ try {
41
+ let n = {};
42
+ for (let [r, a] of Object.entries(e)) n[r] = o.test(r) ? i : c(a, t);
43
+ return n;
44
+ } finally {
45
+ t.delete(e);
46
+ }
47
+ }
48
+ return e;
49
+ }
50
+ function l(e) {
51
+ return e.map((e) => c(e));
52
+ }
53
+ var u = /* @__PURE__ */ new Set(), d = !1;
54
+ function f(e) {
55
+ let t = /* @__PURE__ */ new WeakSet();
56
+ try {
57
+ return JSON.stringify(e, (e, n) => {
58
+ if (typeof n == "bigint") return n.toString();
59
+ if (typeof n == "object" && n) {
60
+ if (t.has(n)) return "[Circular]";
61
+ t.add(n);
62
+ }
63
+ return n;
64
+ }) ?? String(e);
65
+ } catch {
66
+ return String(e);
67
+ }
68
+ }
69
+ function p(e) {
70
+ return typeof e == "string" ? e : e instanceof Error ? e.stack ?? `${e.name}: ${e.message}` : typeof e == "object" && e ? f(e) : String(e);
71
+ }
72
+ function m(e) {
73
+ return s(e.map((e) => e instanceof Error ? p(e) : p(c(e))).join(" "));
74
+ }
75
+ function h(e) {
76
+ return u.add(e), () => {
77
+ u.delete(e);
78
+ };
79
+ }
80
+ function g(e, t) {
81
+ if (u.size === 0 || d) return;
82
+ d = !0;
83
+ let n = {
84
+ level: e,
85
+ message: m(t),
86
+ timestamp: Date.now()
87
+ };
88
+ try {
89
+ for (let e of u) try {
90
+ e(n);
91
+ } catch (e) {
92
+ console.error("[manim-web] log listener threw:", m([e]));
93
+ }
94
+ } finally {
95
+ d = !1;
96
+ }
97
+ }
98
+ function _(e, t) {
99
+ r(e) && (console[e]("[manim-web]", ...l(t)), g(e, t));
100
+ }
101
+ var v = {
102
+ debug: (...e) => _("debug", e),
103
+ info: (...e) => _("info", e),
104
+ warn: (...e) => _("warn", e),
105
+ error: (...e) => _("error", e)
106
+ }, y = class {
107
+ _scene;
108
+ _panel;
109
+ _options;
110
+ constructor(e, t = {}) {
111
+ this._scene = e, this._options = {
112
+ position: t.position ?? "top-right",
113
+ theme: t.theme ?? "dark",
114
+ width: t.width ?? 250
115
+ }, this._panel = this._createPanel();
116
+ }
117
+ get panel() {
118
+ return this._panel;
119
+ }
120
+ get scene() {
121
+ return this._scene;
122
+ }
123
+ _createPanel() {
124
+ let e = document.createElement("div");
125
+ e.className = "manimweb-controls", e.style.cssText = `
126
+ position: absolute;
127
+ ${this._getPositionStyles()}
128
+ width: ${this._options.width}px;
129
+ max-height: calc(100% - 24px);
130
+ overflow-y: auto;
131
+ padding: 12px;
132
+ background: ${this._options.theme === "dark" ? "rgba(0, 0, 0, 0.85)" : "rgba(255, 255, 255, 0.95)"};
133
+ color: ${this._options.theme === "dark" ? "#ffffff" : "#000000"};
134
+ border-radius: 8px;
135
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
136
+ font-size: 14px;
137
+ line-height: 1.4;
138
+ z-index: 1000;
139
+ box-sizing: border-box;
140
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
141
+ user-select: none;
142
+ -webkit-user-select: none;
143
+ `;
144
+ let t = this._scene.getContainer();
145
+ return t.style.position = "relative", t.appendChild(e), e;
146
+ }
147
+ _getPositionStyles() {
148
+ let e = "12px";
149
+ switch (this._options.position) {
150
+ case "top-left": return `top: ${e}; left: ${e};`;
151
+ case "top-right": return `top: ${e}; right: ${e};`;
152
+ case "bottom-left": return `bottom: ${e}; left: ${e};`;
153
+ case "bottom-right": return `bottom: ${e}; right: ${e};`;
154
+ default: return `top: ${e}; right: ${e};`;
155
+ }
156
+ }
157
+ _getAccentColor() {
158
+ return this._options.theme === "dark" ? "#4a90d9" : "#3b7fc4";
159
+ }
160
+ _getHoverColor() {
161
+ return this._options.theme === "dark" ? "#5a9fe9" : "#4b8fd4";
162
+ }
163
+ _getBorderColor() {
164
+ return this._options.theme === "dark" ? "rgba(255, 255, 255, 0.2)" : "rgba(0, 0, 0, 0.2)";
165
+ }
166
+ addSlider(e) {
167
+ let t = document.createElement("div");
168
+ t.style.cssText = "margin-bottom: 12px;";
169
+ let n = document.createElement("label");
170
+ n.style.cssText = "\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 6px;\n cursor: default;\n ";
171
+ let r = document.createElement("span");
172
+ r.textContent = e.label, r.style.cssText = "font-weight: 500;";
173
+ let i = e.value ?? e.min, a = document.createElement("span");
174
+ a.textContent = this._formatNumber(i), a.style.cssText = "\n font-family: 'SF Mono', Monaco, Consolas, monospace;\n font-size: 12px;\n opacity: 0.8;\n ", n.appendChild(r), n.appendChild(a);
175
+ let o = document.createElement("input");
176
+ return o.type = "range", o.min = String(e.min), o.max = String(e.max), o.step = String(e.step ?? (e.max - e.min) / 100), o.value = String(i), o.style.cssText = `
177
+ width: 100%;
178
+ height: 6px;
179
+ appearance: none;
180
+ -webkit-appearance: none;
181
+ background: ${this._getBorderColor()};
182
+ border-radius: 3px;
183
+ outline: none;
184
+ cursor: pointer;
185
+ `, this._styleSliderThumb(o), o.addEventListener("input", () => {
186
+ let t = parseFloat(o.value);
187
+ a.textContent = this._formatNumber(t), e.onChange(t);
188
+ }), t.appendChild(n), t.appendChild(o), this._panel.appendChild(t), t;
189
+ }
190
+ _styleSliderThumb(e) {
191
+ let t = this._getAccentColor(), n = "manimweb-slider-styles";
192
+ if (!document.getElementById(n)) {
193
+ let e = document.createElement("style");
194
+ e.id = n, e.textContent = `
195
+ .manimweb-controls input[type="range"]::-webkit-slider-thumb {
196
+ appearance: none;
197
+ -webkit-appearance: none;
198
+ width: 18px;
199
+ height: 18px;
200
+ background: ${t};
201
+ border-radius: 50%;
202
+ cursor: pointer;
203
+ border: 2px solid white;
204
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
205
+ }
206
+ .manimweb-controls input[type="range"]::-moz-range-thumb {
207
+ width: 18px;
208
+ height: 18px;
209
+ background: ${t};
210
+ border-radius: 50%;
211
+ cursor: pointer;
212
+ border: 2px solid white;
213
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
214
+ }
215
+ .manimweb-controls input[type="range"]:focus::-webkit-slider-thumb {
216
+ box-shadow: 0 0 0 3px rgba(74, 144, 217, 0.3);
217
+ }
218
+ `, document.head.appendChild(e);
219
+ }
220
+ }
221
+ _formatNumber(e) {
222
+ return Number.isInteger(e) ? String(e) : e.toFixed(2);
223
+ }
224
+ addButton(e) {
225
+ let t = document.createElement("button");
226
+ t.textContent = e.label;
227
+ let n = this._getAccentColor(), r = this._getHoverColor();
228
+ return t.style.cssText = `
229
+ width: 100%;
230
+ padding: 10px 16px;
231
+ margin-bottom: 8px;
232
+ border: none;
233
+ border-radius: 6px;
234
+ background: ${n};
235
+ color: white;
236
+ cursor: pointer;
237
+ font-size: 14px;
238
+ font-weight: 500;
239
+ font-family: inherit;
240
+ transition: background-color 0.15s ease, transform 0.1s ease;
241
+ outline: none;
242
+ touch-action: manipulation;
243
+ `, t.addEventListener("mouseenter", () => {
244
+ t.style.background = r;
245
+ }), t.addEventListener("mouseleave", () => {
246
+ t.style.background = n;
247
+ }), t.addEventListener("mousedown", () => {
248
+ t.style.transform = "scale(0.98)";
249
+ }), t.addEventListener("mouseup", () => {
250
+ t.style.transform = "scale(1)";
251
+ }), t.addEventListener("click", e.onClick), this._panel.appendChild(t), t;
252
+ }
253
+ addCheckbox(e) {
254
+ let t = document.createElement("label");
255
+ t.style.cssText = "\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 10px;\n cursor: pointer;\n padding: 4px 0;\n ";
256
+ let n = document.createElement("div");
257
+ n.style.cssText = "\n position: relative;\n width: 20px;\n height: 20px;\n flex-shrink: 0;\n ";
258
+ let r = document.createElement("input");
259
+ r.type = "checkbox", r.checked = e.checked ?? !1, r.style.cssText = "\n position: absolute;\n opacity: 0;\n width: 100%;\n height: 100%;\n margin: 0;\n cursor: pointer;\n ";
260
+ let i = document.createElement("div"), a = this._getAccentColor(), o = () => {
261
+ i.style.cssText = `
262
+ position: absolute;
263
+ top: 0;
264
+ left: 0;
265
+ width: 100%;
266
+ height: 100%;
267
+ border-radius: 4px;
268
+ border: 2px solid ${r.checked ? a : this._getBorderColor()};
269
+ background: ${r.checked ? a : "transparent"};
270
+ transition: all 0.15s ease;
271
+ pointer-events: none;
272
+ display: flex;
273
+ align-items: center;
274
+ justify-content: center;
275
+ `, i.innerHTML = r.checked ? "<svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\"><path d=\"M2 6L5 9L10 3\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>" : "";
276
+ };
277
+ o(), r.addEventListener("change", () => {
278
+ o(), e.onChange(r.checked);
279
+ }), n.appendChild(r), n.appendChild(i);
280
+ let s = document.createElement("span");
281
+ return s.textContent = e.label, s.style.cssText = "font-weight: 500;", t.appendChild(n), t.appendChild(s), this._panel.appendChild(t), t;
282
+ }
283
+ addColorPicker(e) {
284
+ let t = document.createElement("div");
285
+ t.style.cssText = "margin-bottom: 12px;";
286
+ let n = document.createElement("div");
287
+ n.style.cssText = "\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 6px;\n ";
288
+ let r = document.createElement("span");
289
+ r.textContent = e.label, r.style.cssText = "font-weight: 500;";
290
+ let i = e.value ?? "#ffffff", a = document.createElement("span");
291
+ a.textContent = i.toUpperCase(), a.style.cssText = "\n font-family: 'SF Mono', Monaco, Consolas, monospace;\n font-size: 12px;\n opacity: 0.8;\n ", n.appendChild(r), n.appendChild(a);
292
+ let o = document.createElement("div");
293
+ o.style.cssText = "\n display: flex;\n align-items: center;\n gap: 8px;\n ";
294
+ let s = document.createElement("input");
295
+ s.type = "color", s.value = i, s.style.cssText = `
296
+ width: 40px;
297
+ height: 32px;
298
+ padding: 0;
299
+ border: 2px solid ${this._getBorderColor()};
300
+ border-radius: 6px;
301
+ cursor: pointer;
302
+ background: transparent;
303
+ `;
304
+ let c = document.createElement("input");
305
+ return c.type = "text", c.value = i, c.style.cssText = `
306
+ flex: 1;
307
+ padding: 6px 10px;
308
+ border: 2px solid ${this._getBorderColor()};
309
+ border-radius: 6px;
310
+ background: transparent;
311
+ color: inherit;
312
+ font-family: 'SF Mono', Monaco, Consolas, monospace;
313
+ font-size: 13px;
314
+ outline: none;
315
+ `, c.addEventListener("focus", () => {
316
+ c.style.borderColor = this._getAccentColor();
317
+ }), c.addEventListener("blur", () => {
318
+ c.style.borderColor = this._getBorderColor();
319
+ }), s.addEventListener("input", () => {
320
+ let t = s.value;
321
+ c.value = t, a.textContent = t.toUpperCase(), e.onChange(t);
322
+ }), c.addEventListener("input", () => {
323
+ let t = c.value;
324
+ /^#[0-9A-Fa-f]{6}$/.test(t) && (s.value = t, a.textContent = t.toUpperCase(), e.onChange(t));
325
+ }), o.appendChild(s), o.appendChild(c), t.appendChild(n), t.appendChild(o), this._panel.appendChild(t), t;
326
+ }
327
+ addSeparator() {
328
+ let e = document.createElement("hr");
329
+ e.style.cssText = `
330
+ border: none;
331
+ border-top: 1px solid ${this._getBorderColor()};
332
+ margin: 14px 0;
333
+ `, this._panel.appendChild(e);
334
+ }
335
+ addLabel(e) {
336
+ let t = document.createElement("div");
337
+ return t.textContent = e, t.style.cssText = "\n font-weight: 600;\n font-size: 13px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n opacity: 0.7;\n margin-bottom: 10px;\n margin-top: 4px;\n ", this._panel.appendChild(t), t;
338
+ }
339
+ show() {
340
+ this._panel.style.display = "block";
341
+ }
342
+ hide() {
343
+ this._panel.style.display = "none";
344
+ }
345
+ toggle() {
346
+ this._panel.style.display === "none" ? this.show() : this.hide();
347
+ }
348
+ isVisible() {
349
+ return this._panel.style.display !== "none";
350
+ }
351
+ dispose() {
352
+ this._panel.remove();
353
+ }
354
+ }, b = class extends y {
355
+ _timeline = null;
356
+ _playPauseBtn = null;
357
+ _speedSelect = null;
358
+ _timeDisplay = null;
359
+ _durationDisplay = null;
360
+ _isPlaying = !1;
361
+ _playbackRate = 1;
362
+ _updateInterval = null;
363
+ _onTimeUpdate = null;
364
+ constructor(e, t = {}) {
365
+ super(e, t), this._createPlaybackUI(t), this._startUpdateLoop();
366
+ }
367
+ onTimeUpdate(e) {
368
+ this._onTimeUpdate = e;
369
+ }
370
+ get playbackRate() {
371
+ return this._playbackRate;
372
+ }
373
+ set playbackRate(e) {
374
+ this._playbackRate = e, this._speedSelect && (this._speedSelect.value = String(e));
375
+ }
376
+ _createPlaybackUI(e) {
377
+ this.addLabel("Playback"), e.showPlayPause !== !1 && (this._playPauseBtn = this._createPlayPauseButton()), e.showTimeline !== !1 && (this._timeline = this._createTimelineScrubber()), e.showSpeed !== !1 && (this._speedSelect = this._createSpeedControl());
378
+ }
379
+ _createPlayPauseButton() {
380
+ let e = document.createElement("div");
381
+ e.style.cssText = "\n display: flex;\n gap: 8px;\n margin-bottom: 12px;\n ";
382
+ let t = document.createElement("button");
383
+ t.innerHTML = this._getPlayIcon();
384
+ let n = this._getAccentColor(), r = this._getHoverColor();
385
+ t.style.cssText = `
386
+ flex: 1;
387
+ display: flex;
388
+ align-items: center;
389
+ justify-content: center;
390
+ gap: 8px;
391
+ padding: 10px 16px;
392
+ border: none;
393
+ border-radius: 6px;
394
+ background: ${n};
395
+ color: white;
396
+ cursor: pointer;
397
+ font-size: 14px;
398
+ font-weight: 500;
399
+ font-family: inherit;
400
+ transition: background-color 0.15s ease;
401
+ outline: none;
402
+ touch-action: manipulation;
403
+ `, t.addEventListener("mouseenter", () => {
404
+ t.style.background = r;
405
+ }), t.addEventListener("mouseleave", () => {
406
+ t.style.background = n;
407
+ }), t.addEventListener("click", () => {
408
+ this._togglePlayPause();
409
+ });
410
+ let i = document.createElement("button");
411
+ return i.innerHTML = this._getStopIcon(), i.style.cssText = `
412
+ padding: 10px 14px;
413
+ border: 2px solid ${this._getBorderColor()};
414
+ border-radius: 6px;
415
+ background: transparent;
416
+ color: inherit;
417
+ cursor: pointer;
418
+ transition: border-color 0.15s ease;
419
+ outline: none;
420
+ touch-action: manipulation;
421
+ `, i.addEventListener("mouseenter", () => {
422
+ i.style.borderColor = n;
423
+ }), i.addEventListener("mouseleave", () => {
424
+ i.style.borderColor = this._getBorderColor();
425
+ }), i.addEventListener("click", () => {
426
+ this._scene.stop(), this._isPlaying = !1, this._updatePlayPauseButton();
427
+ }), e.appendChild(t), e.appendChild(i), this._panel.appendChild(e), t;
428
+ }
429
+ _togglePlayPause() {
430
+ this._isPlaying ? (this._scene.pause(), this._isPlaying = !1) : (this._scene.resume(), this._isPlaying = !0), this._updatePlayPauseButton();
431
+ }
432
+ _updatePlayPauseButton() {
433
+ this._playPauseBtn && (this._playPauseBtn.innerHTML = this._isPlaying ? this._getPauseIcon() : this._getPlayIcon());
434
+ }
435
+ _createTimelineScrubber() {
436
+ let e = document.createElement("div");
437
+ e.style.cssText = "margin-bottom: 12px;";
438
+ let t = document.createElement("div");
439
+ t.style.cssText = "\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 6px;\n font-family: 'SF Mono', Monaco, Consolas, monospace;\n font-size: 12px;\n ", this._timeDisplay = document.createElement("span"), this._timeDisplay.textContent = "0:00.00", this._timeDisplay.style.opacity = "0.8";
440
+ let n = document.createElement("span");
441
+ n.textContent = "0:00.00", n.style.opacity = "0.6", n.id = "manimweb-duration-display", t.appendChild(this._timeDisplay), t.appendChild(n);
442
+ let r = document.createElement("input");
443
+ return r.type = "range", r.min = "0", r.max = "100", r.step = "0.1", r.value = "0", r.style.cssText = `
444
+ width: 100%;
445
+ height: 8px;
446
+ appearance: none;
447
+ -webkit-appearance: none;
448
+ background: ${this._getBorderColor()};
449
+ border-radius: 4px;
450
+ outline: none;
451
+ cursor: pointer;
452
+ `, r.addEventListener("input", () => {
453
+ let e = this._scene.timeline;
454
+ if (e) {
455
+ let t = e.getDuration(), n = parseFloat(r.value) / 100 * t;
456
+ this._scene.seek(n), this._updateTimeDisplay(n, t);
457
+ }
458
+ }), this._durationDisplay = n, e.appendChild(t), e.appendChild(r), this._panel.appendChild(e), r;
459
+ }
460
+ _createSpeedControl() {
461
+ let e = document.createElement("div");
462
+ e.style.cssText = "\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 8px;\n ";
463
+ let t = document.createElement("span");
464
+ t.textContent = "Speed", t.style.cssText = "font-weight: 500;";
465
+ let n = document.createElement("select");
466
+ n.style.cssText = `
467
+ flex: 1;
468
+ padding: 8px 12px;
469
+ border: 2px solid ${this._getBorderColor()};
470
+ border-radius: 6px;
471
+ background: transparent;
472
+ color: inherit;
473
+ font-size: 14px;
474
+ font-family: inherit;
475
+ cursor: pointer;
476
+ outline: none;
477
+ appearance: none;
478
+ -webkit-appearance: none;
479
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23888' d='M3 4l3 4 3-4H3z'/%3E%3C/svg%3E");
480
+ background-repeat: no-repeat;
481
+ background-position: right 10px center;
482
+ padding-right: 30px;
483
+ `;
484
+ for (let e of [
485
+ {
486
+ value: .25,
487
+ label: "0.25x"
488
+ },
489
+ {
490
+ value: .5,
491
+ label: "0.5x"
492
+ },
493
+ {
494
+ value: .75,
495
+ label: "0.75x"
496
+ },
497
+ {
498
+ value: 1,
499
+ label: "1x"
500
+ },
501
+ {
502
+ value: 1.25,
503
+ label: "1.25x"
504
+ },
505
+ {
506
+ value: 1.5,
507
+ label: "1.5x"
508
+ },
509
+ {
510
+ value: 2,
511
+ label: "2x"
512
+ }
513
+ ]) {
514
+ let t = document.createElement("option");
515
+ t.value = String(e.value), t.textContent = e.label, e.value === 1 && (t.selected = !0), n.appendChild(t);
516
+ }
517
+ return n.addEventListener("change", () => {
518
+ this._playbackRate = parseFloat(n.value);
519
+ }), n.addEventListener("focus", () => {
520
+ n.style.borderColor = this._getAccentColor();
521
+ }), n.addEventListener("blur", () => {
522
+ n.style.borderColor = this._getBorderColor();
523
+ }), e.appendChild(t), e.appendChild(n), this._panel.appendChild(e), n;
524
+ }
525
+ updateTime(e, t) {
526
+ this._updateTimeDisplay(e, t), this._updateTimelineSlider(e, t), this._onTimeUpdate && this._onTimeUpdate(e, t);
527
+ }
528
+ _updateTimeDisplay(e, t) {
529
+ this._timeDisplay && (this._timeDisplay.textContent = this._formatTime(e)), this._timeline && this._durationDisplay && (this._durationDisplay.textContent = this._formatTime(t));
530
+ }
531
+ _updateTimelineSlider(e, t) {
532
+ if (this._timeline && t > 0) {
533
+ let n = e / t * 100;
534
+ this._timeline.value = String(n);
535
+ }
536
+ }
537
+ _formatTime(e) {
538
+ return `${Math.floor(e / 60)}:${(e % 60).toFixed(2).padStart(5, "0")}`;
539
+ }
540
+ _startUpdateLoop() {
541
+ let e = () => {
542
+ let t = this._scene.timeline;
543
+ if (t) {
544
+ let e = t.getCurrentTime(), n = t.getDuration();
545
+ this.updateTime(e, n);
546
+ }
547
+ let n = this._isPlaying;
548
+ this._isPlaying = this._scene.isPlaying, n !== this._isPlaying && this._updatePlayPauseButton(), this._updateInterval = requestAnimationFrame(e);
549
+ };
550
+ this._updateInterval = requestAnimationFrame(e);
551
+ }
552
+ _getPlayIcon() {
553
+ return "\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <path d=\"M4 2l10 6-10 6V2z\"/>\n </svg>\n <span>Play</span>\n ";
554
+ }
555
+ _getPauseIcon() {
556
+ return "\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <rect x=\"3\" y=\"2\" width=\"4\" height=\"12\"/>\n <rect x=\"9\" y=\"2\" width=\"4\" height=\"12\"/>\n </svg>\n <span>Pause</span>\n ";
557
+ }
558
+ _getStopIcon() {
559
+ return "\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <rect x=\"3\" y=\"3\" width=\"10\" height=\"10\"/>\n </svg>\n ";
560
+ }
561
+ dispose() {
562
+ this._updateInterval !== null && (cancelAnimationFrame(this._updateInterval), this._updateInterval = null), super.dispose();
563
+ }
564
+ }, x = 800, S = 450, C = { importModule: (e) => import(
565
+ /* @vite-ignore */
566
+ e
567
+ ) };
568
+ function w(e) {
569
+ return typeof e.togglePlayPause == "function";
570
+ }
571
+ function T(e) {
572
+ try {
573
+ e.dispose();
574
+ } catch (e) {
575
+ v.error("<manim-scene> failed to dispose instance:", e);
576
+ }
577
+ }
578
+ function E(e, t) {
579
+ let n = e?.trim();
580
+ return n ? /^\d+(\.\d+)?$/.test(n) ? `${n}px` : n : `${t}px`;
581
+ }
582
+ function D(e) {
583
+ let t = e?.trim();
584
+ return !t || !/^\d+(\.\d+)?$/.test(t) ? null : Number(t);
585
+ }
586
+ var O = typeof HTMLElement < "u" ? HTMLElement : class {}, k = class extends O {
587
+ static get observedAttributes() {
588
+ return [
589
+ "width",
590
+ "height",
591
+ "background",
592
+ "src",
593
+ "autoplay",
594
+ "controls",
595
+ "loop"
596
+ ];
597
+ }
598
+ _container = null;
599
+ _instance = null;
600
+ _controls = null;
601
+ _sceneFactory = null;
602
+ _connected = !1;
603
+ _loadToken = 0;
604
+ _mountPromise = Promise.resolve();
605
+ get scene() {
606
+ return this._sceneFactory;
607
+ }
608
+ set scene(e) {
609
+ this._sceneFactory = e, this._connected && this._mount();
610
+ }
611
+ async whenReady() {
612
+ await new Promise((e) => setTimeout(e, 0)), await this._mountPromise;
613
+ }
614
+ connectedCallback() {
615
+ this._connected = !0, this._ensureContainer(), this._mount();
616
+ }
617
+ disconnectedCallback() {
618
+ this._connected = !1, this._loadToken++, this._teardownInstance();
619
+ }
620
+ attributeChangedCallback(e, t, n) {
621
+ !this._connected || t === n || (e === "width" || e === "height" || e === "background" ? (this._applyContainerStyle(), this._resizeInstance()) : e === "src" ? this._mount() : this._applyPlaybackOptions());
622
+ }
623
+ _ensureContainer() {
624
+ if (!this._container) {
625
+ let e = document.createElement("div");
626
+ this._container = e, this.appendChild(e);
627
+ }
628
+ return this._applyContainerStyle(), this._container;
629
+ }
630
+ _applyContainerStyle() {
631
+ let e = this._container;
632
+ e && (e.style.width = E(this.getAttribute("width"), x), e.style.height = E(this.getAttribute("height"), S), e.style.position = "relative", e.style.overflow = "hidden", e.style.background = this.getAttribute("background") ?? "");
633
+ }
634
+ _mount() {
635
+ return this._mountPromise = this._doMount(), this._mountPromise;
636
+ }
637
+ async _doMount() {
638
+ this._teardownInstance();
639
+ let e = ++this._loadToken, t = this._ensureContainer();
640
+ this._clearContainerChildren();
641
+ let n = await this._resolveFactory(e);
642
+ if (n === null || e !== this._loadToken) return;
643
+ let r;
644
+ try {
645
+ r = await n(t);
646
+ } catch (e) {
647
+ v.error("<manim-scene> scene factory threw:", e);
648
+ return;
649
+ }
650
+ if (e !== this._loadToken) {
651
+ T(r);
652
+ return;
653
+ }
654
+ this._instance = r, this._applyPlaybackOptions();
655
+ }
656
+ async _resolveFactory(e) {
657
+ if (this._sceneFactory) return this._sceneFactory;
658
+ let t = this.getAttribute("src");
659
+ if (!t) return null;
660
+ let n = await C.importModule(t);
661
+ if (e !== this._loadToken) return null;
662
+ let r = n.default;
663
+ return typeof r == "function" ? r : (v.error(`<manim-scene> module "${t}" has no default-export factory function.`), null);
664
+ }
665
+ _applyPlaybackOptions() {
666
+ let e = this._instance;
667
+ if (!e) return;
668
+ let t = w(e);
669
+ t && (e.loop = this.hasAttribute("loop")), t || this._syncSceneControls(e), this.hasAttribute("autoplay") && !e.isPlaying && (t ? e.play() : e.resume());
670
+ }
671
+ _syncSceneControls(e) {
672
+ let t = this.hasAttribute("controls");
673
+ t && !this._controls ? this._controls = new b(e) : !t && this._controls && (this._controls.dispose(), this._controls = null);
674
+ }
675
+ _resizeInstance() {
676
+ let e = this._instance;
677
+ if (!e) return;
678
+ let t = D(this.getAttribute("width")), n = D(this.getAttribute("height"));
679
+ if (t === null || n === null) return;
680
+ let r = w(e) ? e.scene : e;
681
+ try {
682
+ r.resize(t, n);
683
+ } catch (e) {
684
+ v.error("<manim-scene> failed to resize scene:", e);
685
+ }
686
+ }
687
+ _teardownInstance() {
688
+ if (this._controls) {
689
+ try {
690
+ this._controls.dispose();
691
+ } catch (e) {
692
+ v.error("<manim-scene> failed to dispose controls:", e);
693
+ }
694
+ this._controls = null;
695
+ }
696
+ this._instance &&= (T(this._instance), null);
697
+ }
698
+ _clearContainerChildren() {
699
+ let e = this._container;
700
+ if (e) for (; e.firstChild;) e.removeChild(e.firstChild);
701
+ }
702
+ };
703
+ function A(e = "manim-scene") {
704
+ typeof customElements > "u" || typeof HTMLElement > "u" || customElements.get(e) || customElements.define(e, k);
705
+ }
706
+ //#endregion
707
+ export { y as a, b as i, C as n, v as o, A as r, h as s, k as t };