textmode.export.js 1.0.0 → 1.1.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.
- package/dist/textmode.export.esm.js +47 -47
- package/dist/textmode.export.umd.js +2 -2
- package/dist/types/exporters/base/DataExtractor.d.ts.map +1 -1
- package/dist/types/exporters/svg/SVGDataExtractor.d.ts +2 -3
- package/dist/types/exporters/svg/SVGDataExtractor.d.ts.map +1 -1
- package/dist/types/exporters/svg/SVGPathGenerator.d.ts +27 -1
- package/dist/types/exporters/svg/SVGPathGenerator.d.ts.map +1 -1
- package/dist/types/exporters/svg/types.d.ts +0 -2
- package/dist/types/exporters/svg/types.d.ts.map +1 -1
- package/package.json +72 -72
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
class At {
|
|
2
2
|
$extractFramebufferData(t) {
|
|
3
|
-
|
|
4
|
-
return { characterPixels: e, primaryColorPixels: r, secondaryColorPixels: a, transformPixels: t.readPixels(4), rotationPixels: i };
|
|
3
|
+
return { characterPixels: t.readPixels(0), primaryColorPixels: t.readPixels(1), secondaryColorPixels: t.readPixels(2) };
|
|
5
4
|
}
|
|
6
5
|
$getCharacterIndex(t, e) {
|
|
7
6
|
return t[e] + (t[e + 1] << 8);
|
|
@@ -29,9 +28,9 @@ function ft(s, t) {
|
|
|
29
28
|
return { r: s[t], g: s[t + 1], b: s[t + 2], a: s[t + 3] };
|
|
30
29
|
}
|
|
31
30
|
class Wt extends At {
|
|
32
|
-
_extractTransformData(t, e
|
|
33
|
-
const
|
|
34
|
-
return { isInverted: a, flipHorizontal: i, flipVertical: n, rotation: Math.round(360 * c
|
|
31
|
+
_extractTransformData(t, e) {
|
|
32
|
+
const r = t[e + 2], a = !!(1 & r), i = !!(2 & r), n = !!(4 & r), c = t[e + 3] / 255;
|
|
33
|
+
return { isInverted: a, flipHorizontal: i, flipVertical: n, rotation: Math.round(360 * c * 100) / 100 };
|
|
35
34
|
}
|
|
36
35
|
_calculateCellPosition(t, e, r) {
|
|
37
36
|
return { x: t, y: e, cellX: t * r.cellWidth, cellY: e * r.cellHeight };
|
|
@@ -42,7 +41,7 @@ class Wt extends At {
|
|
|
42
41
|
for (let i = 0; i < e.rows; i++) for (let n = 0; n < e.cols; n++) {
|
|
43
42
|
const c = 4 * a, l = this.$getCharacterIndex(t.characterPixels, c);
|
|
44
43
|
let p = ft(t.primaryColorPixels, c), o = ft(t.secondaryColorPixels, c);
|
|
45
|
-
const d = this._extractTransformData(t.
|
|
44
|
+
const d = this._extractTransformData(t.characterPixels, c);
|
|
46
45
|
if (d.isInverted) {
|
|
47
46
|
const m = p;
|
|
48
47
|
p = o, o = m;
|
|
@@ -56,7 +55,7 @@ class Wt extends At {
|
|
|
56
55
|
class qt {
|
|
57
56
|
_createGlyphPath(t, e, r, a, i) {
|
|
58
57
|
const n = i / t.head.unitsPerEm;
|
|
59
|
-
return { getBoundingBox: () => ({ x1: r + e.xMin * n, y1: a + -e.yMax * n, x2: r + e.xMax * n, y2: a + -e.yMin * n }), toSVG: () => this._glyphToSVGPath(e, r, a, n) };
|
|
58
|
+
return console.log("Scale factor:", n), { getBoundingBox: () => ({ x1: r + e.xMin * n, y1: a + -e.yMax * n, x2: r + e.xMax * n, y2: a + -e.yMin * n }), toSVG: () => this._glyphToSVGPath(e, r, a, n) };
|
|
60
59
|
}
|
|
61
60
|
_glyphToSVGPath(t, e, r, a) {
|
|
62
61
|
if (!t || !t.xs) return "";
|
|
@@ -93,12 +92,13 @@ class qt {
|
|
|
93
92
|
return p;
|
|
94
93
|
}
|
|
95
94
|
_generateCharacterPath(t, e, r, a, i) {
|
|
96
|
-
const n =
|
|
97
|
-
return
|
|
95
|
+
const n = e.characterMap.get(t).glyphData;
|
|
96
|
+
return console.log("Glyph data for character", t, n), n ? this._createGlyphPath(e.font, n, r, a, i) : null;
|
|
98
97
|
}
|
|
99
98
|
$generatePositionedCharacterPath(t, e, r, a, i, n, c, l) {
|
|
100
|
-
|
|
101
|
-
|
|
99
|
+
if (!l) return null;
|
|
100
|
+
const p = c / e.font.head.unitsPerEm, o = r + (i - l.advanceWidth * p) / 2, d = a + (n + 0.7 * c) / 2, u = this._generateCharacterPath(t, e, o, d, c);
|
|
101
|
+
return u && u.toSVG() || null;
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
104
|
class Ht {
|
|
@@ -131,7 +131,7 @@ class Ht {
|
|
|
131
131
|
_generateCharacterPath(t, e, r, a) {
|
|
132
132
|
const i = r.characters[t.charIndex];
|
|
133
133
|
if (!i) return "";
|
|
134
|
-
const n = this._pathGenerator.$generatePositionedCharacterPath(i.character, r, t.position.cellX, t.position.cellY, e.cellWidth, e.cellHeight, r.fontSize, i.
|
|
134
|
+
const n = this._pathGenerator.$generatePositionedCharacterPath(i.character, r, t.position.cellX, t.position.cellY, e.cellWidth, e.cellHeight, r.fontSize, i.glyphData);
|
|
135
135
|
if (!n) return "";
|
|
136
136
|
const { r: c, g: l, b: p, a: o } = t.primaryColor, d = `rgba(${c},${l},${p},${o / 255})`;
|
|
137
137
|
return a.drawMode === "stroke" ? `<path d="${n}" stroke="${d}" stroke-width="${a.strokeWidth}" fill="none"/>` : `<path d="${n}" fill="${d}"/>`;
|
|
@@ -337,9 +337,9 @@ function te(s, t, e, r, a, i, n, c) {
|
|
|
337
337
|
i.fill(0), c.fill(0), L();
|
|
338
338
|
let o = 0, d = 0, u = p + 1, m = u, x = !1, h = m, f = D(h), _ = 1 << u - 1, v = _ + 1, g = _ + 2, C = 0, S = e[0], E = 0;
|
|
339
339
|
for (let k = l; k < 65536; k *= 2) ++E;
|
|
340
|
-
E = 8 - E, a.writeByte(p),
|
|
340
|
+
E = 8 - E, a.writeByte(p), O(_);
|
|
341
341
|
for (let k = 1; k < e.length; k++) V(e[k]);
|
|
342
|
-
return
|
|
342
|
+
return O(S), O(v), a.writeByte(0), a.bytesView();
|
|
343
343
|
function A(k) {
|
|
344
344
|
i[C++] = k, C >= 254 && B();
|
|
345
345
|
}
|
|
@@ -356,7 +356,7 @@ function te(s, t, e, r, a, i, n, c) {
|
|
|
356
356
|
if (y -= w, y < 0 && (y += l), n[y] === R) return void (S = c[y]);
|
|
357
357
|
while (n[y] >= 0);
|
|
358
358
|
}
|
|
359
|
-
|
|
359
|
+
O(S), S = k, g < 1 << Z ? (c[y] = g++, n[y] = R) : (L(), g = _ + 2, x = !0, O(_));
|
|
360
360
|
}
|
|
361
361
|
}
|
|
362
362
|
function B() {
|
|
@@ -365,7 +365,7 @@ function te(s, t, e, r, a, i, n, c) {
|
|
|
365
365
|
function D(k) {
|
|
366
366
|
return (1 << k) - 1;
|
|
367
367
|
}
|
|
368
|
-
function
|
|
368
|
+
function O(k) {
|
|
369
369
|
for (o &= Zt[d], d > 0 ? o |= k << d : o = k, d += h; d >= 8; ) A(255 & o), o >>= 8, d -= 8;
|
|
370
370
|
if ((g > f || x) && (x ? (h = m, f = D(h), x = !1) : (++h, f = h == Z ? 1 << Z : D(h))), k == v) {
|
|
371
371
|
for (; d > 0; ) A(255 & o), o >>= 8, d -= 8;
|
|
@@ -377,10 +377,10 @@ var ee = te;
|
|
|
377
377
|
function Vt(s, t, e) {
|
|
378
378
|
return s << 8 & 63488 | t << 2 & 992 | e >> 3 & 31;
|
|
379
379
|
}
|
|
380
|
-
function
|
|
380
|
+
function Tt(s, t, e, r) {
|
|
381
381
|
return s >> 4 | 240 & t | (240 & e) << 4 | (240 & r) << 8;
|
|
382
382
|
}
|
|
383
|
-
function
|
|
383
|
+
function Ot(s, t, e) {
|
|
384
384
|
return s >> 4 << 8 | t >> 4 << 4 | e >> 4;
|
|
385
385
|
}
|
|
386
386
|
function tt(s, t, e) {
|
|
@@ -405,11 +405,11 @@ function dt() {
|
|
|
405
405
|
function re(s, t) {
|
|
406
406
|
let e = new Array(t === "rgb444" ? 4096 : 65536), r = s.length;
|
|
407
407
|
if (t === "rgba4444") for (let a = 0; a < r; ++a) {
|
|
408
|
-
let i = s[a], n = i >> 24 & 255, c = i >> 16 & 255, l = i >> 8 & 255, p = 255 & i, o =
|
|
408
|
+
let i = s[a], n = i >> 24 & 255, c = i >> 16 & 255, l = i >> 8 & 255, p = 255 & i, o = Tt(p, l, c, n), d = o in e ? e[o] : e[o] = dt();
|
|
409
409
|
d.rc += p, d.gc += l, d.bc += c, d.ac += n, d.cnt++;
|
|
410
410
|
}
|
|
411
411
|
else if (t === "rgb444") for (let a = 0; a < r; ++a) {
|
|
412
|
-
let i = s[a], n = i >> 16 & 255, c = i >> 8 & 255, l = 255 & i, p =
|
|
412
|
+
let i = s[a], n = i >> 16 & 255, c = i >> 8 & 255, l = 255 & i, p = Ot(l, c, n), o = p in e ? e[p] : e[p] = dt();
|
|
413
413
|
o.rc += l, o.gc += c, o.bc += n, o.cnt++;
|
|
414
414
|
}
|
|
415
415
|
else for (let a = 0; a < r; ++a) {
|
|
@@ -447,8 +447,8 @@ function ae(s, t, e) {
|
|
|
447
447
|
f = 1 / (V + B), p && (E.ac = f * (V * E.ac + B * L.ac)), E.rc = f * (V * E.rc + B * L.rc), E.gc = f * (V * E.gc + B * L.gc), E.bc = f * (V * E.bc + B * L.bc), E.cnt += L.cnt, E.mtm = ++h, o[L.bk].fw = L.fw, o[L.fw].bk = L.bk, L.mtm = u;
|
|
448
448
|
}
|
|
449
449
|
let D = [];
|
|
450
|
-
var
|
|
451
|
-
for (h = 0; ; ++
|
|
450
|
+
var O = 0;
|
|
451
|
+
for (h = 0; ; ++O) {
|
|
452
452
|
let k = tt(Math.round(o[h].rc), 0, 255), R = tt(Math.round(o[h].gc), 0, 255), y = tt(Math.round(o[h].bc), 0, 255), w = 255;
|
|
453
453
|
p && (w = tt(Math.round(o[h].ac), 0, 255), c && (w = w <= (typeof c == "number" ? c : 127) ? 0 : 255), a && w <= n && (k = R = y = i, w = 0));
|
|
454
454
|
let F = p ? [k, R, y, w] : [k, R, y];
|
|
@@ -466,11 +466,11 @@ function ie(s, t) {
|
|
|
466
466
|
function oe(s, t, e) {
|
|
467
467
|
let r = (e = e || "rgb565") === "rgb444" ? 4096 : 65536, a = new Uint8Array(s.length), i = new Array(r);
|
|
468
468
|
if (e === "rgba4444") for (let n = 0; n < s.length; n++) {
|
|
469
|
-
let c, l = s[n], p = l >> 24 & 255, o = l >> 16 & 255, d = l >> 8 & 255, u = 255 & l, m =
|
|
469
|
+
let c, l = s[n], p = l >> 24 & 255, o = l >> 16 & 255, d = l >> 8 & 255, u = 255 & l, m = Tt(u, d, o, p);
|
|
470
470
|
i[m] != null ? c = i[m] : (c = ne(u, d, o, p, t), i[m] = c), a[n] = c;
|
|
471
471
|
}
|
|
472
472
|
else for (let n = 0; n < s.length; n++) {
|
|
473
|
-
let c, l = s[n], p = l >> 16 & 255, o = l >> 8 & 255, d = 255 & l, u = e === "rgb444" ?
|
|
473
|
+
let c, l = s[n], p = l >> 16 & 255, o = l >> 8 & 255, d = 255 & l, u = e === "rgb444" ? Ot(d, o, p) : Vt(d, o, p);
|
|
474
474
|
i[u] != null ? c = i[u] : (c = se(d, o, p, t), i[u] = c), a[n] = c;
|
|
475
475
|
}
|
|
476
476
|
return a;
|
|
@@ -644,7 +644,7 @@ function ge() {
|
|
|
644
644
|
function D(y) {
|
|
645
645
|
return y - d.dataOffset;
|
|
646
646
|
}
|
|
647
|
-
function
|
|
647
|
+
function O() {
|
|
648
648
|
u = (function() {
|
|
649
649
|
let M = { id: 21420, size: 5, data: 0 }, U = { id: 290298740, data: [] };
|
|
650
650
|
for (let I in A) {
|
|
@@ -683,7 +683,7 @@ function ge() {
|
|
|
683
683
|
n(w, B.pos, F), B.write(w.getAsDataArray()), $ = 1, M = Math.round(C), U = F.offset, V.push({ id: 187, data: [{ id: 179, data: M }, { id: 183, data: [{ id: 247, data: $ }, { id: 241, data: D(U) }] }] }), g = [], C += S, S = 0;
|
|
684
684
|
}
|
|
685
685
|
this.addFrame = function(y, w, F) {
|
|
686
|
-
m || (x = y.width || 0, h = y.height || 0,
|
|
686
|
+
m || (x = y.width || 0, h = y.height || 0, O());
|
|
687
687
|
let $, M = r(t(y, o.quality)), U = null;
|
|
688
688
|
$ = F || (typeof w == "number" ? w : o.frameDuration), o.transparent && (w instanceof HTMLCanvasElement || typeof w == "string" ? U = w : M.hasAlpha && (U = (function(I) {
|
|
689
689
|
f !== null && f.width === I.width && f.height === I.height || (f = document.createElement("canvas"), f.width = I.width, f.height = I.height, _ = f.getContext("2d"), v = _.createImageData(f.width, f.height));
|
|
@@ -697,7 +697,7 @@ function ge() {
|
|
|
697
697
|
I.trackNumber = 1, I.timecode = Math.round(S), g.push(I), S += I.duration, S >= 5e3 && R();
|
|
698
698
|
})({ frame: M.frame, duration: $, alpha: U ? r(t(U, o.alphaQuality)).frame : null });
|
|
699
699
|
}, this.complete = function() {
|
|
700
|
-
return m ||
|
|
700
|
+
return m || O(), R(), (function() {
|
|
701
701
|
let y = { id: 475249515, data: V }, w = new l(16 + 32 * V.length);
|
|
702
702
|
n(w, B.pos, y), B.write(w.getAsDataArray()), A.Cues.positionEBML.data = D(y.offset);
|
|
703
703
|
})(), (function() {
|
|
@@ -950,7 +950,7 @@ class Ce {
|
|
|
950
950
|
}
|
|
951
951
|
}
|
|
952
952
|
const b = { root: "textmode-export-overlay", stack: "textmode-export-overlay__stack", stackDense: "textmode-export-overlay__stack--dense", stackCompact: "textmode-export-overlay__stack--compact", section: "textmode-export-overlay__section", header: "textmode-export-overlay__header", headerTitleRow: "textmode-export-overlay__header-title-row", headerLinks: "textmode-export-overlay__header-links", row: "textmode-export-overlay__row", label: "textmode-export-overlay__label", field: "textmode-export-overlay__field", fieldCompact: "textmode-export-overlay__field--compact", fieldDense: "textmode-export-overlay__field--dense", fieldFull: "textmode-export-overlay__field--full", fieldChannel: "textmode-export-overlay__field--channel", input: "textmode-export-overlay__input", checkbox: "textmode-export-overlay__checkbox", muted: "textmode-export-overlay__muted", status: "textmode-export-overlay__status", statusGif: "textmode-export-overlay__status--gif", statusVideo: "textmode-export-overlay__status--video", statusTitle: "textmode-export-overlay__status-title", statusValue: "textmode-export-overlay__status-value", divider: "textmode-export-overlay__divider", title: "textmode-export-overlay__title", button: "textmode-export-overlay__button", buttonPrimary: "textmode-export-overlay__button--primary", buttonSecondary: "textmode-export-overlay__button--secondary", buttonFull: "textmode-export-overlay__button--full", supportLink: "textmode-export-overlay__support-link", supportIcon: "textmode-export-overlay__support-icon", linkIcon: "textmode-export-overlay__link-icon" };
|
|
953
|
-
class
|
|
953
|
+
class T {
|
|
954
954
|
element;
|
|
955
955
|
mounted = !1;
|
|
956
956
|
destroyed = !1;
|
|
@@ -985,7 +985,7 @@ class O {
|
|
|
985
985
|
return this.mounted;
|
|
986
986
|
}
|
|
987
987
|
}
|
|
988
|
-
class H extends
|
|
988
|
+
class H extends T {
|
|
989
989
|
static _iconNamespace = "http://www.w3.org/2000/svg";
|
|
990
990
|
render() {
|
|
991
991
|
const t = document.createElement("div");
|
|
@@ -1016,7 +1016,7 @@ class H extends O {
|
|
|
1016
1016
|
return r;
|
|
1017
1017
|
}
|
|
1018
1018
|
}
|
|
1019
|
-
class P extends
|
|
1019
|
+
class P extends T {
|
|
1020
1020
|
props;
|
|
1021
1021
|
constructor(t) {
|
|
1022
1022
|
super(), this.props = t;
|
|
@@ -1063,7 +1063,7 @@ class P extends O {
|
|
|
1063
1063
|
}
|
|
1064
1064
|
}
|
|
1065
1065
|
}
|
|
1066
|
-
class mt extends
|
|
1066
|
+
class mt extends T {
|
|
1067
1067
|
props;
|
|
1068
1068
|
select;
|
|
1069
1069
|
handleChange = () => {
|
|
@@ -1104,7 +1104,7 @@ class mt extends O {
|
|
|
1104
1104
|
}
|
|
1105
1105
|
}
|
|
1106
1106
|
}
|
|
1107
|
-
class Lt extends
|
|
1107
|
+
class Lt extends T {
|
|
1108
1108
|
props;
|
|
1109
1109
|
button;
|
|
1110
1110
|
constructor(t) {
|
|
@@ -1219,7 +1219,7 @@ const X = "textmode-export-number-input", Ie = `${X}__field`, Se = `${X}__contro
|
|
|
1219
1219
|
const t = document.createElement("button");
|
|
1220
1220
|
return t.type = "button", t.className = Fe, t.textContent = s > 0 ? "▲" : "▼", t;
|
|
1221
1221
|
};
|
|
1222
|
-
class G extends
|
|
1222
|
+
class G extends T {
|
|
1223
1223
|
props;
|
|
1224
1224
|
input;
|
|
1225
1225
|
display;
|
|
@@ -1323,7 +1323,7 @@ class G extends O {
|
|
|
1323
1323
|
this.holdTimeoutId !== void 0 && (window.clearTimeout(this.holdTimeoutId), this.holdTimeoutId = void 0), this.holdIntervalId !== void 0 && (window.clearInterval(this.holdIntervalId), this.holdIntervalId = void 0);
|
|
1324
1324
|
}
|
|
1325
1325
|
}
|
|
1326
|
-
class j extends
|
|
1326
|
+
class j extends T {
|
|
1327
1327
|
variant;
|
|
1328
1328
|
additionalClasses;
|
|
1329
1329
|
constructor(t = "stack", e = []) {
|
|
@@ -1335,7 +1335,7 @@ class j extends O {
|
|
|
1335
1335
|
}
|
|
1336
1336
|
}
|
|
1337
1337
|
const $t = { neutral: "textmode-export-overlay__status-value--neutral", active: "textmode-export-overlay__status-value--active", alert: "textmode-export-overlay__status-value--alert" };
|
|
1338
|
-
class Nt extends
|
|
1338
|
+
class Nt extends T {
|
|
1339
1339
|
props;
|
|
1340
1340
|
container;
|
|
1341
1341
|
messageElement;
|
|
@@ -1357,7 +1357,7 @@ class Nt extends O {
|
|
|
1357
1357
|
this.messageElement.classList.remove(...Object.values($t)), this.messageElement.classList.add($t[t]);
|
|
1358
1358
|
}
|
|
1359
1359
|
}
|
|
1360
|
-
class Y extends
|
|
1360
|
+
class Y extends T {
|
|
1361
1361
|
_config;
|
|
1362
1362
|
_managedComponents = /* @__PURE__ */ new Set();
|
|
1363
1363
|
constructor(t) {
|
|
@@ -1456,7 +1456,7 @@ const it = "textmode-export-range-input", Me = `${it}__field`, $e = `${it}__tool
|
|
|
1456
1456
|
const e = Number.parseFloat(s);
|
|
1457
1457
|
return Number.isFinite(e) ? e : t;
|
|
1458
1458
|
}, Ae = (s, t, e) => Math.min(e, Math.max(t, s));
|
|
1459
|
-
class Pe extends
|
|
1459
|
+
class Pe extends T {
|
|
1460
1460
|
props;
|
|
1461
1461
|
input;
|
|
1462
1462
|
tooltip;
|
|
@@ -1641,8 +1641,8 @@ class pt extends Y {
|
|
|
1641
1641
|
this.frameCountInput.value = String(e), this.frameRateInput.value = String(r), this.qualityInput.value = String(a), this.frameCountInput.refresh(), this.frameRateInput.refresh();
|
|
1642
1642
|
}
|
|
1643
1643
|
}
|
|
1644
|
-
const
|
|
1645
|
-
class
|
|
1644
|
+
const Te = `@layer textmode-export-overlay{.textmode-export-overlay{--overlay-bg: rgba(20, 20, 20, .8);--overlay-surface: rgba(40, 40, 40, .9);--overlay-border: rgba(255, 255, 255, .14);--overlay-border-strong: rgba(255, 255, 255, .2);--overlay-border-focus: rgba(160, 160, 160, .6);--overlay-focus-shadow: 0 0 0 1px rgba(140, 140, 140, .28);--overlay-text: #ffffff;--overlay-muted: rgba(200, 200, 200, .74);--overlay-radius: .75rem;--overlay-stack-gap: .55rem;position:absolute;top:0;left:0;display:flex;flex-direction:column;gap:var(--overlay-stack-gap);min-width:236px;max-width:236px;padding:.65rem .8rem;background:var(--overlay-bg);color:var(--overlay-text);border-radius:var(--overlay-radius);border:1px solid var(--overlay-border);box-shadow:0 12px 28px #0000004d;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-size:.82rem;line-height:1.35;pointer-events:auto;z-index:2147483647}.textmode-export-overlay *{box-sizing:border-box}.textmode-export-overlay__header{display:flex;flex-direction:column;gap:.4rem}.textmode-export-overlay__header-title-row{display:flex;align-items:center;justify-content:space-between;gap:.4rem}.textmode-export-overlay__header-links{display:inline-flex;align-items:center;gap:.3rem}.textmode-export-overlay__support-link{display:inline-flex;align-items:center;justify-content:center;padding:.2rem;border-radius:.45rem;border:1px solid transparent;color:#d7d7d7d1;background:transparent;text-decoration:none;line-height:0;transition:background .18s ease,color .18s ease,transform .18s ease,border-color .18s ease}.textmode-export-overlay__support-link:hover{color:#fff;background:#5a5a5a4d;border-color:#c8c8c824}.textmode-export-overlay__support-link:focus-visible{outline:none;border-color:var(--overlay-border-focus);box-shadow:var(--overlay-focus-shadow)}.textmode-export-overlay__support-icon,.textmode-export-overlay__link-icon{display:block;width:1rem;height:1rem}.textmode-export-overlay__stack{display:flex;flex-direction:column;gap:var(--overlay-stack-gap)}.textmode-export-overlay__stack--dense{gap:.3rem}.textmode-export-overlay__stack--compact{gap:.45rem}.textmode-export-overlay__section{display:flex;flex-direction:column;gap:.4rem}.textmode-export-overlay__title{font-size:.92rem;font-weight:600}.textmode-export-overlay__divider{width:100%;height:1px;background:#ffffff29;margin-top:.25rem}.textmode-export-overlay__label{font-weight:500;opacity:.9}.textmode-export-overlay__checkbox{display:flex;align-items:center;gap:.5rem}.textmode-export-overlay__checkbox input[type=checkbox]{width:1rem;height:1rem;accent-color:rgba(100,100,100,.9)}.textmode-export-overlay__row{display:flex;gap:.6rem;flex-wrap:wrap;align-items:flex-start;width:100%}.textmode-export-overlay__field{display:flex;flex-direction:column;gap:.3rem;flex:1 1 120px;min-width:120px}.textmode-export-overlay__field--compact{flex:1 1 100px;min-width:100px}.textmode-export-overlay__field--dense{flex:1 1 90px;min-width:90px}.textmode-export-overlay__field--channel{flex:1 1 0;min-width:0}.textmode-export-overlay__field--full{width:100%;flex:1 1 100%}.textmode-export-overlay__input,.textmode-export-overlay select.textmode-export-overlay__input,.textmode-export-overlay input.textmode-export-overlay__input{width:100%;padding:.35rem .5rem;border-radius:.4rem;border:1px solid var(--overlay-border-strong);background:var(--overlay-surface);color:var(--overlay-text);font:inherit;line-height:1.35;transition:border-color .18s ease,box-shadow .18s ease,background .18s ease}.textmode-export-overlay select.textmode-export-overlay__input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='rgba(200, 200, 200, 0.74)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .5rem center;background-size:1rem;padding-right:2rem}.textmode-export-overlay__input:focus{outline:none;border-color:var(--overlay-border-focus);box-shadow:var(--overlay-focus-shadow);background:#2d2f42eb}.textmode-export-overlay__input::placeholder{color:var(--overlay-muted);opacity:.7}.textmode-export-overlay__muted{font-size:.75rem;opacity:.7;display:block}.textmode-export-overlay__button{display:inline-flex;align-items:center;justify-content:center;gap:.35rem;border-radius:.45rem;border:none;font-weight:600;padding:.45rem .7rem;cursor:pointer;transition:background .2s ease,transform .2s ease,box-shadow .2s ease}.textmode-export-overlay__button--primary{background:#505050;color:#fff}.textmode-export-overlay__button--secondary{background:#606060;color:#fff}.textmode-export-overlay__button--full{width:100%}.textmode-export-overlay__button:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 7px 18px #00000073}.textmode-export-overlay__button--primary:hover:not(:disabled){background:#404040}.textmode-export-overlay__button--secondary:hover:not(:disabled){background:#4a4a4a}.textmode-export-overlay__button:disabled{cursor:default;opacity:.55;transform:none;box-shadow:none}.textmode-export-overlay__status{display:flex;flex-direction:column;gap:.25rem;padding:.45rem .55rem;border-radius:.45rem;border:1px solid rgba(110,110,110,.22);background:#4646462e}.textmode-export-overlay__status--gif{background:#5050501f;border-color:#78787840}.textmode-export-overlay__status--video{background:#4646461f;border-color:#6e6e6e40}.textmode-export-overlay__status-title{font-weight:600;font-size:.75rem;opacity:.85;text-transform:uppercase;letter-spacing:.04em}.textmode-export-overlay__status-value{font-size:.82rem;color:#dedede;transition:color .18s ease}.textmode-export-overlay__status-value--neutral{color:#cfcfcf}.textmode-export-overlay__status-value--active{color:#f5f5f5}.textmode-export-overlay__status-value--alert{color:#b8b8b8}.textmode-export-number-input,.textmode-export-overlay .textmode-export-number-input{display:flex;align-items:stretch;width:100%;background:var(--overlay-surface);border:1px solid var(--overlay-border-strong);border-radius:.4rem;overflow:hidden;transition:border-color .18s ease,box-shadow .18s ease,background .18s ease;position:relative}.textmode-export-number-input:focus-within{border-color:var(--overlay-border-focus);box-shadow:var(--overlay-focus-shadow)}.textmode-export-number-input.is-disabled{opacity:.55}.textmode-export-number-input__field{flex:1 1 auto;min-width:0;border:none;background:transparent;color:var(--overlay-text);font:inherit;padding:.35rem .5rem;appearance:textfield}.textmode-export-number-input__field::-webkit-outer-spin-button,.textmode-export-number-input__field::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.textmode-export-number-input__field:focus{outline:none}.textmode-export-number-input__controls{display:flex;flex-direction:column;border-left:1px solid rgba(255,255,255,.12);min-width:1.6rem}.textmode-export-number-input__control{display:flex;align-items:center;justify-content:center;width:100%;flex:1;border:none;background:#32323299;color:#d0d0d0;font-size:.68rem;line-height:1;cursor:pointer;transition:background .15s ease,color .15s ease;padding:0}.textmode-export-number-input__control:hover:not(:disabled){background:#5a5a5ad9;color:#fff}.textmode-export-number-input__control:disabled{cursor:default;opacity:.4;background:#28282880;color:#c8c8c866}.textmode-export-number-input:focus-within .textmode-export-number-input__control{background:#3c3c3cbf;color:#e8e8e8}.textmode-export-number-input__display{position:absolute;inset:0;display:flex;align-items:center;padding:.4rem .55rem;pointer-events:none;color:#f8fafc;opacity:0;transition:opacity .14s ease}.textmode-export-number-input__display--visible{opacity:1}.textmode-export-range-input{position:relative;width:100%}.textmode-export-range-input.is-disabled{opacity:.55}.textmode-export-range-input__field{width:100%;height:1.4rem;padding:0;margin:0;background:transparent;cursor:pointer;appearance:none;-webkit-appearance:none}.textmode-export-range-input__field::-webkit-slider-thumb{width:12px;height:12px;margin-top:-3.5px;-webkit-appearance:none;border-radius:50%;background:#a0a0a0;border:2px solid #303030;box-shadow:0 0 0 2px #00000059}.textmode-export-range-input__field::-webkit-slider-runnable-track{height:5px;border-radius:999px;background:linear-gradient(90deg,#8c8c8cd9,#646464a6)}.textmode-export-range-input__field::-moz-range-thumb{width:12px;height:12px;border-radius:50%;background:#a0a0a0;border:2px solid #303030;margin-top:-3.5px}.textmode-export-range-input__field::-moz-range-track{height:5px;border-radius:999px;background:linear-gradient(90deg,#8c8c8cd9,#646464a6)}.textmode-export-range-input__tooltip{position:absolute;top:-1.5rem;left:0;transform:translate(-50%);padding:.2rem .35rem;border-radius:.35rem;background:#1e1e1ee0;color:#f8fafc;font-size:.68rem;line-height:1;white-space:nowrap;pointer-events:none;opacity:0;transition:opacity .15s ease}.textmode-export-range-input__tooltip--visible{opacity:1}}`;
|
|
1645
|
+
class Oe {
|
|
1646
1646
|
_textmodifier;
|
|
1647
1647
|
_state;
|
|
1648
1648
|
_events;
|
|
@@ -1699,7 +1699,7 @@ class Te {
|
|
|
1699
1699
|
_createOverlay() {
|
|
1700
1700
|
this._shadowHost = document.createElement("div"), this._shadowHost.dataset.plugin = "textmode-export-overlay-host", this._shadowHost.style.cssText = "position: absolute; top: 0; left: 0; pointer-events: none; z-index: 2147483647;", this._shadowRoot = this._shadowHost.attachShadow({ mode: "open" });
|
|
1701
1701
|
const t = document.createElement("style");
|
|
1702
|
-
t.textContent =
|
|
1702
|
+
t.textContent = Te, this._shadowRoot.appendChild(t), this._overlayElement = document.createElement("div"), this._overlayElement.dataset.plugin = "textmode-export-overlay", this._overlayElement.classList.add(b.root, b.stack), this._shadowRoot.appendChild(this._overlayElement), document.body.appendChild(this._shadowHost);
|
|
1703
1703
|
}
|
|
1704
1704
|
_renderStaticContent() {
|
|
1705
1705
|
this._header.mount(this._overlayElement);
|
|
@@ -1877,7 +1877,7 @@ class Ue {
|
|
|
1877
1877
|
}
|
|
1878
1878
|
}
|
|
1879
1879
|
const Ne = (s) => ({ format: s, isBusy: !1 });
|
|
1880
|
-
class Gt extends
|
|
1880
|
+
class Gt extends T {
|
|
1881
1881
|
props;
|
|
1882
1882
|
checkbox;
|
|
1883
1883
|
labelElement;
|
|
@@ -1908,7 +1908,7 @@ class Gt extends O {
|
|
|
1908
1908
|
this.props = t, t.id && (this.checkbox.id = t.id, this.labelElement.htmlFor = t.id), this.checkbox.checked = !!t.defaultChecked, this.labelElement.lastElementChild && (this.labelElement.lastElementChild.textContent = t.label);
|
|
1909
1909
|
}
|
|
1910
1910
|
}
|
|
1911
|
-
class Ge extends
|
|
1911
|
+
class Ge extends T {
|
|
1912
1912
|
props;
|
|
1913
1913
|
input;
|
|
1914
1914
|
handleInput = () => {
|
|
@@ -2040,18 +2040,18 @@ function je() {
|
|
|
2040
2040
|
return He;
|
|
2041
2041
|
}
|
|
2042
2042
|
function Qe(s, t) {
|
|
2043
|
-
const e = je(), r = e[0]?.format, a = new Ue(Ne(r)), i = new Re(), n = new
|
|
2043
|
+
const e = je(), r = e[0]?.format, a = new Ue(Ne(r)), i = new Re(), n = new Oe(s, t, a, i, e);
|
|
2044
2044
|
return n.$mount(), n;
|
|
2045
2045
|
}
|
|
2046
2046
|
const Xe = (s = {}) => {
|
|
2047
2047
|
const t = s.overlay ?? !0;
|
|
2048
2048
|
let e;
|
|
2049
2049
|
return { name: "textmode-export", version: "1.0.0", async install(r, a) {
|
|
2050
|
-
const i = { saveCanvas: async (n = {}) =>
|
|
2051
|
-
|
|
2050
|
+
const i = { saveCanvas: async (n = {}) => new bt().$saveImage(r.canvas, n), copyCanvas: async (n = {}) => new bt().$copyImageToClipboard(r.canvas, n), saveSVG: (n = {}) => {
|
|
2051
|
+
new gt().$saveSVG(r, n);
|
|
2052
2052
|
}, saveStrings: (n = {}) => {
|
|
2053
|
-
|
|
2054
|
-
}, toSVG: (n = {}) =>
|
|
2053
|
+
new vt().$saveTXT(r, n);
|
|
2054
|
+
}, toSVG: (n = {}) => new gt().$generateSVG(r, n), toString: (n = {}) => new vt().$generateTXT(r, n), saveGIF: async (n = {}) => new me(r, a.registerPostDrawHook).$saveGIF(n), saveWEBM: async (n = {}) => new Ce(r, a.registerPostDrawHook).$saveWEBM(n) };
|
|
2055
2055
|
Object.assign(r, i), t && (e = Qe(r, i));
|
|
2056
2056
|
}, async uninstall(r) {
|
|
2057
2057
|
e?.$dispose(), e = void 0;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(function(Q,j){typeof exports=="object"&&typeof module<"u"?j(exports):typeof define=="function"&&define.amd?define(["exports"],j):j((Q=typeof globalThis<"u"?globalThis:Q||self).TextmodeExport={})})(this,function(Q){"use strict";class j{$extractFramebufferData(t){
|
|
2
|
-
`)}$generateTXT(t,e={}){return this._createTXTContent(t,this._applyDefaultOptions(e))}$saveTXT(t,e={}){const r=this._applyDefaultOptions(e),a=this._createTXTContent(t,r),i=new Blob([a],{type:"text/plain;charset=utf-8"});new X().$downloadFile(i,r.filename)}}class pe{_canvas;_ctx;async $record(t,e,r,a){const i=Math.max(1,Math.round(e.frameRate)),n=Math.round(1e3/i),u=Math.max(1,Math.round(e.frameCount));return await new Promise((l,h)=>{const o=[];let s,d=0,m=!1;const y=()=>{s&&(s(),s=void 0)},p=E=>{m||(m=!0,y(),l(E))},b=()=>{if(d>=u)p(o);else try{const E=e.scale,x=Math.max(1,Math.round(t.width*E)),g=Math.max(1,Math.round(t.height*E));this._canvas||(this._canvas=document.createElement("canvas")),this._canvas.width===x&&this._canvas.height===g||(this._canvas.width=x,this._canvas.height=g),this._ctx||(this._ctx=this._canvas.getContext("2d"));const B=this._ctx;B.imageSmoothingEnabled=!1,B.clearRect(0,0,x,g),B.drawImage(t,0,0,t.width,t.height,0,0,x,g);const S={imageData:B.getImageData(0,0,x,g),width:x,height:g,delayMs:n};o.push(S),d+=1,a?.({state:"recording",frameIndex:d,totalFrames:u}),d>=u&&p(o)}catch(E){(x=>{if(m)return;m=!0,y();const g=x instanceof Error?x.message:"GIF recording failed";a?.({state:"error",message:g}),h(x instanceof Error?x:new Error(String(x)))})(E)}};s=r(()=>{b()}),a?.({state:"recording",frameIndex:0,totalFrames:u})})}}var wt,tt,Ct=Object.defineProperty,he=(wt=c=>{function t(s,d,m){return .29889531*s+.58662247*d+.11448223*m}function e(s,d,m){return .59597799*s-.2741761*d-.32180189*m}function r(s,d,m){return .21147017*s-.52261711*d+.31114694*m}function a(s,d){let m=s[0]-d[0],y=s[1]-d[1],p=s[2]-d[2],b=i(s)-i(d);return m*m*.5053+y*y*.299+p*p*.1957+b*b}function i(s){return s[3]!=null?s[3]:255}function n(s,d){return Math.sqrt(a(s,d))}function u(s,d){let[m,y,p]=s,[b,E,x]=d,g=t(m,y,p)-t(b,E,x),B=e(m,y,p)-e(b,E,x),S=r(m,y,p)-r(b,E,x),k=i(s)-i(d);return g*g*.5053+B*B*.299+S*S*.1957+k*k}function l(s,d){return Math.sqrt(u(s,d))}function h(s,d){var m,y=0;for(m=0;m<s.length;m++){let p=s[m]-d[m];y+=p*p}return y}function o(s,d){return Math.sqrt(h(s,d))}Ct(c,"__esModule",{value:!0}),((s,d)=>{for(var m in d)Ct(s,m,{get:d[m],enumerable:!0})})(c,{colorDifferenceRGBToYIQ:()=>l,colorDifferenceRGBToYIQSquared:()=>u,colorDifferenceYIQ:()=>n,colorDifferenceYIQSquared:()=>a,euclideanDistance:()=>o,euclideanDistanceSquared:()=>h})},()=>(tt||wt((tt={exports:{}}).exports,tt),tt.exports)),me=59;function Et(c=256){let t=0,e=new Uint8Array(c);return{get buffer(){return e.buffer},reset(){t=0},bytesView:()=>e.subarray(0,t),bytes:()=>e.slice(0,t),writeByte(a){r(t+1),e[t]=a,t++},writeBytes(a,i=0,n=a.length){r(t+n);for(let u=0;u<n;u++)e[t++]=a[u+i]},writeBytesView(a,i=0,n=a.byteLength){r(t+n),e.set(a.subarray(i,i+n),t),t+=n}};function r(a){var i=e.length;if(i>=a)return;a=Math.max(a,i*(i<1048576?2:1.125)>>>0),i!=0&&(a=Math.max(a,256));let n=e;e=new Uint8Array(a),t>0&&e.set(n.subarray(0,t),0)}}var fe=[0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535],ge=function(c,t,e,r,a,i,n,u){a=a||Et(512),i=i||new Uint8Array(256),n=n||new Int32Array(5003),u=u||new Int32Array(5003);let l=n.length,h=Math.max(2,r);i.fill(0),u.fill(0),F();let o=0,s=0,d=h+1,m=d,y=!1,p=m,b=$(p),E=1<<d-1,x=E+1,g=E+2,B=0,S=e[0],k=0;for(let v=l;v<65536;v*=2)++k;k=8-k,a.writeByte(h),V(E);for(let v=1;v<e.length;v++)L(e[v]);return V(S),V(x),a.writeByte(0),a.bytesView();function C(v){i[B++]=v,B>=254&&w()}function F(){n.fill(-1)}function L(v){let D=(v<<12)+S,f=v<<k^S;if(n[f]===D)S=u[f];else{if(n[f]>=0){let _=f===0?1:l-f;do if(f-=_,f<0&&(f+=l),n[f]===D)return void(S=u[f]);while(n[f]>=0)}V(S),S=v,g<4096?(u[f]=g++,n[f]=D):(F(),g=E+2,y=!0,V(E))}}function w(){B>0&&(a.writeByte(B),a.writeBytesView(i,0,B),B=0)}function $(v){return(1<<v)-1}function V(v){for(o&=fe[s],s>0?o|=v<<s:o=v,s+=p;s>=8;)C(255&o),o>>=8,s-=8;if((g>b||y)&&(y?(p=m,b=$(p),y=!1):(++p,b=p==12?4096:$(p))),v==x){for(;s>0;)C(255&o),o>>=8,s-=8;w()}}};function Bt(c,t,e){return c<<8&63488|t<<2&992|e>>3&31}function kt(c,t,e,r){return c>>4|240&t|(240&e)<<4|(240&r)<<8}function It(c,t,e){return c>>4<<8|t>>4<<4|e>>4}function et(c,t,e){return c<t?t:c>e?e:c}function rt(c){return c*c}function Ft(c,t,e){for(var r=0,a=1e100,i=c[t],n=i.cnt,u=(i.ac,i.rc),l=i.gc,h=i.bc,o=i.fw;o!=0;o=c[o].fw){var s=c[o].cnt,d=n*s/(n+s);if(!(d>=a)){var m=0;!((m+=d*rt(c[o].rc-u))>=a)&&!((m+=d*rt(c[o].gc-l))>=a)&&!((m+=d*rt(c[o].bc-h))>=a)&&(a=m,r=o)}}i.err=a,i.nn=r}function st(){return{ac:0,rc:0,gc:0,bc:0,cnt:0,nn:0,fw:0,bk:0,tm:0,mtm:0,err:0}}function be(c,t,e){let{format:r="rgb565",clearAlpha:a=!0,clearAlphaColor:i=0,clearAlphaThreshold:n=0,oneBitAlpha:u=!1}=e||{},l=e.useSqrt!==!1,h=r==="rgba4444",o=(function(v,D){let f=new Array(D==="rgb444"?4096:65536),_=v.length;if(D==="rgba4444")for(let M=0;M<_;++M){let P=v[M],A=P>>24&255,O=P>>16&255,I=P>>8&255,T=255&P,U=kt(T,I,O,A),G=U in f?f[U]:f[U]=st();G.rc+=T,G.gc+=I,G.bc+=O,G.ac+=A,G.cnt++}else if(D==="rgb444")for(let M=0;M<_;++M){let P=v[M],A=P>>16&255,O=P>>8&255,I=255&P,T=It(I,O,A),U=T in f?f[T]:f[T]=st();U.rc+=I,U.gc+=O,U.bc+=A,U.cnt++}else for(let M=0;M<_;++M){let P=v[M],A=P>>16&255,O=P>>8&255,I=255&P,T=Bt(I,O,A),U=T in f?f[T]:f[T]=st();U.rc+=I,U.gc+=O,U.bc+=A,U.cnt++}return f})(c,r),s=o.length,d=s-1,m=new Uint32Array(s+1);for(var y=0,p=0;p<o.length;++p){let v=o[p];if(v!=null){var b=1/v.cnt;h&&(v.ac*=b),v.rc*=b,v.gc*=b,v.bc*=b,o[y++]=v}}for(rt(t)/y<.022&&(l=!1),p=0;p<y-1;++p)o[p].fw=p+1,o[p+1].bk=p,l&&(o[p].cnt=Math.sqrt(o[p].cnt));var E,x,g;for(l&&(o[p].cnt=Math.sqrt(o[p].cnt)),p=0;p<y;++p){Ft(o,p);var B=o[p].err;for(x=++m[0];x>1&&!(o[E=m[g=x>>1]].err<=B);x=g)m[x]=E;m[x]=p}var S=y-t;for(p=0;p<S;){for(var k;;){var C=m[1];if((k=o[C]).tm>=k.mtm&&o[k.nn].mtm<=k.tm)break;for(k.mtm==d?C=m[1]=m[m[0]--]:(Ft(o,C),k.tm=p),B=o[C].err,x=1;(g=x+x)<=m[0]&&(g<m[0]&&o[m[g]].err>o[m[g+1]].err&&g++,!(B<=o[E=m[g]].err));x=g)m[x]=E;m[x]=C}var F=o[k.nn],L=k.cnt,w=F.cnt;b=1/(L+w),h&&(k.ac=b*(L*k.ac+w*F.ac)),k.rc=b*(L*k.rc+w*F.rc),k.gc=b*(L*k.gc+w*F.gc),k.bc=b*(L*k.bc+w*F.bc),k.cnt+=F.cnt,k.mtm=++p,o[F.bk].fw=F.fw,o[F.fw].bk=F.bk,F.mtm=d}let $=[];var V=0;for(p=0;;++V){let v=et(Math.round(o[p].rc),0,255),D=et(Math.round(o[p].gc),0,255),f=et(Math.round(o[p].bc),0,255),_=255;h&&(_=et(Math.round(o[p].ac),0,255),u&&(_=_<=(typeof u=="number"?u:127)?0:255),a&&_<=n&&(v=D=f=i,_=0));let M=h?[v,D,f,_]:[v,D,f];if(ve($,M)||$.push(M),(p=o[p].fw)==0)break}return $}function ve(c,t){for(let e=0;e<c.length;e++){let r=c[e],a=r[0]===t[0]&&r[1]===t[1]&&r[2]===t[2],i=!(r.length>=4&&t.length>=4)||r[3]===t[3];if(a&&i)return!0}return!1}function xe(c,t,e,r,a){let i=0,n=1e100;for(let u=0;u<a.length;u++){let l=a[u],h=l[0],o=l[1],s=l[2],d=H(l[3]-r);d>n||(d+=H(h-c),!(d>n)&&(d+=H(o-t),!(d>n)&&(d+=H(s-e),!(d>n)&&(n=d,i=u))))}return i}function ye(c,t,e,r){let a=0,i=1e100;for(let n=0;n<r.length;n++){let u=r[n],l=u[0],h=u[1],o=u[2],s=H(l-c);s>i||(s+=H(h-t),!(s>i)&&(s+=H(o-e),!(s>i)&&(i=s,a=n)))}return a}function H(c){return c*c}function _e(c={}){let{initialCapacity:t=4096,auto:e=!0}=c,r=Et(t),a=new Uint8Array(256),i=new Int32Array(5003),n=new Int32Array(5003),u=!1;return{reset(){r.reset(),u=!1},finish(){r.writeByte(me)},bytes:()=>r.bytes(),bytesView:()=>r.bytesView(),get buffer(){return r.buffer},get stream(){return r},writeHeader:l,writeFrame(h,o,s,d={}){let{transparent:m=!1,transparentIndex:y=0,delay:p=0,palette:b=null,repeat:E=0,colorDepth:x=8,dispose:g=-1}=d,B=!1;if(e?u||(B=!0,l(),u=!0):B=!!d.first,o=Math.max(0,Math.floor(o)),s=Math.max(0,Math.floor(s)),B){if(!b)throw new Error("First frame must include a { palette } option");(function(C,F,L,w,$=8){let V=1,v=0,D=lt(w.length)-1,f=V<<7|$-1<<4|v<<3|D;W(C,F),W(C,L),C.writeBytes([f,0,0])})(r,o,s,b,x),Mt(r,b),E>=0&&(function(C,F){C.writeByte(33),C.writeByte(255),C.writeByte(11),$t(C,"NETSCAPE2.0"),C.writeByte(3),C.writeByte(1),W(C,F),C.writeByte(0)})(r,E)}let S=Math.round(p/10);(function(C,F,L,w,$){var V,v;C.writeByte(33),C.writeByte(249),C.writeByte(4),$<0&&($=0,w=!1),w?(V=1,v=2):(V=0,v=0),F>=0&&(v=7&F),v<<=2,C.writeByte(0|v|0|V),W(C,L),C.writeByte($||0),C.writeByte(0)})(r,g,S,m,y);let k=!!b&&!B;(function(C,F,L,w){if(C.writeByte(44),W(C,0),W(C,0),W(C,F),W(C,L),w){let $=0,V=0,v=lt(w.length)-1;C.writeByte(128|$|V|v)}else C.writeByte(0)})(r,o,s,k?b:null),k&&Mt(r,b),(function(C,F,L,w,$=8,V,v,D){ge(L,w,F,$,C,V,v,D)})(r,h,o,s,x,a,i,n)}};function l(){$t(r,"GIF89a")}}function Mt(c,t){let e=1<<lt(t.length);for(let r=0;r<e;r++){let a=[0,0,0];r<t.length&&(a=t[r]),c.writeByte(a[0]),c.writeByte(a[1]),c.writeByte(a[2])}}function W(c,t){c.writeByte(255&t),c.writeByte(t>>8&255)}function $t(c,t){for(var e=0;e<t.length;e++)c.writeByte(t.charCodeAt(e))}function lt(c){return Math.max(Math.ceil(Math.log2(c)),1)}he();class we{_recorder;_textmodifier;_registerPostDrawHook;constructor(t,e){this._recorder=new pe,this._textmodifier=t,this._registerPostDrawHook=e}async $saveGIF(t={}){const e=this._textmodifier.canvas,r=this._applyDefaultOptions(t),a=t.onProgress;try{const i=await this._recorder.$record(e,r,this._registerPostDrawHook,a),n=_e(),{repeat:u}=t;i.forEach((o,s)=>{const{width:d,height:m,imageData:y,delayMs:p}=o,b=new Uint32Array(y.data.buffer.slice(0)),E=be(b,256,{}),x=(function(g,B,S){let k=(S=S||"rgb565")==="rgb444"?4096:65536,C=new Uint8Array(g.length),F=new Array(k);if(S==="rgba4444")for(let L=0;L<g.length;L++){let w,$=g[L],V=$>>24&255,v=$>>16&255,D=$>>8&255,f=255&$,_=kt(f,D,v,V);F[_]!=null?w=F[_]:(w=xe(f,D,v,V,B),F[_]=w),C[L]=w}else for(let L=0;L<g.length;L++){let w,$=g[L],V=$>>16&255,v=$>>8&255,D=255&$,f=S==="rgb444"?It(D,v,V):Bt(D,v,V);F[f]!=null?w=F[f]:(w=ye(D,v,V,B),F[f]=w),C[L]=w}return C})(b,E);n.writeFrame(x,d,m,{palette:E,delay:p,repeat:s===0?u:-1})}),n.finish();const l=n.bytes(),h=l.buffer.slice(l.byteOffset,l.byteOffset+l.byteLength);new X().$downloadFile(new Blob([h],{type:"image/gif"}),r.filename),a?.({state:"completed",totalFrames:r.frameCount})}catch(i){throw a?.({state:"error",message:i instanceof Error?i.message:"GIF export failed"}),i}}_applyDefaultOptions(t){const e=Math.abs(Math.round(t.frameCount??300)),r=Math.abs(t.frameRate??60),a=Math.abs(t.scale??1),i=Math.max(-1,Math.round(t.repeat??0));return{filename:t.filename,frameCount:e,frameRate:r,scale:a,repeat:i}}}function Ce(c){return c&&c.__esModule&&Object.prototype.hasOwnProperty.call(c,"default")?c.default:c}var St,Lt={exports:{}};function Ee(){return St||(St=1,(function(c){(function(){function t(l,h){return(function(o){if(typeof o!="string"||!o.match(/^data:image\/webp;base64,/i))throw new Error("Failed to decode WebP Base64 URL");return window.atob(o.substring(23))})(typeof l=="string"&&/^data:image\/webp/.test(l)?l:l.toDataURL("image/webp",h))}function e(l){return(l.charCodeAt(0)|l.charCodeAt(1)<<8|l.charCodeAt(2)<<16|l.charCodeAt(3)<<24)>>>0}function r(l){let h=l.indexOf("VP8",12);if(h===-1)throw new Error("Bad image format, does this browser support WebP?");let o=!1;for(;h<l.length-8;){let s,d;switch(d=l.substring(h,h+4),h+=4,s=e(l.substring(h,h+4)),h+=4,d){case"VP8 ":return{frame:l.substring(h,h+s),hasAlpha:o};case"ALPH":o=!0}h+=s,1&s&&h++}throw new Error("Failed to find VP8 keyframe in WebP image, is this image mistakenly encoded in the Lossless WebP format?")}function a(l){this.value=l}function i(l){this.value=l}function n(l,h,o){if(Array.isArray(o))for(let s=0;s<o.length;s++)n(l,h,o[s]);else if(typeof o=="string")l.writeString(o);else if(o instanceof Uint8Array)l.writeBytes(o);else{if(!o.id)throw new Error("Bad EBML datatype "+typeof o.data);if(o.offset=l.pos+h,l.writeUnsignedIntBE(o.id),Array.isArray(o.data)){let s,d,m;o.size===-1?l.writeByte(255):o.size===-2?(s=l.pos,l.writeBytes([15,255,255,255,255])):(s=l.pos,l.writeBytes([0,0,0,0])),d=l.pos,o.dataOffset=d+h,n(l,h,o.data),o.size!==-1&&o.size!==-2&&(m=l.pos,o.size=m-d,l.seek(s),l.writeEBMLVarIntWidth(o.size,4),l.seek(m))}else if(typeof o.data=="string")l.writeEBMLVarInt(o.data.length),o.dataOffset=l.pos+h,l.writeString(o.data);else if(typeof o.data=="number")o.size||(o.size=l.measureUnsignedInt(o.data)),l.writeEBMLVarInt(o.size),o.dataOffset=l.pos+h,l.writeUnsignedIntBE(o.data,o.size);else if(o.data instanceof i)l.writeEBMLVarInt(8),o.dataOffset=l.pos+h,l.writeDoubleBE(o.data.value);else if(o.data instanceof a)l.writeEBMLVarInt(4),o.dataOffset=l.pos+h,l.writeFloatBE(o.data.value);else{if(!(o.data instanceof Uint8Array))throw new Error("Bad EBML datatype "+typeof o.data);l.writeEBMLVarInt(o.data.byteLength),o.dataOffset=l.pos+h,l.writeBytes(o.data)}}}let u=function(l,h){return function(o){let s,d,m=!1,y=0,p=0,b=null,E=null,x=null,g=[],B=0,S=0,k={quality:.95,transparent:!1,alphaQuality:void 0,fileWriter:null,fd:null,frameDuration:null,frameRate:null},C={Cues:{id:new Uint8Array([28,83,187,107]),positionEBML:null},SegmentInfo:{id:new Uint8Array([21,73,169,102]),positionEBML:null},Tracks:{id:new Uint8Array([22,84,174,107]),positionEBML:null}},F={id:17545,data:new i(0)},L=[],w=new h(o.fileWriter||o.fd);function $(f){return f-s.dataOffset}function V(){d=(function(){let A={id:21420,size:5,data:0},O={id:290298740,data:[]};for(let I in C){let T=C[I];T.positionEBML=Object.create(A),O.data.push({id:19899,data:[{id:21419,data:T.id},T.positionEBML]})}return O})();let f={id:357149030,data:[{id:2807729,data:1e6},{id:19840,data:"webm-writer-js"},{id:22337,data:"webm-writer-js"},F]},_=[{id:176,data:y},{id:186,data:p}];o.transparent&&_.push({id:21440,data:1});let M={id:374648427,data:[{id:174,data:[{id:215,data:1},{id:29637,data:1},{id:156,data:0},{id:2274716,data:"und"},{id:134,data:"V_VP8"},{id:2459272,data:"VP8"},{id:131,data:1},{id:224,data:_}]}]};s={id:408125543,size:-2,data:[d,f,M]};let P=new l(256);n(P,w.pos,[{id:440786851,data:[{id:17030,data:1},{id:17143,data:1},{id:17138,data:4},{id:17139,data:8},{id:17026,data:"webm"},{id:17031,data:2},{id:17029,data:2}]},s]),w.write(P.getAsDataArray()),C.SegmentInfo.positionEBML.data=$(f.offset),C.Tracks.positionEBML.data=$(M.offset),m=!0}function v(f){return f.alpha?(function(_){let M,P,A=new l(4);if(!(_.trackNumber>0&&_.trackNumber<127))throw new Error("TrackNumber must be > 0 and < 127");return A.writeEBMLVarInt(_.trackNumber),A.writeU16BE(_.timecode),A.writeByte(0),M={id:161,data:[A.getAsDataArray(),_.frame]},P={id:30113,data:[{id:166,data:[{id:238,data:1},{id:165,data:_.alpha}]}]},{id:160,data:[M,P]}})(f):(function(_){let M=new l(4);if(!(_.trackNumber>0&&_.trackNumber<127))throw new Error("TrackNumber must be > 0 and < 127");return M.writeEBMLVarInt(_.trackNumber),M.writeU16BE(_.timecode),M.writeByte(128),{id:163,data:[M.getAsDataArray(),_.frame]}})(f)}function D(){if(g.length===0)return;let f=0;for(let I=0;I<g.length;I++)f+=g[I].frame.length+(g[I].alpha?g[I].alpha.length:0);let _=new l(f+64*g.length),M=(function(I){return{id:524531317,data:[{id:231,data:Math.round(I.timecode)}]}})({timecode:Math.round(B)});for(let I=0;I<g.length;I++)M.data.push(v(g[I]));var P,A,O;n(_,w.pos,M),w.write(_.getAsDataArray()),P=1,A=Math.round(B),O=M.offset,L.push({id:187,data:[{id:179,data:A},{id:183,data:[{id:247,data:P},{id:241,data:$(O)}]}]}),g=[],B+=S,S=0}this.addFrame=function(f,_,M){m||(y=f.width||0,p=f.height||0,V());let P,A=r(t(f,o.quality)),O=null;P=M||(typeof _=="number"?_:o.frameDuration),o.transparent&&(_ instanceof HTMLCanvasElement||typeof _=="string"?O=_:A.hasAlpha&&(O=(function(I){b!==null&&b.width===I.width&&b.height===I.height||(b=document.createElement("canvas"),b.width=I.width,b.height=I.height,E=b.getContext("2d"),x=E.createImageData(b.width,b.height));let T=I.getContext("2d").getImageData(0,0,I.width,I.height).data,U=x.data,G=0,mr=I.width*I.height*4;for(let gt=3;gt<mr;gt+=4){let bt=T[gt];U[G++]=bt,U[G++]=bt,U[G++]=bt,U[G++]=255}return E.putImageData(x,0,0),b})(f))),(function(I){I.trackNumber=1,I.timecode=Math.round(S),g.push(I),S+=I.duration,S>=5e3&&D()})({frame:A.frame,duration:P,alpha:O?r(t(O,o.alphaQuality)).frame:null})},this.complete=function(){return m||V(),D(),(function(){let f={id:475249515,data:L},_=new l(16+32*L.length);n(_,w.pos,f),w.write(_.getAsDataArray()),C.Cues.positionEBML.data=$(f.offset)})(),(function(){let f=new l(d.size),_=w.pos;n(f,d.dataOffset,d.data),w.seek(d.dataOffset),w.write(f.getAsDataArray()),w.seek(_)})(),(function(){let f=new l(8),_=w.pos;f.writeDoubleBE(B),w.seek(F.dataOffset),w.write(f.getAsDataArray()),w.seek(_)})(),(function(){let f=new l(10),_=w.pos;f.writeUnsignedIntBE(s.id),f.writeEBMLVarIntWidth(w.pos-s.dataOffset,5),w.seek(s.offset),w.write(f.getAsDataArray()),w.seek(_)})(),w.complete("video/webm")},this.getWrittenSize=function(){return w.length},o=(function(f,_){let M={};return[f,_].forEach(function(P){for(let A in P)Object.prototype.hasOwnProperty.call(P,A)&&(M[A]=P[A])}),M})(k,o||{}),(function(){if(!o.frameDuration){if(!o.frameRate)throw new Error("Missing required frameDuration or frameRate setting");o.frameDuration=1e3/o.frameRate}o.quality=Math.max(Math.min(o.quality,.99999),0),o.alphaQuality===void 0?o.alphaQuality=o.quality:o.alphaQuality=Math.max(Math.min(o.alphaQuality,.99999),0)})()}};c.exports=u})()})(Lt)),Lt.exports}var Pt,Vt={exports:{}};function Be(){return Pt||(Pt=1,(function(c){(function(){let t=function(e){this.data=new Uint8Array(e),this.pos=0};t.prototype.seek=function(e){this.pos=e},t.prototype.writeBytes=function(e){for(let r=0;r<e.length;r++)this.data[this.pos++]=e[r]},t.prototype.writeByte=function(e){this.data[this.pos++]=e},t.prototype.writeU8=t.prototype.writeByte,t.prototype.writeU16BE=function(e){this.data[this.pos++]=e>>8,this.data[this.pos++]=e},t.prototype.writeDoubleBE=function(e){let r=new Uint8Array(new Float64Array([e]).buffer);for(let a=r.length-1;a>=0;a--)this.writeByte(r[a])},t.prototype.writeFloatBE=function(e){let r=new Uint8Array(new Float32Array([e]).buffer);for(let a=r.length-1;a>=0;a--)this.writeByte(r[a])},t.prototype.writeString=function(e){for(let r=0;r<e.length;r++)this.data[this.pos++]=e.charCodeAt(r)},t.prototype.writeEBMLVarIntWidth=function(e,r){switch(r){case 1:this.writeU8(128|e);break;case 2:this.writeU8(64|e>>8),this.writeU8(e);break;case 3:this.writeU8(32|e>>16),this.writeU8(e>>8),this.writeU8(e);break;case 4:this.writeU8(16|e>>24),this.writeU8(e>>16),this.writeU8(e>>8),this.writeU8(e);break;case 5:this.writeU8(8|e/4294967296&7),this.writeU8(e>>24),this.writeU8(e>>16),this.writeU8(e>>8),this.writeU8(e);break;default:throw new Error("Bad EBML VINT size "+r)}},t.prototype.measureEBMLVarInt=function(e){if(e<127)return 1;if(e<16383)return 2;if(e<2097151)return 3;if(e<268435455)return 4;if(e<34359738367)return 5;throw new Error("EBML VINT size not supported "+e)},t.prototype.writeEBMLVarInt=function(e){this.writeEBMLVarIntWidth(e,this.measureEBMLVarInt(e))},t.prototype.writeUnsignedIntBE=function(e,r){switch(r===void 0&&(r=this.measureUnsignedInt(e)),r){case 5:this.writeU8(Math.floor(e/4294967296));case 4:this.writeU8(e>>24);case 3:this.writeU8(e>>16);case 2:this.writeU8(e>>8);case 1:this.writeU8(e);break;default:throw new Error("Bad UINT size "+r)}},t.prototype.measureUnsignedInt=function(e){return e<256?1:e<65536?2:e<1<<24?3:e<4294967296?4:5},t.prototype.getAsDataArray=function(){if(this.pos<this.data.byteLength)return this.data.subarray(0,this.pos);if(this.pos==this.data.byteLength)return this.data;throw new Error("ArrayBufferDataStream's pos lies beyond end of buffer")},c.exports=t})()})(Vt)),Vt.exports}var Dt,At,Ot,Ut={exports:{}};function ke(){return Dt||(Dt=1,(function(c){(function(){let t=function(e){return function(r){let a=[],i=Promise.resolve(),n=null,u=null;function l(s){return new Promise(function(d,m){let y=new FileReader;y.addEventListener("loadend",function(){d(y.result)}),y.readAsArrayBuffer(s)})}function h(s){return new Promise(function(d,m){s instanceof Uint8Array?d(s):s instanceof ArrayBuffer||ArrayBuffer.isView(s)?d(new Uint8Array(s)):s instanceof Blob?d(l(s).then(function(y){return new Uint8Array(y)})):d(l(new Blob([s])).then(function(y){return new Uint8Array(y)}))})}function o(s){let d=s.byteLength||s.length||s.size;if(!Number.isInteger(d))throw new Error("Failed to determine size of element");return d}r&&r.constructor.name==="FileWriter"?n=r:e&&r&&(u=r),this.pos=0,this.length=0,this.seek=function(s){if(s<0)throw new Error("Offset may not be negative");if(isNaN(s))throw new Error("Offset may not be NaN");if(s>this.length)throw new Error("Seeking beyond the end of file is not allowed");this.pos=s},this.write=function(s){let d={offset:this.pos,data:s,length:o(s)},m=d.offset>=this.length;this.pos+=d.length,this.length=Math.max(this.length,this.pos),i=i.then(function(){if(u)return new Promise(function(y,p){h(d.data).then(function(b){let E=0,x=Buffer.from(b.buffer),g=function(B,S,k){E+=S,E>=k.length?y():e.write(u,k,E,k.length-E,d.offset+E,g)};e.write(u,x,0,x.length,d.offset,g)})});if(n)return new Promise(function(y,p){n.onwriteend=y,n.seek(d.offset),n.write(new Blob([d.data]))});if(!m)for(let y=0;y<a.length;y++){let p=a[y];if(!(d.offset+d.length<=p.offset||d.offset>=p.offset+p.length)){if(d.offset<p.offset||d.offset+d.length>p.offset+p.length)throw new Error("Overwrite crosses blob boundaries");return d.offset==p.offset&&d.length==p.length?void(p.data=d.data):h(p.data).then(function(b){return p.data=b,h(d.data)}).then(function(b){d.data=b,p.data.set(d.data,d.offset-p.offset)})}}a.push(d)})},this.complete=function(s){return i=u||n?i.then(function(){return null}):i.then(function(){let d=[];for(let m=0;m<a.length;m++)d.push(a[m].data);return new Blob(d,{type:s})}),i}}};c.exports=t})()})(Ut)),Ut.exports}function Ie(){return Ot?At:(Ot=1,At=Ee()(Be(),ke()(null)))}const Fe=Ce(Ie());class Me{async $record(t,e,r,a){const i=Math.max(1,Math.round(e.frameRate)),n=Math.max(1,Math.round(e.frameCount)),u=new Fe({quality:e.quality,alphaQuality:e.transparent?e.quality:void 0,transparent:e.transparent,frameRate:i}),l=this._createSnapshotSurface();return await new Promise((h,o)=>{let s,d="capturing",m=!1,y=0;const p=()=>{s&&(s(),s=void 0)},b=()=>{a?.({state:"recording",frameIndex:y,totalFrames:n})},E=g=>{if(m)return;m=!0,p();const B=g instanceof Error?g.message:"WEBM export failed";a?.({state:"error",message:B}),o(g instanceof Error?g:new Error(String(g)))},x=()=>{d!=="capturing"||m||(d="encoding",p(),u.complete().then(g=>{(B=>{m||(m=!0,a?.({state:"completed",frameIndex:Math.min(n,y),totalFrames:n}),h(B))})(g)}).catch(E))};s=r(()=>{(()=>{if(d==="capturing")if(y>=n)x();else try{const g=l(t);u.addFrame(g),y+=1,b(),y>=n&&x()}catch(g){E(g)}})()}),b()})}_createSnapshotSurface(){let t=null,e=null;return r=>{const a=Math.max(1,r.width),i=Math.max(1,r.height),n=((u,l)=>(t||(t=document.createElement("canvas")),t.width!==u||t.height!==l?(t.width=u,t.height=l,e=t.getContext("2d"),e&&(e.imageSmoothingEnabled=!1)):e||(e=t.getContext("2d"),e&&(e.imageSmoothingEnabled=!1)),e?t:null))(a,i);return n&&e?(e.clearRect(0,0,a,i),e.drawImage(r,0,0,a,i),n):r}}}class $e{_recorder;_textmodifier;_registerPostDrawHook;constructor(t,e){this._recorder=new Me,this._textmodifier=t,this._registerPostDrawHook=e}async $saveWEBM(t={}){const e=this._textmodifier.canvas,r=this._applyDefaultOptions(t);try{const a=await this._recorder.$record(e,r,this._registerPostDrawHook,t.onProgress);new X().$downloadFile(a,r.filename)}catch(a){throw t.onProgress?.({state:"error",message:a instanceof Error?a.message:"WEBM export failed"}),a}}_applyDefaultOptions(t){return{filename:t.filename,frameRate:Math.abs(Math.round(t.frameRate??60)),frameCount:Math.abs(Math.round(t.frameCount??300)),quality:Math.abs(Math.min(Math.max(t.quality??1,0),1)),transparent:!!t.transparent,debugLogging:!!t.debugLogging}}}const Se="textmode-export-overlay",z="textmode-export-overlay__stack",dt="textmode-export-overlay__stack--dense",Tt="textmode-export-overlay__stack--compact",Rt="textmode-export-overlay__section",Le="textmode-export-overlay__header",Pe="textmode-export-overlay__header-title-row",Ve="textmode-export-overlay__header-links",De="textmode-export-overlay__row",Nt="textmode-export-overlay__label",zt="textmode-export-overlay__field",Gt="textmode-export-overlay__field--compact",Wt="textmode-export-overlay__field--dense",qt="textmode-export-overlay__field--full",Ht="textmode-export-overlay__field--channel",jt="textmode-export-overlay__input",Ae="textmode-export-overlay__checkbox",Qt="textmode-export-overlay__muted",Oe="textmode-export-overlay__status",Ue="textmode-export-overlay__status--gif",Te="textmode-export-overlay__status--video",Re="textmode-export-overlay__status-title",Ne="textmode-export-overlay__status-value",ze="textmode-export-overlay__divider",Ge="textmode-export-overlay__title",We="textmode-export-overlay__button",ct="textmode-export-overlay__button--primary",ut="textmode-export-overlay__button--secondary",Xt="textmode-export-overlay__button--full",qe="textmode-export-overlay__support-link",He="textmode-export-overlay__support-icon",je="textmode-export-overlay__link-icon";class N{element;mounted=!1;destroyed=!1;mount(t){if(this.destroyed)throw new Error("Cannot mount a destroyed component");if(this.mounted)return;const e=this.render();t.appendChild(e),this.element=e,this.onMount(),this.mounted=!0}unmount(){this.mounted&&this.element&&(this._onUnmount(),this.element.remove(),this.element=void 0,this.mounted=!1)}destroy(){this.destroyed||(this.unmount(),this._onDestroy(),this.destroyed=!0)}update(t){this.mounted&&this.onUpdate(t)}onMount(){}_onUnmount(){}_onDestroy(){}onUpdate(t){}get root(){if(!this.element)throw new Error("Component is not mounted yet");return this.element}isMounted(){return this.mounted}}class Y extends N{static _iconNamespace="http://www.w3.org/2000/svg";render(){const t=document.createElement("div");t.classList.add(z,dt,Le);const e=document.createElement("div");e.classList.add(Pe);const r=document.createElement("strong");r.textContent="textmode.export.js",r.classList.add(Ge);const a=document.createElement("div");a.classList.add(Ve);const i=this._createLink("https://github.com/humanbydefinition/textmode.export.js","View repository on GitHub",je,[{d:"M0 0h24v24H0z",fill:"none",stroke:"none"},{d:"M9 19c-4.3 1.4 -4.3 -2.5 -6 -3m12 5v-3.5c0 -1 .1 -1.4 -.5 -2c2.8 -.3 5.5 -1.4 5.5 -6a4.6 4.6 0 0 0 -1.3 -3.2a4.2 4.2 0 0 0 -.1 -3.2s-1.1 -.3 -3.5 1.3a12.3 12.3 0 0 0 -6.2 0c-2.4 -1.6 -3.5 -1.3 -3.5 -1.3a4.2 4.2 0 0 0 -.1 3.2a4.6 4.6 0 0 0 -1.3 3.2c0 4.6 2.7 5.7 5.5 6c-.6 .6 -.6 1.2 -.5 2v3.5"}]),n=this._createLink("https://code.textmode.art/support.html","Support textmode.export.js",He,[{d:"M0 0h24v24H0z",fill:"none",stroke:"none"},{d:"M3 14c.83 .642 2.077 1.017 3.5 1c1.423 .017 2.67 -.358 3.5 -1c.83 -.642 2.077 -1.017 3.5 -1c1.423 -.017 2.67 .358 3.5 1"},{d:"M8 3a2.4 2.4 0 0 0 -1 2a2.4 2.4 0 0 0 1 2"},{d:"M12 3a2.4 2.4 0 0 0 -1 2a2.4 2.4 0 0 0 1 2"},{d:"M3 10h14v5a6 6 0 0 1 -6 6h-2a6 6 0 0 1 -6 -6v-5z"},{d:"M16.746 16.726a3 3 0 1 0 .252 -5.555"}]);a.appendChild(i),a.appendChild(n),e.appendChild(r),e.appendChild(a);const u=document.createElement("div");return u.classList.add(ze),t.appendChild(e),t.appendChild(u),t}_createLink(t,e,r,a){const i=document.createElement("a");return i.href=t,i.target="_blank",i.rel="noopener noreferrer",i.classList.add(qe),i.setAttribute("aria-label",e),i.appendChild(this._createIcon(r,a)),i}_createIcon(t,e){const r=document.createElementNS(Y._iconNamespace,"svg");r.setAttribute("xmlns",Y._iconNamespace),r.setAttribute("width","18"),r.setAttribute("height","18"),r.setAttribute("viewBox","0 0 24 24"),r.setAttribute("fill","none"),r.setAttribute("stroke","currentColor"),r.setAttribute("stroke-width","2"),r.setAttribute("stroke-linecap","round"),r.setAttribute("stroke-linejoin","round"),r.classList.add(t);for(const a of e){const i=document.createElementNS(Y._iconNamespace,"path");for(const[n,u]of Object.entries(a))i.setAttribute(n,u);r.appendChild(i)}return r}}class R extends N{props;constructor(t){super(),this.props=t}render(){const t=document.createElement("div");t.classList.add(zt),this.applyVariant(t,this.props.variant);const e=document.createElement("label");if(e.classList.add(Nt),e.textContent=this.props.label,this.props.labelFor&&(e.htmlFor=this.props.labelFor),t.appendChild(e),this.props.description){const r=document.createElement("span");r.classList.add(Qt),r.textContent=this.props.description,t.appendChild(r)}return t}attachControl(t){this.root.appendChild(t)}update(t){this.props=t,super.update(t)}onUpdate(t){const e=this.root;for(;e.firstChild;)e.removeChild(e.firstChild);this.props=t,e.classList.add(zt),this.applyVariant(e,t.variant);const r=document.createElement("label");if(r.classList.add(Nt),r.textContent=t.label,t.labelFor&&(r.htmlFor=t.labelFor),e.appendChild(r),t.description){const a=document.createElement("span");a.classList.add(Qt),a.textContent=t.description,e.appendChild(a)}}applyVariant(t,e){switch(t.classList.remove(Gt,Wt,qt,Ht),e){case"compact":t.classList.add(Gt);break;case"dense":t.classList.add(Wt);break;case"full":t.classList.add(qt);break;case"channel":t.classList.add(Ht)}}}class pt extends N{props;select;handleChange=()=>{this.props.defaultValue=this.select.value};constructor(t){super(),this.props=t}render(){return this.select=document.createElement("select"),this.select.classList.add(jt),this.props.id&&(this.select.id=this.props.id),this.populateOptions(),this.select.addEventListener("change",this.handleChange),this.select}get selectElement(){return this.select}get value(){return this.select.value}set value(t){this.select&&(this.select.value=t),this.props.defaultValue=t}_onUnmount(){this.select.removeEventListener("change",this.handleChange)}onUpdate(t){this.props=t,this.populateOptions(),t.defaultValue&&(this.select.value=t.defaultValue)}update(t){this.props={...this.props,...t},this.select&&(t.id&&(this.select.id=t.id),t.options&&this.populateOptions(),t.defaultValue!==void 0&&(this.select.value=t.defaultValue))}populateOptions(){if(this.select){this.select.innerHTML="";for(const t of this.props.options){const e=document.createElement("option");e.value=t.value,e.textContent=t.label,this.select.appendChild(e)}this.props.defaultValue&&(this.select.value=this.props.defaultValue)}}}class Yt extends N{props;button;constructor(t){super(),this.props=t}render(){return this.button=document.createElement("button"),this.button.type="button",this.button.textContent=this.props.label,this.button.classList.add(We),this.props.variant==="secondary"?this.button.classList.add(ut):this.button.classList.add(ct),this.props.fullWidth&&this.button.classList.add(Xt),this.button.disabled=!!this.props.disabled,this.button}get buttonElement(){return this.button}setLabel(t){this.props.label=t,this.button.textContent=t}setDisabled(t){this.props.disabled=t,this.button.disabled=t}onUpdate(t){this.props=t,this.button.textContent=t.label,this.button.disabled=!!t.disabled,t.variant==="secondary"?(this.button.classList.add(ut),this.button.classList.remove(ct)):(this.button.classList.add(ct),this.button.classList.remove(ut)),this.button.classList.toggle(Xt,!!t.fullWidth)}}class Qe{api;constructor(t){this.api=t}async $copy(t,e){switch(t){case"txt":{const r=this.api.toString(e);await navigator.clipboard.writeText(r);break}case"svg":{const r=this.api.toSVG(e);await navigator.clipboard.writeText(r);break}case"image":await this.api.copyCanvas(e);break;default:throw new Error(`Clipboard not supported for ${t}`)}}}class Xe{api;events;constructor(t,e){this.api=t,this.events=e}async $requestExport(t,e,r={}){this.events.$emit("export:request",{format:t});try{const a={onGIFProgress:r.onGIFProgress?i=>{r.onGIFProgress?.(i),this.events.$emit("export:progress",{format:t,progress:i})}:t==="gif"?i=>this.events.$emit("export:progress",{format:t,progress:i}):void 0,onVideoProgress:r.onVideoProgress?i=>{r.onVideoProgress?.(i),this.events.$emit("export:progress",{format:t,progress:i})}:t==="video"?i=>this.events.$emit("export:progress",{format:t,progress:i}):void 0};await this._execute(t,e,a),this.events.$emit("export:success",{format:t})}catch(a){throw this.events.$emit("export:error",{format:t,error:a}),a}}_execute(t,e,r){switch(t){case"txt":return Promise.resolve(this.api.saveStrings(e));case"image":return this.api.saveCanvas(e);case"svg":return Promise.resolve(this.api.saveSVG(e));case"gif":{const a={...e,onProgress:r.onGIFProgress};return this.api.saveGIF(a)}case"video":{const a={...e,onProgress:r.onVideoProgress};return this.api.saveWEBM(a)}}}}class Ye{modifier;overlay;animationFrameId=null;handleUpdate;bound=!1;constructor(t,e){this.modifier=t,this.overlay=e,this.handleUpdate=()=>this.scheduleUpdate()}scheduleUpdate(){this.animationFrameId!==null&&cancelAnimationFrame(this.animationFrameId),this.animationFrameId=requestAnimationFrame(()=>this.update())}bind(){this.bound||(window.addEventListener("resize",this.handleUpdate),window.addEventListener("scroll",this.handleUpdate,!0),this.bound=!0,this.handleUpdate())}update(){this.animationFrameId=null;const t=this.modifier.canvas.getBoundingClientRect();this.overlay.style.top=`${t.top+window.scrollY+8}px`,this.overlay.style.left=`${t.left+window.scrollX+8}px`}dispose(){this.animationFrameId!==null&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),this.bound&&(window.removeEventListener("resize",this.handleUpdate),window.removeEventListener("scroll",this.handleUpdate,!0),this.bound=!1)}}const J="textmode-export-number-input",Je=`${J}__field`,Ze=`${J}__controls`,Ke=`${J}__control`,Jt=`${J}__display`,at=`${Jt}--visible`,Zt=c=>{const t=document.createElement("button");return t.type="button",t.className=Ke,t.textContent=c>0?"▲":"▼",t};class q extends N{props;input;display;incrementButton;decrementButton;suppressClickAfterPointer=new WeakMap;holdTimeoutId;holdIntervalId;activePointerId;disabledObserver;constructor(t){super(),this.props=t}render(){const t=document.createElement("div");t.className=J,this.input=document.createElement("input"),this.input.type="number",this.input.value=this.props.defaultValue,Object.assign(this.input,this.props.attributes),this.input.className=Je,this.display=document.createElement("div"),this.display.className=Jt;const e=document.createElement("div");return e.className=Ze,this.incrementButton=Zt(1),this.decrementButton=Zt(-1),e.appendChild(this.incrementButton),e.appendChild(this.decrementButton),t.appendChild(this.input),t.appendChild(this.display),t.appendChild(e),this.bindStepControls(),this.bindHoldBehavior(),this.bindInputListeners(),this.observeDisabledState(t),this.updateDisplay(),t}get inputElement(){return this.input}get value(){return this.input.value}set value(t){this.input.value=t,this.updateDisplay()}refresh(){this.updateDisplay()}_onDestroy(){this.clearHoldTimers(),this.disabledObserver?.disconnect()}bindStepControls(){const t=i=>()=>{if(this.input.disabled)return;const n=this.input.value,u=this.input.getAttribute("step");if(u&&u!=="any")i>0?this.input.stepUp():this.input.stepDown();else{const h=i>0?1:-1,o=Number.parseFloat(this.input.value||"0"),s=Number.isFinite(o)?o+h:h;this.input.value=String(s)}var l;this.input.value!==n&&((l=this.input).dispatchEvent(new Event("input",{bubbles:!0})),l.dispatchEvent(new Event("change",{bubbles:!0}))),this.updateDisplay(),this.input.focus({preventScroll:!0})},e=t(1),r=t(-1),a=(i,n)=>u=>{if(this.suppressClickAfterPointer.get(i))return this.suppressClickAfterPointer.set(i,!1),void u.preventDefault();n()};this.incrementButton.addEventListener("click",a(this.incrementButton,e)),this.decrementButton.addEventListener("click",a(this.decrementButton,r))}bindHoldBehavior(){const t=(e,r)=>{const a=r>0?()=>this.incrementButton.click():()=>this.decrementButton.click();e.addEventListener("pointerdown",u=>{if(u.button===0){u.preventDefault(),this.suppressClickAfterPointer.set(e,!0),this.activePointerId=u.pointerId;try{e.setPointerCapture(u.pointerId)}catch{}a(),this.holdTimeoutId=window.setTimeout(()=>{this.holdIntervalId=window.setInterval(a,80)},380)}});const i=()=>{if(this.activePointerId!==void 0){try{e.releasePointerCapture(this.activePointerId)}catch{}this.activePointerId=void 0}},n=()=>{this.clearHoldTimers(),i()};e.addEventListener("pointerup",n),e.addEventListener("pointerleave",n),e.addEventListener("pointercancel",n)};t(this.incrementButton,1),t(this.decrementButton,-1)}bindInputListeners(){const t=()=>{this.props.defaultValue=this.input.value,this.updateDisplay()};this.input.addEventListener("input",t),this.input.addEventListener("change",t)}observeDisabledState(t){const e=()=>{const r=this.input.disabled;this.incrementButton.disabled=r,this.decrementButton.disabled=r,t.classList.toggle("is-disabled",r),r?(this.display.classList.remove(at),this.input.style.removeProperty("color"),this.input.style.removeProperty("caretColor")):this.updateDisplay()};typeof MutationObserver<"u"&&(this.disabledObserver=new MutationObserver(e),this.disabledObserver.observe(this.input,{attributes:!0,attributeFilter:["disabled"]})),e()}updateDisplay(){const t=this.props.formatDisplay;if(!t)return this.display.textContent="",this.display.classList.remove(at),this.input.style.removeProperty("color"),void this.input.style.removeProperty("caretColor");const e=this.input.value,r=Number.parseFloat(e),a=t(Number.isFinite(r)?r:Number.NaN,e,this.input);a?(this.display.textContent=a,this.display.classList.add(at),this.input.style.color="transparent",this.input.style.caretColor="#f8fafc"):(this.display.textContent="",this.display.classList.remove(at),this.input.style.removeProperty("color"),this.input.style.removeProperty("caretColor"))}clearHoldTimers(){this.holdTimeoutId!==void 0&&(window.clearTimeout(this.holdTimeoutId),this.holdTimeoutId=void 0),this.holdIntervalId!==void 0&&(window.clearInterval(this.holdIntervalId),this.holdIntervalId=void 0)}}class Z extends N{variant;additionalClasses;constructor(t="stack",e=[]){super(),this.variant=t,this.additionalClasses=e}render(){const t=document.createElement("div"),e=[this.variant==="stack"?z:void 0,this.variant==="stackDense"?dt:void 0,this.variant==="stackCompact"?Tt:void 0,this.variant==="row"?De:void 0,this.variant==="section"?Rt:void 0,...this.additionalClasses].filter(Boolean);return t.classList.add(...e),t}}const Kt={neutral:"textmode-export-overlay__status-value--neutral",active:"textmode-export-overlay__status-value--active",alert:"textmode-export-overlay__status-value--alert"};class te extends N{props;container;messageElement;constructor(t){super(),this.props=t}render(){this.container=document.createElement("div"),this.container.classList.add(Oe),this.props.context==="gif"?this.container.classList.add(Ue):this.props.context==="video"&&this.container.classList.add(Te);const t=document.createElement("span");return t.classList.add(Re),t.textContent=this.props.title,this.messageElement=document.createElement("span"),this.messageElement.classList.add(Ne),this.messageElement.textContent=this.props.message,this.applyVariant(this.props.variant??"neutral"),this.container.appendChild(t),this.container.appendChild(this.messageElement),this.container}setMessage(t,e="neutral"){this.messageElement.textContent=t,this.applyVariant(e)}onUpdate(t){this.props=t,this.setMessage(t.message,t.variant??"neutral")}applyVariant(t){this.messageElement.classList.remove(...Object.values(Kt)),this.messageElement.classList.add(Kt[t])}}class K extends N{_config;_managedComponents=new Set;constructor(t){super(),this._config=t}_manageComponent(t){return this._managedComponents.add(t),t}_onUnmount(){for(const t of this._managedComponents)t.unmount()}_onDestroy(){for(const t of this._managedComponents)t.destroy();this._managedComponents.clear()}}const ee=300,re=60,ae=1,tr=0;class ht extends K{frameCountInput=this._manageComponent(new q({defaultValue:String(ee),attributes:{min:"1",max:"600",step:"1"}}));frameRateInput=this._manageComponent(new q({defaultValue:String(re),attributes:{min:"1",max:"60",step:"1"}}));scaleInput=this._manageComponent(new q({defaultValue:String(ae),attributes:{min:"0.1",max:"8",step:"0.1"}}));repeatInput=this._manageComponent(new q({defaultValue:"0",attributes:{min:"0",max:"50",step:"1"},formatDisplay:(t,e)=>Number.isFinite(t)?t===0?"∞":null:e.trim()===""?null:e}));status=this._manageComponent(new te({title:"status",message:"ready to record",variant:"neutral",context:"gif"}));recordingState="idle";constructor(t){super(t)}render(){const t=document.createElement("div");t.classList.add(z);const e=new Z("row");e.mount(t);const r=new R({label:"number of frames",labelFor:"textmode-export-gif-frame-count",variant:"dense"});r.mount(e.root),this.frameCountInput.mount(r.root),this.frameCountInput.inputElement.id="textmode-export-gif-frame-count";const a=new R({label:"frame rate (fps)",labelFor:"textmode-export-gif-frame-rate",variant:"dense"});a.mount(e.root),this.frameRateInput.mount(a.root),this.frameRateInput.inputElement.id="textmode-export-gif-frame-rate";const i=new Z("row");i.mount(t);const n=new R({label:"scale",labelFor:"textmode-export-gif-scale",variant:"dense"});n.mount(i.root),this.scaleInput.mount(n.root),this.scaleInput.inputElement.id="textmode-export-gif-scale";const u=new R({label:"loop count",labelFor:"textmode-export-gif-repeat",variant:"dense"});return u.mount(i.root),this.repeatInput.mount(u.root),this.repeatInput.inputElement.id="textmode-export-gif-repeat",this.status.mount(t),t}getOptions(){const t=this._config.defaultOptions??{};return{frameCount:this.safeParseInt(this.frameCountInput.value,t.frameCount??300),frameRate:this.safeParseInt(this.frameRateInput.value,t.frameRate??60),scale:this.safeParseFloat(this.scaleInput.value,t.scale??1),repeat:this.safeParseInt(this.repeatInput.value,t.repeat??0)}}reset(){this.recordingState="idle",this.applyDefaults(),this.setRecordingState("idle")}validate(){const t=Number.parseInt(this.frameCountInput.value,10),e=Number.parseInt(this.frameRateInput.value,10),r=Number.parseFloat(this.scaleInput.value);return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0&&Number.isFinite(r)&&r>0}isRecording(){return this.recordingState==="recording"}setRecordingState(t,e){this.recordingState=t;const r=t==="recording";switch(this.frameCountInput.inputElement.disabled=r,this.frameRateInput.inputElement.disabled=r,this.scaleInput.inputElement.disabled=r,this.repeatInput.inputElement.disabled=r,t){case"recording":if(e?.totalFrames){const a=e.frameIndex??0;this.status.setMessage(`recording ${a}/${e.totalFrames}`,"active")}else this.status.setMessage("recording…","active");break;case"completed":this.status.setMessage("GIF saved successfully","active");break;case"error":this.status.setMessage(e?.message??"failed to export GIF","alert");break;default:this.status.setMessage("ready to record","neutral")}}handleProgress(t){t.state==="recording"&&t.totalFrames?this.status.setMessage(`recording ${t.frameIndex??0}/${t.totalFrames}`,"active"):t.state==="completed"?this.status.setMessage("GIF saved successfully","active"):t.state==="error"&&this.status.setMessage(t.message??"failed to export GIF","alert")}applyDefaults(){const t=this._config.defaultOptions??{},e=t.frameCount??ee,r=t.frameRate??re,a=t.scale??ae,i=t.repeat??tr;this.frameCountInput.value=String(e),this.frameRateInput.value=String(r),this.scaleInput.value=String(a),this.repeatInput.value=String(i),this.frameCountInput.refresh(),this.frameRateInput.refresh(),this.scaleInput.refresh(),this.repeatInput.refresh()}safeParseInt(t,e){const r=Number.parseInt(t,10);return Number.isFinite(r)?r:e}safeParseFloat(t,e){const r=Number.parseFloat(t);return Number.isFinite(r)?r:e}}const it="textmode-export-range-input",er=`${it}__field`,rr=`${it}__tooltip`,mt=`${it}__tooltip--visible`,ot=(c,t)=>{if(typeof c!="string"||c.length===0)return t;const e=Number.parseFloat(c);return Number.isFinite(e)?e:t};class ar extends N{props;input;tooltip;hoverActive=!1;focusActive=!1;pointerActive=!1;suppressFocusFromPointer=!1;activePointerId;disabledObserver;resizeObserver;constructor(t){super(),this.props=t}render(){const t=document.createElement("div");return t.className=it,this.input=document.createElement("input"),this.input.type="range",this.input.value=this.props.defaultValue,Object.assign(this.input,this.props.attributes),this.input.className=er,this.tooltip=document.createElement("div"),this.tooltip.className=rr,t.appendChild(this.input),t.appendChild(this.tooltip),this.bindEvents(t),this.updateTooltip(),this.syncDisabledState(t),t}get inputElement(){return this.input}get value(){return this.input.value}set value(t){this.input.value=t,this.updateTooltip()}_onDestroy(){this.disabledObserver?.disconnect(),this.resizeObserver?.disconnect()}bindEvents(t){this.input.addEventListener("pointerenter",()=>{this.hoverActive=!0,this.refreshTooltipVisibility()}),this.input.addEventListener("pointerleave",()=>{this.hoverActive=!1,this.refreshTooltipVisibility()}),this.input.addEventListener("focus",()=>{let r=!1;try{r=this.input.matches(":focus-visible")}catch{r=!this.suppressFocusFromPointer}this.suppressFocusFromPointer||!r||this.input.disabled?this.focusActive=!1:this.focusActive=!0,this.suppressFocusFromPointer=!1,this.refreshTooltipVisibility()}),this.input.addEventListener("blur",()=>{this.focusActive=!1,this.refreshTooltipVisibility()}),this.input.addEventListener("pointerdown",r=>{this.pointerActive=!0,this.suppressFocusFromPointer=!0,this.hoverActive=!0,this.refreshTooltipVisibility();try{this.input.setPointerCapture(r.pointerId),this.activePointerId=r.pointerId}catch{this.activePointerId=void 0}});const e=()=>{this.pointerActive=!1,this.suppressFocusFromPointer=!1,this.hoverActive=this.input.matches(":hover"),this.releasePointerCapture(),this.refreshTooltipVisibility()};this.input.addEventListener("pointerup",e),this.input.addEventListener("pointercancel",e),this.input.addEventListener("lostpointercapture",e),this.input.addEventListener("input",()=>{(this.hoverActive||this.focusActive||this.pointerActive)&&this.updateTooltip(),this.props.defaultValue=this.input.value}),this.input.addEventListener("change",()=>{this.pointerActive||this.updateTooltip(),this.props.defaultValue=this.input.value}),typeof ResizeObserver<"u"&&(this.resizeObserver=new ResizeObserver(()=>{this.tooltip.classList.contains(mt)&&this.updateTooltipPosition()}),this.resizeObserver.observe(t))}refreshTooltipVisibility(){const t=(this.hoverActive||this.focusActive||this.pointerActive)&&!this.input.disabled;t&&this.updateTooltip(),this.tooltip.classList.toggle(mt,t)}syncDisabledState(t){const e=()=>{const r=this.input.disabled;t.classList.toggle("is-disabled",r),r&&(this.hoverActive=!1,this.focusActive=!1,this.pointerActive=!1,this.suppressFocusFromPointer=!1,this.releasePointerCapture(),this.tooltip.classList.remove(mt))};typeof MutationObserver<"u"&&(this.disabledObserver=new MutationObserver(e),this.disabledObserver.observe(this.input,{attributes:!0,attributeFilter:["disabled"]})),e()}releasePointerCapture(){if(this.activePointerId!==void 0){try{this.input.releasePointerCapture(this.activePointerId)}catch{}this.activePointerId=void 0}}updateTooltip(){this.updateTooltipContent(),this.updateTooltipPosition()}updateTooltipContent(){const t=this.props.formatValue??(r=>`${r}`),e=this.getCurrentValue();this.tooltip.textContent=t(e,this.input)}updateTooltipPosition(){const t=this.getMin(),e=this.getMax(),r=((n,u,l)=>Math.min(l,Math.max(u,n)))(this.getCurrentValue(),t,e),a=e-t,i=a===0?0:(r-t)/a;this.tooltip.style.left=100*i+"%"}getMin(){return ot(this.input.min,0)}getMax(){return ot(this.input.max,100)}getCurrentValue(){return ot(this.input.value,ot(this.props.defaultValue,0))}}function ir(c){return`${(function(e){if(!Number.isFinite(e))return"default quality";const r=Math.max(0,Math.min(1,e));return r>=.995?"near-lossless":r>=.98?"maximum detail":r>=.88?"ultra quality":r>=.7?"high quality":r>=.5?"balanced":r>=.25?"compact":r>=.1?"lightweight":"draft"})(c)} (quality ≈ ${c.toFixed(3)})`}class ft extends K{frameRateInput=this._manageComponent(new q({defaultValue:String(60),attributes:{min:String(1),max:String(60),step:"1"},formatDisplay:t=>Number.isFinite(t)?`${t} fps`:null}));frameCountInput=this._manageComponent(new q({defaultValue:String(480),attributes:{min:String(1),max:String(3600),step:"1"}}));qualityInput=this._manageComponent(new ar({defaultValue:String(.7),attributes:{min:String(0),max:String(1),step:"0.001"},formatValue:t=>ir(t)}));status=this._manageComponent(new te({title:"status",message:"ready to record",variant:"neutral",context:"video"}));recordingState="idle";constructor(t){super(t)}render(){const t=document.createElement("div");t.classList.add(z);const e=new Z("row");e.mount(t);const r=new R({label:"number of frames",labelFor:"textmode-export-video-frame-count",variant:"compact"});r.mount(e.root),this.frameCountInput.mount(r.root),this.frameCountInput.inputElement.id="textmode-export-video-frame-count";const a=new R({label:"frame rate (fps)",labelFor:"textmode-export-video-frame-rate",variant:"compact"});a.mount(e.root),this.frameRateInput.mount(a.root),this.frameRateInput.inputElement.id="textmode-export-video-frame-rate";const i=new R({label:"quality",labelFor:"textmode-export-video-quality",variant:"full"});return i.mount(t),this.qualityInput.mount(i.root),this.qualityInput.inputElement.id="textmode-export-video-quality",this.status.mount(t),t}getOptions(){const t=this._config.defaultOptions??{},e=Number.parseInt(this.frameCountInput.value,10),r=Number.parseFloat(this.frameRateInput.value),a=Number.parseFloat(this.qualityInput.value);return{frameCount:Number.isFinite(e)?e:t.frameCount??480,frameRate:Number.isFinite(r)?r:t.frameRate??60,quality:Number.isFinite(a)?a:t.quality??.7}}reset(){this.recordingState="idle",this.applyDefaults(),this.status.setMessage("ready to record","neutral")}validate(){const t=Number.parseInt(this.frameCountInput.value,10),e=Number.parseFloat(this.frameRateInput.value);return Number.isFinite(t)&&t>=1&&Number.isFinite(e)&&e>=1}isRecording(){return this.recordingState==="recording"}setRecordingState(t,e){this.recordingState=t;const r=t==="recording";this.frameCountInput.inputElement.disabled=r,this.frameRateInput.inputElement.disabled=r,this.qualityInput.inputElement.disabled=r,this.syncStatus(t,e)}handleProgress(t){this.syncStatus(t.state,t)}syncStatus(t,e){switch(t){case"recording":{const r=e?.frameIndex??0,a=e?.totalFrames??this.resolvePlannedFrameCount();if(a){const i=Math.min(Math.max(0,Math.round(r)),a);this.status.setMessage(`recording ${i}/${a} frames`,"active")}else this.status.setMessage(`recording ${Math.max(0,Math.round(r))} frames`,"active");break}case"completed":this.status.setMessage("saved to disk","active");break;case"error":this.status.setMessage(e?.message?`error: ${e.message}`:"recording failed","alert");break;default:this.status.setMessage("ready to record","neutral")}}resolvePlannedFrameCount(){const t=Number.parseInt(this.frameCountInput.value,10);return Number.isFinite(t)&&t>0?Math.round(t):void 0}applyDefaults(){const t=this._config.defaultOptions??{},e=t.frameCount??480,r=t.frameRate??60,a=t.quality??.7;this.frameCountInput.value=String(e),this.frameRateInput.value=String(r),this.qualityInput.value=String(a),this.frameCountInput.refresh(),this.frameRateInput.refresh()}}class or{_textmodifier;_state;_events;_exportService;_clipboardService;_definitions;_formats=new Map;_eventUnsubscribers=[];_shadowHost;_shadowRoot;_overlayElement;_optionsContainer;_copyButtonContainer;_positionService;_header=new Y;_formatField=new R({label:"export format",labelFor:"textmode-export-format",variant:"full"});_formatSelect=new pt({id:"textmode-export-format",options:[]});_exportButton=new Yt({label:"download file",fullWidth:!0,variant:"primary"});_copyButton=new Yt({label:"copy to clipboard",fullWidth:!0,variant:"primary"});_currentFormat;_currentBlade;_handleFormatSelectChange=()=>{this._handleFormatChange(this._formatSelect.value)};_handleExportClickSafe=()=>{this._handleExportClick().catch(t=>{console.error("[textmode-export] Export failed",t)})};_handleCopyClickSafe=()=>{this._handleCopyClick().catch(t=>{console.error("[textmode-export] Copy failed",t)})};constructor(t,e,r,a,i){this._textmodifier=t,this._state=r,this._events=a,this._exportService=new Xe(e,a),this._clipboardService=new Qe(e),this._definitions=i,this._currentFormat=r.snapshot.format,this._initializeFormatMap(),this._registerEventHandlers()}$mount(){this._createOverlay(),this._renderStaticContent(),this._positionService=new Ye(this._textmodifier,this._shadowHost),this._positionService.bind(),this._switchFormat(this._currentFormat)}$dispose(){this._formatSelect.isMounted()&&this._formatSelect.selectElement.removeEventListener("change",this._handleFormatSelectChange),this._exportButton.isMounted()&&this._exportButton.buttonElement.removeEventListener("click",this._handleExportClickSafe),this._copyButton.isMounted()&&this._copyButton.buttonElement.removeEventListener("click",this._handleCopyClickSafe);for(const t of this._eventUnsubscribers)t();this._eventUnsubscribers.length=0,this._events.$clear();for(const t of this._formats.values())t.blade.destroy();this._formats.clear(),this._currentBlade=void 0,this._shadowHost?.isConnected&&this._shadowHost.remove(),this._positionService?.dispose()}_initializeFormatMap(){for(const t of this._definitions){const e=t.createBlade();this._formats.set(t.format,{definition:t,blade:e,initialized:!1})}}_createOverlay(){this._shadowHost=document.createElement("div"),this._shadowHost.dataset.plugin="textmode-export-overlay-host",this._shadowHost.style.cssText="position: absolute; top: 0; left: 0; pointer-events: none; z-index: 2147483647;",this._shadowRoot=this._shadowHost.attachShadow({mode:"open"});const t=document.createElement("style");t.textContent="@layer textmode-export-overlay{.textmode-export-overlay{--overlay-bg: rgba(20, 20, 20, .8);--overlay-surface: rgba(40, 40, 40, .9);--overlay-border: rgba(255, 255, 255, .14);--overlay-border-strong: rgba(255, 255, 255, .2);--overlay-border-focus: rgba(160, 160, 160, .6);--overlay-focus-shadow: 0 0 0 1px rgba(140, 140, 140, .28);--overlay-text: #ffffff;--overlay-muted: rgba(200, 200, 200, .74);--overlay-radius: .75rem;--overlay-stack-gap: .55rem;position:absolute;top:0;left:0;display:flex;flex-direction:column;gap:var(--overlay-stack-gap);min-width:236px;max-width:236px;padding:.65rem .8rem;background:var(--overlay-bg);color:var(--overlay-text);border-radius:var(--overlay-radius);border:1px solid var(--overlay-border);box-shadow:0 12px 28px #0000004d;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-size:.82rem;line-height:1.35;pointer-events:auto;z-index:2147483647}.textmode-export-overlay *{box-sizing:border-box}.textmode-export-overlay__header{display:flex;flex-direction:column;gap:.4rem}.textmode-export-overlay__header-title-row{display:flex;align-items:center;justify-content:space-between;gap:.4rem}.textmode-export-overlay__header-links{display:inline-flex;align-items:center;gap:.3rem}.textmode-export-overlay__support-link{display:inline-flex;align-items:center;justify-content:center;padding:.2rem;border-radius:.45rem;border:1px solid transparent;color:#d7d7d7d1;background:transparent;text-decoration:none;line-height:0;transition:background .18s ease,color .18s ease,transform .18s ease,border-color .18s ease}.textmode-export-overlay__support-link:hover{color:#fff;background:#5a5a5a4d;border-color:#c8c8c824}.textmode-export-overlay__support-link:focus-visible{outline:none;border-color:var(--overlay-border-focus);box-shadow:var(--overlay-focus-shadow)}.textmode-export-overlay__support-icon,.textmode-export-overlay__link-icon{display:block;width:1rem;height:1rem}.textmode-export-overlay__stack{display:flex;flex-direction:column;gap:var(--overlay-stack-gap)}.textmode-export-overlay__stack--dense{gap:.3rem}.textmode-export-overlay__stack--compact{gap:.45rem}.textmode-export-overlay__section{display:flex;flex-direction:column;gap:.4rem}.textmode-export-overlay__title{font-size:.92rem;font-weight:600}.textmode-export-overlay__divider{width:100%;height:1px;background:#ffffff29;margin-top:.25rem}.textmode-export-overlay__label{font-weight:500;opacity:.9}.textmode-export-overlay__checkbox{display:flex;align-items:center;gap:.5rem}.textmode-export-overlay__checkbox input[type=checkbox]{width:1rem;height:1rem;accent-color:rgba(100,100,100,.9)}.textmode-export-overlay__row{display:flex;gap:.6rem;flex-wrap:wrap;align-items:flex-start;width:100%}.textmode-export-overlay__field{display:flex;flex-direction:column;gap:.3rem;flex:1 1 120px;min-width:120px}.textmode-export-overlay__field--compact{flex:1 1 100px;min-width:100px}.textmode-export-overlay__field--dense{flex:1 1 90px;min-width:90px}.textmode-export-overlay__field--channel{flex:1 1 0;min-width:0}.textmode-export-overlay__field--full{width:100%;flex:1 1 100%}.textmode-export-overlay__input,.textmode-export-overlay select.textmode-export-overlay__input,.textmode-export-overlay input.textmode-export-overlay__input{width:100%;padding:.35rem .5rem;border-radius:.4rem;border:1px solid var(--overlay-border-strong);background:var(--overlay-surface);color:var(--overlay-text);transition:border-color .18s ease,box-shadow .18s ease,background .18s ease}.textmode-export-overlay__input:focus{outline:none;border-color:var(--overlay-border-focus);box-shadow:var(--overlay-focus-shadow);background:#2d2f42eb}.textmode-export-overlay__input::placeholder{color:var(--overlay-muted);opacity:.7}.textmode-export-overlay__muted{font-size:.75rem;opacity:.7;display:block}.textmode-export-overlay__button{display:inline-flex;align-items:center;justify-content:center;gap:.35rem;border-radius:.45rem;border:none;font-weight:600;padding:.45rem .7rem;cursor:pointer;transition:background .2s ease,transform .2s ease,box-shadow .2s ease}.textmode-export-overlay__button--primary{background:#505050;color:#fff}.textmode-export-overlay__button--secondary{background:#606060;color:#fff}.textmode-export-overlay__button--full{width:100%}.textmode-export-overlay__button:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 7px 18px #00000073}.textmode-export-overlay__button--primary:hover:not(:disabled){background:#404040}.textmode-export-overlay__button--secondary:hover:not(:disabled){background:#4a4a4a}.textmode-export-overlay__button:disabled{cursor:default;opacity:.55;transform:none;box-shadow:none}.textmode-export-overlay__status{display:flex;flex-direction:column;gap:.25rem;padding:.45rem .55rem;border-radius:.45rem;border:1px solid rgba(110,110,110,.22);background:#4646462e}.textmode-export-overlay__status--gif{background:#5050501f;border-color:#78787840}.textmode-export-overlay__status--video{background:#4646461f;border-color:#6e6e6e40}.textmode-export-overlay__status-title{font-weight:600;font-size:.75rem;opacity:.85;text-transform:uppercase;letter-spacing:.04em}.textmode-export-overlay__status-value{font-size:.82rem;color:#dedede;transition:color .18s ease}.textmode-export-overlay__status-value--neutral{color:#cfcfcf}.textmode-export-overlay__status-value--active{color:#f5f5f5}.textmode-export-overlay__status-value--alert{color:#b8b8b8}.textmode-export-number-input,.textmode-export-overlay .textmode-export-number-input{display:flex;align-items:stretch;width:100%;background:var(--overlay-surface);border:1px solid var(--overlay-border-strong);border-radius:.4rem;overflow:hidden;transition:border-color .18s ease,box-shadow .18s ease,background .18s ease;position:relative}.textmode-export-number-input:focus-within{border-color:var(--overlay-border-focus);box-shadow:var(--overlay-focus-shadow)}.textmode-export-number-input.is-disabled{opacity:.55}.textmode-export-number-input__field{flex:1 1 auto;min-width:0;border:none;background:transparent;color:var(--overlay-text);font:inherit;padding:.35rem .5rem;appearance:textfield}.textmode-export-number-input__field::-webkit-outer-spin-button,.textmode-export-number-input__field::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.textmode-export-number-input__field:focus{outline:none}.textmode-export-number-input__controls{display:flex;flex-direction:column;border-left:1px solid rgba(255,255,255,.12);min-width:1.6rem}.textmode-export-number-input__control{display:flex;align-items:center;justify-content:center;width:100%;flex:1;border:none;background:#32323299;color:#d0d0d0;font-size:.68rem;line-height:1;cursor:pointer;transition:background .15s ease,color .15s ease;padding:0}.textmode-export-number-input__control:hover:not(:disabled){background:#5a5a5ad9;color:#fff}.textmode-export-number-input__control:disabled{cursor:default;opacity:.4;background:#28282880;color:#c8c8c866}.textmode-export-number-input:focus-within .textmode-export-number-input__control{background:#3c3c3cbf;color:#e8e8e8}.textmode-export-number-input__display{position:absolute;inset:0;display:flex;align-items:center;padding:.4rem .55rem;pointer-events:none;color:#f8fafc;opacity:0;transition:opacity .14s ease}.textmode-export-number-input__display--visible{opacity:1}.textmode-export-range-input{position:relative;width:100%}.textmode-export-range-input.is-disabled{opacity:.55}.textmode-export-range-input__field{width:100%;height:1.4rem;padding:0;margin:0;background:transparent;cursor:pointer;appearance:none;-webkit-appearance:none}.textmode-export-range-input__field::-webkit-slider-thumb{width:12px;height:12px;margin-top:-3.5px;-webkit-appearance:none;border-radius:50%;background:#a0a0a0;border:2px solid #303030;box-shadow:0 0 0 2px #00000059}.textmode-export-range-input__field::-webkit-slider-runnable-track{height:5px;border-radius:999px;background:linear-gradient(90deg,#8c8c8cd9,#646464a6)}.textmode-export-range-input__field::-moz-range-thumb{width:12px;height:12px;border-radius:50%;background:#a0a0a0;border:2px solid #303030;margin-top:-3.5px}.textmode-export-range-input__field::-moz-range-track{height:5px;border-radius:999px;background:linear-gradient(90deg,#8c8c8cd9,#646464a6)}.textmode-export-range-input__tooltip{position:absolute;top:-1.5rem;left:0;transform:translate(-50%);padding:.2rem .35rem;border-radius:.35rem;background:#1e1e1ee0;color:#f8fafc;font-size:.68rem;line-height:1;white-space:nowrap;pointer-events:none;opacity:0;transition:opacity .15s ease}.textmode-export-range-input__tooltip--visible{opacity:1}}",this._shadowRoot.appendChild(t),this._overlayElement=document.createElement("div"),this._overlayElement.dataset.plugin="textmode-export-overlay",this._overlayElement.classList.add(Se,z),this._shadowRoot.appendChild(this._overlayElement),document.body.appendChild(this._shadowHost)}_renderStaticContent(){this._header.mount(this._overlayElement);const t=document.createElement("div");t.classList.add(Rt),this._overlayElement.appendChild(t),this._formatField.mount(t),this._prepareFormatOptions(),this._formatSelect.mount(this._formatField.root),this._formatSelect.selectElement.addEventListener("change",this._handleFormatSelectChange),this._optionsContainer=document.createElement("div"),this._optionsContainer.classList.add(z,Tt),this._overlayElement.appendChild(this._optionsContainer),this._exportButton.mount(this._overlayElement),this._exportButton.buttonElement.addEventListener("click",this._handleExportClickSafe),this._copyButtonContainer=document.createElement("div"),this._copyButtonContainer.classList.add(z,dt),this._overlayElement.appendChild(this._copyButtonContainer),this._copyButton.mount(this._copyButtonContainer),this._copyButton.buttonElement.dataset.defaultLabel="copy to clipboard",this._copyButton.buttonElement.addEventListener("click",this._handleCopyClickSafe)}_prepareFormatOptions(){const t=this._definitions.map(e=>({value:e.format,label:e.label}));this._formatSelect.update({options:t,defaultValue:this._currentFormat})}_registerEventHandlers(){this._eventUnsubscribers.push(this._events.$on("export:request",({format:t})=>{t===this._currentFormat&&(this._state.$set({isBusy:!0,error:void 0}),this._updateExportButton())}),this._events.$on("export:success",({format:t})=>{if(t===this._currentFormat){const e={isBusy:!1};t==="gif"&&(e.gifProgress=void 0),t==="video"&&(e.videoProgress=void 0),this._state.$set(e),this._updateExportButton()}}),this._events.$on("export:error",({format:t,error:e})=>{t===this._currentFormat&&(this._state.$set({isBusy:!1,error:e}),this._updateExportButton())}),this._events.$on("export:progress",({format:t,progress:e})=>{if(e){if(t==="gif"&&this._currentBlade?.blade instanceof ht){const r=e;this._state.$set({gifProgress:r}),this._currentBlade.blade.handleProgress(r)}else if(t==="video"&&this._currentBlade?.blade instanceof ft){const r=e;this._state.$set({videoProgress:r}),this._currentBlade.blade.handleProgress(r)}this._updateExportButton()}}))}_handleFormatChange(t){this._currentFormat=t,this._state.$set({format:t}),this._switchFormat(t),this._events.$emit("format:change",{format:t})}_switchFormat(t){const e=this._formats.get(t);if(!e)throw new Error(`Unknown export format: ${t}`);this._currentBlade&&this._currentBlade.blade.unmount(),this._optionsContainer.innerHTML="",e.blade.mount(this._optionsContainer),e.initialized||(e.blade.reset(),e.initialized=!0),this._currentBlade=e,this._formatSelect.value=t,this._updateCopyButtonState(),this._updateExportButton(),this._positionService?.scheduleUpdate()}_updateCopyButtonState(){const t=this._currentBlade?.definition.supportsClipboard??!1;this._copyButtonContainer.style.display=t?"flex":"none",this._copyButton.setDisabled(!t)}async _handleExportClick(){if(!this._currentBlade)return;const t=this._currentBlade.definition.format,e=this._currentBlade.blade.getOptions();if(this._currentBlade.blade.validate()){if(t==="gif"){const r=this._currentBlade.blade;if(r.isRecording())return;r.setRecordingState("recording");try{await this._exportService.$requestExport("gif",e,{onGIFProgress:a=>{r.setRecordingState(a.state,a)}})}catch(a){throw r.setRecordingState("error"),a}return void window.setTimeout(()=>{r.setRecordingState("idle"),this._updateExportButton()},1600)}if(t==="video"){const r=this._currentBlade.blade;if(r.isRecording())return;r.setRecordingState("recording");try{await this._exportService.$requestExport("video",e,{onVideoProgress:a=>{r.setRecordingState(a.state,a)}})}catch(a){throw r.setRecordingState("error"),a}return void window.setTimeout(()=>{r.setRecordingState("idle"),this._updateExportButton()},1600)}this._exportButton.setDisabled(!0),this._exportButton.setLabel("exporting…");try{await this._exportService.$requestExport(t,e)}finally{this._exportButton.setDisabled(!1),this._exportButton.setLabel("download file")}}else console.warn("[textmode-export] Export options failed validation")}async _handleCopyClick(){if(!this._currentBlade||!this._currentBlade.definition.supportsClipboard)return;const t=this._currentBlade.definition.format,e=this._currentBlade.blade.getOptions(),r=this._copyButton.buttonElement.dataset.defaultLabel??"copy to clipboard";this._copyButton.setDisabled(!0),this._copyButton.setLabel("copying…");try{await this._clipboardService.$copy(t,e),this._copyButton.setLabel("copied!")}catch(a){console.error("[textmode-export] Failed to copy to clipboard",a),this._copyButton.setLabel("copy failed!")}finally{window.setTimeout(()=>{this._copyButton.setLabel(r),this._copyButton.setDisabled(!1)},1200)}}_updateExportButton(){if(!this._currentBlade)return;const t=this._currentBlade.definition.format;if(t==="gif"&&this._currentBlade.blade instanceof ht){const r=this._currentBlade.blade,a=this._state.snapshot.gifProgress;if(r.isRecording())if(this._exportButton.setDisabled(!0),a?.totalFrames){const i=a.frameIndex??0;this._exportButton.setLabel(`recording ${i}/${a.totalFrames}`)}else this._exportButton.setLabel("recording…");else this._exportButton.setDisabled(!1),this._exportButton.setLabel("start recording");return}if(t==="video"&&this._currentBlade.blade instanceof ft){const r=this._currentBlade.blade,a=this._state.snapshot.videoProgress;if(r.isRecording())if(this._exportButton.setDisabled(!0),a?.totalFrames){const i=a.frameIndex??0;this._exportButton.setLabel(`recording ${i}/${a.totalFrames} frames`)}else this._exportButton.setLabel("recording…");else this._exportButton.setDisabled(!1),this._exportButton.setLabel("start recording");return}const e=this._state.snapshot.isBusy;this._exportButton.setDisabled(e),this._exportButton.setLabel(e?"exporting…":"download file")}}class nr{_listeners=new Map;$on(t,e){this._listeners.has(t)||this._listeners.set(t,new Set);const r=this._listeners.get(t);return r.add(e),()=>{r.delete(e),r.size===0&&this._listeners.delete(t)}}$emit(t,e){const r=this._listeners.get(t);if(r)for(const a of[...r])try{a(e)}catch(i){console.error("[textmode-export] Event handler failed",i)}}$clear(){this._listeners.clear()}}class sr{_state;_listeners=new Set;constructor(t){this._state=t}get snapshot(){return Object.freeze({...this._state})}$set(t){this._state=Object.assign({},this._state,t);const e=this.snapshot;for(const r of[...this._listeners])try{r(e)}catch(a){console.error("[textmode-export] State listener failed",a)}}$subscribe(t){return this._listeners.add(t),t(this.snapshot),()=>{this._listeners.delete(t)}}$reset(t){this._state=t;const e=this.snapshot;for(const r of[...this._listeners])r(e)}}class ie extends N{props;checkbox;labelElement;handleChange=()=>{this.props.defaultChecked=this.checkbox.checked};constructor(t){super(),this.props=t}render(){this.labelElement=document.createElement("label"),this.labelElement.classList.add(Ae),this.checkbox=document.createElement("input"),this.checkbox.type="checkbox",this.props.id&&(this.checkbox.id=this.props.id),this.checkbox.checked=!!this.props.defaultChecked,this.checkbox.addEventListener("change",this.handleChange);const t=document.createElement("span");return t.textContent=this.props.label,this.labelElement.htmlFor=this.props.id??"",this.labelElement.appendChild(this.checkbox),this.labelElement.appendChild(t),this.labelElement}get inputElement(){return this.checkbox}get checked(){return this.checkbox.checked}set checked(t){this.checkbox.checked=t}_onUnmount(){this.checkbox.removeEventListener("change",this.handleChange)}onUpdate(t){this.props=t,t.id&&(this.checkbox.id=t.id,this.labelElement.htmlFor=t.id),this.checkbox.checked=!!t.defaultChecked,this.labelElement.lastElementChild&&(this.labelElement.lastElementChild.textContent=t.label)}}class lr extends N{props;input;handleInput=()=>{this.props.defaultValue=this.input.value};constructor(t){super(),this.props=t}render(){return this.input=document.createElement("input"),this.input.type="text",this.input.classList.add(jt),this.props.id&&(this.input.id=this.props.id),this.props.maxLength!==void 0&&(this.input.maxLength=this.props.maxLength),this.props.defaultValue!==void 0&&(this.input.value=this.props.defaultValue),this.input.addEventListener("input",this.handleInput),this.input}get inputElement(){return this.input}get value(){return this.input.value}set value(t){this.input.value=t}_onUnmount(){this.input.removeEventListener("input",this.handleInput)}onUpdate(t){this.props=t,t.id&&(this.input.id=t.id),t.maxLength!==void 0&&(this.input.maxLength=t.maxLength),t.defaultValue!==void 0&&(this.input.value=t.defaultValue)}}class dr extends K{trailingSpaces=this._manageComponent(new ie({label:"preserve trailing spaces",defaultChecked:!1}));emptyCharacter=this._manageComponent(new lr({id:"textmode-export-empty-character",defaultValue:" ",maxLength:1}));constructor(t){super(t)}render(){const t=document.createElement("div");t.classList.add(z),this.trailingSpaces.mount(t);const e=new R({label:"empty character",labelFor:"textmode-export-empty-character",variant:"full"});return e.mount(t),this.emptyCharacter.mount(e.root),t}getOptions(){const t=this._config.defaultOptions??{},e=this.emptyCharacter.value||t.emptyCharacter||" ";return{preserveTrailingSpaces:this.trailingSpaces.checked,emptyCharacter:e}}reset(){this.applyDefaults()}validate(){return this.emptyCharacter.value.length<=1}applyDefaults(){const t=this._config.defaultOptions??{};this.trailingSpaces.checked=t.preserveTrailingSpaces??!1,this.emptyCharacter.value=t.emptyCharacter??" "}}class cr extends K{formatSelect=this._manageComponent(new pt({id:"textmode-export-image-format",options:[{value:"png",label:`PNG (${de})`},{value:"jpg",label:`JPG (${ce})`},{value:"webp",label:`WEBP (${ue})`}],defaultValue:"png"}));scaleInput=this._manageComponent(new q({defaultValue:"1",attributes:{min:"0.1",step:"0.1"}}));constructor(t){super(t)}render(){const t=document.createElement("div");t.classList.add(z);const e=new Z("row");e.mount(t);const r=new R({label:"image format",labelFor:"textmode-export-image-format",variant:"compact"});r.mount(e.root),this.formatSelect.mount(r.root);const a=new R({label:"scale",labelFor:"textmode-export-image-scale",variant:"dense"});return a.mount(e.root),this.scaleInput.mount(a.root),this.scaleInput.inputElement.id="textmode-export-image-scale",t}getOptions(){const t=Number.parseFloat(this.scaleInput.value);return{format:this.formatSelect.value,scale:Number.isFinite(t)?t:this._config.defaultOptions?.scale??1}}reset(){this.applyDefaults(),this.scaleInput.refresh()}validate(){const t=Number.parseFloat(this.scaleInput.value);return Number.isFinite(t)&&t>0}applyDefaults(){const t=this._config.defaultOptions??{};this.formatSelect.value=t.format??"png";const e=t.scale??1;this.scaleInput.value=String(e)}}class ur extends K{includeBackground=this._manageComponent(new ie({id:"textmode-export-svg-include-backgrounds",label:"include cell backgrounds",defaultChecked:!0}));drawMode=this._manageComponent(new pt({id:"textmode-export-svg-draw-mode",options:[{value:"fill",label:"fill"},{value:"stroke",label:"stroke"}],defaultValue:"fill"}));strokeWidth=this._manageComponent(new q({defaultValue:"1",attributes:{min:"0",step:"0.1"}}));constructor(t){super(t)}render(){const t=document.createElement("div");t.classList.add(z),this.includeBackground.mount(t);const e=new Z("row");e.mount(t);const r=new R({label:"draw mode",labelFor:"textmode-export-svg-draw-mode",variant:"compact"});r.mount(e.root),this.drawMode.mount(r.root);const a=new R({label:"stroke width",labelFor:"textmode-export-svg-stroke-width",variant:"compact"});return a.mount(e.root),this.strokeWidth.mount(a.root),this.strokeWidth.inputElement.id="textmode-export-svg-stroke-width",this.drawMode.selectElement.addEventListener("change",()=>this.updateStrokeControls()),this.updateStrokeControls(),t}getOptions(){return{includeBackgroundRectangles:this.includeBackground.checked,drawMode:this.drawMode.value,strokeWidth:Number.parseFloat(this.strokeWidth.value)}}reset(){this.applyDefaults(),this.updateStrokeControls()}validate(){const t=Number.parseFloat(this.strokeWidth.value);return this.drawMode.value!=="stroke"||Number.isFinite(t)&&t>=0}updateStrokeControls(){const t=this.drawMode.value==="stroke";this.strokeWidth.inputElement.disabled=!t,this.strokeWidth.refresh()}applyDefaults(){const t=this._config.defaultOptions??{};this.includeBackground.checked=t.includeBackgroundRectangles??!0,this.drawMode.value=t.drawMode??"fill";const e=t.strokeWidth??1;this.strokeWidth.value=String(e),this.strokeWidth.refresh()}}const pr=[{format:"txt",label:"plain text (.txt)",supportsClipboard:!0,createBlade:()=>new dr({format:"txt",label:"plain text (.txt)",supportsClipboard:!0,defaultOptions:{preserveTrailingSpaces:!1,emptyCharacter:" "}})},{format:"image",label:"image (.png / .jpg / .webp)",supportsClipboard:!0,createBlade:()=>new cr({format:"image",label:"image (.png / .jpg / .webp)",supportsClipboard:!0,defaultOptions:{format:"png",scale:1}})},{format:"svg",label:"vector (.svg)",supportsClipboard:!0,createBlade:()=>new ur({format:"svg",label:"vector (.svg)",supportsClipboard:!0,defaultOptions:{includeBackgroundRectangles:!0,drawMode:"fill",strokeWidth:1}})},{format:"gif",label:"animated GIF (.gif)",supportsClipboard:!1,createBlade:()=>new ht({format:"gif",label:"animated GIF (.gif)",supportsClipboard:!1,defaultOptions:{frameCount:300,frameRate:60,scale:1,repeat:0}})},{format:"video",label:"video (.webm)",supportsClipboard:!1,createBlade:()=>new ft({format:"video",label:"video (.webm)",supportsClipboard:!1,defaultOptions:{frameCount:480,frameRate:60,quality:.7}})}];function hr(c,t){const e=pr,r=e[0]?.format,a=new sr((u=>({format:u,isBusy:!1}))(r)),i=new nr,n=new or(c,t,a,i,e);return n.$mount(),n}const oe=(c={})=>{const t=c.overlay??!0;let e;return{name:"textmode-export",version:"1.0.0",async install(r,a){const i={saveCanvas:async(n={})=>(a.flushDrawCommands(),new yt().$saveImage(r.canvas,n)),copyCanvas:async(n={})=>(a.flushDrawCommands(),new yt().$copyImageToClipboard(r.canvas,n)),saveSVG:(n={})=>{a.flushDrawCommands(),new xt().$saveSVG(r,n)},saveStrings:(n={})=>{a.flushDrawCommands(),new _t().$saveTXT(r,n)},toSVG:(n={})=>(a.flushDrawCommands(),new xt().$generateSVG(r,n)),toString:(n={})=>(a.flushDrawCommands(),new _t().$generateTXT(r,n)),saveGIF:async(n={})=>(a.flushDrawCommands(),new we(r,a.registerPostDrawHook).$saveGIF(n)),saveWEBM:async(n={})=>(a.flushDrawCommands(),new $e(r,a.registerPostDrawHook).$saveWEBM(n))};Object.assign(r,i),t&&(e=hr(r,i))},async uninstall(r){e?.$dispose(),e=void 0;const a=["saveCanvas","copyCanvas","saveSVG","saveStrings","toSVG","toString","saveGIF","saveWEBM"];for(const i of a)delete r[i]}}};typeof window<"u"&&(window.createTextmodeExportPlugin=oe),Q.createTextmodeExportPlugin=oe,Object.defineProperty(Q,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(Q,j){typeof exports=="object"&&typeof module<"u"?j(exports):typeof define=="function"&&define.amd?define(["exports"],j):j((Q=typeof globalThis<"u"?globalThis:Q||self).TextmodeExport={})})(this,function(Q){"use strict";class j{$extractFramebufferData(t){return{characterPixels:t.readPixels(0),primaryColorPixels:t.readPixels(1),secondaryColorPixels:t.readPixels(2)}}$getCharacterIndex(t,e){return t[e]+(t[e+1]<<8)}}class X{$downloadFile(t,e){try{const r=this._sanitizeFilename(e),a=URL.createObjectURL(t),i=document.createElement("a");i.href=a,i.download=r,i.style.display="none",i.rel="noopener",document.body.appendChild(i),i.click(),document.body.removeChild(i),URL.revokeObjectURL(a)}catch(r){console.error("[textmode-export] Failed to download file:",r)}}_sanitizeFilename(t){if(!t)return this._generateDefaultFilename();const e=t.trim();return e?e.replace(/[<>:"/\\|?*]/g,"_").replace(/\s+/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").substring(0,255)||this._generateDefaultFilename():this._generateDefaultFilename()}_generateDefaultFilename(){return`textmode-export-${new Date().toISOString().slice(0,19).replace(/:/g,"-")}`}}function vt(c,t){return{r:c[t],g:c[t+1],b:c[t+2],a:c[t+3]}}class ne extends j{_extractTransformData(t,e){const r=t[e+2],a=!!(1&r),i=!!(2&r),n=!!(4&r),u=t[e+3]/255;return{isInverted:a,flipHorizontal:i,flipVertical:n,rotation:Math.round(360*u*100)/100}}_calculateCellPosition(t,e,r){return{x:t,y:e,cellX:t*r.cellWidth,cellY:e*r.cellHeight}}$extractSVGCellData(t,e){const r=[];let a=0;for(let i=0;i<e.rows;i++)for(let n=0;n<e.cols;n++){const u=4*a,l=this.$getCharacterIndex(t.characterPixels,u);let h=vt(t.primaryColorPixels,u),o=vt(t.secondaryColorPixels,u);const s=this._extractTransformData(t.characterPixels,u);if(s.isInverted){const m=h;h=o,o=m}const d=this._calculateCellPosition(n,i,e);r.push({charIndex:l,primaryColor:h,secondaryColor:o,transform:s,position:d}),a++}return r}}class se{_createGlyphPath(t,e,r,a,i){const n=i/t.head.unitsPerEm;return console.log("Scale factor:",n),{getBoundingBox:()=>({x1:r+e.xMin*n,y1:a+-e.yMax*n,x2:r+e.xMax*n,y2:a+-e.yMin*n}),toSVG:()=>this._glyphToSVGPath(e,r,a,n)}}_glyphToSVGPath(t,e,r,a){if(!t||!t.xs)return"";const{xs:i,ys:n,endPts:u,flags:l}=t;if(!(i&&n&&u&&l))return"";let h="",o=0;for(let s=0;s<u.length;s++){const d=u[s];if(!(d<o)){if(d>=o){const m=e+i[o]*a,y=r-n[o]*a;h+=`M${m.toFixed(2)},${y.toFixed(2)}`;let p=o+1;for(;p<=d;)if(1&l[p]){const b=e+i[p]*a,E=r-n[p]*a;h+=`L${b.toFixed(2)},${E.toFixed(2)}`,p++}else{const b=e+i[p]*a,E=r-n[p]*a;let x=p+1>d?o:p+1;if(1&l[x]){const g=e+i[x]*a,k=r-n[x]*a;h+=`Q${b.toFixed(2)},${E.toFixed(2)} ${g.toFixed(2)},${k.toFixed(2)}`,p=x+1}else{const g=(b+(e+i[x]*a))/2,k=(E+(r-n[x]*a))/2;h+=`Q${b.toFixed(2)},${E.toFixed(2)} ${g.toFixed(2)},${k.toFixed(2)}`,p=x}}h+="Z"}o=d+1}}return h}_generateCharacterPath(t,e,r,a,i){const n=e.characterMap.get(t).glyphData;return console.log("Glyph data for character",t,n),n?this._createGlyphPath(e.font,n,r,a,i):null}$generatePositionedCharacterPath(t,e,r,a,i,n,u,l){if(!l)return null;const h=u/e.font.head.unitsPerEm,o=r+(i-l.advanceWidth*h)/2,s=a+(n+.7*u)/2,d=this._generateCharacterPath(t,e,o,s,u);return d&&d.toSVG()||null}}class le{_pathGenerator;constructor(){this._pathGenerator=new se}$generateSVGHeader(t){const{width:e,height:r}=t;return`<?xml version="1.0" encoding="UTF-8"?><svg width="${e}" height="${r}" viewBox="0 0 ${e} ${r}" xmlns="http://www.w3.org/2000/svg"><title>textmode.js sketch</title>`}$generateSVGFooter(){return"</g></svg>"}_generateTransformAttribute(t,e){const{transform:r,position:a}=t;if(!r.flipHorizontal&&!r.flipVertical&&!r.rotation)return"";const i=a.cellX+e.cellWidth/2,n=a.cellY+e.cellHeight/2,u=[];if(r.flipHorizontal||r.flipVertical){const l=r.flipHorizontal?-1:1,h=r.flipVertical?-1:1;u.push(`translate(${i} ${n})scale(${l} ${h})translate(${-i} ${-n})`)}return r.rotation&&u.push(`rotate(${r.rotation} ${i} ${n})`),` transform="${u.join(" ")}"`}_generateCellBackground(t,e,r){if(!r.includeBackgroundRectangles||t.secondaryColor.a===0)return"";const{position:a}=t,{r:i,g:n,b:u,a:l}=t.secondaryColor,h=`rgba(${i},${n},${u},${l/255})`;return r.drawMode==="stroke"?`<rect x="${a.cellX}" y="${a.cellY}" width="${e.cellWidth}" height="${e.cellHeight}" stroke="${h}" fill="none" stroke-width="${r.strokeWidth}"/>`:`<rect x="${a.cellX}" y="${a.cellY}" width="${e.cellWidth}" height="${e.cellHeight}" fill="${h}"/>`}_generateCharacterPath(t,e,r,a){const i=r.characters[t.charIndex];if(!i)return"";const n=this._pathGenerator.$generatePositionedCharacterPath(i.character,r,t.position.cellX,t.position.cellY,e.cellWidth,e.cellHeight,r.fontSize,i.glyphData);if(!n)return"";const{r:u,g:l,b:h,a:o}=t.primaryColor,s=`rgba(${u},${l},${h},${o/255})`;return a.drawMode==="stroke"?`<path d="${n}" stroke="${s}" stroke-width="${a.strokeWidth}" fill="none"/>`:`<path d="${n}" fill="${s}"/>`}$generateCellContent(t,e,r,a){const i=[],n=this._generateCellBackground(t,e,a);n&&i.push(n);const u=this._generateCharacterPath(t,e,r,a);if(u){const l=this._generateTransformAttribute(t,e);i.push(l?`<g${l}>${u}</g>`:u)}return i.join("")}$generateSVGContent(t,e,r,a){const i=[this.$generateSVGHeader(e),'<g id="ascii-cells">'];for(const n of t)i.push(this.$generateCellContent(n,e,r,a));return i.push(this.$generateSVGFooter()),i.join("")}$optimizeSVGContent(t){return t.replace(/<path[^>]*d=""[^>]*\/>/g,"").replace(/\s+/g," ").replace(/> </g,"><")}}class xt{_applyDefaultOptions(t){return{includeBackgroundRectangles:t.includeBackgroundRectangles??!0,drawMode:t.drawMode??"fill",strokeWidth:t.strokeWidth??1,filename:t.filename}}$generateSVG(t,e={}){const r=new ne,a=new le,i=r.$extractSVGCellData(r.$extractFramebufferData(t.drawFramebuffer),t.grid),n=a.$generateSVGContent(i,t.grid,t.font,this._applyDefaultOptions(e));return a.$optimizeSVGContent(n)}$saveSVG(t,e={}){new X().$downloadFile(new Blob([this.$generateSVG(t,e)],{type:"image/svg+xml;charset=utf-8"}),e.filename)}}const nt={png:"image/png",jpg:"image/jpeg",webp:"image/webp"},de=".png",ce=".jpg",ue=".webp";class yt{_applyDefaultOptions(t){return{format:t.format??"png",scale:Math.abs(t.scale??1),filename:t.filename}}_validateOptions(t){if(!(t.format in nt))throw new Error(`Saving '${t.format}' files is not supported`)}async $generateImageBlob(t,e){const r=t,a=document.createElement("canvas"),i=a.getContext("2d"),n=Math.round(r.width*e.scale),u=Math.round(r.height*e.scale);return a.width=n,a.height=u,i.imageSmoothingEnabled=!1,i.clearRect(0,0,n,u),i.drawImage(r,0,0,r.width,r.height,0,0,n,u),await new Promise((l,h)=>{a.toBlob(o=>{o?l(o):h(new Error(`Failed to generate ${e.format.toUpperCase()} blob`))},nt[e.format])})}async $saveImage(t,e={}){const r=this._applyDefaultOptions(e);this._validateOptions(r);const a=await this.$generateImageBlob(t,r);new X().$downloadFile(a,r.filename)}async $copyImageToClipboard(t,e={}){if(typeof navigator>"u"||!navigator.clipboard||typeof navigator.clipboard.write!="function")throw new Error("Clipboard API is not available in this environment");const r=this._applyDefaultOptions(e);this._validateOptions(r);const a=await this.$generateImageBlob(t,r),i=new ClipboardItem({[nt[r.format]]:a});await navigator.clipboard.write([i])}}class _t{_applyDefaultOptions(t){return{preserveTrailingSpaces:t.preserveTrailingSpaces??!1,emptyCharacter:t.emptyCharacter??" ",filename:t.filename}}_createTXTContent(t,e){const r=new j;let a=r.$extractFramebufferData(t.drawFramebuffer);const i=[];let n=0;for(let l=0;l<t.grid.rows;l++){const h=[];for(let o=0;o<t.grid.cols;o++){const s=4*n,d=r.$getCharacterIndex(a.characterPixels,s),m=t.font.characters[d]?.character||e.emptyCharacter;h.push(m),n++}i.push(h)}const u=[];for(const l of i){let h=l.join("");e.preserveTrailingSpaces||(h=h.replace(/\s+$/,"")),u.push(h)}return u.join(`
|
|
2
|
+
`)}$generateTXT(t,e={}){return this._createTXTContent(t,this._applyDefaultOptions(e))}$saveTXT(t,e={}){const r=this._applyDefaultOptions(e),a=this._createTXTContent(t,r),i=new Blob([a],{type:"text/plain;charset=utf-8"});new X().$downloadFile(i,r.filename)}}class pe{_canvas;_ctx;async $record(t,e,r,a){const i=Math.max(1,Math.round(e.frameRate)),n=Math.round(1e3/i),u=Math.max(1,Math.round(e.frameCount));return await new Promise((l,h)=>{const o=[];let s,d=0,m=!1;const y=()=>{s&&(s(),s=void 0)},p=E=>{m||(m=!0,y(),l(E))},b=()=>{if(d>=u)p(o);else try{const E=e.scale,x=Math.max(1,Math.round(t.width*E)),g=Math.max(1,Math.round(t.height*E));this._canvas||(this._canvas=document.createElement("canvas")),this._canvas.width===x&&this._canvas.height===g||(this._canvas.width=x,this._canvas.height=g),this._ctx||(this._ctx=this._canvas.getContext("2d"));const k=this._ctx;k.imageSmoothingEnabled=!1,k.clearRect(0,0,x,g),k.drawImage(t,0,0,t.width,t.height,0,0,x,g);const S={imageData:k.getImageData(0,0,x,g),width:x,height:g,delayMs:n};o.push(S),d+=1,a?.({state:"recording",frameIndex:d,totalFrames:u}),d>=u&&p(o)}catch(E){(x=>{if(m)return;m=!0,y();const g=x instanceof Error?x.message:"GIF recording failed";a?.({state:"error",message:g}),h(x instanceof Error?x:new Error(String(x)))})(E)}};s=r(()=>{b()}),a?.({state:"recording",frameIndex:0,totalFrames:u})})}}var wt,tt,Ct=Object.defineProperty,he=(wt=c=>{function t(s,d,m){return .29889531*s+.58662247*d+.11448223*m}function e(s,d,m){return .59597799*s-.2741761*d-.32180189*m}function r(s,d,m){return .21147017*s-.52261711*d+.31114694*m}function a(s,d){let m=s[0]-d[0],y=s[1]-d[1],p=s[2]-d[2],b=i(s)-i(d);return m*m*.5053+y*y*.299+p*p*.1957+b*b}function i(s){return s[3]!=null?s[3]:255}function n(s,d){return Math.sqrt(a(s,d))}function u(s,d){let[m,y,p]=s,[b,E,x]=d,g=t(m,y,p)-t(b,E,x),k=e(m,y,p)-e(b,E,x),S=r(m,y,p)-r(b,E,x),B=i(s)-i(d);return g*g*.5053+k*k*.299+S*S*.1957+B*B}function l(s,d){return Math.sqrt(u(s,d))}function h(s,d){var m,y=0;for(m=0;m<s.length;m++){let p=s[m]-d[m];y+=p*p}return y}function o(s,d){return Math.sqrt(h(s,d))}Ct(c,"__esModule",{value:!0}),((s,d)=>{for(var m in d)Ct(s,m,{get:d[m],enumerable:!0})})(c,{colorDifferenceRGBToYIQ:()=>l,colorDifferenceRGBToYIQSquared:()=>u,colorDifferenceYIQ:()=>n,colorDifferenceYIQSquared:()=>a,euclideanDistance:()=>o,euclideanDistanceSquared:()=>h})},()=>(tt||wt((tt={exports:{}}).exports,tt),tt.exports)),me=59;function Et(c=256){let t=0,e=new Uint8Array(c);return{get buffer(){return e.buffer},reset(){t=0},bytesView:()=>e.subarray(0,t),bytes:()=>e.slice(0,t),writeByte(a){r(t+1),e[t]=a,t++},writeBytes(a,i=0,n=a.length){r(t+n);for(let u=0;u<n;u++)e[t++]=a[u+i]},writeBytesView(a,i=0,n=a.byteLength){r(t+n),e.set(a.subarray(i,i+n),t),t+=n}};function r(a){var i=e.length;if(i>=a)return;a=Math.max(a,i*(i<1048576?2:1.125)>>>0),i!=0&&(a=Math.max(a,256));let n=e;e=new Uint8Array(a),t>0&&e.set(n.subarray(0,t),0)}}var fe=[0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535],ge=function(c,t,e,r,a,i,n,u){a=a||Et(512),i=i||new Uint8Array(256),n=n||new Int32Array(5003),u=u||new Int32Array(5003);let l=n.length,h=Math.max(2,r);i.fill(0),u.fill(0),F();let o=0,s=0,d=h+1,m=d,y=!1,p=m,b=$(p),E=1<<d-1,x=E+1,g=E+2,k=0,S=e[0],B=0;for(let v=l;v<65536;v*=2)++B;B=8-B,a.writeByte(h),A(E);for(let v=1;v<e.length;v++)L(e[v]);return A(S),A(x),a.writeByte(0),a.bytesView();function C(v){i[k++]=v,k>=254&&w()}function F(){n.fill(-1)}function L(v){let V=(v<<12)+S,f=v<<B^S;if(n[f]===V)S=u[f];else{if(n[f]>=0){let _=f===0?1:l-f;do if(f-=_,f<0&&(f+=l),n[f]===V)return void(S=u[f]);while(n[f]>=0)}A(S),S=v,g<4096?(u[f]=g++,n[f]=V):(F(),g=E+2,y=!0,A(E))}}function w(){k>0&&(a.writeByte(k),a.writeBytesView(i,0,k),k=0)}function $(v){return(1<<v)-1}function A(v){for(o&=fe[s],s>0?o|=v<<s:o=v,s+=p;s>=8;)C(255&o),o>>=8,s-=8;if((g>b||y)&&(y?(p=m,b=$(p),y=!1):(++p,b=p==12?4096:$(p))),v==x){for(;s>0;)C(255&o),o>>=8,s-=8;w()}}};function kt(c,t,e){return c<<8&63488|t<<2&992|e>>3&31}function Bt(c,t,e,r){return c>>4|240&t|(240&e)<<4|(240&r)<<8}function It(c,t,e){return c>>4<<8|t>>4<<4|e>>4}function et(c,t,e){return c<t?t:c>e?e:c}function rt(c){return c*c}function Ft(c,t,e){for(var r=0,a=1e100,i=c[t],n=i.cnt,u=(i.ac,i.rc),l=i.gc,h=i.bc,o=i.fw;o!=0;o=c[o].fw){var s=c[o].cnt,d=n*s/(n+s);if(!(d>=a)){var m=0;!((m+=d*rt(c[o].rc-u))>=a)&&!((m+=d*rt(c[o].gc-l))>=a)&&!((m+=d*rt(c[o].bc-h))>=a)&&(a=m,r=o)}}i.err=a,i.nn=r}function st(){return{ac:0,rc:0,gc:0,bc:0,cnt:0,nn:0,fw:0,bk:0,tm:0,mtm:0,err:0}}function be(c,t,e){let{format:r="rgb565",clearAlpha:a=!0,clearAlphaColor:i=0,clearAlphaThreshold:n=0,oneBitAlpha:u=!1}=e||{},l=e.useSqrt!==!1,h=r==="rgba4444",o=(function(v,V){let f=new Array(V==="rgb444"?4096:65536),_=v.length;if(V==="rgba4444")for(let M=0;M<_;++M){let P=v[M],D=P>>24&255,O=P>>16&255,I=P>>8&255,T=255&P,U=Bt(T,I,O,D),G=U in f?f[U]:f[U]=st();G.rc+=T,G.gc+=I,G.bc+=O,G.ac+=D,G.cnt++}else if(V==="rgb444")for(let M=0;M<_;++M){let P=v[M],D=P>>16&255,O=P>>8&255,I=255&P,T=It(I,O,D),U=T in f?f[T]:f[T]=st();U.rc+=I,U.gc+=O,U.bc+=D,U.cnt++}else for(let M=0;M<_;++M){let P=v[M],D=P>>16&255,O=P>>8&255,I=255&P,T=kt(I,O,D),U=T in f?f[T]:f[T]=st();U.rc+=I,U.gc+=O,U.bc+=D,U.cnt++}return f})(c,r),s=o.length,d=s-1,m=new Uint32Array(s+1);for(var y=0,p=0;p<o.length;++p){let v=o[p];if(v!=null){var b=1/v.cnt;h&&(v.ac*=b),v.rc*=b,v.gc*=b,v.bc*=b,o[y++]=v}}for(rt(t)/y<.022&&(l=!1),p=0;p<y-1;++p)o[p].fw=p+1,o[p+1].bk=p,l&&(o[p].cnt=Math.sqrt(o[p].cnt));var E,x,g;for(l&&(o[p].cnt=Math.sqrt(o[p].cnt)),p=0;p<y;++p){Ft(o,p);var k=o[p].err;for(x=++m[0];x>1&&!(o[E=m[g=x>>1]].err<=k);x=g)m[x]=E;m[x]=p}var S=y-t;for(p=0;p<S;){for(var B;;){var C=m[1];if((B=o[C]).tm>=B.mtm&&o[B.nn].mtm<=B.tm)break;for(B.mtm==d?C=m[1]=m[m[0]--]:(Ft(o,C),B.tm=p),k=o[C].err,x=1;(g=x+x)<=m[0]&&(g<m[0]&&o[m[g]].err>o[m[g+1]].err&&g++,!(k<=o[E=m[g]].err));x=g)m[x]=E;m[x]=C}var F=o[B.nn],L=B.cnt,w=F.cnt;b=1/(L+w),h&&(B.ac=b*(L*B.ac+w*F.ac)),B.rc=b*(L*B.rc+w*F.rc),B.gc=b*(L*B.gc+w*F.gc),B.bc=b*(L*B.bc+w*F.bc),B.cnt+=F.cnt,B.mtm=++p,o[F.bk].fw=F.fw,o[F.fw].bk=F.bk,F.mtm=d}let $=[];var A=0;for(p=0;;++A){let v=et(Math.round(o[p].rc),0,255),V=et(Math.round(o[p].gc),0,255),f=et(Math.round(o[p].bc),0,255),_=255;h&&(_=et(Math.round(o[p].ac),0,255),u&&(_=_<=(typeof u=="number"?u:127)?0:255),a&&_<=n&&(v=V=f=i,_=0));let M=h?[v,V,f,_]:[v,V,f];if(ve($,M)||$.push(M),(p=o[p].fw)==0)break}return $}function ve(c,t){for(let e=0;e<c.length;e++){let r=c[e],a=r[0]===t[0]&&r[1]===t[1]&&r[2]===t[2],i=!(r.length>=4&&t.length>=4)||r[3]===t[3];if(a&&i)return!0}return!1}function xe(c,t,e,r,a){let i=0,n=1e100;for(let u=0;u<a.length;u++){let l=a[u],h=l[0],o=l[1],s=l[2],d=H(l[3]-r);d>n||(d+=H(h-c),!(d>n)&&(d+=H(o-t),!(d>n)&&(d+=H(s-e),!(d>n)&&(n=d,i=u))))}return i}function ye(c,t,e,r){let a=0,i=1e100;for(let n=0;n<r.length;n++){let u=r[n],l=u[0],h=u[1],o=u[2],s=H(l-c);s>i||(s+=H(h-t),!(s>i)&&(s+=H(o-e),!(s>i)&&(i=s,a=n)))}return a}function H(c){return c*c}function _e(c={}){let{initialCapacity:t=4096,auto:e=!0}=c,r=Et(t),a=new Uint8Array(256),i=new Int32Array(5003),n=new Int32Array(5003),u=!1;return{reset(){r.reset(),u=!1},finish(){r.writeByte(me)},bytes:()=>r.bytes(),bytesView:()=>r.bytesView(),get buffer(){return r.buffer},get stream(){return r},writeHeader:l,writeFrame(h,o,s,d={}){let{transparent:m=!1,transparentIndex:y=0,delay:p=0,palette:b=null,repeat:E=0,colorDepth:x=8,dispose:g=-1}=d,k=!1;if(e?u||(k=!0,l(),u=!0):k=!!d.first,o=Math.max(0,Math.floor(o)),s=Math.max(0,Math.floor(s)),k){if(!b)throw new Error("First frame must include a { palette } option");(function(C,F,L,w,$=8){let A=1,v=0,V=lt(w.length)-1,f=A<<7|$-1<<4|v<<3|V;W(C,F),W(C,L),C.writeBytes([f,0,0])})(r,o,s,b,x),Mt(r,b),E>=0&&(function(C,F){C.writeByte(33),C.writeByte(255),C.writeByte(11),$t(C,"NETSCAPE2.0"),C.writeByte(3),C.writeByte(1),W(C,F),C.writeByte(0)})(r,E)}let S=Math.round(p/10);(function(C,F,L,w,$){var A,v;C.writeByte(33),C.writeByte(249),C.writeByte(4),$<0&&($=0,w=!1),w?(A=1,v=2):(A=0,v=0),F>=0&&(v=7&F),v<<=2,C.writeByte(0|v|0|A),W(C,L),C.writeByte($||0),C.writeByte(0)})(r,g,S,m,y);let B=!!b&&!k;(function(C,F,L,w){if(C.writeByte(44),W(C,0),W(C,0),W(C,F),W(C,L),w){let $=0,A=0,v=lt(w.length)-1;C.writeByte(128|$|A|v)}else C.writeByte(0)})(r,o,s,B?b:null),B&&Mt(r,b),(function(C,F,L,w,$=8,A,v,V){ge(L,w,F,$,C,A,v,V)})(r,h,o,s,x,a,i,n)}};function l(){$t(r,"GIF89a")}}function Mt(c,t){let e=1<<lt(t.length);for(let r=0;r<e;r++){let a=[0,0,0];r<t.length&&(a=t[r]),c.writeByte(a[0]),c.writeByte(a[1]),c.writeByte(a[2])}}function W(c,t){c.writeByte(255&t),c.writeByte(t>>8&255)}function $t(c,t){for(var e=0;e<t.length;e++)c.writeByte(t.charCodeAt(e))}function lt(c){return Math.max(Math.ceil(Math.log2(c)),1)}he();class we{_recorder;_textmodifier;_registerPostDrawHook;constructor(t,e){this._recorder=new pe,this._textmodifier=t,this._registerPostDrawHook=e}async $saveGIF(t={}){const e=this._textmodifier.canvas,r=this._applyDefaultOptions(t),a=t.onProgress;try{const i=await this._recorder.$record(e,r,this._registerPostDrawHook,a),n=_e(),{repeat:u}=t;i.forEach((o,s)=>{const{width:d,height:m,imageData:y,delayMs:p}=o,b=new Uint32Array(y.data.buffer.slice(0)),E=be(b,256,{}),x=(function(g,k,S){let B=(S=S||"rgb565")==="rgb444"?4096:65536,C=new Uint8Array(g.length),F=new Array(B);if(S==="rgba4444")for(let L=0;L<g.length;L++){let w,$=g[L],A=$>>24&255,v=$>>16&255,V=$>>8&255,f=255&$,_=Bt(f,V,v,A);F[_]!=null?w=F[_]:(w=xe(f,V,v,A,k),F[_]=w),C[L]=w}else for(let L=0;L<g.length;L++){let w,$=g[L],A=$>>16&255,v=$>>8&255,V=255&$,f=S==="rgb444"?It(V,v,A):kt(V,v,A);F[f]!=null?w=F[f]:(w=ye(V,v,A,k),F[f]=w),C[L]=w}return C})(b,E);n.writeFrame(x,d,m,{palette:E,delay:p,repeat:s===0?u:-1})}),n.finish();const l=n.bytes(),h=l.buffer.slice(l.byteOffset,l.byteOffset+l.byteLength);new X().$downloadFile(new Blob([h],{type:"image/gif"}),r.filename),a?.({state:"completed",totalFrames:r.frameCount})}catch(i){throw a?.({state:"error",message:i instanceof Error?i.message:"GIF export failed"}),i}}_applyDefaultOptions(t){const e=Math.abs(Math.round(t.frameCount??300)),r=Math.abs(t.frameRate??60),a=Math.abs(t.scale??1),i=Math.max(-1,Math.round(t.repeat??0));return{filename:t.filename,frameCount:e,frameRate:r,scale:a,repeat:i}}}function Ce(c){return c&&c.__esModule&&Object.prototype.hasOwnProperty.call(c,"default")?c.default:c}var St,Lt={exports:{}};function Ee(){return St||(St=1,(function(c){(function(){function t(l,h){return(function(o){if(typeof o!="string"||!o.match(/^data:image\/webp;base64,/i))throw new Error("Failed to decode WebP Base64 URL");return window.atob(o.substring(23))})(typeof l=="string"&&/^data:image\/webp/.test(l)?l:l.toDataURL("image/webp",h))}function e(l){return(l.charCodeAt(0)|l.charCodeAt(1)<<8|l.charCodeAt(2)<<16|l.charCodeAt(3)<<24)>>>0}function r(l){let h=l.indexOf("VP8",12);if(h===-1)throw new Error("Bad image format, does this browser support WebP?");let o=!1;for(;h<l.length-8;){let s,d;switch(d=l.substring(h,h+4),h+=4,s=e(l.substring(h,h+4)),h+=4,d){case"VP8 ":return{frame:l.substring(h,h+s),hasAlpha:o};case"ALPH":o=!0}h+=s,1&s&&h++}throw new Error("Failed to find VP8 keyframe in WebP image, is this image mistakenly encoded in the Lossless WebP format?")}function a(l){this.value=l}function i(l){this.value=l}function n(l,h,o){if(Array.isArray(o))for(let s=0;s<o.length;s++)n(l,h,o[s]);else if(typeof o=="string")l.writeString(o);else if(o instanceof Uint8Array)l.writeBytes(o);else{if(!o.id)throw new Error("Bad EBML datatype "+typeof o.data);if(o.offset=l.pos+h,l.writeUnsignedIntBE(o.id),Array.isArray(o.data)){let s,d,m;o.size===-1?l.writeByte(255):o.size===-2?(s=l.pos,l.writeBytes([15,255,255,255,255])):(s=l.pos,l.writeBytes([0,0,0,0])),d=l.pos,o.dataOffset=d+h,n(l,h,o.data),o.size!==-1&&o.size!==-2&&(m=l.pos,o.size=m-d,l.seek(s),l.writeEBMLVarIntWidth(o.size,4),l.seek(m))}else if(typeof o.data=="string")l.writeEBMLVarInt(o.data.length),o.dataOffset=l.pos+h,l.writeString(o.data);else if(typeof o.data=="number")o.size||(o.size=l.measureUnsignedInt(o.data)),l.writeEBMLVarInt(o.size),o.dataOffset=l.pos+h,l.writeUnsignedIntBE(o.data,o.size);else if(o.data instanceof i)l.writeEBMLVarInt(8),o.dataOffset=l.pos+h,l.writeDoubleBE(o.data.value);else if(o.data instanceof a)l.writeEBMLVarInt(4),o.dataOffset=l.pos+h,l.writeFloatBE(o.data.value);else{if(!(o.data instanceof Uint8Array))throw new Error("Bad EBML datatype "+typeof o.data);l.writeEBMLVarInt(o.data.byteLength),o.dataOffset=l.pos+h,l.writeBytes(o.data)}}}let u=function(l,h){return function(o){let s,d,m=!1,y=0,p=0,b=null,E=null,x=null,g=[],k=0,S=0,B={quality:.95,transparent:!1,alphaQuality:void 0,fileWriter:null,fd:null,frameDuration:null,frameRate:null},C={Cues:{id:new Uint8Array([28,83,187,107]),positionEBML:null},SegmentInfo:{id:new Uint8Array([21,73,169,102]),positionEBML:null},Tracks:{id:new Uint8Array([22,84,174,107]),positionEBML:null}},F={id:17545,data:new i(0)},L=[],w=new h(o.fileWriter||o.fd);function $(f){return f-s.dataOffset}function A(){d=(function(){let D={id:21420,size:5,data:0},O={id:290298740,data:[]};for(let I in C){let T=C[I];T.positionEBML=Object.create(D),O.data.push({id:19899,data:[{id:21419,data:T.id},T.positionEBML]})}return O})();let f={id:357149030,data:[{id:2807729,data:1e6},{id:19840,data:"webm-writer-js"},{id:22337,data:"webm-writer-js"},F]},_=[{id:176,data:y},{id:186,data:p}];o.transparent&&_.push({id:21440,data:1});let M={id:374648427,data:[{id:174,data:[{id:215,data:1},{id:29637,data:1},{id:156,data:0},{id:2274716,data:"und"},{id:134,data:"V_VP8"},{id:2459272,data:"VP8"},{id:131,data:1},{id:224,data:_}]}]};s={id:408125543,size:-2,data:[d,f,M]};let P=new l(256);n(P,w.pos,[{id:440786851,data:[{id:17030,data:1},{id:17143,data:1},{id:17138,data:4},{id:17139,data:8},{id:17026,data:"webm"},{id:17031,data:2},{id:17029,data:2}]},s]),w.write(P.getAsDataArray()),C.SegmentInfo.positionEBML.data=$(f.offset),C.Tracks.positionEBML.data=$(M.offset),m=!0}function v(f){return f.alpha?(function(_){let M,P,D=new l(4);if(!(_.trackNumber>0&&_.trackNumber<127))throw new Error("TrackNumber must be > 0 and < 127");return D.writeEBMLVarInt(_.trackNumber),D.writeU16BE(_.timecode),D.writeByte(0),M={id:161,data:[D.getAsDataArray(),_.frame]},P={id:30113,data:[{id:166,data:[{id:238,data:1},{id:165,data:_.alpha}]}]},{id:160,data:[M,P]}})(f):(function(_){let M=new l(4);if(!(_.trackNumber>0&&_.trackNumber<127))throw new Error("TrackNumber must be > 0 and < 127");return M.writeEBMLVarInt(_.trackNumber),M.writeU16BE(_.timecode),M.writeByte(128),{id:163,data:[M.getAsDataArray(),_.frame]}})(f)}function V(){if(g.length===0)return;let f=0;for(let I=0;I<g.length;I++)f+=g[I].frame.length+(g[I].alpha?g[I].alpha.length:0);let _=new l(f+64*g.length),M=(function(I){return{id:524531317,data:[{id:231,data:Math.round(I.timecode)}]}})({timecode:Math.round(k)});for(let I=0;I<g.length;I++)M.data.push(v(g[I]));var P,D,O;n(_,w.pos,M),w.write(_.getAsDataArray()),P=1,D=Math.round(k),O=M.offset,L.push({id:187,data:[{id:179,data:D},{id:183,data:[{id:247,data:P},{id:241,data:$(O)}]}]}),g=[],k+=S,S=0}this.addFrame=function(f,_,M){m||(y=f.width||0,p=f.height||0,A());let P,D=r(t(f,o.quality)),O=null;P=M||(typeof _=="number"?_:o.frameDuration),o.transparent&&(_ instanceof HTMLCanvasElement||typeof _=="string"?O=_:D.hasAlpha&&(O=(function(I){b!==null&&b.width===I.width&&b.height===I.height||(b=document.createElement("canvas"),b.width=I.width,b.height=I.height,E=b.getContext("2d"),x=E.createImageData(b.width,b.height));let T=I.getContext("2d").getImageData(0,0,I.width,I.height).data,U=x.data,G=0,mr=I.width*I.height*4;for(let gt=3;gt<mr;gt+=4){let bt=T[gt];U[G++]=bt,U[G++]=bt,U[G++]=bt,U[G++]=255}return E.putImageData(x,0,0),b})(f))),(function(I){I.trackNumber=1,I.timecode=Math.round(S),g.push(I),S+=I.duration,S>=5e3&&V()})({frame:D.frame,duration:P,alpha:O?r(t(O,o.alphaQuality)).frame:null})},this.complete=function(){return m||A(),V(),(function(){let f={id:475249515,data:L},_=new l(16+32*L.length);n(_,w.pos,f),w.write(_.getAsDataArray()),C.Cues.positionEBML.data=$(f.offset)})(),(function(){let f=new l(d.size),_=w.pos;n(f,d.dataOffset,d.data),w.seek(d.dataOffset),w.write(f.getAsDataArray()),w.seek(_)})(),(function(){let f=new l(8),_=w.pos;f.writeDoubleBE(k),w.seek(F.dataOffset),w.write(f.getAsDataArray()),w.seek(_)})(),(function(){let f=new l(10),_=w.pos;f.writeUnsignedIntBE(s.id),f.writeEBMLVarIntWidth(w.pos-s.dataOffset,5),w.seek(s.offset),w.write(f.getAsDataArray()),w.seek(_)})(),w.complete("video/webm")},this.getWrittenSize=function(){return w.length},o=(function(f,_){let M={};return[f,_].forEach(function(P){for(let D in P)Object.prototype.hasOwnProperty.call(P,D)&&(M[D]=P[D])}),M})(B,o||{}),(function(){if(!o.frameDuration){if(!o.frameRate)throw new Error("Missing required frameDuration or frameRate setting");o.frameDuration=1e3/o.frameRate}o.quality=Math.max(Math.min(o.quality,.99999),0),o.alphaQuality===void 0?o.alphaQuality=o.quality:o.alphaQuality=Math.max(Math.min(o.alphaQuality,.99999),0)})()}};c.exports=u})()})(Lt)),Lt.exports}var Pt,At={exports:{}};function ke(){return Pt||(Pt=1,(function(c){(function(){let t=function(e){this.data=new Uint8Array(e),this.pos=0};t.prototype.seek=function(e){this.pos=e},t.prototype.writeBytes=function(e){for(let r=0;r<e.length;r++)this.data[this.pos++]=e[r]},t.prototype.writeByte=function(e){this.data[this.pos++]=e},t.prototype.writeU8=t.prototype.writeByte,t.prototype.writeU16BE=function(e){this.data[this.pos++]=e>>8,this.data[this.pos++]=e},t.prototype.writeDoubleBE=function(e){let r=new Uint8Array(new Float64Array([e]).buffer);for(let a=r.length-1;a>=0;a--)this.writeByte(r[a])},t.prototype.writeFloatBE=function(e){let r=new Uint8Array(new Float32Array([e]).buffer);for(let a=r.length-1;a>=0;a--)this.writeByte(r[a])},t.prototype.writeString=function(e){for(let r=0;r<e.length;r++)this.data[this.pos++]=e.charCodeAt(r)},t.prototype.writeEBMLVarIntWidth=function(e,r){switch(r){case 1:this.writeU8(128|e);break;case 2:this.writeU8(64|e>>8),this.writeU8(e);break;case 3:this.writeU8(32|e>>16),this.writeU8(e>>8),this.writeU8(e);break;case 4:this.writeU8(16|e>>24),this.writeU8(e>>16),this.writeU8(e>>8),this.writeU8(e);break;case 5:this.writeU8(8|e/4294967296&7),this.writeU8(e>>24),this.writeU8(e>>16),this.writeU8(e>>8),this.writeU8(e);break;default:throw new Error("Bad EBML VINT size "+r)}},t.prototype.measureEBMLVarInt=function(e){if(e<127)return 1;if(e<16383)return 2;if(e<2097151)return 3;if(e<268435455)return 4;if(e<34359738367)return 5;throw new Error("EBML VINT size not supported "+e)},t.prototype.writeEBMLVarInt=function(e){this.writeEBMLVarIntWidth(e,this.measureEBMLVarInt(e))},t.prototype.writeUnsignedIntBE=function(e,r){switch(r===void 0&&(r=this.measureUnsignedInt(e)),r){case 5:this.writeU8(Math.floor(e/4294967296));case 4:this.writeU8(e>>24);case 3:this.writeU8(e>>16);case 2:this.writeU8(e>>8);case 1:this.writeU8(e);break;default:throw new Error("Bad UINT size "+r)}},t.prototype.measureUnsignedInt=function(e){return e<256?1:e<65536?2:e<1<<24?3:e<4294967296?4:5},t.prototype.getAsDataArray=function(){if(this.pos<this.data.byteLength)return this.data.subarray(0,this.pos);if(this.pos==this.data.byteLength)return this.data;throw new Error("ArrayBufferDataStream's pos lies beyond end of buffer")},c.exports=t})()})(At)),At.exports}var Vt,Dt,Ot,Ut={exports:{}};function Be(){return Vt||(Vt=1,(function(c){(function(){let t=function(e){return function(r){let a=[],i=Promise.resolve(),n=null,u=null;function l(s){return new Promise(function(d,m){let y=new FileReader;y.addEventListener("loadend",function(){d(y.result)}),y.readAsArrayBuffer(s)})}function h(s){return new Promise(function(d,m){s instanceof Uint8Array?d(s):s instanceof ArrayBuffer||ArrayBuffer.isView(s)?d(new Uint8Array(s)):s instanceof Blob?d(l(s).then(function(y){return new Uint8Array(y)})):d(l(new Blob([s])).then(function(y){return new Uint8Array(y)}))})}function o(s){let d=s.byteLength||s.length||s.size;if(!Number.isInteger(d))throw new Error("Failed to determine size of element");return d}r&&r.constructor.name==="FileWriter"?n=r:e&&r&&(u=r),this.pos=0,this.length=0,this.seek=function(s){if(s<0)throw new Error("Offset may not be negative");if(isNaN(s))throw new Error("Offset may not be NaN");if(s>this.length)throw new Error("Seeking beyond the end of file is not allowed");this.pos=s},this.write=function(s){let d={offset:this.pos,data:s,length:o(s)},m=d.offset>=this.length;this.pos+=d.length,this.length=Math.max(this.length,this.pos),i=i.then(function(){if(u)return new Promise(function(y,p){h(d.data).then(function(b){let E=0,x=Buffer.from(b.buffer),g=function(k,S,B){E+=S,E>=B.length?y():e.write(u,B,E,B.length-E,d.offset+E,g)};e.write(u,x,0,x.length,d.offset,g)})});if(n)return new Promise(function(y,p){n.onwriteend=y,n.seek(d.offset),n.write(new Blob([d.data]))});if(!m)for(let y=0;y<a.length;y++){let p=a[y];if(!(d.offset+d.length<=p.offset||d.offset>=p.offset+p.length)){if(d.offset<p.offset||d.offset+d.length>p.offset+p.length)throw new Error("Overwrite crosses blob boundaries");return d.offset==p.offset&&d.length==p.length?void(p.data=d.data):h(p.data).then(function(b){return p.data=b,h(d.data)}).then(function(b){d.data=b,p.data.set(d.data,d.offset-p.offset)})}}a.push(d)})},this.complete=function(s){return i=u||n?i.then(function(){return null}):i.then(function(){let d=[];for(let m=0;m<a.length;m++)d.push(a[m].data);return new Blob(d,{type:s})}),i}}};c.exports=t})()})(Ut)),Ut.exports}function Ie(){return Ot?Dt:(Ot=1,Dt=Ee()(ke(),Be()(null)))}const Fe=Ce(Ie());class Me{async $record(t,e,r,a){const i=Math.max(1,Math.round(e.frameRate)),n=Math.max(1,Math.round(e.frameCount)),u=new Fe({quality:e.quality,alphaQuality:e.transparent?e.quality:void 0,transparent:e.transparent,frameRate:i}),l=this._createSnapshotSurface();return await new Promise((h,o)=>{let s,d="capturing",m=!1,y=0;const p=()=>{s&&(s(),s=void 0)},b=()=>{a?.({state:"recording",frameIndex:y,totalFrames:n})},E=g=>{if(m)return;m=!0,p();const k=g instanceof Error?g.message:"WEBM export failed";a?.({state:"error",message:k}),o(g instanceof Error?g:new Error(String(g)))},x=()=>{d!=="capturing"||m||(d="encoding",p(),u.complete().then(g=>{(k=>{m||(m=!0,a?.({state:"completed",frameIndex:Math.min(n,y),totalFrames:n}),h(k))})(g)}).catch(E))};s=r(()=>{(()=>{if(d==="capturing")if(y>=n)x();else try{const g=l(t);u.addFrame(g),y+=1,b(),y>=n&&x()}catch(g){E(g)}})()}),b()})}_createSnapshotSurface(){let t=null,e=null;return r=>{const a=Math.max(1,r.width),i=Math.max(1,r.height),n=((u,l)=>(t||(t=document.createElement("canvas")),t.width!==u||t.height!==l?(t.width=u,t.height=l,e=t.getContext("2d"),e&&(e.imageSmoothingEnabled=!1)):e||(e=t.getContext("2d"),e&&(e.imageSmoothingEnabled=!1)),e?t:null))(a,i);return n&&e?(e.clearRect(0,0,a,i),e.drawImage(r,0,0,a,i),n):r}}}class $e{_recorder;_textmodifier;_registerPostDrawHook;constructor(t,e){this._recorder=new Me,this._textmodifier=t,this._registerPostDrawHook=e}async $saveWEBM(t={}){const e=this._textmodifier.canvas,r=this._applyDefaultOptions(t);try{const a=await this._recorder.$record(e,r,this._registerPostDrawHook,t.onProgress);new X().$downloadFile(a,r.filename)}catch(a){throw t.onProgress?.({state:"error",message:a instanceof Error?a.message:"WEBM export failed"}),a}}_applyDefaultOptions(t){return{filename:t.filename,frameRate:Math.abs(Math.round(t.frameRate??60)),frameCount:Math.abs(Math.round(t.frameCount??300)),quality:Math.abs(Math.min(Math.max(t.quality??1,0),1)),transparent:!!t.transparent,debugLogging:!!t.debugLogging}}}const Se="textmode-export-overlay",z="textmode-export-overlay__stack",dt="textmode-export-overlay__stack--dense",Tt="textmode-export-overlay__stack--compact",Rt="textmode-export-overlay__section",Le="textmode-export-overlay__header",Pe="textmode-export-overlay__header-title-row",Ae="textmode-export-overlay__header-links",Ve="textmode-export-overlay__row",Nt="textmode-export-overlay__label",zt="textmode-export-overlay__field",Gt="textmode-export-overlay__field--compact",Wt="textmode-export-overlay__field--dense",qt="textmode-export-overlay__field--full",Ht="textmode-export-overlay__field--channel",jt="textmode-export-overlay__input",De="textmode-export-overlay__checkbox",Qt="textmode-export-overlay__muted",Oe="textmode-export-overlay__status",Ue="textmode-export-overlay__status--gif",Te="textmode-export-overlay__status--video",Re="textmode-export-overlay__status-title",Ne="textmode-export-overlay__status-value",ze="textmode-export-overlay__divider",Ge="textmode-export-overlay__title",We="textmode-export-overlay__button",ct="textmode-export-overlay__button--primary",ut="textmode-export-overlay__button--secondary",Xt="textmode-export-overlay__button--full",qe="textmode-export-overlay__support-link",He="textmode-export-overlay__support-icon",je="textmode-export-overlay__link-icon";class N{element;mounted=!1;destroyed=!1;mount(t){if(this.destroyed)throw new Error("Cannot mount a destroyed component");if(this.mounted)return;const e=this.render();t.appendChild(e),this.element=e,this.onMount(),this.mounted=!0}unmount(){this.mounted&&this.element&&(this._onUnmount(),this.element.remove(),this.element=void 0,this.mounted=!1)}destroy(){this.destroyed||(this.unmount(),this._onDestroy(),this.destroyed=!0)}update(t){this.mounted&&this.onUpdate(t)}onMount(){}_onUnmount(){}_onDestroy(){}onUpdate(t){}get root(){if(!this.element)throw new Error("Component is not mounted yet");return this.element}isMounted(){return this.mounted}}class Y extends N{static _iconNamespace="http://www.w3.org/2000/svg";render(){const t=document.createElement("div");t.classList.add(z,dt,Le);const e=document.createElement("div");e.classList.add(Pe);const r=document.createElement("strong");r.textContent="textmode.export.js",r.classList.add(Ge);const a=document.createElement("div");a.classList.add(Ae);const i=this._createLink("https://github.com/humanbydefinition/textmode.export.js","View repository on GitHub",je,[{d:"M0 0h24v24H0z",fill:"none",stroke:"none"},{d:"M9 19c-4.3 1.4 -4.3 -2.5 -6 -3m12 5v-3.5c0 -1 .1 -1.4 -.5 -2c2.8 -.3 5.5 -1.4 5.5 -6a4.6 4.6 0 0 0 -1.3 -3.2a4.2 4.2 0 0 0 -.1 -3.2s-1.1 -.3 -3.5 1.3a12.3 12.3 0 0 0 -6.2 0c-2.4 -1.6 -3.5 -1.3 -3.5 -1.3a4.2 4.2 0 0 0 -.1 3.2a4.6 4.6 0 0 0 -1.3 3.2c0 4.6 2.7 5.7 5.5 6c-.6 .6 -.6 1.2 -.5 2v3.5"}]),n=this._createLink("https://code.textmode.art/support.html","Support textmode.export.js",He,[{d:"M0 0h24v24H0z",fill:"none",stroke:"none"},{d:"M3 14c.83 .642 2.077 1.017 3.5 1c1.423 .017 2.67 -.358 3.5 -1c.83 -.642 2.077 -1.017 3.5 -1c1.423 -.017 2.67 .358 3.5 1"},{d:"M8 3a2.4 2.4 0 0 0 -1 2a2.4 2.4 0 0 0 1 2"},{d:"M12 3a2.4 2.4 0 0 0 -1 2a2.4 2.4 0 0 0 1 2"},{d:"M3 10h14v5a6 6 0 0 1 -6 6h-2a6 6 0 0 1 -6 -6v-5z"},{d:"M16.746 16.726a3 3 0 1 0 .252 -5.555"}]);a.appendChild(i),a.appendChild(n),e.appendChild(r),e.appendChild(a);const u=document.createElement("div");return u.classList.add(ze),t.appendChild(e),t.appendChild(u),t}_createLink(t,e,r,a){const i=document.createElement("a");return i.href=t,i.target="_blank",i.rel="noopener noreferrer",i.classList.add(qe),i.setAttribute("aria-label",e),i.appendChild(this._createIcon(r,a)),i}_createIcon(t,e){const r=document.createElementNS(Y._iconNamespace,"svg");r.setAttribute("xmlns",Y._iconNamespace),r.setAttribute("width","18"),r.setAttribute("height","18"),r.setAttribute("viewBox","0 0 24 24"),r.setAttribute("fill","none"),r.setAttribute("stroke","currentColor"),r.setAttribute("stroke-width","2"),r.setAttribute("stroke-linecap","round"),r.setAttribute("stroke-linejoin","round"),r.classList.add(t);for(const a of e){const i=document.createElementNS(Y._iconNamespace,"path");for(const[n,u]of Object.entries(a))i.setAttribute(n,u);r.appendChild(i)}return r}}class R extends N{props;constructor(t){super(),this.props=t}render(){const t=document.createElement("div");t.classList.add(zt),this.applyVariant(t,this.props.variant);const e=document.createElement("label");if(e.classList.add(Nt),e.textContent=this.props.label,this.props.labelFor&&(e.htmlFor=this.props.labelFor),t.appendChild(e),this.props.description){const r=document.createElement("span");r.classList.add(Qt),r.textContent=this.props.description,t.appendChild(r)}return t}attachControl(t){this.root.appendChild(t)}update(t){this.props=t,super.update(t)}onUpdate(t){const e=this.root;for(;e.firstChild;)e.removeChild(e.firstChild);this.props=t,e.classList.add(zt),this.applyVariant(e,t.variant);const r=document.createElement("label");if(r.classList.add(Nt),r.textContent=t.label,t.labelFor&&(r.htmlFor=t.labelFor),e.appendChild(r),t.description){const a=document.createElement("span");a.classList.add(Qt),a.textContent=t.description,e.appendChild(a)}}applyVariant(t,e){switch(t.classList.remove(Gt,Wt,qt,Ht),e){case"compact":t.classList.add(Gt);break;case"dense":t.classList.add(Wt);break;case"full":t.classList.add(qt);break;case"channel":t.classList.add(Ht)}}}class pt extends N{props;select;handleChange=()=>{this.props.defaultValue=this.select.value};constructor(t){super(),this.props=t}render(){return this.select=document.createElement("select"),this.select.classList.add(jt),this.props.id&&(this.select.id=this.props.id),this.populateOptions(),this.select.addEventListener("change",this.handleChange),this.select}get selectElement(){return this.select}get value(){return this.select.value}set value(t){this.select&&(this.select.value=t),this.props.defaultValue=t}_onUnmount(){this.select.removeEventListener("change",this.handleChange)}onUpdate(t){this.props=t,this.populateOptions(),t.defaultValue&&(this.select.value=t.defaultValue)}update(t){this.props={...this.props,...t},this.select&&(t.id&&(this.select.id=t.id),t.options&&this.populateOptions(),t.defaultValue!==void 0&&(this.select.value=t.defaultValue))}populateOptions(){if(this.select){this.select.innerHTML="";for(const t of this.props.options){const e=document.createElement("option");e.value=t.value,e.textContent=t.label,this.select.appendChild(e)}this.props.defaultValue&&(this.select.value=this.props.defaultValue)}}}class Yt extends N{props;button;constructor(t){super(),this.props=t}render(){return this.button=document.createElement("button"),this.button.type="button",this.button.textContent=this.props.label,this.button.classList.add(We),this.props.variant==="secondary"?this.button.classList.add(ut):this.button.classList.add(ct),this.props.fullWidth&&this.button.classList.add(Xt),this.button.disabled=!!this.props.disabled,this.button}get buttonElement(){return this.button}setLabel(t){this.props.label=t,this.button.textContent=t}setDisabled(t){this.props.disabled=t,this.button.disabled=t}onUpdate(t){this.props=t,this.button.textContent=t.label,this.button.disabled=!!t.disabled,t.variant==="secondary"?(this.button.classList.add(ut),this.button.classList.remove(ct)):(this.button.classList.add(ct),this.button.classList.remove(ut)),this.button.classList.toggle(Xt,!!t.fullWidth)}}class Qe{api;constructor(t){this.api=t}async $copy(t,e){switch(t){case"txt":{const r=this.api.toString(e);await navigator.clipboard.writeText(r);break}case"svg":{const r=this.api.toSVG(e);await navigator.clipboard.writeText(r);break}case"image":await this.api.copyCanvas(e);break;default:throw new Error(`Clipboard not supported for ${t}`)}}}class Xe{api;events;constructor(t,e){this.api=t,this.events=e}async $requestExport(t,e,r={}){this.events.$emit("export:request",{format:t});try{const a={onGIFProgress:r.onGIFProgress?i=>{r.onGIFProgress?.(i),this.events.$emit("export:progress",{format:t,progress:i})}:t==="gif"?i=>this.events.$emit("export:progress",{format:t,progress:i}):void 0,onVideoProgress:r.onVideoProgress?i=>{r.onVideoProgress?.(i),this.events.$emit("export:progress",{format:t,progress:i})}:t==="video"?i=>this.events.$emit("export:progress",{format:t,progress:i}):void 0};await this._execute(t,e,a),this.events.$emit("export:success",{format:t})}catch(a){throw this.events.$emit("export:error",{format:t,error:a}),a}}_execute(t,e,r){switch(t){case"txt":return Promise.resolve(this.api.saveStrings(e));case"image":return this.api.saveCanvas(e);case"svg":return Promise.resolve(this.api.saveSVG(e));case"gif":{const a={...e,onProgress:r.onGIFProgress};return this.api.saveGIF(a)}case"video":{const a={...e,onProgress:r.onVideoProgress};return this.api.saveWEBM(a)}}}}class Ye{modifier;overlay;animationFrameId=null;handleUpdate;bound=!1;constructor(t,e){this.modifier=t,this.overlay=e,this.handleUpdate=()=>this.scheduleUpdate()}scheduleUpdate(){this.animationFrameId!==null&&cancelAnimationFrame(this.animationFrameId),this.animationFrameId=requestAnimationFrame(()=>this.update())}bind(){this.bound||(window.addEventListener("resize",this.handleUpdate),window.addEventListener("scroll",this.handleUpdate,!0),this.bound=!0,this.handleUpdate())}update(){this.animationFrameId=null;const t=this.modifier.canvas.getBoundingClientRect();this.overlay.style.top=`${t.top+window.scrollY+8}px`,this.overlay.style.left=`${t.left+window.scrollX+8}px`}dispose(){this.animationFrameId!==null&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),this.bound&&(window.removeEventListener("resize",this.handleUpdate),window.removeEventListener("scroll",this.handleUpdate,!0),this.bound=!1)}}const J="textmode-export-number-input",Je=`${J}__field`,Ze=`${J}__controls`,Ke=`${J}__control`,Jt=`${J}__display`,at=`${Jt}--visible`,Zt=c=>{const t=document.createElement("button");return t.type="button",t.className=Ke,t.textContent=c>0?"▲":"▼",t};class q extends N{props;input;display;incrementButton;decrementButton;suppressClickAfterPointer=new WeakMap;holdTimeoutId;holdIntervalId;activePointerId;disabledObserver;constructor(t){super(),this.props=t}render(){const t=document.createElement("div");t.className=J,this.input=document.createElement("input"),this.input.type="number",this.input.value=this.props.defaultValue,Object.assign(this.input,this.props.attributes),this.input.className=Je,this.display=document.createElement("div"),this.display.className=Jt;const e=document.createElement("div");return e.className=Ze,this.incrementButton=Zt(1),this.decrementButton=Zt(-1),e.appendChild(this.incrementButton),e.appendChild(this.decrementButton),t.appendChild(this.input),t.appendChild(this.display),t.appendChild(e),this.bindStepControls(),this.bindHoldBehavior(),this.bindInputListeners(),this.observeDisabledState(t),this.updateDisplay(),t}get inputElement(){return this.input}get value(){return this.input.value}set value(t){this.input.value=t,this.updateDisplay()}refresh(){this.updateDisplay()}_onDestroy(){this.clearHoldTimers(),this.disabledObserver?.disconnect()}bindStepControls(){const t=i=>()=>{if(this.input.disabled)return;const n=this.input.value,u=this.input.getAttribute("step");if(u&&u!=="any")i>0?this.input.stepUp():this.input.stepDown();else{const h=i>0?1:-1,o=Number.parseFloat(this.input.value||"0"),s=Number.isFinite(o)?o+h:h;this.input.value=String(s)}var l;this.input.value!==n&&((l=this.input).dispatchEvent(new Event("input",{bubbles:!0})),l.dispatchEvent(new Event("change",{bubbles:!0}))),this.updateDisplay(),this.input.focus({preventScroll:!0})},e=t(1),r=t(-1),a=(i,n)=>u=>{if(this.suppressClickAfterPointer.get(i))return this.suppressClickAfterPointer.set(i,!1),void u.preventDefault();n()};this.incrementButton.addEventListener("click",a(this.incrementButton,e)),this.decrementButton.addEventListener("click",a(this.decrementButton,r))}bindHoldBehavior(){const t=(e,r)=>{const a=r>0?()=>this.incrementButton.click():()=>this.decrementButton.click();e.addEventListener("pointerdown",u=>{if(u.button===0){u.preventDefault(),this.suppressClickAfterPointer.set(e,!0),this.activePointerId=u.pointerId;try{e.setPointerCapture(u.pointerId)}catch{}a(),this.holdTimeoutId=window.setTimeout(()=>{this.holdIntervalId=window.setInterval(a,80)},380)}});const i=()=>{if(this.activePointerId!==void 0){try{e.releasePointerCapture(this.activePointerId)}catch{}this.activePointerId=void 0}},n=()=>{this.clearHoldTimers(),i()};e.addEventListener("pointerup",n),e.addEventListener("pointerleave",n),e.addEventListener("pointercancel",n)};t(this.incrementButton,1),t(this.decrementButton,-1)}bindInputListeners(){const t=()=>{this.props.defaultValue=this.input.value,this.updateDisplay()};this.input.addEventListener("input",t),this.input.addEventListener("change",t)}observeDisabledState(t){const e=()=>{const r=this.input.disabled;this.incrementButton.disabled=r,this.decrementButton.disabled=r,t.classList.toggle("is-disabled",r),r?(this.display.classList.remove(at),this.input.style.removeProperty("color"),this.input.style.removeProperty("caretColor")):this.updateDisplay()};typeof MutationObserver<"u"&&(this.disabledObserver=new MutationObserver(e),this.disabledObserver.observe(this.input,{attributes:!0,attributeFilter:["disabled"]})),e()}updateDisplay(){const t=this.props.formatDisplay;if(!t)return this.display.textContent="",this.display.classList.remove(at),this.input.style.removeProperty("color"),void this.input.style.removeProperty("caretColor");const e=this.input.value,r=Number.parseFloat(e),a=t(Number.isFinite(r)?r:Number.NaN,e,this.input);a?(this.display.textContent=a,this.display.classList.add(at),this.input.style.color="transparent",this.input.style.caretColor="#f8fafc"):(this.display.textContent="",this.display.classList.remove(at),this.input.style.removeProperty("color"),this.input.style.removeProperty("caretColor"))}clearHoldTimers(){this.holdTimeoutId!==void 0&&(window.clearTimeout(this.holdTimeoutId),this.holdTimeoutId=void 0),this.holdIntervalId!==void 0&&(window.clearInterval(this.holdIntervalId),this.holdIntervalId=void 0)}}class Z extends N{variant;additionalClasses;constructor(t="stack",e=[]){super(),this.variant=t,this.additionalClasses=e}render(){const t=document.createElement("div"),e=[this.variant==="stack"?z:void 0,this.variant==="stackDense"?dt:void 0,this.variant==="stackCompact"?Tt:void 0,this.variant==="row"?Ve:void 0,this.variant==="section"?Rt:void 0,...this.additionalClasses].filter(Boolean);return t.classList.add(...e),t}}const Kt={neutral:"textmode-export-overlay__status-value--neutral",active:"textmode-export-overlay__status-value--active",alert:"textmode-export-overlay__status-value--alert"};class te extends N{props;container;messageElement;constructor(t){super(),this.props=t}render(){this.container=document.createElement("div"),this.container.classList.add(Oe),this.props.context==="gif"?this.container.classList.add(Ue):this.props.context==="video"&&this.container.classList.add(Te);const t=document.createElement("span");return t.classList.add(Re),t.textContent=this.props.title,this.messageElement=document.createElement("span"),this.messageElement.classList.add(Ne),this.messageElement.textContent=this.props.message,this.applyVariant(this.props.variant??"neutral"),this.container.appendChild(t),this.container.appendChild(this.messageElement),this.container}setMessage(t,e="neutral"){this.messageElement.textContent=t,this.applyVariant(e)}onUpdate(t){this.props=t,this.setMessage(t.message,t.variant??"neutral")}applyVariant(t){this.messageElement.classList.remove(...Object.values(Kt)),this.messageElement.classList.add(Kt[t])}}class K extends N{_config;_managedComponents=new Set;constructor(t){super(),this._config=t}_manageComponent(t){return this._managedComponents.add(t),t}_onUnmount(){for(const t of this._managedComponents)t.unmount()}_onDestroy(){for(const t of this._managedComponents)t.destroy();this._managedComponents.clear()}}const ee=300,re=60,ae=1,tr=0;class ht extends K{frameCountInput=this._manageComponent(new q({defaultValue:String(ee),attributes:{min:"1",max:"600",step:"1"}}));frameRateInput=this._manageComponent(new q({defaultValue:String(re),attributes:{min:"1",max:"60",step:"1"}}));scaleInput=this._manageComponent(new q({defaultValue:String(ae),attributes:{min:"0.1",max:"8",step:"0.1"}}));repeatInput=this._manageComponent(new q({defaultValue:"0",attributes:{min:"0",max:"50",step:"1"},formatDisplay:(t,e)=>Number.isFinite(t)?t===0?"∞":null:e.trim()===""?null:e}));status=this._manageComponent(new te({title:"status",message:"ready to record",variant:"neutral",context:"gif"}));recordingState="idle";constructor(t){super(t)}render(){const t=document.createElement("div");t.classList.add(z);const e=new Z("row");e.mount(t);const r=new R({label:"number of frames",labelFor:"textmode-export-gif-frame-count",variant:"dense"});r.mount(e.root),this.frameCountInput.mount(r.root),this.frameCountInput.inputElement.id="textmode-export-gif-frame-count";const a=new R({label:"frame rate (fps)",labelFor:"textmode-export-gif-frame-rate",variant:"dense"});a.mount(e.root),this.frameRateInput.mount(a.root),this.frameRateInput.inputElement.id="textmode-export-gif-frame-rate";const i=new Z("row");i.mount(t);const n=new R({label:"scale",labelFor:"textmode-export-gif-scale",variant:"dense"});n.mount(i.root),this.scaleInput.mount(n.root),this.scaleInput.inputElement.id="textmode-export-gif-scale";const u=new R({label:"loop count",labelFor:"textmode-export-gif-repeat",variant:"dense"});return u.mount(i.root),this.repeatInput.mount(u.root),this.repeatInput.inputElement.id="textmode-export-gif-repeat",this.status.mount(t),t}getOptions(){const t=this._config.defaultOptions??{};return{frameCount:this.safeParseInt(this.frameCountInput.value,t.frameCount??300),frameRate:this.safeParseInt(this.frameRateInput.value,t.frameRate??60),scale:this.safeParseFloat(this.scaleInput.value,t.scale??1),repeat:this.safeParseInt(this.repeatInput.value,t.repeat??0)}}reset(){this.recordingState="idle",this.applyDefaults(),this.setRecordingState("idle")}validate(){const t=Number.parseInt(this.frameCountInput.value,10),e=Number.parseInt(this.frameRateInput.value,10),r=Number.parseFloat(this.scaleInput.value);return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0&&Number.isFinite(r)&&r>0}isRecording(){return this.recordingState==="recording"}setRecordingState(t,e){this.recordingState=t;const r=t==="recording";switch(this.frameCountInput.inputElement.disabled=r,this.frameRateInput.inputElement.disabled=r,this.scaleInput.inputElement.disabled=r,this.repeatInput.inputElement.disabled=r,t){case"recording":if(e?.totalFrames){const a=e.frameIndex??0;this.status.setMessage(`recording ${a}/${e.totalFrames}`,"active")}else this.status.setMessage("recording…","active");break;case"completed":this.status.setMessage("GIF saved successfully","active");break;case"error":this.status.setMessage(e?.message??"failed to export GIF","alert");break;default:this.status.setMessage("ready to record","neutral")}}handleProgress(t){t.state==="recording"&&t.totalFrames?this.status.setMessage(`recording ${t.frameIndex??0}/${t.totalFrames}`,"active"):t.state==="completed"?this.status.setMessage("GIF saved successfully","active"):t.state==="error"&&this.status.setMessage(t.message??"failed to export GIF","alert")}applyDefaults(){const t=this._config.defaultOptions??{},e=t.frameCount??ee,r=t.frameRate??re,a=t.scale??ae,i=t.repeat??tr;this.frameCountInput.value=String(e),this.frameRateInput.value=String(r),this.scaleInput.value=String(a),this.repeatInput.value=String(i),this.frameCountInput.refresh(),this.frameRateInput.refresh(),this.scaleInput.refresh(),this.repeatInput.refresh()}safeParseInt(t,e){const r=Number.parseInt(t,10);return Number.isFinite(r)?r:e}safeParseFloat(t,e){const r=Number.parseFloat(t);return Number.isFinite(r)?r:e}}const it="textmode-export-range-input",er=`${it}__field`,rr=`${it}__tooltip`,mt=`${it}__tooltip--visible`,ot=(c,t)=>{if(typeof c!="string"||c.length===0)return t;const e=Number.parseFloat(c);return Number.isFinite(e)?e:t};class ar extends N{props;input;tooltip;hoverActive=!1;focusActive=!1;pointerActive=!1;suppressFocusFromPointer=!1;activePointerId;disabledObserver;resizeObserver;constructor(t){super(),this.props=t}render(){const t=document.createElement("div");return t.className=it,this.input=document.createElement("input"),this.input.type="range",this.input.value=this.props.defaultValue,Object.assign(this.input,this.props.attributes),this.input.className=er,this.tooltip=document.createElement("div"),this.tooltip.className=rr,t.appendChild(this.input),t.appendChild(this.tooltip),this.bindEvents(t),this.updateTooltip(),this.syncDisabledState(t),t}get inputElement(){return this.input}get value(){return this.input.value}set value(t){this.input.value=t,this.updateTooltip()}_onDestroy(){this.disabledObserver?.disconnect(),this.resizeObserver?.disconnect()}bindEvents(t){this.input.addEventListener("pointerenter",()=>{this.hoverActive=!0,this.refreshTooltipVisibility()}),this.input.addEventListener("pointerleave",()=>{this.hoverActive=!1,this.refreshTooltipVisibility()}),this.input.addEventListener("focus",()=>{let r=!1;try{r=this.input.matches(":focus-visible")}catch{r=!this.suppressFocusFromPointer}this.suppressFocusFromPointer||!r||this.input.disabled?this.focusActive=!1:this.focusActive=!0,this.suppressFocusFromPointer=!1,this.refreshTooltipVisibility()}),this.input.addEventListener("blur",()=>{this.focusActive=!1,this.refreshTooltipVisibility()}),this.input.addEventListener("pointerdown",r=>{this.pointerActive=!0,this.suppressFocusFromPointer=!0,this.hoverActive=!0,this.refreshTooltipVisibility();try{this.input.setPointerCapture(r.pointerId),this.activePointerId=r.pointerId}catch{this.activePointerId=void 0}});const e=()=>{this.pointerActive=!1,this.suppressFocusFromPointer=!1,this.hoverActive=this.input.matches(":hover"),this.releasePointerCapture(),this.refreshTooltipVisibility()};this.input.addEventListener("pointerup",e),this.input.addEventListener("pointercancel",e),this.input.addEventListener("lostpointercapture",e),this.input.addEventListener("input",()=>{(this.hoverActive||this.focusActive||this.pointerActive)&&this.updateTooltip(),this.props.defaultValue=this.input.value}),this.input.addEventListener("change",()=>{this.pointerActive||this.updateTooltip(),this.props.defaultValue=this.input.value}),typeof ResizeObserver<"u"&&(this.resizeObserver=new ResizeObserver(()=>{this.tooltip.classList.contains(mt)&&this.updateTooltipPosition()}),this.resizeObserver.observe(t))}refreshTooltipVisibility(){const t=(this.hoverActive||this.focusActive||this.pointerActive)&&!this.input.disabled;t&&this.updateTooltip(),this.tooltip.classList.toggle(mt,t)}syncDisabledState(t){const e=()=>{const r=this.input.disabled;t.classList.toggle("is-disabled",r),r&&(this.hoverActive=!1,this.focusActive=!1,this.pointerActive=!1,this.suppressFocusFromPointer=!1,this.releasePointerCapture(),this.tooltip.classList.remove(mt))};typeof MutationObserver<"u"&&(this.disabledObserver=new MutationObserver(e),this.disabledObserver.observe(this.input,{attributes:!0,attributeFilter:["disabled"]})),e()}releasePointerCapture(){if(this.activePointerId!==void 0){try{this.input.releasePointerCapture(this.activePointerId)}catch{}this.activePointerId=void 0}}updateTooltip(){this.updateTooltipContent(),this.updateTooltipPosition()}updateTooltipContent(){const t=this.props.formatValue??(r=>`${r}`),e=this.getCurrentValue();this.tooltip.textContent=t(e,this.input)}updateTooltipPosition(){const t=this.getMin(),e=this.getMax(),r=((n,u,l)=>Math.min(l,Math.max(u,n)))(this.getCurrentValue(),t,e),a=e-t,i=a===0?0:(r-t)/a;this.tooltip.style.left=100*i+"%"}getMin(){return ot(this.input.min,0)}getMax(){return ot(this.input.max,100)}getCurrentValue(){return ot(this.input.value,ot(this.props.defaultValue,0))}}function ir(c){return`${(function(e){if(!Number.isFinite(e))return"default quality";const r=Math.max(0,Math.min(1,e));return r>=.995?"near-lossless":r>=.98?"maximum detail":r>=.88?"ultra quality":r>=.7?"high quality":r>=.5?"balanced":r>=.25?"compact":r>=.1?"lightweight":"draft"})(c)} (quality ≈ ${c.toFixed(3)})`}class ft extends K{frameRateInput=this._manageComponent(new q({defaultValue:String(60),attributes:{min:String(1),max:String(60),step:"1"},formatDisplay:t=>Number.isFinite(t)?`${t} fps`:null}));frameCountInput=this._manageComponent(new q({defaultValue:String(480),attributes:{min:String(1),max:String(3600),step:"1"}}));qualityInput=this._manageComponent(new ar({defaultValue:String(.7),attributes:{min:String(0),max:String(1),step:"0.001"},formatValue:t=>ir(t)}));status=this._manageComponent(new te({title:"status",message:"ready to record",variant:"neutral",context:"video"}));recordingState="idle";constructor(t){super(t)}render(){const t=document.createElement("div");t.classList.add(z);const e=new Z("row");e.mount(t);const r=new R({label:"number of frames",labelFor:"textmode-export-video-frame-count",variant:"compact"});r.mount(e.root),this.frameCountInput.mount(r.root),this.frameCountInput.inputElement.id="textmode-export-video-frame-count";const a=new R({label:"frame rate (fps)",labelFor:"textmode-export-video-frame-rate",variant:"compact"});a.mount(e.root),this.frameRateInput.mount(a.root),this.frameRateInput.inputElement.id="textmode-export-video-frame-rate";const i=new R({label:"quality",labelFor:"textmode-export-video-quality",variant:"full"});return i.mount(t),this.qualityInput.mount(i.root),this.qualityInput.inputElement.id="textmode-export-video-quality",this.status.mount(t),t}getOptions(){const t=this._config.defaultOptions??{},e=Number.parseInt(this.frameCountInput.value,10),r=Number.parseFloat(this.frameRateInput.value),a=Number.parseFloat(this.qualityInput.value);return{frameCount:Number.isFinite(e)?e:t.frameCount??480,frameRate:Number.isFinite(r)?r:t.frameRate??60,quality:Number.isFinite(a)?a:t.quality??.7}}reset(){this.recordingState="idle",this.applyDefaults(),this.status.setMessage("ready to record","neutral")}validate(){const t=Number.parseInt(this.frameCountInput.value,10),e=Number.parseFloat(this.frameRateInput.value);return Number.isFinite(t)&&t>=1&&Number.isFinite(e)&&e>=1}isRecording(){return this.recordingState==="recording"}setRecordingState(t,e){this.recordingState=t;const r=t==="recording";this.frameCountInput.inputElement.disabled=r,this.frameRateInput.inputElement.disabled=r,this.qualityInput.inputElement.disabled=r,this.syncStatus(t,e)}handleProgress(t){this.syncStatus(t.state,t)}syncStatus(t,e){switch(t){case"recording":{const r=e?.frameIndex??0,a=e?.totalFrames??this.resolvePlannedFrameCount();if(a){const i=Math.min(Math.max(0,Math.round(r)),a);this.status.setMessage(`recording ${i}/${a} frames`,"active")}else this.status.setMessage(`recording ${Math.max(0,Math.round(r))} frames`,"active");break}case"completed":this.status.setMessage("saved to disk","active");break;case"error":this.status.setMessage(e?.message?`error: ${e.message}`:"recording failed","alert");break;default:this.status.setMessage("ready to record","neutral")}}resolvePlannedFrameCount(){const t=Number.parseInt(this.frameCountInput.value,10);return Number.isFinite(t)&&t>0?Math.round(t):void 0}applyDefaults(){const t=this._config.defaultOptions??{},e=t.frameCount??480,r=t.frameRate??60,a=t.quality??.7;this.frameCountInput.value=String(e),this.frameRateInput.value=String(r),this.qualityInput.value=String(a),this.frameCountInput.refresh(),this.frameRateInput.refresh()}}class or{_textmodifier;_state;_events;_exportService;_clipboardService;_definitions;_formats=new Map;_eventUnsubscribers=[];_shadowHost;_shadowRoot;_overlayElement;_optionsContainer;_copyButtonContainer;_positionService;_header=new Y;_formatField=new R({label:"export format",labelFor:"textmode-export-format",variant:"full"});_formatSelect=new pt({id:"textmode-export-format",options:[]});_exportButton=new Yt({label:"download file",fullWidth:!0,variant:"primary"});_copyButton=new Yt({label:"copy to clipboard",fullWidth:!0,variant:"primary"});_currentFormat;_currentBlade;_handleFormatSelectChange=()=>{this._handleFormatChange(this._formatSelect.value)};_handleExportClickSafe=()=>{this._handleExportClick().catch(t=>{console.error("[textmode-export] Export failed",t)})};_handleCopyClickSafe=()=>{this._handleCopyClick().catch(t=>{console.error("[textmode-export] Copy failed",t)})};constructor(t,e,r,a,i){this._textmodifier=t,this._state=r,this._events=a,this._exportService=new Xe(e,a),this._clipboardService=new Qe(e),this._definitions=i,this._currentFormat=r.snapshot.format,this._initializeFormatMap(),this._registerEventHandlers()}$mount(){this._createOverlay(),this._renderStaticContent(),this._positionService=new Ye(this._textmodifier,this._shadowHost),this._positionService.bind(),this._switchFormat(this._currentFormat)}$dispose(){this._formatSelect.isMounted()&&this._formatSelect.selectElement.removeEventListener("change",this._handleFormatSelectChange),this._exportButton.isMounted()&&this._exportButton.buttonElement.removeEventListener("click",this._handleExportClickSafe),this._copyButton.isMounted()&&this._copyButton.buttonElement.removeEventListener("click",this._handleCopyClickSafe);for(const t of this._eventUnsubscribers)t();this._eventUnsubscribers.length=0,this._events.$clear();for(const t of this._formats.values())t.blade.destroy();this._formats.clear(),this._currentBlade=void 0,this._shadowHost?.isConnected&&this._shadowHost.remove(),this._positionService?.dispose()}_initializeFormatMap(){for(const t of this._definitions){const e=t.createBlade();this._formats.set(t.format,{definition:t,blade:e,initialized:!1})}}_createOverlay(){this._shadowHost=document.createElement("div"),this._shadowHost.dataset.plugin="textmode-export-overlay-host",this._shadowHost.style.cssText="position: absolute; top: 0; left: 0; pointer-events: none; z-index: 2147483647;",this._shadowRoot=this._shadowHost.attachShadow({mode:"open"});const t=document.createElement("style");t.textContent=`@layer textmode-export-overlay{.textmode-export-overlay{--overlay-bg: rgba(20, 20, 20, .8);--overlay-surface: rgba(40, 40, 40, .9);--overlay-border: rgba(255, 255, 255, .14);--overlay-border-strong: rgba(255, 255, 255, .2);--overlay-border-focus: rgba(160, 160, 160, .6);--overlay-focus-shadow: 0 0 0 1px rgba(140, 140, 140, .28);--overlay-text: #ffffff;--overlay-muted: rgba(200, 200, 200, .74);--overlay-radius: .75rem;--overlay-stack-gap: .55rem;position:absolute;top:0;left:0;display:flex;flex-direction:column;gap:var(--overlay-stack-gap);min-width:236px;max-width:236px;padding:.65rem .8rem;background:var(--overlay-bg);color:var(--overlay-text);border-radius:var(--overlay-radius);border:1px solid var(--overlay-border);box-shadow:0 12px 28px #0000004d;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-size:.82rem;line-height:1.35;pointer-events:auto;z-index:2147483647}.textmode-export-overlay *{box-sizing:border-box}.textmode-export-overlay__header{display:flex;flex-direction:column;gap:.4rem}.textmode-export-overlay__header-title-row{display:flex;align-items:center;justify-content:space-between;gap:.4rem}.textmode-export-overlay__header-links{display:inline-flex;align-items:center;gap:.3rem}.textmode-export-overlay__support-link{display:inline-flex;align-items:center;justify-content:center;padding:.2rem;border-radius:.45rem;border:1px solid transparent;color:#d7d7d7d1;background:transparent;text-decoration:none;line-height:0;transition:background .18s ease,color .18s ease,transform .18s ease,border-color .18s ease}.textmode-export-overlay__support-link:hover{color:#fff;background:#5a5a5a4d;border-color:#c8c8c824}.textmode-export-overlay__support-link:focus-visible{outline:none;border-color:var(--overlay-border-focus);box-shadow:var(--overlay-focus-shadow)}.textmode-export-overlay__support-icon,.textmode-export-overlay__link-icon{display:block;width:1rem;height:1rem}.textmode-export-overlay__stack{display:flex;flex-direction:column;gap:var(--overlay-stack-gap)}.textmode-export-overlay__stack--dense{gap:.3rem}.textmode-export-overlay__stack--compact{gap:.45rem}.textmode-export-overlay__section{display:flex;flex-direction:column;gap:.4rem}.textmode-export-overlay__title{font-size:.92rem;font-weight:600}.textmode-export-overlay__divider{width:100%;height:1px;background:#ffffff29;margin-top:.25rem}.textmode-export-overlay__label{font-weight:500;opacity:.9}.textmode-export-overlay__checkbox{display:flex;align-items:center;gap:.5rem}.textmode-export-overlay__checkbox input[type=checkbox]{width:1rem;height:1rem;accent-color:rgba(100,100,100,.9)}.textmode-export-overlay__row{display:flex;gap:.6rem;flex-wrap:wrap;align-items:flex-start;width:100%}.textmode-export-overlay__field{display:flex;flex-direction:column;gap:.3rem;flex:1 1 120px;min-width:120px}.textmode-export-overlay__field--compact{flex:1 1 100px;min-width:100px}.textmode-export-overlay__field--dense{flex:1 1 90px;min-width:90px}.textmode-export-overlay__field--channel{flex:1 1 0;min-width:0}.textmode-export-overlay__field--full{width:100%;flex:1 1 100%}.textmode-export-overlay__input,.textmode-export-overlay select.textmode-export-overlay__input,.textmode-export-overlay input.textmode-export-overlay__input{width:100%;padding:.35rem .5rem;border-radius:.4rem;border:1px solid var(--overlay-border-strong);background:var(--overlay-surface);color:var(--overlay-text);font:inherit;line-height:1.35;transition:border-color .18s ease,box-shadow .18s ease,background .18s ease}.textmode-export-overlay select.textmode-export-overlay__input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='rgba(200, 200, 200, 0.74)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .5rem center;background-size:1rem;padding-right:2rem}.textmode-export-overlay__input:focus{outline:none;border-color:var(--overlay-border-focus);box-shadow:var(--overlay-focus-shadow);background:#2d2f42eb}.textmode-export-overlay__input::placeholder{color:var(--overlay-muted);opacity:.7}.textmode-export-overlay__muted{font-size:.75rem;opacity:.7;display:block}.textmode-export-overlay__button{display:inline-flex;align-items:center;justify-content:center;gap:.35rem;border-radius:.45rem;border:none;font-weight:600;padding:.45rem .7rem;cursor:pointer;transition:background .2s ease,transform .2s ease,box-shadow .2s ease}.textmode-export-overlay__button--primary{background:#505050;color:#fff}.textmode-export-overlay__button--secondary{background:#606060;color:#fff}.textmode-export-overlay__button--full{width:100%}.textmode-export-overlay__button:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 7px 18px #00000073}.textmode-export-overlay__button--primary:hover:not(:disabled){background:#404040}.textmode-export-overlay__button--secondary:hover:not(:disabled){background:#4a4a4a}.textmode-export-overlay__button:disabled{cursor:default;opacity:.55;transform:none;box-shadow:none}.textmode-export-overlay__status{display:flex;flex-direction:column;gap:.25rem;padding:.45rem .55rem;border-radius:.45rem;border:1px solid rgba(110,110,110,.22);background:#4646462e}.textmode-export-overlay__status--gif{background:#5050501f;border-color:#78787840}.textmode-export-overlay__status--video{background:#4646461f;border-color:#6e6e6e40}.textmode-export-overlay__status-title{font-weight:600;font-size:.75rem;opacity:.85;text-transform:uppercase;letter-spacing:.04em}.textmode-export-overlay__status-value{font-size:.82rem;color:#dedede;transition:color .18s ease}.textmode-export-overlay__status-value--neutral{color:#cfcfcf}.textmode-export-overlay__status-value--active{color:#f5f5f5}.textmode-export-overlay__status-value--alert{color:#b8b8b8}.textmode-export-number-input,.textmode-export-overlay .textmode-export-number-input{display:flex;align-items:stretch;width:100%;background:var(--overlay-surface);border:1px solid var(--overlay-border-strong);border-radius:.4rem;overflow:hidden;transition:border-color .18s ease,box-shadow .18s ease,background .18s ease;position:relative}.textmode-export-number-input:focus-within{border-color:var(--overlay-border-focus);box-shadow:var(--overlay-focus-shadow)}.textmode-export-number-input.is-disabled{opacity:.55}.textmode-export-number-input__field{flex:1 1 auto;min-width:0;border:none;background:transparent;color:var(--overlay-text);font:inherit;padding:.35rem .5rem;appearance:textfield}.textmode-export-number-input__field::-webkit-outer-spin-button,.textmode-export-number-input__field::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.textmode-export-number-input__field:focus{outline:none}.textmode-export-number-input__controls{display:flex;flex-direction:column;border-left:1px solid rgba(255,255,255,.12);min-width:1.6rem}.textmode-export-number-input__control{display:flex;align-items:center;justify-content:center;width:100%;flex:1;border:none;background:#32323299;color:#d0d0d0;font-size:.68rem;line-height:1;cursor:pointer;transition:background .15s ease,color .15s ease;padding:0}.textmode-export-number-input__control:hover:not(:disabled){background:#5a5a5ad9;color:#fff}.textmode-export-number-input__control:disabled{cursor:default;opacity:.4;background:#28282880;color:#c8c8c866}.textmode-export-number-input:focus-within .textmode-export-number-input__control{background:#3c3c3cbf;color:#e8e8e8}.textmode-export-number-input__display{position:absolute;inset:0;display:flex;align-items:center;padding:.4rem .55rem;pointer-events:none;color:#f8fafc;opacity:0;transition:opacity .14s ease}.textmode-export-number-input__display--visible{opacity:1}.textmode-export-range-input{position:relative;width:100%}.textmode-export-range-input.is-disabled{opacity:.55}.textmode-export-range-input__field{width:100%;height:1.4rem;padding:0;margin:0;background:transparent;cursor:pointer;appearance:none;-webkit-appearance:none}.textmode-export-range-input__field::-webkit-slider-thumb{width:12px;height:12px;margin-top:-3.5px;-webkit-appearance:none;border-radius:50%;background:#a0a0a0;border:2px solid #303030;box-shadow:0 0 0 2px #00000059}.textmode-export-range-input__field::-webkit-slider-runnable-track{height:5px;border-radius:999px;background:linear-gradient(90deg,#8c8c8cd9,#646464a6)}.textmode-export-range-input__field::-moz-range-thumb{width:12px;height:12px;border-radius:50%;background:#a0a0a0;border:2px solid #303030;margin-top:-3.5px}.textmode-export-range-input__field::-moz-range-track{height:5px;border-radius:999px;background:linear-gradient(90deg,#8c8c8cd9,#646464a6)}.textmode-export-range-input__tooltip{position:absolute;top:-1.5rem;left:0;transform:translate(-50%);padding:.2rem .35rem;border-radius:.35rem;background:#1e1e1ee0;color:#f8fafc;font-size:.68rem;line-height:1;white-space:nowrap;pointer-events:none;opacity:0;transition:opacity .15s ease}.textmode-export-range-input__tooltip--visible{opacity:1}}`,this._shadowRoot.appendChild(t),this._overlayElement=document.createElement("div"),this._overlayElement.dataset.plugin="textmode-export-overlay",this._overlayElement.classList.add(Se,z),this._shadowRoot.appendChild(this._overlayElement),document.body.appendChild(this._shadowHost)}_renderStaticContent(){this._header.mount(this._overlayElement);const t=document.createElement("div");t.classList.add(Rt),this._overlayElement.appendChild(t),this._formatField.mount(t),this._prepareFormatOptions(),this._formatSelect.mount(this._formatField.root),this._formatSelect.selectElement.addEventListener("change",this._handleFormatSelectChange),this._optionsContainer=document.createElement("div"),this._optionsContainer.classList.add(z,Tt),this._overlayElement.appendChild(this._optionsContainer),this._exportButton.mount(this._overlayElement),this._exportButton.buttonElement.addEventListener("click",this._handleExportClickSafe),this._copyButtonContainer=document.createElement("div"),this._copyButtonContainer.classList.add(z,dt),this._overlayElement.appendChild(this._copyButtonContainer),this._copyButton.mount(this._copyButtonContainer),this._copyButton.buttonElement.dataset.defaultLabel="copy to clipboard",this._copyButton.buttonElement.addEventListener("click",this._handleCopyClickSafe)}_prepareFormatOptions(){const t=this._definitions.map(e=>({value:e.format,label:e.label}));this._formatSelect.update({options:t,defaultValue:this._currentFormat})}_registerEventHandlers(){this._eventUnsubscribers.push(this._events.$on("export:request",({format:t})=>{t===this._currentFormat&&(this._state.$set({isBusy:!0,error:void 0}),this._updateExportButton())}),this._events.$on("export:success",({format:t})=>{if(t===this._currentFormat){const e={isBusy:!1};t==="gif"&&(e.gifProgress=void 0),t==="video"&&(e.videoProgress=void 0),this._state.$set(e),this._updateExportButton()}}),this._events.$on("export:error",({format:t,error:e})=>{t===this._currentFormat&&(this._state.$set({isBusy:!1,error:e}),this._updateExportButton())}),this._events.$on("export:progress",({format:t,progress:e})=>{if(e){if(t==="gif"&&this._currentBlade?.blade instanceof ht){const r=e;this._state.$set({gifProgress:r}),this._currentBlade.blade.handleProgress(r)}else if(t==="video"&&this._currentBlade?.blade instanceof ft){const r=e;this._state.$set({videoProgress:r}),this._currentBlade.blade.handleProgress(r)}this._updateExportButton()}}))}_handleFormatChange(t){this._currentFormat=t,this._state.$set({format:t}),this._switchFormat(t),this._events.$emit("format:change",{format:t})}_switchFormat(t){const e=this._formats.get(t);if(!e)throw new Error(`Unknown export format: ${t}`);this._currentBlade&&this._currentBlade.blade.unmount(),this._optionsContainer.innerHTML="",e.blade.mount(this._optionsContainer),e.initialized||(e.blade.reset(),e.initialized=!0),this._currentBlade=e,this._formatSelect.value=t,this._updateCopyButtonState(),this._updateExportButton(),this._positionService?.scheduleUpdate()}_updateCopyButtonState(){const t=this._currentBlade?.definition.supportsClipboard??!1;this._copyButtonContainer.style.display=t?"flex":"none",this._copyButton.setDisabled(!t)}async _handleExportClick(){if(!this._currentBlade)return;const t=this._currentBlade.definition.format,e=this._currentBlade.blade.getOptions();if(this._currentBlade.blade.validate()){if(t==="gif"){const r=this._currentBlade.blade;if(r.isRecording())return;r.setRecordingState("recording");try{await this._exportService.$requestExport("gif",e,{onGIFProgress:a=>{r.setRecordingState(a.state,a)}})}catch(a){throw r.setRecordingState("error"),a}return void window.setTimeout(()=>{r.setRecordingState("idle"),this._updateExportButton()},1600)}if(t==="video"){const r=this._currentBlade.blade;if(r.isRecording())return;r.setRecordingState("recording");try{await this._exportService.$requestExport("video",e,{onVideoProgress:a=>{r.setRecordingState(a.state,a)}})}catch(a){throw r.setRecordingState("error"),a}return void window.setTimeout(()=>{r.setRecordingState("idle"),this._updateExportButton()},1600)}this._exportButton.setDisabled(!0),this._exportButton.setLabel("exporting…");try{await this._exportService.$requestExport(t,e)}finally{this._exportButton.setDisabled(!1),this._exportButton.setLabel("download file")}}else console.warn("[textmode-export] Export options failed validation")}async _handleCopyClick(){if(!this._currentBlade||!this._currentBlade.definition.supportsClipboard)return;const t=this._currentBlade.definition.format,e=this._currentBlade.blade.getOptions(),r=this._copyButton.buttonElement.dataset.defaultLabel??"copy to clipboard";this._copyButton.setDisabled(!0),this._copyButton.setLabel("copying…");try{await this._clipboardService.$copy(t,e),this._copyButton.setLabel("copied!")}catch(a){console.error("[textmode-export] Failed to copy to clipboard",a),this._copyButton.setLabel("copy failed!")}finally{window.setTimeout(()=>{this._copyButton.setLabel(r),this._copyButton.setDisabled(!1)},1200)}}_updateExportButton(){if(!this._currentBlade)return;const t=this._currentBlade.definition.format;if(t==="gif"&&this._currentBlade.blade instanceof ht){const r=this._currentBlade.blade,a=this._state.snapshot.gifProgress;if(r.isRecording())if(this._exportButton.setDisabled(!0),a?.totalFrames){const i=a.frameIndex??0;this._exportButton.setLabel(`recording ${i}/${a.totalFrames}`)}else this._exportButton.setLabel("recording…");else this._exportButton.setDisabled(!1),this._exportButton.setLabel("start recording");return}if(t==="video"&&this._currentBlade.blade instanceof ft){const r=this._currentBlade.blade,a=this._state.snapshot.videoProgress;if(r.isRecording())if(this._exportButton.setDisabled(!0),a?.totalFrames){const i=a.frameIndex??0;this._exportButton.setLabel(`recording ${i}/${a.totalFrames} frames`)}else this._exportButton.setLabel("recording…");else this._exportButton.setDisabled(!1),this._exportButton.setLabel("start recording");return}const e=this._state.snapshot.isBusy;this._exportButton.setDisabled(e),this._exportButton.setLabel(e?"exporting…":"download file")}}class nr{_listeners=new Map;$on(t,e){this._listeners.has(t)||this._listeners.set(t,new Set);const r=this._listeners.get(t);return r.add(e),()=>{r.delete(e),r.size===0&&this._listeners.delete(t)}}$emit(t,e){const r=this._listeners.get(t);if(r)for(const a of[...r])try{a(e)}catch(i){console.error("[textmode-export] Event handler failed",i)}}$clear(){this._listeners.clear()}}class sr{_state;_listeners=new Set;constructor(t){this._state=t}get snapshot(){return Object.freeze({...this._state})}$set(t){this._state=Object.assign({},this._state,t);const e=this.snapshot;for(const r of[...this._listeners])try{r(e)}catch(a){console.error("[textmode-export] State listener failed",a)}}$subscribe(t){return this._listeners.add(t),t(this.snapshot),()=>{this._listeners.delete(t)}}$reset(t){this._state=t;const e=this.snapshot;for(const r of[...this._listeners])r(e)}}class ie extends N{props;checkbox;labelElement;handleChange=()=>{this.props.defaultChecked=this.checkbox.checked};constructor(t){super(),this.props=t}render(){this.labelElement=document.createElement("label"),this.labelElement.classList.add(De),this.checkbox=document.createElement("input"),this.checkbox.type="checkbox",this.props.id&&(this.checkbox.id=this.props.id),this.checkbox.checked=!!this.props.defaultChecked,this.checkbox.addEventListener("change",this.handleChange);const t=document.createElement("span");return t.textContent=this.props.label,this.labelElement.htmlFor=this.props.id??"",this.labelElement.appendChild(this.checkbox),this.labelElement.appendChild(t),this.labelElement}get inputElement(){return this.checkbox}get checked(){return this.checkbox.checked}set checked(t){this.checkbox.checked=t}_onUnmount(){this.checkbox.removeEventListener("change",this.handleChange)}onUpdate(t){this.props=t,t.id&&(this.checkbox.id=t.id,this.labelElement.htmlFor=t.id),this.checkbox.checked=!!t.defaultChecked,this.labelElement.lastElementChild&&(this.labelElement.lastElementChild.textContent=t.label)}}class lr extends N{props;input;handleInput=()=>{this.props.defaultValue=this.input.value};constructor(t){super(),this.props=t}render(){return this.input=document.createElement("input"),this.input.type="text",this.input.classList.add(jt),this.props.id&&(this.input.id=this.props.id),this.props.maxLength!==void 0&&(this.input.maxLength=this.props.maxLength),this.props.defaultValue!==void 0&&(this.input.value=this.props.defaultValue),this.input.addEventListener("input",this.handleInput),this.input}get inputElement(){return this.input}get value(){return this.input.value}set value(t){this.input.value=t}_onUnmount(){this.input.removeEventListener("input",this.handleInput)}onUpdate(t){this.props=t,t.id&&(this.input.id=t.id),t.maxLength!==void 0&&(this.input.maxLength=t.maxLength),t.defaultValue!==void 0&&(this.input.value=t.defaultValue)}}class dr extends K{trailingSpaces=this._manageComponent(new ie({label:"preserve trailing spaces",defaultChecked:!1}));emptyCharacter=this._manageComponent(new lr({id:"textmode-export-empty-character",defaultValue:" ",maxLength:1}));constructor(t){super(t)}render(){const t=document.createElement("div");t.classList.add(z),this.trailingSpaces.mount(t);const e=new R({label:"empty character",labelFor:"textmode-export-empty-character",variant:"full"});return e.mount(t),this.emptyCharacter.mount(e.root),t}getOptions(){const t=this._config.defaultOptions??{},e=this.emptyCharacter.value||t.emptyCharacter||" ";return{preserveTrailingSpaces:this.trailingSpaces.checked,emptyCharacter:e}}reset(){this.applyDefaults()}validate(){return this.emptyCharacter.value.length<=1}applyDefaults(){const t=this._config.defaultOptions??{};this.trailingSpaces.checked=t.preserveTrailingSpaces??!1,this.emptyCharacter.value=t.emptyCharacter??" "}}class cr extends K{formatSelect=this._manageComponent(new pt({id:"textmode-export-image-format",options:[{value:"png",label:`PNG (${de})`},{value:"jpg",label:`JPG (${ce})`},{value:"webp",label:`WEBP (${ue})`}],defaultValue:"png"}));scaleInput=this._manageComponent(new q({defaultValue:"1",attributes:{min:"0.1",step:"0.1"}}));constructor(t){super(t)}render(){const t=document.createElement("div");t.classList.add(z);const e=new Z("row");e.mount(t);const r=new R({label:"image format",labelFor:"textmode-export-image-format",variant:"compact"});r.mount(e.root),this.formatSelect.mount(r.root);const a=new R({label:"scale",labelFor:"textmode-export-image-scale",variant:"dense"});return a.mount(e.root),this.scaleInput.mount(a.root),this.scaleInput.inputElement.id="textmode-export-image-scale",t}getOptions(){const t=Number.parseFloat(this.scaleInput.value);return{format:this.formatSelect.value,scale:Number.isFinite(t)?t:this._config.defaultOptions?.scale??1}}reset(){this.applyDefaults(),this.scaleInput.refresh()}validate(){const t=Number.parseFloat(this.scaleInput.value);return Number.isFinite(t)&&t>0}applyDefaults(){const t=this._config.defaultOptions??{};this.formatSelect.value=t.format??"png";const e=t.scale??1;this.scaleInput.value=String(e)}}class ur extends K{includeBackground=this._manageComponent(new ie({id:"textmode-export-svg-include-backgrounds",label:"include cell backgrounds",defaultChecked:!0}));drawMode=this._manageComponent(new pt({id:"textmode-export-svg-draw-mode",options:[{value:"fill",label:"fill"},{value:"stroke",label:"stroke"}],defaultValue:"fill"}));strokeWidth=this._manageComponent(new q({defaultValue:"1",attributes:{min:"0",step:"0.1"}}));constructor(t){super(t)}render(){const t=document.createElement("div");t.classList.add(z),this.includeBackground.mount(t);const e=new Z("row");e.mount(t);const r=new R({label:"draw mode",labelFor:"textmode-export-svg-draw-mode",variant:"compact"});r.mount(e.root),this.drawMode.mount(r.root);const a=new R({label:"stroke width",labelFor:"textmode-export-svg-stroke-width",variant:"compact"});return a.mount(e.root),this.strokeWidth.mount(a.root),this.strokeWidth.inputElement.id="textmode-export-svg-stroke-width",this.drawMode.selectElement.addEventListener("change",()=>this.updateStrokeControls()),this.updateStrokeControls(),t}getOptions(){return{includeBackgroundRectangles:this.includeBackground.checked,drawMode:this.drawMode.value,strokeWidth:Number.parseFloat(this.strokeWidth.value)}}reset(){this.applyDefaults(),this.updateStrokeControls()}validate(){const t=Number.parseFloat(this.strokeWidth.value);return this.drawMode.value!=="stroke"||Number.isFinite(t)&&t>=0}updateStrokeControls(){const t=this.drawMode.value==="stroke";this.strokeWidth.inputElement.disabled=!t,this.strokeWidth.refresh()}applyDefaults(){const t=this._config.defaultOptions??{};this.includeBackground.checked=t.includeBackgroundRectangles??!0,this.drawMode.value=t.drawMode??"fill";const e=t.strokeWidth??1;this.strokeWidth.value=String(e),this.strokeWidth.refresh()}}const pr=[{format:"txt",label:"plain text (.txt)",supportsClipboard:!0,createBlade:()=>new dr({format:"txt",label:"plain text (.txt)",supportsClipboard:!0,defaultOptions:{preserveTrailingSpaces:!1,emptyCharacter:" "}})},{format:"image",label:"image (.png / .jpg / .webp)",supportsClipboard:!0,createBlade:()=>new cr({format:"image",label:"image (.png / .jpg / .webp)",supportsClipboard:!0,defaultOptions:{format:"png",scale:1}})},{format:"svg",label:"vector (.svg)",supportsClipboard:!0,createBlade:()=>new ur({format:"svg",label:"vector (.svg)",supportsClipboard:!0,defaultOptions:{includeBackgroundRectangles:!0,drawMode:"fill",strokeWidth:1}})},{format:"gif",label:"animated GIF (.gif)",supportsClipboard:!1,createBlade:()=>new ht({format:"gif",label:"animated GIF (.gif)",supportsClipboard:!1,defaultOptions:{frameCount:300,frameRate:60,scale:1,repeat:0}})},{format:"video",label:"video (.webm)",supportsClipboard:!1,createBlade:()=>new ft({format:"video",label:"video (.webm)",supportsClipboard:!1,defaultOptions:{frameCount:480,frameRate:60,quality:.7}})}];function hr(c,t){const e=pr,r=e[0]?.format,a=new sr((u=>({format:u,isBusy:!1}))(r)),i=new nr,n=new or(c,t,a,i,e);return n.$mount(),n}const oe=(c={})=>{const t=c.overlay??!0;let e;return{name:"textmode-export",version:"1.0.0",async install(r,a){const i={saveCanvas:async(n={})=>new yt().$saveImage(r.canvas,n),copyCanvas:async(n={})=>new yt().$copyImageToClipboard(r.canvas,n),saveSVG:(n={})=>{new xt().$saveSVG(r,n)},saveStrings:(n={})=>{new _t().$saveTXT(r,n)},toSVG:(n={})=>new xt().$generateSVG(r,n),toString:(n={})=>new _t().$generateTXT(r,n),saveGIF:async(n={})=>new we(r,a.registerPostDrawHook).$saveGIF(n),saveWEBM:async(n={})=>new $e(r,a.registerPostDrawHook).$saveWEBM(n)};Object.assign(r,i),t&&(e=hr(r,i))},async uninstall(r){e?.$dispose(),e=void 0;const a=["saveCanvas","copyCanvas","saveSVG","saveStrings","toSVG","toString","saveGIF","saveWEBM"];for(const i of a)delete r[i]}}};typeof window<"u"&&(window.createTextmodeExportPlugin=oe),Q.createTextmodeExportPlugin=oe,Object.defineProperty(Q,Symbol.toStringTag,{value:"Module"})});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataExtractor.d.ts","sourceRoot":"","sources":["../../../../src/exporters/base/DataExtractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD;;;GAGG;AACH,qBAAa,aAAa;IACtB;;;;OAIG;IACI,uBAAuB,CAAC,WAAW,EAAE,mBAAmB,GAAG,eAAe;
|
|
1
|
+
{"version":3,"file":"DataExtractor.d.ts","sourceRoot":"","sources":["../../../../src/exporters/base/DataExtractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD;;;GAGG;AACH,qBAAa,aAAa;IACtB;;;;OAIG;IACI,uBAAuB,CAAC,WAAW,EAAE,mBAAmB,GAAG,eAAe;IAQjF;;;;;;OAMG;IACI,kBAAkB,CAAC,eAAe,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM;CAMrF"}
|
|
@@ -7,9 +7,8 @@ import type { TextmodeGrid } from 'textmode.js';
|
|
|
7
7
|
*/
|
|
8
8
|
export declare class SVGDataExtractor extends DataExtractor {
|
|
9
9
|
/**
|
|
10
|
-
* Extracts transform data from
|
|
11
|
-
* @param
|
|
12
|
-
* @param rotationPixels Rotation framebuffer pixels
|
|
10
|
+
* Extracts transform data from character pixels
|
|
11
|
+
* @param characterPixels Character framebuffer pixels
|
|
13
12
|
* @param pixelIndex Pixel index in the array
|
|
14
13
|
* @returns Transform data object
|
|
15
14
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SVGDataExtractor.d.ts","sourceRoot":"","sources":["../../../../src/exporters/svg/SVGDataExtractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAA+B,MAAM,SAAS,CAAC;AACzF,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,aAAa;IAE/C
|
|
1
|
+
{"version":3,"file":"SVGDataExtractor.d.ts","sourceRoot":"","sources":["../../../../src/exporters/svg/SVGDataExtractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAA+B,MAAM,SAAS,CAAC;AACzF,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,aAAa;IAE/C;;;;;OAKG;IACH,OAAO,CAAC,qBAAqB;IAuB7B;;;;;;OAMG;IACH,OAAO,CAAC,sBAAsB;IAS9B;;;;;;OAMG;IACI,mBAAmB,CACtB,eAAe,EAAE,eAAe,EAChC,IAAI,EAAE,YAAY,GACnB,WAAW,EAAE;CAgDnB"}
|
|
@@ -1,4 +1,29 @@
|
|
|
1
1
|
import type { TextmodeFont } from 'textmode.js';
|
|
2
|
+
/**
|
|
3
|
+
* Glyph data structure for parsed glyphs.
|
|
4
|
+
* Mirrors the shape used by textmode.js internally for Typr glyph data.
|
|
5
|
+
*/
|
|
6
|
+
interface GlyphData {
|
|
7
|
+
/** Number of contours (-1 for composite glyphs) */
|
|
8
|
+
noc: number;
|
|
9
|
+
/** Bounding box coordinates */
|
|
10
|
+
xMin: number;
|
|
11
|
+
yMin: number;
|
|
12
|
+
xMax: number;
|
|
13
|
+
yMax: number;
|
|
14
|
+
/** End points of each contour */
|
|
15
|
+
endPts: number[];
|
|
16
|
+
/** Point flags indicating curve/line segments */
|
|
17
|
+
flags: number[];
|
|
18
|
+
/** X coordinates of all points */
|
|
19
|
+
xs: number[];
|
|
20
|
+
/** Y coordinates of all points */
|
|
21
|
+
ys: number[];
|
|
22
|
+
/** Composite glyph parts (for composite glyphs) */
|
|
23
|
+
parts?: unknown[];
|
|
24
|
+
/** Advance width of the glyph */
|
|
25
|
+
advanceWidth: number;
|
|
26
|
+
}
|
|
2
27
|
/**
|
|
3
28
|
* Handles SVG path generation for character glyphs.
|
|
4
29
|
* This class is responsible for converting font glyph data into SVG path strings.
|
|
@@ -45,6 +70,7 @@ export declare class SVGPathGenerator {
|
|
|
45
70
|
* @param advanceWidth Character advance width
|
|
46
71
|
* @returns SVG path data string or null if generation fails
|
|
47
72
|
*/
|
|
48
|
-
$generatePositionedCharacterPath(character: string, font: TextmodeFont, cellX: number, cellY: number, cellWidth: number, cellHeight: number, fontSize: number,
|
|
73
|
+
$generatePositionedCharacterPath(character: string, font: TextmodeFont, cellX: number, cellY: number, cellWidth: number, cellHeight: number, fontSize: number, glyphData: GlyphData | null): string | null;
|
|
49
74
|
}
|
|
75
|
+
export {};
|
|
50
76
|
//# sourceMappingURL=SVGPathGenerator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SVGPathGenerator.d.ts","sourceRoot":"","sources":["../../../../src/exporters/svg/SVGPathGenerator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"SVGPathGenerator.d.ts","sourceRoot":"","sources":["../../../../src/exporters/svg/SVGPathGenerator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD;;;GAGG;AACH,UAAU,SAAS;IACf,mDAAmD;IACnD,GAAG,EAAE,MAAM,CAAC;IACZ,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,iDAAiD;IACjD,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,kCAAkC;IAClC,EAAE,EAAE,MAAM,EAAE,CAAC;IACb,kCAAkC;IAClC,EAAE,EAAE,MAAM,EAAE,CAAC;IACb,mDAAmD;IACnD,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;IAClB,iCAAiC;IACjC,YAAY,EAAE,MAAM,CAAC;CACxB;AAYD;;;GAGG;AACH,qBAAa,gBAAgB;IACzB;;;;;;;;OAQG;IACH,OAAO,CAAC,gBAAgB;IA0BxB;;;;;;;OAOG;IACH,OAAO,CAAC,eAAe;IAwDvB;;;;;;;;OAQG;IACH,OAAO,CAAC,sBAAsB;IAkB9B;;;;;;;;;;;OAWG;IACI,gCAAgC,CACnC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,SAAS,GAAG,IAAI,GAC5B,MAAM,GAAG,IAAI;CAuBnB"}
|
|
@@ -49,8 +49,6 @@ export interface FramebufferData {
|
|
|
49
49
|
characterPixels: Uint8Array;
|
|
50
50
|
primaryColorPixels: Uint8Array;
|
|
51
51
|
secondaryColorPixels: Uint8Array;
|
|
52
|
-
transformPixels: Uint8Array;
|
|
53
|
-
rotationPixels: Uint8Array;
|
|
54
52
|
}
|
|
55
53
|
/**
|
|
56
54
|
* Options for exporting the textmode content to SVG format.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/exporters/svg/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,IAAI;IACjB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACrB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IACzB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC1B,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,IAAI,CAAC;IACnB,cAAc,EAAE,IAAI,CAAC;IACrB,SAAS,EAAE,aAAa,CAAC;IACzB,QAAQ,EAAE,YAAY,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC5B,eAAe,EAAE,UAAU,CAAC;IAC5B,kBAAkB,EAAE,UAAU,CAAC;IAC/B,oBAAoB,EAAE,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/exporters/svg/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,IAAI;IACjB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACrB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IACzB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC1B,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,IAAI,CAAC;IACnB,cAAc,EAAE,IAAI,CAAC;IACrB,SAAS,EAAE,aAAa,CAAC;IACzB,QAAQ,EAAE,YAAY,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC5B,eAAe,EAAE,UAAU,CAAC;IAC5B,kBAAkB,EAAE,UAAU,CAAC;IAC/B,oBAAoB,EAAE,UAAU,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;;;OAMG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;IAEtC;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAE7B;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB,CAAA;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACtB,cAAc,IAAI;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IACrE,KAAK,IAAI,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,2BAA2B,EAAE,OAAO,CAAC;IACrC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB"}
|
package/package.json
CHANGED
|
@@ -1,72 +1,72 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "textmode.export.js",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Export plugin for textmode.js - Save your creations as images, GIFs, videos, SVG, and plain text.",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"types": "./dist/types/index.d.ts",
|
|
7
|
-
"main": "./dist/textmode.export.umd.js",
|
|
8
|
-
"module": "./dist/textmode.export.esm.js",
|
|
9
|
-
"exports": {
|
|
10
|
-
".": {
|
|
11
|
-
"types": "./dist/types/index.d.ts",
|
|
12
|
-
"import": "./dist/textmode.export.esm.js",
|
|
13
|
-
"require": "./dist/textmode.export.umd.js"
|
|
14
|
-
}
|
|
15
|
-
},
|
|
16
|
-
"scripts": {
|
|
17
|
-
"dev": "vite",
|
|
18
|
-
"build": "vite build && tsc",
|
|
19
|
-
"preview": "vite preview",
|
|
20
|
-
"build:docs": "typedoc",
|
|
21
|
-
"dev:docs": "typedoc --watch"
|
|
22
|
-
},
|
|
23
|
-
"devDependencies": {
|
|
24
|
-
"@rollup/plugin-terser": "^0.4.4",
|
|
25
|
-
"@types/node": "^24.5.2",
|
|
26
|
-
"terser": "^5.44.0",
|
|
27
|
-
"typedoc": "^0.28.13",
|
|
28
|
-
"typedoc-plugin-markdown": "^4.9.0",
|
|
29
|
-
"typescript": "~5.8.3",
|
|
30
|
-
"vite": "^7.1.7",
|
|
31
|
-
"vite-plugin-css-injected-by-js": "^3.5.2"
|
|
32
|
-
},
|
|
33
|
-
"dependencies": {
|
|
34
|
-
"gifenc": "^1.0.1",
|
|
35
|
-
"textmode.js": "^0.
|
|
36
|
-
"webm-writer": "^1.0.0"
|
|
37
|
-
},
|
|
38
|
-
"peerDependencies": {
|
|
39
|
-
"textmode.js": ">=0.
|
|
40
|
-
},
|
|
41
|
-
"repository": {
|
|
42
|
-
"type": "git",
|
|
43
|
-
"url": "git+https://github.com/humanbydefinition/textmode.export.js.git"
|
|
44
|
-
},
|
|
45
|
-
"keywords": [
|
|
46
|
-
"textmode",
|
|
47
|
-
"textmode.js",
|
|
48
|
-
"ascii",
|
|
49
|
-
"petscii",
|
|
50
|
-
"export",
|
|
51
|
-
"plugin",
|
|
52
|
-
"gif",
|
|
53
|
-
"video",
|
|
54
|
-
"webm",
|
|
55
|
-
"svg",
|
|
56
|
-
"image",
|
|
57
|
-
"png",
|
|
58
|
-
"jpg",
|
|
59
|
-
"webp",
|
|
60
|
-
"creative-coding",
|
|
61
|
-
"canvas"
|
|
62
|
-
],
|
|
63
|
-
"author": "humanbydefinition",
|
|
64
|
-
"license": "MIT",
|
|
65
|
-
"bugs": {
|
|
66
|
-
"url": "https://github.com/humanbydefinition/textmode.export.js/issues"
|
|
67
|
-
},
|
|
68
|
-
"homepage": "https://code.textmode.art",
|
|
69
|
-
"files": [
|
|
70
|
-
"dist"
|
|
71
|
-
]
|
|
72
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "textmode.export.js",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "Export plugin for textmode.js - Save your creations as images, GIFs, videos, SVG, and plain text.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"types": "./dist/types/index.d.ts",
|
|
7
|
+
"main": "./dist/textmode.export.umd.js",
|
|
8
|
+
"module": "./dist/textmode.export.esm.js",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/types/index.d.ts",
|
|
12
|
+
"import": "./dist/textmode.export.esm.js",
|
|
13
|
+
"require": "./dist/textmode.export.umd.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"dev": "vite --port 5174",
|
|
18
|
+
"build": "vite build && tsc",
|
|
19
|
+
"preview": "vite preview",
|
|
20
|
+
"build:docs": "typedoc",
|
|
21
|
+
"dev:docs": "typedoc --watch"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@rollup/plugin-terser": "^0.4.4",
|
|
25
|
+
"@types/node": "^24.5.2",
|
|
26
|
+
"terser": "^5.44.0",
|
|
27
|
+
"typedoc": "^0.28.13",
|
|
28
|
+
"typedoc-plugin-markdown": "^4.9.0",
|
|
29
|
+
"typescript": "~5.8.3",
|
|
30
|
+
"vite": "^7.1.7",
|
|
31
|
+
"vite-plugin-css-injected-by-js": "^3.5.2"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"gifenc": "^1.0.1",
|
|
35
|
+
"textmode.js": "^0.6.0",
|
|
36
|
+
"webm-writer": "^1.0.0"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"textmode.js": ">=0.6.0"
|
|
40
|
+
},
|
|
41
|
+
"repository": {
|
|
42
|
+
"type": "git",
|
|
43
|
+
"url": "git+https://github.com/humanbydefinition/textmode.export.js.git"
|
|
44
|
+
},
|
|
45
|
+
"keywords": [
|
|
46
|
+
"textmode",
|
|
47
|
+
"textmode.js",
|
|
48
|
+
"ascii",
|
|
49
|
+
"petscii",
|
|
50
|
+
"export",
|
|
51
|
+
"plugin",
|
|
52
|
+
"gif",
|
|
53
|
+
"video",
|
|
54
|
+
"webm",
|
|
55
|
+
"svg",
|
|
56
|
+
"image",
|
|
57
|
+
"png",
|
|
58
|
+
"jpg",
|
|
59
|
+
"webp",
|
|
60
|
+
"creative-coding",
|
|
61
|
+
"canvas"
|
|
62
|
+
],
|
|
63
|
+
"author": "humanbydefinition",
|
|
64
|
+
"license": "MIT",
|
|
65
|
+
"bugs": {
|
|
66
|
+
"url": "https://github.com/humanbydefinition/textmode.export.js/issues"
|
|
67
|
+
},
|
|
68
|
+
"homepage": "https://code.textmode.art",
|
|
69
|
+
"files": [
|
|
70
|
+
"dist"
|
|
71
|
+
]
|
|
72
|
+
}
|