textmode.js 0.1.4-beta.3 → 0.1.4-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,12 +1,12 @@
1
1
  var se = Object.defineProperty;
2
- var oe = (h, e, t) => e in h ? se(h, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : h[e] = t;
3
- var a = (h, e, t) => oe(h, typeof e != "symbol" ? e + "" : e, t);
2
+ var ae = (l, e, t) => e in l ? se(l, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : l[e] = t;
3
+ var n = (l, e, t) => ae(l, typeof e != "symbol" ? e + "" : e, t);
4
4
  class F extends Error {
5
5
  constructor(t, r, i = {}) {
6
6
  const s = F.createFormattedMessage(t, i);
7
7
  super(s);
8
- a(this, "originalError");
9
- a(this, "context");
8
+ n(this, "originalError");
9
+ n(this, "context");
10
10
  this.name = "TextmodeError", this.originalError = r, this.context = i;
11
11
  }
12
12
  /**
@@ -18,10 +18,10 @@ class F extends Error {
18
18
  i += `
19
19
 
20
20
  📋 Context:`;
21
- for (const [s, o] of Object.entries(r)) {
22
- const n = F.formatValue(o);
21
+ for (const [s, a] of Object.entries(r)) {
22
+ const o = F.formatValue(a);
23
23
  i += `
24
- - ${s}: ${n}`;
24
+ - ${s}: ${o}`;
25
25
  }
26
26
  }
27
27
  return i += `
@@ -41,15 +41,15 @@ class F extends Error {
41
41
  return t.length === 0 ? "[]" : t.length <= 5 ? `[${t.map((r) => F.formatValue(r)).join(", ")}]` : `[${t.slice(0, 3).map((r) => F.formatValue(r)).join(", ")}, ... +${t.length - 3} more]`;
42
42
  if (typeof t == "object") {
43
43
  const r = Object.keys(t);
44
- return r.length === 0 ? "{}" : r.length <= 3 ? `{ ${r.map((o) => `${o}: ${F.formatValue(t[o])}`).join(", ")} }` : `{ ${r.slice(0, 2).map((s) => `${s}: ${F.formatValue(t[s])}`).join(", ")}, ... +${r.length - 2} more }`;
44
+ return r.length === 0 ? "{}" : r.length <= 3 ? `{ ${r.map((a) => `${a}: ${F.formatValue(t[a])}`).join(", ")} }` : `{ ${r.slice(0, 2).map((s) => `${s}: ${F.formatValue(t[s])}`).join(", ")}, ... +${r.length - 2} more }`;
45
45
  }
46
46
  return String(t);
47
47
  }
48
48
  }
49
- var ne = /* @__PURE__ */ ((h) => (h[h.SILENT = 0] = "SILENT", h[h.WARNING = 1] = "WARNING", h[h.ERROR = 2] = "ERROR", h[h.THROW = 3] = "THROW", h))(ne || {});
49
+ var oe = /* @__PURE__ */ ((l) => (l[l.SILENT = 0] = "SILENT", l[l.WARNING = 1] = "WARNING", l[l.ERROR = 2] = "ERROR", l[l.THROW = 3] = "THROW", l))(oe || {});
50
50
  const E = class E {
51
51
  constructor() {
52
- a(this, "_options", {
52
+ n(this, "_options", {
53
53
  globalLevel: 3
54
54
  /* THROW */
55
55
  });
@@ -103,19 +103,19 @@ const E = class E {
103
103
  this._options.globalLevel = e;
104
104
  }
105
105
  };
106
- a(E, "_instance", null);
106
+ n(E, "_instance", null);
107
107
  let $ = E;
108
108
  const x = $.getInstance();
109
- class ae {
109
+ class ne {
110
110
  constructor(e, t, r = t, i = {}) {
111
- a(this, "gl");
112
- a(this, "_framebuffer");
113
- a(this, "_texture");
114
- a(this, "_width");
115
- a(this, "_height");
116
- a(this, "options");
117
- a(this, "previousState", null);
118
- a(this, "_pixels", null);
111
+ n(this, "gl");
112
+ n(this, "_framebuffer");
113
+ n(this, "_texture");
114
+ n(this, "_width");
115
+ n(this, "_height");
116
+ n(this, "options");
117
+ n(this, "previousState", null);
118
+ n(this, "_pixels", null);
119
119
  this.gl = e, this._width = t, this._height = r, this.options = {
120
120
  filter: "nearest",
121
121
  wrap: "clamp",
@@ -189,16 +189,16 @@ class ae {
189
189
  get(e, t, r, i) {
190
190
  const { gl: s } = this;
191
191
  if (e === void 0 && t === void 0) {
192
- const o = new Uint8Array(this._width * this._height * 4), n = s.getParameter(s.FRAMEBUFFER_BINDING);
193
- return s.bindFramebuffer(s.FRAMEBUFFER, this._framebuffer), s.readPixels(0, 0, this._width, this._height, s.RGBA, s.UNSIGNED_BYTE, o), s.bindFramebuffer(s.FRAMEBUFFER, n), o;
192
+ const a = new Uint8Array(this._width * this._height * 4), o = s.getParameter(s.FRAMEBUFFER_BINDING);
193
+ return s.bindFramebuffer(s.FRAMEBUFFER, this._framebuffer), s.readPixels(0, 0, this._width, this._height, s.RGBA, s.UNSIGNED_BYTE, a), s.bindFramebuffer(s.FRAMEBUFFER, o), a;
194
194
  } else if (r === void 0 && i === void 0) {
195
195
  (e < 0 || t < 0 || e >= this._width || t >= this._height) && (console.warn("The x and y values passed to Framebuffer.get are outside of its range and will be clamped."), e = Math.max(0, Math.min(e, this._width - 1)), t = Math.max(0, Math.min(t, this._height - 1)));
196
- const o = new Uint8Array(4), n = s.getParameter(s.FRAMEBUFFER_BINDING);
197
- return s.bindFramebuffer(s.FRAMEBUFFER, this._framebuffer), s.readPixels(e, t, 1, 1, s.RGBA, s.UNSIGNED_BYTE, o), s.bindFramebuffer(s.FRAMEBUFFER, n), [o[0], o[1], o[2], o[3]];
196
+ const a = new Uint8Array(4), o = s.getParameter(s.FRAMEBUFFER_BINDING);
197
+ return s.bindFramebuffer(s.FRAMEBUFFER, this._framebuffer), s.readPixels(e, t, 1, 1, s.RGBA, s.UNSIGNED_BYTE, a), s.bindFramebuffer(s.FRAMEBUFFER, o), [a[0], a[1], a[2], a[3]];
198
198
  } else {
199
199
  e = Math.max(0, Math.min(e, this._width - 1)), t = Math.max(0, Math.min(t, this._height - 1)), r = Math.max(1, Math.min(r, this._width - e)), i = Math.max(1, Math.min(i, this._height - t));
200
- const o = new Uint8Array(r * i * 4), n = s.getParameter(s.FRAMEBUFFER_BINDING);
201
- return s.bindFramebuffer(s.FRAMEBUFFER, this._framebuffer), s.readPixels(e, t, r, i, s.RGBA, s.UNSIGNED_BYTE, o), s.bindFramebuffer(s.FRAMEBUFFER, n), o;
200
+ const a = new Uint8Array(r * i * 4), o = s.getParameter(s.FRAMEBUFFER_BINDING);
201
+ return s.bindFramebuffer(s.FRAMEBUFFER, this._framebuffer), s.readPixels(e, t, r, i, s.RGBA, s.UNSIGNED_BYTE, a), s.bindFramebuffer(s.FRAMEBUFFER, o), a;
202
202
  }
203
203
  }
204
204
  /**
@@ -209,12 +209,6 @@ class ae {
209
209
  const { gl: e } = this;
210
210
  this._framebuffer && (e.deleteFramebuffer(this._framebuffer), this._framebuffer = null), this._texture && (e.deleteTexture(this._texture), this._texture = null), this._pixels = null;
211
211
  }
212
- /**
213
- * Check if this framebuffer has been disposed
214
- */
215
- get isDisposed() {
216
- return this._framebuffer === null || this._texture === null;
217
- }
218
212
  get framebuffer() {
219
213
  return this._framebuffer;
220
214
  }
@@ -233,29 +227,29 @@ class ae {
233
227
  }
234
228
  class Q {
235
229
  constructor(e, t, r) {
236
- a(this, "gl");
237
- a(this, "x");
238
- a(this, "y");
230
+ n(this, "gl");
231
+ n(this, "x");
232
+ n(this, "y");
239
233
  this.gl = e, this.x = t, this.y = r;
240
234
  }
241
235
  }
242
- class A {
236
+ class M {
243
237
  constructor(e, t, r, i, s) {
244
238
  /** The WebGL rendering context */
245
- a(this, "gl");
239
+ n(this, "gl");
246
240
  /** The vertex buffer containing position and texture coordinates */
247
- a(this, "vertexBuffer");
241
+ n(this, "vertexBuffer");
248
242
  /** The number of vertices in this geometry (always 6 for two triangles) */
249
- a(this, "vertexCount", 6);
243
+ n(this, "vertexCount", 6);
250
244
  /** Bytes per vertex: depends on position format (vec2 vs vec3) */
251
- a(this, "bytesPerVertex");
245
+ n(this, "bytesPerVertex");
252
246
  this.gl = e, this.bytesPerVertex = 16;
253
- const o = e.getParameter(e.VIEWPORT), n = o[2], l = o[3], c = e.getParameter(e.FRAMEBUFFER_BINDING) !== null, u = t / n * 2 - 1, d = (t + i) / n * 2 - 1;
247
+ const a = e.getParameter(e.VIEWPORT), o = a[2], h = a[3], c = e.getParameter(e.FRAMEBUFFER_BINDING) !== null, u = t / o * 2 - 1, d = (t + i) / o * 2 - 1;
254
248
  let f, g;
255
- c ? (f = r / l * 2 - 1, g = (r + s) / l * 2 - 1) : (f = 1 - r / l * 2, g = 1 - (r + s) / l * 2);
256
- let p, _, b, C;
257
- p = u, b = d, _ = f, C = g;
258
- const v = this.generateVertices(p, _, b, C);
249
+ c ? (f = r / h * 2 - 1, g = (r + s) / h * 2 - 1) : (f = 1 - r / h * 2, g = 1 - (r + s) / h * 2);
250
+ let _, p, b, C;
251
+ _ = u, b = d, p = f, C = g;
252
+ const v = this.generateVertices(_, p, b, C);
259
253
  this.vertexBuffer = e.createBuffer(), e.bindBuffer(e.ARRAY_BUFFER, this.vertexBuffer), e.bufferData(e.ARRAY_BUFFER, v, e.STATIC_DRAW);
260
254
  }
261
255
  /**
@@ -306,18 +300,18 @@ class A {
306
300
  this.gl.enableVertexAttribArray(t), this.gl.vertexAttribPointer(t, 2, this.gl.FLOAT, !1, this.bytesPerVertex, 0), this.gl.enableVertexAttribArray(r), this.gl.vertexAttribPointer(r, 2, this.gl.FLOAT, !1, this.bytesPerVertex, 8), this.gl.drawArrays(this.gl.TRIANGLES, 0, this.vertexCount), this.gl.disableVertexAttribArray(t), this.gl.disableVertexAttribArray(r);
307
301
  }
308
302
  }
309
- class he extends Q {
310
- constructor(t, r, i, s, o) {
303
+ class le extends Q {
304
+ constructor(t, r, i, s, a) {
311
305
  super(t, r, i);
312
- a(this, "width");
313
- a(this, "height");
314
- this.width = s, this.height = o;
306
+ n(this, "width");
307
+ n(this, "height");
308
+ this.width = s, this.height = a;
315
309
  }
316
310
  /**
317
311
  * Render the filled rectangle using the existing Rectangle geometry.
318
312
  */
319
313
  renderFill() {
320
- new A(this.gl, this.x, this.y, this.width, this.height).render();
314
+ new M(this.gl, this.x, this.y, this.width, this.height).render();
321
315
  }
322
316
  /**
323
317
  * Render the stroke rectangle as four separate Rectangle instances for each edge.
@@ -326,30 +320,30 @@ class he extends Q {
326
320
  */
327
321
  renderStroke(t) {
328
322
  if (t <= 0) return;
329
- const r = new A(this.gl, this.x, this.y, this.width, t), i = new A(this.gl, this.x + this.width - t, this.y, t, this.height), s = new A(this.gl, this.x, this.y + this.height - t, this.width, t), o = new A(this.gl, this.x, this.y, t, this.height);
330
- r.render(), i.render(), s.render(), o.render();
323
+ const r = new M(this.gl, this.x, this.y, this.width, t), i = new M(this.gl, this.x + this.width - t, this.y, t, this.height), s = new M(this.gl, this.x, this.y + this.height - t, this.width, t), a = new M(this.gl, this.x, this.y, t, this.height);
324
+ r.render(), i.render(), s.render(), a.render();
331
325
  }
332
326
  }
333
- class le {
334
- constructor(e, t, r, i, s, o) {
327
+ class he {
328
+ constructor(e, t, r, i, s, a) {
335
329
  /** The WebGL rendering context */
336
- a(this, "gl");
330
+ n(this, "gl");
337
331
  /** The vertex buffer containing position and texture coordinates */
338
- a(this, "vertexBuffer");
332
+ n(this, "vertexBuffer");
339
333
  /** The number of vertices in this geometry (always 6 for two triangles) */
340
- a(this, "vertexCount", 6);
334
+ n(this, "vertexCount", 6);
341
335
  /** Bytes per vertex: vec2+vec2 = 16 bytes */
342
- a(this, "bytesPerVertex");
336
+ n(this, "bytesPerVertex");
343
337
  this.gl = e, this.bytesPerVertex = 16;
344
- const n = e.getParameter(e.VIEWPORT), l = n[2], c = n[3], u = e.getParameter(e.FRAMEBUFFER_BINDING) !== null, d = i - t, f = s - r, g = Math.sqrt(d * d + f * f);
338
+ const o = e.getParameter(e.VIEWPORT), h = o[2], c = o[3], u = e.getParameter(e.FRAMEBUFFER_BINDING) !== null, d = i - t, f = s - r, g = Math.sqrt(d * d + f * f);
345
339
  if (g === 0) {
346
340
  const ie = this.generateVertices(0, 0, 0, 0);
347
341
  this.vertexBuffer = e.createBuffer(), e.bindBuffer(e.ARRAY_BUFFER, this.vertexBuffer), e.bufferData(e.ARRAY_BUFFER, ie, e.STATIC_DRAW);
348
342
  return;
349
343
  }
350
- const p = d / g, b = -(f / g), C = p, v = o / 2, w = t + b * v, D = r + C * v, R = t - b * v, y = r - C * v, P = i + b * v, M = s + C * v, Z = i - b * v, W = s - C * v, J = w / l * 2 - 1, K = R / l * 2 - 1, ee = P / l * 2 - 1, te = Z / l * 2 - 1;
344
+ const _ = d / g, b = -(f / g), C = _, v = a / 2, w = t + b * v, A = r + C * v, R = t - b * v, S = r - C * v, P = i + b * v, D = s + C * v, Z = i - b * v, W = s - C * v, J = w / h * 2 - 1, K = R / h * 2 - 1, ee = P / h * 2 - 1, te = Z / h * 2 - 1;
351
345
  let B, G, V, k;
352
- u ? (B = D / c * 2 - 1, G = y / c * 2 - 1, V = M / c * 2 - 1, k = W / c * 2 - 1) : (B = 1 - D / c * 2, G = 1 - y / c * 2, V = 1 - M / c * 2, k = 1 - W / c * 2);
346
+ u ? (B = A / c * 2 - 1, G = S / c * 2 - 1, V = D / c * 2 - 1, k = W / c * 2 - 1) : (B = 1 - A / c * 2, G = 1 - S / c * 2, V = 1 - D / c * 2, k = 1 - W / c * 2);
353
347
  const re = this.generateLineVertices(
354
348
  J,
355
349
  B,
@@ -405,7 +399,7 @@ class le {
405
399
  * Uses the four corners calculated based on line direction and thickness
406
400
  * @private
407
401
  */
408
- generateLineVertices(e, t, r, i, s, o, n, l) {
402
+ generateLineVertices(e, t, r, i, s, a, o, h) {
409
403
  return new Float32Array([
410
404
  e,
411
405
  t,
@@ -418,7 +412,7 @@ class le {
418
412
  1,
419
413
  // corner2 (start - perpendicular)
420
414
  s,
421
- o,
415
+ a,
422
416
  1,
423
417
  0,
424
418
  // corner3 (end + perpendicular)
@@ -427,13 +421,13 @@ class le {
427
421
  0,
428
422
  1,
429
423
  // corner2 (start - perpendicular)
430
- n,
431
- l,
424
+ o,
425
+ h,
432
426
  1,
433
427
  1,
434
428
  // corner4 (end - perpendicular)
435
429
  s,
436
- o,
430
+ a,
437
431
  1,
438
432
  0
439
433
  // corner3 (end + perpendicular)
@@ -450,11 +444,11 @@ class le {
450
444
  }
451
445
  }
452
446
  class ce extends Q {
453
- constructor(t, r, i, s, o) {
447
+ constructor(t, r, i, s, a) {
454
448
  super(t, r, i);
455
- a(this, "x2");
456
- a(this, "y2");
457
- this.x2 = s, this.y2 = o;
449
+ n(this, "x2");
450
+ n(this, "y2");
451
+ this.x2 = s, this.y2 = a;
458
452
  }
459
453
  /**
460
454
  * Lines don't support fill rendering - this method does nothing.
@@ -468,23 +462,23 @@ class ce extends Q {
468
462
  */
469
463
  renderStroke(t) {
470
464
  if (t <= 0) return;
471
- new le(this.gl, this.x, this.y, this.x2, this.y2, t).render();
465
+ new he(this.gl, this.x, this.y, this.x2, this.y2, t).render();
472
466
  }
473
467
  }
474
- class T {
468
+ class y {
475
469
  constructor(e, t, r) {
476
- a(this, "gl");
477
- a(this, "program");
478
- a(this, "uniformLocations", /* @__PURE__ */ new Map());
479
- a(this, "attributeLocations", /* @__PURE__ */ new Map());
480
- a(this, "textureUnitCounter", 0);
470
+ n(this, "gl");
471
+ n(this, "program");
472
+ n(this, "uniformLocations", /* @__PURE__ */ new Map());
473
+ n(this, "attributeLocations", /* @__PURE__ */ new Map());
474
+ n(this, "textureUnitCounter", 0);
481
475
  this.gl = e, this.program = this.createProgram(t, r), this.cacheLocations();
482
476
  }
483
477
  createProgram(e, t) {
484
478
  const r = this.createShader(this.gl.VERTEX_SHADER, e), i = this.createShader(this.gl.FRAGMENT_SHADER, t), s = this.gl.createProgram();
485
479
  if (this.gl.attachShader(s, r), this.gl.attachShader(s, i), this.gl.linkProgram(s), !this.gl.getProgramParameter(s, this.gl.LINK_STATUS)) {
486
- const o = this.gl.getProgramInfoLog(s);
487
- throw new Error(`Shader program link error: ${o}`);
480
+ const a = this.gl.getProgramInfoLog(s);
481
+ throw new Error(`Shader program link error: ${a}`);
488
482
  }
489
483
  return this.gl.deleteShader(r), this.gl.deleteShader(i), s;
490
484
  }
@@ -534,7 +528,7 @@ class T {
534
528
  this.gl.uniform1i(r, t ? 1 : 0);
535
529
  else if (Array.isArray(t))
536
530
  if (i && (i.type === this.gl.INT_VEC2 || i.type === this.gl.INT_VEC3 || i.type === this.gl.INT_VEC4)) {
537
- const s = t.map((o) => Math.floor(o));
531
+ const s = t.map((a) => Math.floor(a));
538
532
  switch (s.length) {
539
533
  case 2:
540
534
  this.gl.uniform2iv(r, s);
@@ -611,12 +605,6 @@ class T {
611
605
  dispose() {
612
606
  this.program && (this.gl.deleteProgram(this.program), this.program = null), this.uniformLocations.clear(), this.attributeLocations.clear(), this.textureUnitCounter = 0;
613
607
  }
614
- /**
615
- * Check if this shader has been disposed
616
- */
617
- get isDisposed() {
618
- return this.program === null;
619
- }
620
608
  /**
621
609
  * Reset texture unit counter (useful when starting a new frame)
622
610
  */
@@ -624,26 +612,26 @@ class T {
624
612
  this.textureUnitCounter = 0;
625
613
  }
626
614
  }
627
- var S = "attribute vec2 a_position;attribute vec2 a_texCoord;varying vec2 v_uv;uniform float u_rotation;uniform vec2 u_center;uniform float u_aspectRatio;mat2 rotate2D(float angle){float s=sin(angle);float c=cos(angle);return mat2(c,-s,s,c);}void main(){v_uv=a_texCoord;vec2 pos=a_position;pos-=u_center;pos.x*=u_aspectRatio;pos=rotate2D(-u_rotation)*pos;pos.x/=u_aspectRatio;pos+=u_center;gl_Position=vec4(pos,0.0,1.0);}", ue = "precision lowp float;uniform sampler2D u_texture;varying vec2 v_uv;void main(){gl_FragColor=texture2D(u_texture,v_uv);}", de = "precision lowp float;uniform vec4 u_color;void main(){gl_FragColor=u_color;}";
615
+ var T = "attribute vec2 a_position;attribute vec2 a_texCoord;varying vec2 v_uv;uniform float u_rotation;uniform vec2 u_center;uniform float u_aspectRatio;mat2 rotate2D(float angle){float s=sin(angle);float c=cos(angle);return mat2(c,-s,s,c);}void main(){v_uv=a_texCoord;vec2 pos=a_position;pos-=u_center;pos.x*=u_aspectRatio;pos=rotate2D(-u_rotation)*pos;pos.x/=u_aspectRatio;pos+=u_center;gl_Position=vec4(pos,0.0,1.0);}", ue = "precision lowp float;uniform sampler2D u_texture;varying vec2 v_uv;void main(){gl_FragColor=texture2D(u_texture,v_uv);}", de = "precision lowp float;uniform vec4 u_color;void main(){gl_FragColor=u_color;}";
628
616
  class fe {
629
617
  constructor(e) {
630
- a(this, "gl");
631
- a(this, "imageShader");
632
- a(this, "solidColorShader");
633
- a(this, "currentShader", null);
618
+ n(this, "gl");
619
+ n(this, "imageShader");
620
+ n(this, "solidColorShader");
621
+ n(this, "currentShader", null);
634
622
  // Fill state management - default: white fill enabled
635
- a(this, "currentFillColor", [1, 1, 1, 1]);
636
- a(this, "fillMode", !0);
623
+ n(this, "currentFillColor", [1, 1, 1, 1]);
624
+ n(this, "fillMode", !0);
637
625
  // Stroke state management - default: black stroke enabled, weight 1
638
- a(this, "currentStrokeColor", [0, 0, 0, 1]);
639
- a(this, "currentStrokeWeight", 1);
640
- a(this, "strokeMode", !0);
626
+ n(this, "currentStrokeColor", [0, 0, 0, 1]);
627
+ n(this, "currentStrokeWeight", 1);
628
+ n(this, "strokeMode", !0);
641
629
  // Transformation state management
642
- a(this, "currentRotation", 0);
630
+ n(this, "currentRotation", 0);
643
631
  // in degrees
644
632
  // State stack for push/pop functionality
645
- a(this, "stateStack", []);
646
- this.gl = e, this.imageShader = new T(this.gl, S, ue), this.solidColorShader = new T(this.gl, S, de), this.gl.enable(this.gl.BLEND), this.gl.blendEquation(this.gl.FUNC_ADD), this.gl.blendFunc(this.gl.ONE, this.gl.ONE_MINUS_SRC_ALPHA);
633
+ n(this, "stateStack", []);
634
+ this.gl = e, this.imageShader = new y(this.gl, T, ue), this.solidColorShader = new y(this.gl, T, de), this.gl.enable(this.gl.BLEND), this.gl.blendEquation(this.gl.FUNC_ADD), this.gl.blendFunc(this.gl.ONE, this.gl.ONE_MINUS_SRC_ALPHA);
647
635
  }
648
636
  /**
649
637
  * Set the current shader
@@ -744,7 +732,10 @@ class fe {
744
732
  this.currentShader = null, this.stateStack = [], this.currentRotation = 0, this.fillMode = !0, this.strokeMode = !0, this.currentFillColor = [1, 1, 1, 1], this.currentStrokeColor = [0, 0, 0, 1], this.currentStrokeWeight = 1;
745
733
  }
746
734
  createShader(e, t) {
747
- return new T(this.gl, e, t);
735
+ return new y(this.gl, e, t);
736
+ }
737
+ createFilterShader(e) {
738
+ return new y(this.gl, T, e);
748
739
  }
749
740
  /**
750
741
  * Set a uniform value for the current shader
@@ -756,18 +747,18 @@ class fe {
756
747
  * Draw a rectangle with the current fill and/or stroke settings
757
748
  */
758
749
  rect(e, t, r, i) {
759
- const s = new he(this.gl, e, t, r, i);
750
+ const s = new le(this.gl, e, t, r, i);
760
751
  if (this.currentShader !== null) {
761
752
  if (this.currentRotation !== 0) {
762
- const { centerX: d, centerY: f, radians: g, aspectRatio: p } = this.calculateRotationParams(e, t, r, i);
763
- this.setUniform("u_rotation", g), this.setUniform("u_center", [d, f]), this.setUniform("u_aspectRatio", p);
753
+ const { centerX: d, centerY: f, radians: g, aspectRatio: _ } = this.calculateRotationParams(e, t, r, i);
754
+ this.setUniform("u_rotation", g), this.setUniform("u_center", [d, f]), this.setUniform("u_aspectRatio", _);
764
755
  } else
765
756
  this.setUniform("u_rotation", 0), this.setUniform("u_center", [0, 0]), this.setUniform("u_aspectRatio", 1);
766
757
  s.renderFill(), this.currentShader = null;
767
758
  return;
768
759
  }
769
- const o = this.solidColorShader, { centerX: n, centerY: l, radians: c, aspectRatio: u } = this.calculateRotationParams(e, t, r, i);
770
- this.fillMode && (this.shader(o), this.setUniform("u_color", this.currentFillColor), this.setUniform("u_rotation", c), this.setUniform("u_center", [n, l]), this.setUniform("u_aspectRatio", u), s.renderFill()), this.strokeMode && (this.shader(o), this.setUniform("u_color", this.currentStrokeColor), this.setUniform("u_rotation", c), this.setUniform("u_center", [n, l]), this.setUniform("u_aspectRatio", u), s.renderStroke(this.currentStrokeWeight)), this.currentShader = null;
760
+ const a = this.solidColorShader, { centerX: o, centerY: h, radians: c, aspectRatio: u } = this.calculateRotationParams(e, t, r, i);
761
+ this.fillMode && (this.shader(a), this.setUniform("u_color", this.currentFillColor), this.setUniform("u_rotation", c), this.setUniform("u_center", [o, h]), this.setUniform("u_aspectRatio", u), s.renderFill()), this.strokeMode && (this.shader(a), this.setUniform("u_color", this.currentStrokeColor), this.setUniform("u_rotation", c), this.setUniform("u_center", [o, h]), this.setUniform("u_aspectRatio", u), s.renderStroke(this.currentStrokeWeight)), this.currentShader = null;
771
762
  }
772
763
  /**
773
764
  * Draw a line from (x1, y1) to (x2, y2) with the current stroke settings.
@@ -782,31 +773,31 @@ class fe {
782
773
  const s = new ce(this.gl, e, t, r, i);
783
774
  if (this.currentShader !== null) {
784
775
  if (this.currentRotation !== 0) {
785
- const _ = (e + r) / 2, b = (t + i) / 2, C = Math.abs(r - e), v = Math.abs(i - t), { centerX: w, centerY: D, radians: R, aspectRatio: y } = this.calculateRotationParams(_ - C / 2, b - v / 2, C, v);
786
- this.setUniform("u_rotation", R), this.setUniform("u_center", [w, D]), this.setUniform("u_aspectRatio", y);
776
+ const p = (e + r) / 2, b = (t + i) / 2, C = Math.abs(r - e), v = Math.abs(i - t), { centerX: w, centerY: A, radians: R, aspectRatio: S } = this.calculateRotationParams(p - C / 2, b - v / 2, C, v);
777
+ this.setUniform("u_rotation", R), this.setUniform("u_center", [w, A]), this.setUniform("u_aspectRatio", S);
787
778
  } else
788
779
  this.setUniform("u_rotation", 0), this.setUniform("u_center", [0, 0]), this.setUniform("u_aspectRatio", 1);
789
780
  s.renderStroke(this.currentStrokeWeight), this.currentShader = null;
790
781
  return;
791
782
  }
792
- const o = this.solidColorShader, n = (e + r) / 2, l = (t + i) / 2, c = Math.abs(r - e), u = Math.abs(i - t), { centerX: d, centerY: f, radians: g, aspectRatio: p } = this.calculateRotationParams(n - c / 2, l - u / 2, c, u);
793
- this.shader(o), this.setUniform("u_color", this.currentStrokeColor), this.setUniform("u_rotation", g), this.setUniform("u_center", [d, f]), this.setUniform("u_aspectRatio", p), s.renderStroke(this.currentStrokeWeight), this.currentShader = null;
783
+ const a = this.solidColorShader, o = (e + r) / 2, h = (t + i) / 2, c = Math.abs(r - e), u = Math.abs(i - t), { centerX: d, centerY: f, radians: g, aspectRatio: _ } = this.calculateRotationParams(o - c / 2, h - u / 2, c, u);
784
+ this.shader(a), this.setUniform("u_color", this.currentStrokeColor), this.setUniform("u_rotation", g), this.setUniform("u_center", [d, f]), this.setUniform("u_aspectRatio", _), s.renderStroke(this.currentStrokeWeight), this.currentShader = null;
794
785
  }
795
786
  /**
796
787
  * Calculate rotation parameters for built-in shaders (NDC coordinates)
797
788
  */
798
789
  calculateRotationParams(e, t, r, i) {
799
- const s = this.gl.getParameter(this.gl.VIEWPORT), o = s[2], n = s[3], l = o / n, c = this.gl.getParameter(this.gl.FRAMEBUFFER_BINDING) !== null, u = e + r / 2, d = t + i / 2, f = u / o * 2 - 1;
790
+ const s = this.gl.getParameter(this.gl.VIEWPORT), a = s[2], o = s[3], h = a / o, c = this.gl.getParameter(this.gl.FRAMEBUFFER_BINDING) !== null, u = e + r / 2, d = t + i / 2, f = u / a * 2 - 1;
800
791
  let g;
801
- c ? g = d / n * 2 - 1 : g = 1 - d / n * 2;
802
- const p = this.currentRotation * Math.PI / 180;
803
- return { centerX: f, centerY: g, radians: p, aspectRatio: l };
792
+ c ? g = d / o * 2 - 1 : g = 1 - d / o * 2;
793
+ const _ = this.currentRotation * Math.PI / 180;
794
+ return { centerX: f, centerY: g, radians: _, aspectRatio: h };
804
795
  }
805
796
  /**
806
797
  * Create a new framebuffer
807
798
  */
808
799
  createFramebuffer(e, t, r = {}) {
809
- return new ae(this.gl, e, t, r);
800
+ return new ne(this.gl, e, t, r);
810
801
  }
811
802
  /**
812
803
  * Fill the current framebuffer with a solid color
@@ -837,31 +828,25 @@ class fe {
837
828
  * This method is idempotent and safe to call multiple times.
838
829
  */
839
830
  dispose() {
840
- this.imageShader && !this.imageShader.isDisposed && this.imageShader.dispose(), this.solidColorShader && !this.solidColorShader.isDisposed && this.solidColorShader.dispose(), this.imageShader = null, this.solidColorShader = null, this.currentShader = null, this.stateStack = [];
841
- }
842
- /**
843
- * Check if this renderer has been disposed
844
- */
845
- get isDisposed() {
846
- return this.imageShader === null || this.solidColorShader === null;
831
+ this.imageShader.dispose(), this.solidColorShader.dispose(), this.imageShader = null, this.solidColorShader = null, this.currentShader = null, this.stateStack = [];
847
832
  }
848
833
  /**
849
834
  * Render a framebuffer at a specific position with optional scaling
850
835
  */
851
836
  image(e, t, r, i, s) {
852
837
  this.shader(this.imageShader), this.setUniform("u_texture", e.texture);
853
- const { centerX: o, centerY: n, radians: l, aspectRatio: c } = this.calculateRotationParams(
838
+ const { centerX: a, centerY: o, radians: h, aspectRatio: c } = this.calculateRotationParams(
854
839
  t,
855
840
  r,
856
841
  i ?? e.width,
857
842
  s ?? e.height
858
843
  );
859
- this.setUniform("u_rotation", l), this.setUniform("u_center", [o, n]), this.setUniform("u_aspectRatio", c), this.rect(t, r, i ?? e.width, s ?? e.height);
844
+ this.setUniform("u_rotation", h), this.setUniform("u_center", [a, o]), this.setUniform("u_aspectRatio", c), this.rect(t, r, i ?? e.width, s ?? e.height);
860
845
  }
861
846
  }
862
847
  var m = {};
863
- m.parse = function(h) {
864
- var e = function(s, o, n, l) {
848
+ m.parse = function(l) {
849
+ var e = function(s, a, o, h) {
865
850
  var c = m.T, u = {
866
851
  cmap: c.cmap,
867
852
  head: c.head,
@@ -870,119 +855,119 @@ m.parse = function(h) {
870
855
  hmtx: c.hmtx,
871
856
  loca: c.loca,
872
857
  glyf: c.glyf
873
- }, d = { _data: s, _index: o, _offset: n };
858
+ }, d = { _data: s, _index: a, _offset: o };
874
859
  for (var f in u) {
875
- var g = m.findTable(s, f, n);
860
+ var g = m.findTable(s, f, o);
876
861
  if (g) {
877
- var p = g[0], _ = l[p];
878
- _ == null && (_ = u[f].parseTab(s, p, g[1], d)), d[f] = l[p] = _;
862
+ var _ = g[0], p = h[_];
863
+ p == null && (p = u[f].parseTab(s, _, g[1], d)), d[f] = h[_] = p;
879
864
  }
880
865
  }
881
866
  return d;
882
- }, t = new Uint8Array(h), r = {}, i = e(t, 0, 0, r);
867
+ }, t = new Uint8Array(l), r = {}, i = e(t, 0, 0, r);
883
868
  return [i];
884
869
  };
885
- m.findTable = function(h, e, t) {
886
- for (var r = m.B, i = r.readUshort(h, t + 4), s = t + 12, o = 0; o < i; o++) {
887
- var n = r.readASCII(h, s, 4);
888
- r.readUint(h, s + 4);
889
- var l = r.readUint(h, s + 8), c = r.readUint(h, s + 12);
890
- if (n == e) return [l, c];
870
+ m.findTable = function(l, e, t) {
871
+ for (var r = m.B, i = r.readUshort(l, t + 4), s = t + 12, a = 0; a < i; a++) {
872
+ var o = r.readASCII(l, s, 4);
873
+ r.readUint(l, s + 4);
874
+ var h = r.readUint(l, s + 8), c = r.readUint(l, s + 12);
875
+ if (o == e) return [h, c];
891
876
  s += 16;
892
877
  }
893
878
  return null;
894
879
  };
895
880
  m.T = {};
896
881
  m.B = {
897
- readShort: function(h, e) {
882
+ readShort: function(l, e) {
898
883
  var t = m.B.t.uint16;
899
- return t[0] = h[e] << 8 | h[e + 1], m.B.t.int16[0];
884
+ return t[0] = l[e] << 8 | l[e + 1], m.B.t.int16[0];
900
885
  },
901
- readUshort: function(h, e) {
902
- return h[e] << 8 | h[e + 1];
886
+ readUshort: function(l, e) {
887
+ return l[e] << 8 | l[e + 1];
903
888
  },
904
- readUshorts: function(h, e, t) {
889
+ readUshorts: function(l, e, t) {
905
890
  for (var r = [], i = 0; i < t; i++)
906
- r.push(m.B.readUshort(h, e + i * 2));
891
+ r.push(m.B.readUshort(l, e + i * 2));
907
892
  return r;
908
893
  },
909
- readUint: function(h, e) {
894
+ readUint: function(l, e) {
910
895
  var t = m.B.t.uint8;
911
- return t[3] = h[e], t[2] = h[e + 1], t[1] = h[e + 2], t[0] = h[e + 3], m.B.t.uint32[0];
896
+ return t[3] = l[e], t[2] = l[e + 1], t[1] = l[e + 2], t[0] = l[e + 3], m.B.t.uint32[0];
912
897
  },
913
- readASCII: function(h, e, t) {
914
- for (var r = "", i = 0; i < t; i++) r += String.fromCharCode(h[e + i]);
898
+ readASCII: function(l, e, t) {
899
+ for (var r = "", i = 0; i < t; i++) r += String.fromCharCode(l[e + i]);
915
900
  return r;
916
901
  },
917
902
  // Simplified typed array buffer - only what's needed
918
903
  t: function() {
919
- var h = new ArrayBuffer(8);
904
+ var l = new ArrayBuffer(8);
920
905
  return {
921
- uint8: new Uint8Array(h),
922
- int16: new Int16Array(h),
923
- uint16: new Uint16Array(h),
924
- uint32: new Uint32Array(h)
906
+ uint8: new Uint8Array(l),
907
+ int16: new Int16Array(l),
908
+ uint16: new Uint16Array(l),
909
+ uint32: new Uint32Array(l)
925
910
  };
926
911
  }()
927
912
  };
928
913
  m.T.cmap = {
929
- parseTab: function(h, e, t) {
914
+ parseTab: function(l, e, t) {
930
915
  var r = { tables: [], ids: {}, off: e };
931
- h = new Uint8Array(h.buffer, e, t), e = 0;
932
- var i = m.B, s = i.readUshort, o = m.T.cmap;
933
- s(h, e), e += 2;
934
- var n = s(h, e);
916
+ l = new Uint8Array(l.buffer, e, t), e = 0;
917
+ var i = m.B, s = i.readUshort, a = m.T.cmap;
918
+ s(l, e), e += 2;
919
+ var o = s(l, e);
935
920
  e += 2;
936
- for (var l = [], c = 0; c < n; c++) {
937
- var u = s(h, e);
921
+ for (var h = [], c = 0; c < o; c++) {
922
+ var u = s(l, e);
938
923
  e += 2;
939
- var d = s(h, e);
924
+ var d = s(l, e);
940
925
  e += 2;
941
- var f = i.readUint(h, e);
926
+ var f = i.readUint(l, e);
942
927
  e += 4;
943
- var g = "p" + u + "e" + d, p = l.indexOf(f);
944
- if (p == -1) {
945
- p = r.tables.length;
946
- var _ = {};
947
- l.push(f);
948
- var b = _.format = s(h, f);
949
- b == 4 ? _ = o.parse4(h, f, _) : b == 12 && (_ = o.parse12(h, f, _)), r.tables.push(_);
928
+ var g = "p" + u + "e" + d, _ = h.indexOf(f);
929
+ if (_ == -1) {
930
+ _ = r.tables.length;
931
+ var p = {};
932
+ h.push(f);
933
+ var b = p.format = s(l, f);
934
+ b == 4 ? p = a.parse4(l, f, p) : b == 12 && (p = a.parse12(l, f, p)), r.tables.push(p);
950
935
  }
951
- r.ids[g] != null && console.log("multiple tables for one platform+encoding: " + g), r.ids[g] = p;
936
+ r.ids[g] != null && console.log("multiple tables for one platform+encoding: " + g), r.ids[g] = _;
952
937
  }
953
938
  return r;
954
939
  },
955
- parse4: function(h, e, t) {
956
- var r = m.B, i = r.readUshort, s = r.readUshorts, o = e;
940
+ parse4: function(l, e, t) {
941
+ var r = m.B, i = r.readUshort, s = r.readUshorts, a = e;
957
942
  e += 2;
958
- var n = i(h, e);
959
- e += 2, i(h, e), e += 2;
960
- var l = i(h, e);
943
+ var o = i(l, e);
944
+ e += 2, i(l, e), e += 2;
945
+ var h = i(l, e);
961
946
  e += 2;
962
- var c = l >>> 1;
963
- t.searchRange = i(h, e), e += 2, t.entrySelector = i(h, e), e += 2, t.rangeShift = i(h, e), e += 2, t.endCount = s(h, e, c), e += c * 2, e += 2, t.startCount = s(h, e, c), e += c * 2, t.idDelta = [];
947
+ var c = h >>> 1;
948
+ t.searchRange = i(l, e), e += 2, t.entrySelector = i(l, e), e += 2, t.rangeShift = i(l, e), e += 2, t.endCount = s(l, e, c), e += c * 2, e += 2, t.startCount = s(l, e, c), e += c * 2, t.idDelta = [];
964
949
  for (var u = 0; u < c; u++)
965
- t.idDelta.push(r.readShort(h, e)), e += 2;
966
- return t.idRangeOffset = s(h, e, c), e += c * 2, t.glyphIdArray = s(h, e, o + n - e >> 1), t;
950
+ t.idDelta.push(r.readShort(l, e)), e += 2;
951
+ return t.idRangeOffset = s(l, e, c), e += c * 2, t.glyphIdArray = s(l, e, a + o - e >> 1), t;
967
952
  },
968
- parse12: function(h, e, t) {
953
+ parse12: function(l, e, t) {
969
954
  var r = m.B, i = r.readUint;
970
- e += 4, i(h, e), e += 4, i(h, e), e += 4;
971
- var s = i(h, e) * 3;
955
+ e += 4, i(l, e), e += 4, i(l, e), e += 4;
956
+ var s = i(l, e) * 3;
972
957
  e += 4;
973
- for (var o = t.groups = new Uint32Array(s), n = 0; n < s; n += 3)
974
- o[n] = i(h, e + (n << 2)), o[n + 1] = i(h, e + (n << 2) + 4), o[n + 2] = i(h, e + (n << 2) + 8);
958
+ for (var a = t.groups = new Uint32Array(s), o = 0; o < s; o += 3)
959
+ a[o] = i(l, e + (o << 2)), a[o + 1] = i(l, e + (o << 2) + 4), a[o + 2] = i(l, e + (o << 2) + 8);
975
960
  return t;
976
961
  }
977
962
  };
978
963
  m.T.head = {
979
- parseTab: function(h, e, t) {
964
+ parseTab: function(l, e, t) {
980
965
  var r = m.B, i = {};
981
- return e += 18, i.unitsPerEm = r.readUshort(h, e), e += 2, e += 16, i.xMin = r.readShort(h, e), e += 2, i.yMin = r.readShort(h, e), e += 2, i.xMax = r.readShort(h, e), e += 2, i.yMax = r.readShort(h, e), e += 2, e += 6, i.indexToLocFormat = r.readShort(h, e), i;
966
+ return e += 18, i.unitsPerEm = r.readUshort(l, e), e += 2, e += 16, i.xMin = r.readShort(l, e), e += 2, i.yMin = r.readShort(l, e), e += 2, i.xMax = r.readShort(l, e), e += 2, i.yMax = r.readShort(l, e), e += 2, e += 6, i.indexToLocFormat = r.readShort(l, e), i;
982
967
  }
983
968
  };
984
969
  m.T.hhea = {
985
- parseTab: function(h, e, t) {
970
+ parseTab: function(l, e, t) {
986
971
  var r = m.B, i = {};
987
972
  e += 4;
988
973
  for (var s = [
@@ -1002,79 +987,79 @@ m.T.hhea = {
1002
987
  "res3",
1003
988
  "metricDataFormat",
1004
989
  "numberOfHMetrics"
1005
- ], o = 0; o < s.length; o++) {
1006
- var n = s[o], l = n == "advanceWidthMax" || n == "numberOfHMetrics" ? r.readUshort : r.readShort;
1007
- i[n] = l(h, e + o * 2);
990
+ ], a = 0; a < s.length; a++) {
991
+ var o = s[a], h = o == "advanceWidthMax" || o == "numberOfHMetrics" ? r.readUshort : r.readShort;
992
+ i[o] = h(l, e + a * 2);
1008
993
  }
1009
994
  return i;
1010
995
  }
1011
996
  };
1012
997
  m.T.hmtx = {
1013
- parseTab: function(h, e, t, r) {
1014
- for (var i = m.B, s = [], o = [], n = r.maxp.numGlyphs, l = r.hhea.numberOfHMetrics, c = 0, u = 0, d = 0; d < l; )
1015
- c = i.readUshort(h, e + (d << 2)), u = i.readShort(h, e + (d << 2) + 2), s.push(c), o.push(u), d++;
1016
- for (; d < n; )
1017
- s.push(c), o.push(u), d++;
1018
- return { aWidth: s, lsBearing: o };
998
+ parseTab: function(l, e, t, r) {
999
+ for (var i = m.B, s = [], a = [], o = r.maxp.numGlyphs, h = r.hhea.numberOfHMetrics, c = 0, u = 0, d = 0; d < h; )
1000
+ c = i.readUshort(l, e + (d << 2)), u = i.readShort(l, e + (d << 2) + 2), s.push(c), a.push(u), d++;
1001
+ for (; d < o; )
1002
+ s.push(c), a.push(u), d++;
1003
+ return { aWidth: s, lsBearing: a };
1019
1004
  }
1020
1005
  };
1021
1006
  m.T.maxp = {
1022
- parseTab: function(h, e, t) {
1007
+ parseTab: function(l, e, t) {
1023
1008
  var r = m.B, i = r.readUshort, s = {};
1024
- return r.readUint(h, e), e += 4, s.numGlyphs = i(h, e), e += 2, s;
1009
+ return r.readUint(l, e), e += 4, s.numGlyphs = i(l, e), e += 2, s;
1025
1010
  }
1026
1011
  };
1027
1012
  m.T.loca = {
1028
- parseTab: function(h, e, t, r) {
1029
- var i = m.B, s = [], o = r.head.indexToLocFormat, n = r.maxp.numGlyphs + 1;
1030
- if (o == 0) for (var l = 0; l < n; l++) s.push(i.readUshort(h, e + (l << 1)) << 1);
1031
- if (o == 1) for (var l = 0; l < n; l++) s.push(i.readUint(h, e + (l << 2)));
1013
+ parseTab: function(l, e, t, r) {
1014
+ var i = m.B, s = [], a = r.head.indexToLocFormat, o = r.maxp.numGlyphs + 1;
1015
+ if (a == 0) for (var h = 0; h < o; h++) s.push(i.readUshort(l, e + (h << 1)) << 1);
1016
+ if (a == 1) for (var h = 0; h < o; h++) s.push(i.readUint(l, e + (h << 2)));
1032
1017
  return s;
1033
1018
  }
1034
1019
  };
1035
1020
  m.T.glyf = {
1036
- parseTab: function(h, e, t, r) {
1037
- for (var i = [], s = r.maxp.numGlyphs, o = 0; o < s; o++) i.push(null);
1021
+ parseTab: function(l, e, t, r) {
1022
+ for (var i = [], s = r.maxp.numGlyphs, a = 0; a < s; a++) i.push(null);
1038
1023
  return i;
1039
1024
  },
1040
- _parseGlyf: function(h, e) {
1041
- var t = m.B, r = h._data, i = h.loca;
1025
+ _parseGlyf: function(l, e) {
1026
+ var t = m.B, r = l._data, i = l.loca;
1042
1027
  if (i[e] == i[e + 1]) return null;
1043
- var s = m.findTable(r, "glyf", h._offset)[0] + i[e], o = {};
1044
- if (o.noc = t.readShort(r, s), s += 2, o.xMin = t.readShort(r, s), s += 2, o.yMin = t.readShort(r, s), s += 2, o.xMax = t.readShort(r, s), s += 2, o.yMax = t.readShort(r, s), s += 2, o.xMin >= o.xMax || o.yMin >= o.yMax) return null;
1045
- if (o.noc > 0) {
1046
- o.endPts = [];
1047
- for (var n = 0; n < o.noc; n++)
1048
- o.endPts.push(t.readUshort(r, s)), s += 2;
1049
- var l = t.readUshort(r, s);
1050
- if (s += 2, r.length - s < l) return null;
1051
- s += l;
1052
- var c = o.endPts[o.noc - 1] + 1;
1053
- o.flags = [];
1054
- for (var n = 0; n < c; n++) {
1028
+ var s = m.findTable(r, "glyf", l._offset)[0] + i[e], a = {};
1029
+ if (a.noc = t.readShort(r, s), s += 2, a.xMin = t.readShort(r, s), s += 2, a.yMin = t.readShort(r, s), s += 2, a.xMax = t.readShort(r, s), s += 2, a.yMax = t.readShort(r, s), s += 2, a.xMin >= a.xMax || a.yMin >= a.yMax) return null;
1030
+ if (a.noc > 0) {
1031
+ a.endPts = [];
1032
+ for (var o = 0; o < a.noc; o++)
1033
+ a.endPts.push(t.readUshort(r, s)), s += 2;
1034
+ var h = t.readUshort(r, s);
1035
+ if (s += 2, r.length - s < h) return null;
1036
+ s += h;
1037
+ var c = a.endPts[a.noc - 1] + 1;
1038
+ a.flags = [];
1039
+ for (var o = 0; o < c; o++) {
1055
1040
  var u = r[s];
1056
- if (s++, o.flags.push(u), u & 8) {
1041
+ if (s++, a.flags.push(u), u & 8) {
1057
1042
  var d = r[s];
1058
1043
  s++;
1059
1044
  for (var f = 0; f < d; f++)
1060
- o.flags.push(u), n++;
1045
+ a.flags.push(u), o++;
1061
1046
  }
1062
1047
  }
1063
- o.xs = [];
1064
- for (var n = 0; n < c; n++) {
1065
- var g = (o.flags[n] & 2) != 0, p = (o.flags[n] & 16) != 0;
1066
- g ? (o.xs.push(p ? r[s] : -r[s]), s++) : p ? o.xs.push(0) : (o.xs.push(t.readShort(r, s)), s += 2);
1048
+ a.xs = [];
1049
+ for (var o = 0; o < c; o++) {
1050
+ var g = (a.flags[o] & 2) != 0, _ = (a.flags[o] & 16) != 0;
1051
+ g ? (a.xs.push(_ ? r[s] : -r[s]), s++) : _ ? a.xs.push(0) : (a.xs.push(t.readShort(r, s)), s += 2);
1067
1052
  }
1068
- o.ys = [];
1069
- for (var n = 0; n < c; n++) {
1070
- var g = (o.flags[n] & 4) != 0, p = (o.flags[n] & 32) != 0;
1071
- g ? (o.ys.push(p ? r[s] : -r[s]), s++) : p ? o.ys.push(0) : (o.ys.push(t.readShort(r, s)), s += 2);
1053
+ a.ys = [];
1054
+ for (var o = 0; o < c; o++) {
1055
+ var g = (a.flags[o] & 4) != 0, _ = (a.flags[o] & 32) != 0;
1056
+ g ? (a.ys.push(_ ? r[s] : -r[s]), s++) : _ ? a.ys.push(0) : (a.ys.push(t.readShort(r, s)), s += 2);
1072
1057
  }
1073
- for (var _ = 0, b = 0, n = 0; n < c; n++)
1074
- _ += o.xs[n], b += o.ys[n], o.xs[n] = _, o.ys[n] = b;
1058
+ for (var p = 0, b = 0, o = 0; o < c; o++)
1059
+ p += a.xs[o], b += a.ys[o], a.xs[o] = p, a.ys[o] = b;
1075
1060
  } else
1076
- o.parts = [];
1077
- return o;
1061
+ a.parts = [];
1062
+ return a;
1078
1063
  }
1079
1064
  };
1080
1065
  typeof module < "u" && module.exports ? module.exports = m : typeof window < "u" && (window.Typr = m);
@@ -1109,10 +1094,10 @@ class me {
1109
1094
  for (let r = 0; r < e.startCount.length; r++) {
1110
1095
  const i = e.startCount[r], s = e.endCount[r];
1111
1096
  if (!(i === 65535 && s === 65535)) {
1112
- for (let o = i; o <= s; o++)
1113
- if (this._calculateGlyphIndexFormat4(e, o, r) > 0) {
1114
- const l = String.fromCodePoint(o);
1115
- t.push(l);
1097
+ for (let a = i; a <= s; a++)
1098
+ if (this._calculateGlyphIndexFormat4(e, a, r) > 0) {
1099
+ const h = String.fromCodePoint(a);
1100
+ t.push(h);
1116
1101
  }
1117
1102
  }
1118
1103
  }
@@ -1128,10 +1113,10 @@ class me {
1128
1113
  if (!e.groups)
1129
1114
  return t;
1130
1115
  for (let r = 0; r < e.groups.length; r += 3) {
1131
- const i = e.groups[r], s = e.groups[r + 1], o = e.groups[r + 2];
1132
- for (let n = i; n <= s; n++)
1133
- if (o + (n - i) > 0) {
1134
- const c = String.fromCodePoint(n);
1116
+ const i = e.groups[r], s = e.groups[r + 1], a = e.groups[r + 2];
1117
+ for (let o = i; o <= s; o++)
1118
+ if (a + (o - i) > 0) {
1119
+ const c = String.fromCodePoint(o);
1135
1120
  t.push(c);
1136
1121
  }
1137
1122
  }
@@ -1181,9 +1166,9 @@ class ge {
1181
1166
  * @param renderer The WebGL renderer instance
1182
1167
  */
1183
1168
  constructor(e) {
1184
- a(this, "_textureCanvas");
1185
- a(this, "_textureContext");
1186
- a(this, "_renderer");
1169
+ n(this, "_textureCanvas");
1170
+ n(this, "_textureContext");
1171
+ n(this, "_renderer");
1187
1172
  this._renderer = e, this._textureCanvas = document.createElement("canvas"), this._textureContext = this._textureCanvas.getContext("2d", { willReadFrequently: !0, alpha: !1 });
1188
1173
  }
1189
1174
  /**
@@ -1195,13 +1180,13 @@ class ge {
1195
1180
  * @returns Object containing framebuffer, columns, and rows
1196
1181
  */
1197
1182
  createTextureAtlas(e, t, r, i) {
1198
- const s = e.length, o = Math.ceil(Math.sqrt(s)), n = Math.ceil(s / o), l = t.width * o, c = t.height * n;
1199
- this._setupCanvas(l, c, r, i), this._renderCharactersToCanvas(e, t, o, r), this._applyBlackWhiteThreshold();
1200
- const u = this._renderer.createFramebuffer(l, c, { filter: "nearest" });
1183
+ const s = e.length, a = Math.ceil(Math.sqrt(s)), o = Math.ceil(s / a), h = t.width * a, c = t.height * o;
1184
+ this._setupCanvas(h, c, r, i), this._renderCharactersToCanvas(e, t, a, r), this._applyBlackWhiteThreshold();
1185
+ const u = this._renderer.createFramebuffer(h, c, { filter: "nearest" });
1201
1186
  return u.update(this._textureCanvas), {
1202
1187
  framebuffer: u,
1203
- columns: o,
1204
- rows: n
1188
+ columns: a,
1189
+ rows: o
1205
1190
  };
1206
1191
  }
1207
1192
  /**
@@ -1225,7 +1210,7 @@ class ge {
1225
1210
  */
1226
1211
  _renderCharactersToCanvas(e, t, r, i) {
1227
1212
  for (let s = 0; s < e.length; s++) {
1228
- const o = s % r, n = Math.floor(s / r), l = o * t.width + t.width * 0.5, c = n * t.height + t.height * 0.5, u = Math.round(l - t.width * 0.5), d = Math.round(c - i * 0.5);
1213
+ const a = s % r, o = Math.floor(s / r), h = a * t.width + t.width * 0.5, c = o * t.height + t.height * 0.5, u = Math.round(h - t.width * 0.5), d = Math.round(c - i * 0.5);
1229
1214
  this._textureContext.fillText(e[s].character, u, d);
1230
1215
  }
1231
1216
  }
@@ -1238,19 +1223,19 @@ class ge {
1238
1223
  _applyBlackWhiteThreshold(e = 128) {
1239
1224
  const t = this._textureContext.getImageData(0, 0, this._textureCanvas.width, this._textureCanvas.height), r = t.data;
1240
1225
  for (let i = 0; i < r.length; i += 4) {
1241
- const s = 0.299 * r[i] + 0.587 * r[i + 1] + 0.114 * r[i + 2], o = e + 32, n = s > o ? 255 : 0;
1242
- r[i] = n, r[i + 1] = n, r[i + 2] = n;
1226
+ const s = 0.299 * r[i] + 0.587 * r[i + 1] + 0.114 * r[i + 2], a = e + 32, o = s > a ? 255 : 0;
1227
+ r[i] = o, r[i + 1] = o, r[i + 2] = o;
1243
1228
  }
1244
1229
  this._textureContext.putImageData(t, 0, 0);
1245
1230
  }
1246
1231
  }
1247
- class _e {
1232
+ class pe {
1248
1233
  /**
1249
1234
  * Creates a new MetricsCalculation instance.
1250
1235
  */
1251
1236
  constructor() {
1252
- a(this, "_tempCanvas");
1253
- a(this, "_tempContext");
1237
+ n(this, "_tempCanvas");
1238
+ n(this, "_tempContext");
1254
1239
  this._tempCanvas = document.createElement("canvas"), this._tempContext = this._tempCanvas.getContext("2d");
1255
1240
  }
1256
1241
  /**
@@ -1264,9 +1249,9 @@ class _e {
1264
1249
  calculateMaxGlyphDimensions(e, t, r) {
1265
1250
  this._tempContext.font = `${t}px ${r}`;
1266
1251
  let i = 0, s = 0;
1267
- for (const o of e) {
1268
- const n = this._tempContext.measureText(o), l = n.width, c = n.actualBoundingBoxAscent + n.actualBoundingBoxDescent;
1269
- l > 0 && (i = Math.max(i, l), s = Math.max(s, c));
1252
+ for (const a of e) {
1253
+ const o = this._tempContext.measureText(a), h = o.width, c = o.actualBoundingBoxAscent + o.actualBoundingBoxDescent;
1254
+ h > 0 && (i = Math.max(i, h), s = Math.max(s, c));
1270
1255
  }
1271
1256
  return {
1272
1257
  width: Math.ceil(i),
@@ -1274,7 +1259,7 @@ class _e {
1274
1259
  };
1275
1260
  }
1276
1261
  }
1277
- class pe {
1262
+ class _e {
1278
1263
  /**
1279
1264
  * Creates TextmodeCharacter objects with unique color assignments.
1280
1265
  * @param characters Array of character strings
@@ -1283,17 +1268,17 @@ class pe {
1283
1268
  */
1284
1269
  createCharacterObjects(e, t) {
1285
1270
  return e.map((r, i) => {
1286
- const s = r.codePointAt(0) || 0, o = this._generateCharacterColor(i);
1287
- let n = 0;
1271
+ const s = r.codePointAt(0) || 0, a = this._generateCharacterColor(i);
1272
+ let o = 0;
1288
1273
  if (t.hmtx && t.hmtx.aWidth) {
1289
- const l = this._getGlyphIndex(t, s);
1290
- l > 0 && t.hmtx.aWidth[l] !== void 0 && (n = t.hmtx.aWidth[l]);
1274
+ const h = this._getGlyphIndex(t, s);
1275
+ h > 0 && t.hmtx.aWidth[h] !== void 0 && (o = t.hmtx.aWidth[h]);
1291
1276
  }
1292
1277
  return {
1293
1278
  character: r,
1294
1279
  unicode: s,
1295
- color: o,
1296
- advanceWidth: n
1280
+ color: a,
1281
+ advanceWidth: o
1297
1282
  };
1298
1283
  });
1299
1284
  }
@@ -1314,11 +1299,11 @@ class pe {
1314
1299
  if (i.idRangeOffset[s] === 0)
1315
1300
  return t + i.idDelta[s] & 65535;
1316
1301
  {
1317
- const o = i.idRangeOffset[s] / 2 + (t - i.startCount[s]) - (i.startCount.length - s);
1318
- if (o >= 0 && o < i.glyphIdArray.length) {
1319
- const n = i.glyphIdArray[o];
1320
- if (n !== 0)
1321
- return n + i.idDelta[s] & 65535;
1302
+ const a = i.idRangeOffset[s] / 2 + (t - i.startCount[s]) - (i.startCount.length - s);
1303
+ if (a >= 0 && a < i.glyphIdArray.length) {
1304
+ const o = i.glyphIdArray[a];
1305
+ if (o !== 0)
1306
+ return o + i.idDelta[s] & 65535;
1322
1307
  }
1323
1308
  }
1324
1309
  }
@@ -1372,21 +1357,21 @@ class xe {
1372
1357
  * @ignore
1373
1358
  */
1374
1359
  constructor(e, t = 16) {
1375
- a(this, "_font");
1376
- a(this, "_characters", []);
1377
- a(this, "_fontFramebuffer");
1378
- a(this, "_fontSize", 16);
1379
- a(this, "_textureColumns", 0);
1380
- a(this, "_textureRows", 0);
1381
- a(this, "_maxGlyphDimensions", { width: 0, height: 0 });
1382
- a(this, "_fontFace");
1383
- a(this, "_fontFamilyName", "UrsaFont");
1360
+ n(this, "_font");
1361
+ n(this, "_characters", []);
1362
+ n(this, "_fontFramebuffer");
1363
+ n(this, "_fontSize", 16);
1364
+ n(this, "_textureColumns", 0);
1365
+ n(this, "_textureRows", 0);
1366
+ n(this, "_maxGlyphDimensions", { width: 0, height: 0 });
1367
+ n(this, "_fontFace");
1368
+ n(this, "_fontFamilyName", "UrsaFont");
1384
1369
  // Component classes
1385
- a(this, "_characterExtractor");
1386
- a(this, "_textureAtlas");
1387
- a(this, "_metricsCalculator");
1388
- a(this, "_characterColorMapper");
1389
- this._fontSize = t, this._characterExtractor = new me(), this._textureAtlas = new ge(e), this._metricsCalculator = new _e(), this._characterColorMapper = new pe();
1370
+ n(this, "_characterExtractor");
1371
+ n(this, "_textureAtlas");
1372
+ n(this, "_metricsCalculator");
1373
+ n(this, "_characterColorMapper");
1374
+ this._fontSize = t, this._characterExtractor = new me(), this._textureAtlas = new ge(e), this._metricsCalculator = new pe(), this._characterColorMapper = new _e();
1390
1375
  }
1391
1376
  /**
1392
1377
  * Initializes the font manager by loading the font and creating the texture atlas.
@@ -1529,13 +1514,7 @@ class xe {
1529
1514
  * This method is idempotent and safe to call multiple times.
1530
1515
  */
1531
1516
  dispose() {
1532
- this._fontFramebuffer && !this._fontFramebuffer.isDisposed && this._fontFramebuffer.dispose(), this._fontFace && document.fonts.has(this._fontFace) && document.fonts.delete(this._fontFace), this._fontFramebuffer = null, this._fontFace = null, this._font = null, this._characters = [], this._maxGlyphDimensions = { width: 0, height: 0 }, this._textureColumns = 0, this._textureRows = 0;
1533
- }
1534
- /**
1535
- * Check if this font manager has been disposed
1536
- */
1537
- get isDisposed() {
1538
- return this._fontFramebuffer === null || this._font === null;
1517
+ this._fontFramebuffer.dispose(), document.fonts.delete(this._fontFace), this._fontFramebuffer = null, this._fontFace = null, this._font = null, this._characters = [], this._maxGlyphDimensions = { width: 0, height: 0 }, this._textureColumns = 0, this._textureRows = 0;
1539
1518
  }
1540
1519
  /** Returns the font size used for rendering. */
1541
1520
  get fontSize() {
@@ -1556,25 +1535,25 @@ class ve {
1556
1535
  */
1557
1536
  constructor(e, t, r) {
1558
1537
  /** The number of columns in the grid. */
1559
- a(this, "_cols");
1538
+ n(this, "_cols");
1560
1539
  /** The number of rows in the grid. */
1561
- a(this, "_rows");
1540
+ n(this, "_rows");
1562
1541
  /** The total width of the grid in pixels. */
1563
- a(this, "_width");
1542
+ n(this, "_width");
1564
1543
  /** The total height of the grid in pixels. */
1565
- a(this, "_height");
1544
+ n(this, "_height");
1566
1545
  /** The offset to the outer canvas on the x-axis when centering the grid. */
1567
- a(this, "_offsetX");
1546
+ n(this, "_offsetX");
1568
1547
  /** The offset to the outer canvas on the y-axis when centering the grid. */
1569
- a(this, "_offsetY");
1548
+ n(this, "_offsetY");
1570
1549
  /** Whether the grid dimensions are fixed, or responsive based on the canvas dimensions. */
1571
- a(this, "_fixedDimensions", !1);
1550
+ n(this, "_fixedDimensions", !1);
1572
1551
  /** The canvas element used to determine the grid dimensions. */
1573
- a(this, "_canvas");
1552
+ n(this, "_canvas");
1574
1553
  /** The width of each cell in the grid. */
1575
- a(this, "_cellWidth");
1554
+ n(this, "_cellWidth");
1576
1555
  /** The height of each cell in the grid. */
1577
- a(this, "_cellHeight");
1556
+ n(this, "_cellHeight");
1578
1557
  this._canvas = e, this._cellWidth = t, this._cellHeight = r, this.reset();
1579
1558
  }
1580
1559
  /**
@@ -1658,12 +1637,6 @@ class ve {
1658
1637
  dispose() {
1659
1638
  this._canvas = null, this._cols = 0, this._rows = 0, this._width = 0, this._height = 0, this._offsetX = 0, this._offsetY = 0, this._cellWidth = 0, this._cellHeight = 0;
1660
1639
  }
1661
- /**
1662
- * Check if this TextmodeGrid has been disposed
1663
- */
1664
- get isDisposed() {
1665
- return this._canvas === null;
1666
- }
1667
1640
  /** Returns the number of columns in the grid. */
1668
1641
  get cols() {
1669
1642
  return this._cols;
@@ -1691,9 +1664,9 @@ class ve {
1691
1664
  }
1692
1665
  class be {
1693
1666
  constructor(e, t = !1, r = {}) {
1694
- a(this, "_canvas");
1695
- a(this, "captureSource");
1696
- a(this, "_isStandalone");
1667
+ n(this, "_canvas");
1668
+ n(this, "captureSource");
1669
+ n(this, "_isStandalone");
1697
1670
  this.captureSource = e, this._isStandalone = t, this._canvas = this.createCanvas(r.width, r.height);
1698
1671
  }
1699
1672
  createCanvas(e, t) {
@@ -1703,14 +1676,14 @@ class be {
1703
1676
  r.width = e || 800, r.height = t || 600, document.body.appendChild(r);
1704
1677
  else {
1705
1678
  const s = this.captureSource.getBoundingClientRect();
1706
- let o = Math.round(s.width), n = Math.round(s.height);
1679
+ let a = Math.round(s.width), o = Math.round(s.height);
1707
1680
  if (this.captureSource instanceof HTMLVideoElement) {
1708
1681
  const u = this.captureSource;
1709
- (o === 0 || n === 0) && u.videoWidth > 0 && u.videoHeight > 0 && (o = u.videoWidth, n = u.videoHeight);
1682
+ (a === 0 || o === 0) && u.videoWidth > 0 && u.videoHeight > 0 && (a = u.videoWidth, o = u.videoHeight);
1710
1683
  }
1711
- r.width = o, r.height = n, r.style.position = "absolute", r.style.pointerEvents = "none";
1712
- const l = window.getComputedStyle(this.captureSource);
1713
- let c = parseInt(l.zIndex || "0", 10);
1684
+ r.width = a, r.height = o, r.style.position = "absolute", r.style.pointerEvents = "none";
1685
+ const h = window.getComputedStyle(this.captureSource);
1686
+ let c = parseInt(h.zIndex || "0", 10);
1714
1687
  isNaN(c) && (c = 0), r.style.zIndex = (c + 1).toString(), this.positionOverlayCanvas(r), (i = this.captureSource.parentNode) == null || i.insertBefore(r, this.captureSource.nextSibling);
1715
1688
  }
1716
1689
  return r;
@@ -1731,8 +1704,8 @@ class be {
1731
1704
  const r = this.captureSource.getBoundingClientRect();
1732
1705
  let i = Math.round(r.width), s = Math.round(r.height);
1733
1706
  if (this.captureSource instanceof HTMLVideoElement) {
1734
- const o = this.captureSource;
1735
- (i === 0 || s === 0) && o.videoWidth > 0 && o.videoHeight > 0 && (i = o.videoWidth, s = o.videoHeight);
1707
+ const a = this.captureSource;
1708
+ (i === 0 || s === 0) && a.videoWidth > 0 && a.videoHeight > 0 && (i = a.videoWidth, s = a.videoHeight);
1736
1709
  }
1737
1710
  this._canvas.width = i, this._canvas.height = s, this.positionOverlayCanvas(this._canvas);
1738
1711
  }
@@ -1769,12 +1742,6 @@ class be {
1769
1742
  }
1770
1743
  this.captureSource = null;
1771
1744
  }
1772
- /**
1773
- * Check if this TextmodeCanvas has been disposed
1774
- */
1775
- get isDisposed() {
1776
- return this._canvas === null;
1777
- }
1778
1745
  get canvas() {
1779
1746
  return this._canvas;
1780
1747
  }
@@ -1795,15 +1762,15 @@ class U {
1795
1762
  * @ignore
1796
1763
  */
1797
1764
  constructor(e, t, r, i = {}) {
1798
- a(this, "renderer");
1799
- a(this, "fontManager");
1800
- a(this, "grid");
1801
- a(this, "_characterFramebuffer");
1802
- a(this, "_primaryColorFramebuffer");
1803
- a(this, "_secondaryColorFramebuffer");
1804
- a(this, "_rotationFramebuffer");
1805
- a(this, "_transformFramebuffer");
1806
- a(this, "_options");
1765
+ n(this, "renderer");
1766
+ n(this, "fontManager");
1767
+ n(this, "grid");
1768
+ n(this, "_characterFramebuffer");
1769
+ n(this, "_primaryColorFramebuffer");
1770
+ n(this, "_secondaryColorFramebuffer");
1771
+ n(this, "_rotationFramebuffer");
1772
+ n(this, "_transformFramebuffer");
1773
+ n(this, "_options");
1807
1774
  this.renderer = e, this.fontManager = t, this.grid = r, this._options = i, this._characterFramebuffer = this.renderer.createFramebuffer(this.grid.cols, this.grid.rows), this._primaryColorFramebuffer = this.renderer.createFramebuffer(this.grid.cols, this.grid.rows), this._secondaryColorFramebuffer = this.renderer.createFramebuffer(this.grid.cols, this.grid.rows), this._rotationFramebuffer = this.renderer.createFramebuffer(this.grid.cols, this.grid.rows), this._transformFramebuffer = this.renderer.createFramebuffer(this.grid.cols, this.grid.rows);
1808
1775
  }
1809
1776
  /**
@@ -1837,13 +1804,7 @@ class U {
1837
1804
  * This method is idempotent and safe to call multiple times.
1838
1805
  */
1839
1806
  dispose() {
1840
- this._characterFramebuffer && !this._characterFramebuffer.isDisposed && this._characterFramebuffer.dispose(), this._primaryColorFramebuffer && !this._primaryColorFramebuffer.isDisposed && this._primaryColorFramebuffer.dispose(), this._secondaryColorFramebuffer && !this._secondaryColorFramebuffer.isDisposed && this._secondaryColorFramebuffer.dispose(), this._rotationFramebuffer && !this._rotationFramebuffer.isDisposed && this._rotationFramebuffer.dispose(), this._transformFramebuffer && !this._transformFramebuffer.isDisposed && this._transformFramebuffer.dispose(), this._characterFramebuffer = null, this._primaryColorFramebuffer = null, this._secondaryColorFramebuffer = null, this._rotationFramebuffer = null, this._transformFramebuffer = null;
1841
- }
1842
- /**
1843
- * Check if this converter has been disposed
1844
- */
1845
- get isDisposed() {
1846
- return this._characterFramebuffer === null;
1807
+ this._characterFramebuffer.dispose(), this._primaryColorFramebuffer.dispose(), this._secondaryColorFramebuffer.dispose(), this._rotationFramebuffer.dispose(), this._transformFramebuffer.dispose(), this._characterFramebuffer = null, this._primaryColorFramebuffer = null, this._secondaryColorFramebuffer = null, this._rotationFramebuffer = null, this._transformFramebuffer = null;
1847
1808
  }
1848
1809
  /** Returns the framebuffer containing character data. */
1849
1810
  get characterFramebuffer() {
@@ -1878,9 +1839,9 @@ class Ce {
1878
1839
  */
1879
1840
  constructor(e, t) {
1880
1841
  /** The framebuffer used to store the color palette. */
1881
- a(this, "_framebuffer");
1882
- a(this, "_renderer");
1883
- a(this, "_colors");
1842
+ n(this, "_framebuffer");
1843
+ n(this, "_renderer");
1844
+ n(this, "_colors");
1884
1845
  this._renderer = e, this._colors = t;
1885
1846
  const r = Math.max(this._colors.length, 1);
1886
1847
  this._framebuffer = this._renderer.createFramebuffer(r, 1), this._updateFramebuffer();
@@ -1894,8 +1855,8 @@ class Ce {
1894
1855
  this._framebuffer.width !== e && this._framebuffer.resize(e, t);
1895
1856
  const r = new Uint8Array(e * t * 4);
1896
1857
  for (let i = 0; i < e; i++) {
1897
- const s = i < this._colors.length ? this._colors[i] : [0, 0, 0], o = i * 4;
1898
- r[o] = s[0], r[o + 1] = s[1], r[o + 2] = s[2], r[o + 3] = 255;
1858
+ const s = i < this._colors.length ? this._colors[i] : [0, 0, 0], a = i * 4;
1859
+ r[a] = s[0], r[a + 1] = s[1], r[a + 2] = s[2], r[a + 3] = 255;
1899
1860
  }
1900
1861
  this._framebuffer.updatePixels(r, e, t);
1901
1862
  }
@@ -1925,10 +1886,10 @@ class Ce {
1925
1886
  return this._framebuffer.texture;
1926
1887
  }
1927
1888
  }
1928
- class X extends U {
1889
+ class H extends U {
1929
1890
  constructor(t, r, i, s = {}) {
1930
1891
  super(t, r, i, s);
1931
- a(this, "palette");
1892
+ n(this, "palette");
1932
1893
  this.palette = new Ce(this.renderer, this.fontManager.getCharacterColors(" .:-=+*%@#"));
1933
1894
  }
1934
1895
  /**
@@ -1945,17 +1906,31 @@ class X extends U {
1945
1906
  /**
1946
1907
  * Sets the color of the characters affected by the converter.
1947
1908
  * This is only used when `characterColorMode` is set to `'fixed'`.
1948
- * @param r Red component (0-255).
1909
+ * @param r Red component (0-255) or hex string (e.g., '#FF0000', '#F00', 'FF0000', 'F00').
1949
1910
  * @param g Green component (0-255).
1950
1911
  * @param b Blue component (0-255).
1951
1912
  * @param a Alpha component (0-255).
1952
1913
  */
1953
- characterColor(t, r = t, i = t, s = 255) {
1954
- x.validate(
1955
- [t, r, i, s].every((o) => o >= 0 && o <= 255),
1914
+ characterColor(t, r, i, s = 255) {
1915
+ let a, o, h, c;
1916
+ if (typeof t == "string") {
1917
+ const u = this.parseHexColor(t);
1918
+ if (!u) {
1919
+ x.validate(
1920
+ !1,
1921
+ "Invalid hex color format. Use '#FF0000', '#F00', 'FF0000', or 'F00'.",
1922
+ { method: "characterColor", providedValue: t }
1923
+ );
1924
+ return;
1925
+ }
1926
+ [a, o, h, c] = u;
1927
+ } else if (a = t, o = r !== void 0 ? r : t, h = i !== void 0 ? i : t, c = s, !x.validate(
1928
+ [a, o, h, c].every((u) => u >= 0 && u <= 255),
1956
1929
  "Character color values must be between 0 and 255",
1957
- { method: "characterColor", providedValues: { r: t, g: r, b: i, a: s } }
1958
- ) && (this._options.characterColor = [t, r, i, s]);
1930
+ { method: "characterColor", providedValues: { r: a, g: o, b: h, a: c } }
1931
+ ))
1932
+ return;
1933
+ this._options.characterColor = [a, o, h, c];
1959
1934
  }
1960
1935
  /**
1961
1936
  * Sets the character color mode.
@@ -1973,17 +1948,31 @@ class X extends U {
1973
1948
  /**
1974
1949
  * Sets the cell color for all cells affected by the converter.
1975
1950
  * This is only used when `cellColorMode` is set to `'fixed'`.
1976
- * @param r Red component (0-255).
1951
+ * @param r Red component (0-255) or hex string (e.g., '#FF0000', '#F00', 'FF0000', 'F00').
1977
1952
  * @param g Green component (0-255).
1978
1953
  * @param b Blue component (0-255).
1979
1954
  * @param a Alpha component (0-255).
1980
1955
  */
1981
- cellColor(t, r = t, i = t, s = 255) {
1982
- x.validate(
1983
- [t, r, i, s].every((o) => o >= 0 && o <= 255),
1956
+ cellColor(t, r, i, s = 255) {
1957
+ let a, o, h, c;
1958
+ if (typeof t == "string") {
1959
+ const u = this.parseHexColor(t);
1960
+ if (!u) {
1961
+ x.validate(
1962
+ !1,
1963
+ "Invalid hex color format. Use '#FF0000', '#F00', 'FF0000', or 'F00'.",
1964
+ { method: "cellColor", providedValue: t }
1965
+ );
1966
+ return;
1967
+ }
1968
+ [a, o, h, c] = u;
1969
+ } else if (a = t, o = r !== void 0 ? r : t, h = i !== void 0 ? i : t, c = s, !x.validate(
1970
+ [a, o, h, c].every((u) => u >= 0 && u <= 255),
1984
1971
  "Cell color values must be between 0 and 255",
1985
- { method: "cellColor", providedValues: { r: t, g: r, b: i, a: s } }
1986
- ) && (this._options.cellColor = [t, r, i, s]);
1972
+ { method: "cellColor", providedValues: { r: a, g: o, b: h, a: c } }
1973
+ ))
1974
+ return;
1975
+ this._options.cellColor = [a, o, h, c];
1987
1976
  }
1988
1977
  /**
1989
1978
  * Sets the cell color mode.
@@ -2046,6 +2035,18 @@ class X extends U {
2046
2035
  { method: "flipVertically", providedValue: t }
2047
2036
  ) && (this._options.flipVertically = !!t);
2048
2037
  }
2038
+ /**
2039
+ * Parses a hex color string and returns RGBA values.
2040
+ * @param hex Hex color string (e.g., '#FF0000', '#F00', 'FF0000', 'F00').
2041
+ * @returns RGBA array [r, g, b, a] or null if invalid.
2042
+ */
2043
+ parseHexColor(t) {
2044
+ if (t = t.replace(/^#/, ""), !/^[0-9A-Fa-f]{3}$|^[0-9A-Fa-f]{6}$/.test(t))
2045
+ return null;
2046
+ t.length === 3 && (t = t.split("").map((a) => a + a).join(""));
2047
+ const r = parseInt(t.slice(0, 2), 16), i = parseInt(t.slice(2, 4), 16), s = parseInt(t.slice(4, 6), 16);
2048
+ return [r, i, s, 255];
2049
+ }
2049
2050
  }
2050
2051
  var Fe = "precision lowp float;uniform sampler2D u_sketchTexture;uniform vec2 u_gridCellDimensions;uniform vec2 u_brightnessRange;varying vec2 v_uv;void main(){vec2 cellCenter=(floor(v_uv*u_gridCellDimensions)+vec2(0.5))/u_gridCellDimensions;vec4 color=texture2D(u_sketchTexture,cellCenter);float brightness=dot(color.rgb,vec3(0.299,0.587,0.114));float brightnessValue=brightness*255.0;if(brightnessValue>=u_brightnessRange.x&&brightnessValue<=u_brightnessRange.y){gl_FragColor=color;}else{gl_FragColor=vec4(0.0);}}", we = "precision lowp float;uniform sampler2D u_sampleTexture;uniform vec4 u_fillColor;uniform bool u_useFixedColor;varying vec2 v_uv;void main(){vec4 sampleColor=texture2D(u_sampleTexture,v_uv);if(sampleColor.a>0.0){if(u_useFixedColor){gl_FragColor=u_fillColor;}else{gl_FragColor=sampleColor;}}else{gl_FragColor=vec4(0.0);}}", ye = "precision lowp float;uniform sampler2D u_sampleTexture;uniform bool u_invert;uniform bool u_flipHorizontally;uniform bool u_flipVertically;varying vec2 v_uv;void main(){vec4 sampleColor=texture2D(u_sampleTexture,v_uv);if(sampleColor.a>0.0){float invertValue=u_invert ? 1.0 : 0.0;float flipHValue=u_flipHorizontally ? 1.0 : 0.0;float flipVValue=u_flipVertically ? 1.0 : 0.0;gl_FragColor=vec4(invertValue,flipHValue,flipVValue,1.0);}else{gl_FragColor=vec4(0.0);}}", Te = "precision lowp float;uniform sampler2D u_sampleTexture;uniform vec4 u_rotationColor;varying vec2 v_uv;void main(){vec4 sampleColor=texture2D(u_sampleTexture,v_uv);if(sampleColor.a>0.0){gl_FragColor=u_rotationColor;}else{gl_FragColor=vec4(0.0);}}", Se = "precision lowp float;uniform sampler2D u_colorSampleFramebuffer;uniform sampler2D u_charPaletteTexture;uniform vec2 u_charPaletteSize;uniform vec2 u_brightnessRange;varying vec2 v_uv;void main(){vec4 color=texture2D(u_colorSampleFramebuffer,v_uv);if(color.a==0.0){gl_FragColor=vec4(0.0);return;}float brightness=dot(color.rgb,vec3(0.299,0.587,0.114))*255.0;vec2 range=u_brightnessRange;if(brightness<range.x||brightness>range.y){gl_FragColor=vec4(0.0);return;}float t=(brightness-range.x)/(range.y-range.x);float idx=clamp(floor(t*u_charPaletteSize.x),0.0,u_charPaletteSize.x-1.0);vec3 charColor=texture2D(u_charPaletteTexture,vec2((idx+0.5)/u_charPaletteSize.x,0.0)).rgb;gl_FragColor=vec4(charColor,1.0);}";
2051
2052
  const Re = {
@@ -2072,7 +2073,7 @@ const Re = {
2072
2073
  /** Range of brightness values to map to ASCII characters */
2073
2074
  brightnessRange: [0, 255]
2074
2075
  };
2075
- class L extends X {
2076
+ class L extends H {
2076
2077
  /**
2077
2078
  * Creates a new TextmodeBrightnessConverter instance.
2078
2079
  * @param renderer Renderer instance for texture creation
@@ -2082,16 +2083,16 @@ class L extends X {
2082
2083
  */
2083
2084
  constructor(t, r, i) {
2084
2085
  super(t, r, i, { ...Re });
2085
- a(this, "sampleShader");
2086
- a(this, "colorFillShader");
2087
- a(this, "charMappingShader");
2088
- a(this, "transformFillShader");
2089
- a(this, "rotationFillShader");
2090
- a(this, "sampleFramebuffer");
2091
- this.sampleShader = new T(t.context, S, Fe), this.colorFillShader = new T(t.context, S, we), this.transformFillShader = new T(t.context, S, ye), this.rotationFillShader = new T(t.context, S, Te), this.charMappingShader = new T(t.context, S, Se), this.sampleFramebuffer = this.renderer.createFramebuffer(this.grid.cols, this.grid.rows);
2086
+ n(this, "sampleShader");
2087
+ n(this, "colorFillShader");
2088
+ n(this, "charMappingShader");
2089
+ n(this, "transformFillShader");
2090
+ n(this, "rotationFillShader");
2091
+ n(this, "sampleFramebuffer");
2092
+ this.sampleShader = new y(t.context, T, Fe), this.colorFillShader = new y(t.context, T, we), this.transformFillShader = new y(t.context, T, ye), this.rotationFillShader = new y(t.context, T, Te), this.charMappingShader = new y(t.context, T, Se), this.sampleFramebuffer = this.renderer.createFramebuffer(this.grid.cols, this.grid.rows);
2092
2093
  }
2093
2094
  convert(t) {
2094
- this.sampleFramebuffer.begin(), this.renderer.clear(), this.renderer.shader(this.sampleShader), this.renderer.setUniform("u_sketchTexture", t), this.renderer.setUniform("u_gridCellDimensions", [this.grid.cols, this.grid.rows]), this.renderer.setUniform("u_brightnessRange", this._options.brightnessRange), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this.sampleFramebuffer.end(), this._primaryColorFramebuffer.begin(), this.renderer.clear(), this.renderer.shader(this.colorFillShader), this.renderer.setUniform("u_sampleTexture", this.sampleFramebuffer.texture), this.renderer.setUniform("u_fillColor", this._options.characterColor), this.renderer.setUniform("u_useFixedColor", this._options.characterColorMode === "fixed"), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this._primaryColorFramebuffer.end(), this._secondaryColorFramebuffer.begin(), this.renderer.clear(), this.renderer.shader(this.colorFillShader), this.renderer.setUniform("u_sampleTexture", this.sampleFramebuffer.texture), this.renderer.setUniform("u_fillColor", this._options.cellColor), this.renderer.setUniform("u_useFixedColor", this._options.cellColorMode === "fixed"), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this._secondaryColorFramebuffer.end(), this._transformFramebuffer.begin(), this.renderer.clear(), this.renderer.shader(this.transformFillShader), this.renderer.setUniform("u_sampleTexture", this.sampleFramebuffer.texture), this.renderer.setUniform("u_invert", this._options.invert), this.renderer.setUniform("u_flipHorizontally", this._options.flipHorizontally), this.renderer.setUniform("u_flipVertically", this._options.flipVertically), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this._transformFramebuffer.end(), this._rotationFramebuffer.begin(), this.renderer.clear(), this.renderer.shader(this.rotationFillShader), this.renderer.setUniform("u_sampleTexture", this.sampleFramebuffer.texture), this.renderer.setUniform("u_rotationColor", this._options.rotation), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this._rotationFramebuffer.end(), this._characterFramebuffer.begin(), this.renderer.clear(0, 0, 0, 0), this.renderer.shader(this.charMappingShader), this.renderer.setUniform("u_colorSampleFramebuffer", this.sampleFramebuffer.texture), this.renderer.setUniform("u_charPaletteTexture", this.palette.texture), this.renderer.setUniform("u_charPaletteSize", [this.palette.colors.length, 1]), this.renderer.setUniform("u_brightnessRange", this._options.brightnessRange), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this._characterFramebuffer.end();
2095
+ this.sampleFramebuffer.begin(), this.renderer.clear(), this.renderer.shader(this.sampleShader), this.renderer.setUniform("u_sketchTexture", t), this.renderer.setUniform("u_gridCellDimensions", [this.grid.cols, this.grid.rows]), this.renderer.setUniform("u_brightnessRange", this._options.brightnessRange), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this.sampleFramebuffer.end(), console.log("this.options.characterColor:", this._options.characterColor), this._primaryColorFramebuffer.begin(), this.renderer.clear(), this.renderer.shader(this.colorFillShader), this.renderer.setUniform("u_sampleTexture", this.sampleFramebuffer.texture), this.renderer.setUniform("u_fillColor", this._options.characterColor), this.renderer.setUniform("u_useFixedColor", this._options.characterColorMode === "fixed"), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this._primaryColorFramebuffer.end(), this._secondaryColorFramebuffer.begin(), this.renderer.clear(), this.renderer.shader(this.colorFillShader), this.renderer.setUniform("u_sampleTexture", this.sampleFramebuffer.texture), this.renderer.setUniform("u_fillColor", this._options.cellColor), this.renderer.setUniform("u_useFixedColor", this._options.cellColorMode === "fixed"), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this._secondaryColorFramebuffer.end(), this._transformFramebuffer.begin(), this.renderer.clear(), this.renderer.shader(this.transformFillShader), this.renderer.setUniform("u_sampleTexture", this.sampleFramebuffer.texture), this.renderer.setUniform("u_invert", this._options.invert), this.renderer.setUniform("u_flipHorizontally", this._options.flipHorizontally), this.renderer.setUniform("u_flipVertically", this._options.flipVertically), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this._transformFramebuffer.end(), this._rotationFramebuffer.begin(), this.renderer.clear(), this.renderer.shader(this.rotationFillShader), this.renderer.setUniform("u_sampleTexture", this.sampleFramebuffer.texture), this.renderer.setUniform("u_rotationColor", this._options.rotation), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this._rotationFramebuffer.end(), this._characterFramebuffer.begin(), this.renderer.clear(0, 0, 0, 0), this.renderer.shader(this.charMappingShader), this.renderer.setUniform("u_colorSampleFramebuffer", this.sampleFramebuffer.texture), this.renderer.setUniform("u_charPaletteTexture", this.palette.texture), this.renderer.setUniform("u_charPaletteSize", [this.palette.colors.length, 1]), this.renderer.setUniform("u_brightnessRange", this._options.brightnessRange), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this._characterFramebuffer.end();
2095
2096
  }
2096
2097
  resize() {
2097
2098
  super.resize(), this.sampleFramebuffer.resize(this.grid.cols, this.grid.rows);
@@ -2111,11 +2112,11 @@ class L extends X {
2111
2112
  ) && (this._options.brightnessRange = t);
2112
2113
  }
2113
2114
  }
2114
- const Xe = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2115
+ const He = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2115
2116
  __proto__: null,
2116
2117
  TextmodeBrightnessConverter: L,
2117
2118
  TextmodeConverter: U,
2118
- TextmodeFeatureConverter: X
2119
+ TextmodeFeatureConverter: H
2119
2120
  }, Symbol.toStringTag, { value: "Module" }));
2120
2121
  var Ee = "precision mediump float;uniform sampler2D u_characterTexture;uniform vec2 u_charsetDimensions;uniform sampler2D u_primaryColorTexture;uniform sampler2D u_secondaryColorTexture;uniform sampler2D u_transformTexture;uniform sampler2D u_asciiCharacterTexture;uniform sampler2D u_rotationTexture;uniform sampler2D u_captureTexture;uniform vec2 u_captureDimensions;uniform int u_backgroundMode;uniform vec2 u_gridCellDimensions;uniform vec2 u_gridPixelDimensions;mat2 rotate2D(float angle){float s=sin(angle);float c=cos(angle);return mat2(c,-s,s,c);}void main(){vec2 adjustedCoord=gl_FragCoord.xy/u_gridPixelDimensions;vec2 gridCoord=adjustedCoord*u_gridCellDimensions;vec2 cellCoord=floor(gridCoord);vec2 charIndexTexCoord=(cellCoord+0.5)/u_gridCellDimensions;vec4 primaryColor=texture2D(u_primaryColorTexture,charIndexTexCoord);vec4 secondaryColor=texture2D(u_secondaryColorTexture,charIndexTexCoord);vec4 transformColor=texture2D(u_transformTexture,charIndexTexCoord);bool isInverted=transformColor.r>0.5;bool flipHorizontal=transformColor.g>0.5;bool flipVertical=transformColor.b>0.5;vec4 encodedIndexVec=texture2D(u_asciiCharacterTexture,charIndexTexCoord);if(encodedIndexVec.a<0.01){gl_FragColor=(u_backgroundMode==0)? vec4(0.0):texture2D(u_captureTexture,gl_FragCoord.xy/u_captureDimensions);return;}int charIndex=int(encodedIndexVec.r*255.0+0.5)+int(encodedIndexVec.g*255.0+0.5)*256;int charCol=int(mod(float(charIndex),u_charsetDimensions.x));int charRow=charIndex/int(u_charsetDimensions.x);vec2 charCoord=vec2(charCol,charRow)/u_charsetDimensions;vec4 rotationColor=texture2D(u_rotationTexture,charIndexTexCoord);float scaledAngle=rotationColor.r*255.0+rotationColor.g;float rotationAngle=(scaledAngle*360.0/255.0)*0.017453292;vec2 fractionalPart=fract(gridCoord)-0.5;if(flipHorizontal)fractionalPart.x=-fractionalPart.x;if(flipVertical)fractionalPart.y=-fractionalPart.y;fractionalPart=rotate2D(rotationAngle)*fractionalPart+0.5;vec2 cellSize=1.0/u_charsetDimensions;vec2 texCoord=charCoord+fractionalPart*cellSize;vec2 cellMax=charCoord+cellSize;if(any(lessThan(texCoord,charCoord))||any(greaterThan(texCoord,cellMax))){gl_FragColor=isInverted ? primaryColor : secondaryColor;return;}vec4 charTexel=texture2D(u_characterTexture,texCoord);if(isInverted)charTexel.rgb=1.0-charTexel.rgb;gl_FragColor=mix(secondaryColor,primaryColor,charTexel);}";
2121
2122
  class Ue {
@@ -2127,18 +2128,18 @@ class Ue {
2127
2128
  * @ignore
2128
2129
  */
2129
2130
  constructor(e, t, r) {
2130
- a(this, "renderer");
2131
- a(this, "font");
2132
- a(this, "grid");
2133
- a(this, "converters");
2134
- a(this, "_resultFramebuffer");
2135
- a(this, "_asciiShader");
2136
- a(this, "_characterFramebuffer");
2137
- a(this, "_primaryColorFramebuffer");
2138
- a(this, "_secondaryColorFramebuffer");
2139
- a(this, "_rotationFramebuffer");
2140
- a(this, "_transformFramebuffer");
2141
- this.renderer = e, this.font = t, this.grid = r, this._asciiShader = this.renderer.createShader(S, Ee), this.converters = [
2131
+ n(this, "renderer");
2132
+ n(this, "font");
2133
+ n(this, "grid");
2134
+ n(this, "converters");
2135
+ n(this, "_resultFramebuffer");
2136
+ n(this, "_asciiShader");
2137
+ n(this, "_characterFramebuffer");
2138
+ n(this, "_primaryColorFramebuffer");
2139
+ n(this, "_secondaryColorFramebuffer");
2140
+ n(this, "_rotationFramebuffer");
2141
+ n(this, "_transformFramebuffer");
2142
+ this.renderer = e, this.font = t, this.grid = r, this._asciiShader = this.renderer.createShader(T, Ee), this.converters = [
2142
2143
  { name: "brightness", converter: new L(e, t, r) },
2143
2144
  { name: "custom", converter: new U(e, t, r) }
2144
2145
  ], this._characterFramebuffer = this.renderer.createFramebuffer(r.cols, r.rows), this._primaryColorFramebuffer = this.renderer.createFramebuffer(r.cols, r.rows), this._secondaryColorFramebuffer = this.renderer.createFramebuffer(r.cols, r.rows), this._rotationFramebuffer = this.renderer.createFramebuffer(r.cols, r.rows), this._transformFramebuffer = this.renderer.createFramebuffer(r.cols, r.rows), this._resultFramebuffer = this.renderer.createFramebuffer(this.grid.width, this.grid.height);
@@ -2151,13 +2152,13 @@ class Ue {
2151
2152
  render(e) {
2152
2153
  for (const r of this.converters) {
2153
2154
  const i = r.converter;
2154
- i.options.enabled && i instanceof X && i.convert(e);
2155
+ i.options.enabled && i instanceof H && i.convert(e);
2155
2156
  }
2156
2157
  const t = (r, i) => {
2157
2158
  r.begin(), this.renderer.clear();
2158
2159
  for (const s of this.converters) {
2159
- const o = s.converter;
2160
- o.options.enabled && this.renderer.image(i(o), 0, 0);
2160
+ const a = s.converter;
2161
+ a.options.enabled && this.renderer.image(i(a), 0, 0);
2161
2162
  }
2162
2163
  r.end();
2163
2164
  };
@@ -2273,14 +2274,8 @@ class Ue {
2273
2274
  */
2274
2275
  dispose() {
2275
2276
  for (const e of this.converters)
2276
- e.converter && !e.converter.isDisposed && e.converter.dispose();
2277
- this._characterFramebuffer && !this._characterFramebuffer.isDisposed && this._characterFramebuffer.dispose(), this._primaryColorFramebuffer && !this._primaryColorFramebuffer.isDisposed && this._primaryColorFramebuffer.dispose(), this._secondaryColorFramebuffer && !this._secondaryColorFramebuffer.isDisposed && this._secondaryColorFramebuffer.dispose(), this._rotationFramebuffer && !this._rotationFramebuffer.isDisposed && this._rotationFramebuffer.dispose(), this._transformFramebuffer && !this._transformFramebuffer.isDisposed && this._transformFramebuffer.dispose(), this._resultFramebuffer && !this._resultFramebuffer.isDisposed && this._resultFramebuffer.dispose(), this._asciiShader && !this._asciiShader.isDisposed && this._asciiShader.dispose(), this.converters = [], this._characterFramebuffer = null, this._primaryColorFramebuffer = null, this._secondaryColorFramebuffer = null, this._rotationFramebuffer = null, this._transformFramebuffer = null, this._resultFramebuffer = null, this._asciiShader = null;
2278
- }
2279
- /**
2280
- * Check if this conversion pipeline has been disposed
2281
- */
2282
- get isDisposed() {
2283
- return this._resultFramebuffer === null || this._asciiShader === null;
2277
+ e.converter.dispose();
2278
+ this._characterFramebuffer.dispose(), this._primaryColorFramebuffer.dispose(), this._secondaryColorFramebuffer.dispose(), this._rotationFramebuffer.dispose(), this._transformFramebuffer.dispose(), this._resultFramebuffer.dispose(), this._asciiShader.dispose(), this.converters = [], this._characterFramebuffer = null, this._primaryColorFramebuffer = null, this._secondaryColorFramebuffer = null, this._rotationFramebuffer = null, this._transformFramebuffer = null, this._resultFramebuffer = null, this._asciiShader = null;
2284
2279
  }
2285
2280
  /** Returns the character framebuffer containing the combined result of all converters. */
2286
2281
  get characterFramebuffer() {
@@ -2303,20 +2298,20 @@ class Ue {
2303
2298
  return this._transformFramebuffer;
2304
2299
  }
2305
2300
  }
2306
- class H {
2301
+ class X {
2307
2302
  /**
2308
2303
  * Extracts pixel data from all framebuffers needed for export
2309
2304
  * @param pipeline The conversion pipeline containing framebuffers
2310
2305
  * @returns Object containing all pixel data arrays
2311
2306
  */
2312
2307
  extractFramebufferData(e) {
2313
- const t = e.get("brightness"), r = t == null ? void 0 : t.characterFramebuffer, i = t == null ? void 0 : t.primaryColorFramebuffer, s = t == null ? void 0 : t.secondaryColorFramebuffer, o = t == null ? void 0 : t.transformFramebuffer, n = t == null ? void 0 : t.rotationFramebuffer;
2314
- return r == null || r.loadPixels(), i == null || i.loadPixels(), s == null || s.loadPixels(), o == null || o.loadPixels(), n == null || n.loadPixels(), {
2308
+ const t = e.get("brightness"), r = t == null ? void 0 : t.characterFramebuffer, i = t == null ? void 0 : t.primaryColorFramebuffer, s = t == null ? void 0 : t.secondaryColorFramebuffer, a = t == null ? void 0 : t.transformFramebuffer, o = t == null ? void 0 : t.rotationFramebuffer;
2309
+ return r == null || r.loadPixels(), i == null || i.loadPixels(), s == null || s.loadPixels(), a == null || a.loadPixels(), o == null || o.loadPixels(), {
2315
2310
  characterPixels: (r == null ? void 0 : r.pixels) || new Uint8Array(0),
2316
2311
  primaryColorPixels: (i == null ? void 0 : i.pixels) || new Uint8Array(0),
2317
2312
  secondaryColorPixels: (s == null ? void 0 : s.pixels) || new Uint8Array(0),
2318
- transformPixels: (o == null ? void 0 : o.pixels) || new Uint8Array(0),
2319
- rotationPixels: (n == null ? void 0 : n.pixels) || new Uint8Array(0)
2313
+ transformPixels: (a == null ? void 0 : a.pixels) || new Uint8Array(0),
2314
+ rotationPixels: (o == null ? void 0 : o.pixels) || new Uint8Array(0)
2320
2315
  };
2321
2316
  }
2322
2317
  /**
@@ -2363,8 +2358,8 @@ class N {
2363
2358
  */
2364
2359
  downloadFile(e, t, r) {
2365
2360
  try {
2366
- const i = this.createBlob(e, r), s = URL.createObjectURL(i), o = document.createElement("a");
2367
- o.href = s, o.download = t, o.style.display = "none", o.rel = "noopener", document.body.appendChild(o), o.click(), document.body.removeChild(o), URL.revokeObjectURL(s);
2361
+ const i = this.createBlob(e, r), s = URL.createObjectURL(i), a = document.createElement("a");
2362
+ a.href = s, a.download = t, a.style.display = "none", a.rel = "noopener", document.body.appendChild(a), a.click(), document.body.removeChild(a), URL.revokeObjectURL(s);
2368
2363
  } catch (i) {
2369
2364
  throw console.error("Failed to download file:", i), new Error(`File download failed: ${i instanceof Error ? i.message : "Unknown error"}`);
2370
2365
  }
@@ -2402,7 +2397,7 @@ class N {
2402
2397
  return `'textmode-export'-${this.generateTimestamp()}`;
2403
2398
  }
2404
2399
  }
2405
- class De extends H {
2400
+ class Ae extends X {
2406
2401
  /**
2407
2402
  * Extracts transform data from transform pixels
2408
2403
  * @param transformPixels Transform framebuffer pixels
@@ -2411,10 +2406,10 @@ class De extends H {
2411
2406
  * @returns Transform data object
2412
2407
  */
2413
2408
  extractTransformData(e, t, r) {
2414
- const i = e[r], s = e[r + 1], o = e[r + 2], n = i === 255, l = s === 255, c = o === 255, u = t[r], d = t[r + 1], f = u + d / 255, g = Math.round(f * 360 / 255 * 100) / 100;
2409
+ const i = e[r], s = e[r + 1], a = e[r + 2], o = i === 255, h = s === 255, c = a === 255, u = t[r], d = t[r + 1], f = u + d / 255, g = Math.round(f * 360 / 255 * 100) / 100;
2415
2410
  return {
2416
- isInverted: n,
2417
- flipHorizontal: l,
2411
+ isInverted: o,
2412
+ flipHorizontal: h,
2418
2413
  flipVertical: c,
2419
2414
  rotation: g
2420
2415
  };
@@ -2445,24 +2440,24 @@ class De extends H {
2445
2440
  const r = [];
2446
2441
  let i = 0;
2447
2442
  for (let s = 0; s < t.rows; s++)
2448
- for (let o = 0; o < t.cols; o++) {
2449
- const n = i * 4, l = this.getCharacterIndex(
2443
+ for (let a = 0; a < t.cols; a++) {
2444
+ const o = i * 4, h = this.getCharacterIndex(
2450
2445
  e.characterPixels,
2451
- n
2446
+ o
2452
2447
  );
2453
- let c = this.pixelsToRGBA(e.primaryColorPixels, n), u = this.pixelsToRGBA(e.secondaryColorPixels, n);
2448
+ let c = this.pixelsToRGBA(e.primaryColorPixels, o), u = this.pixelsToRGBA(e.secondaryColorPixels, o);
2454
2449
  const d = this.extractTransformData(
2455
2450
  e.transformPixels,
2456
2451
  e.rotationPixels,
2457
- n
2452
+ o
2458
2453
  );
2459
2454
  if (d.isInverted) {
2460
2455
  const g = c;
2461
2456
  c = u, u = g;
2462
2457
  }
2463
- const f = this.calculateCellPosition(o, s, t);
2458
+ const f = this.calculateCellPosition(a, s, t);
2464
2459
  r.push({
2465
- charIndex: l,
2460
+ charIndex: h,
2466
2461
  primaryColor: c,
2467
2462
  secondaryColor: u,
2468
2463
  transform: d,
@@ -2472,7 +2467,7 @@ class De extends H {
2472
2467
  return r;
2473
2468
  }
2474
2469
  }
2475
- class Ae {
2470
+ class Me {
2476
2471
  /**
2477
2472
  * Gets the glyph index for a given Unicode code point in a Typr.js font
2478
2473
  * @param fontData The Typr.js font data
@@ -2489,11 +2484,11 @@ class Ae {
2489
2484
  if (i.idRangeOffset[s] === 0)
2490
2485
  return t + i.idDelta[s] & 65535;
2491
2486
  {
2492
- const o = i.idRangeOffset[s] / 2 + (t - i.startCount[s]) - (i.startCount.length - s);
2493
- if (o >= 0 && o < i.glyphIdArray.length) {
2494
- const n = i.glyphIdArray[o];
2495
- if (n !== 0)
2496
- return n + i.idDelta[s] & 65535;
2487
+ const a = i.idRangeOffset[s] / 2 + (t - i.startCount[s]) - (i.startCount.length - s);
2488
+ if (a >= 0 && a < i.glyphIdArray.length) {
2489
+ const o = i.glyphIdArray[a];
2490
+ if (o !== 0)
2491
+ return o + i.idDelta[s] & 65535;
2497
2492
  }
2498
2493
  }
2499
2494
  }
@@ -2522,15 +2517,15 @@ class Ae {
2522
2517
  createGlyphPath(e, t, r, i, s) {
2523
2518
  if (!t || !t.xs || t.xs.length === 0)
2524
2519
  return this.createEmptyPath();
2525
- const o = s / e.head.unitsPerEm;
2520
+ const a = s / e.head.unitsPerEm;
2526
2521
  return {
2527
2522
  getBoundingBox: () => ({
2528
- x1: r + t.xMin * o,
2529
- y1: i + -t.yMax * o,
2530
- x2: r + t.xMax * o,
2531
- y2: i + -t.yMin * o
2523
+ x1: r + t.xMin * a,
2524
+ y1: i + -t.yMax * a,
2525
+ x2: r + t.xMax * a,
2526
+ y2: i + -t.yMin * a
2532
2527
  }),
2533
- toSVG: () => this.glyphToSVGPath(t, r, i, o)
2528
+ toSVG: () => this.glyphToSVGPath(t, r, i, a)
2534
2529
  };
2535
2530
  }
2536
2531
  /**
@@ -2543,29 +2538,29 @@ class Ae {
2543
2538
  */
2544
2539
  glyphToSVGPath(e, t, r, i) {
2545
2540
  if (!e || !e.xs) return "";
2546
- const { xs: s, ys: o, endPts: n, flags: l } = e;
2547
- if (!s || !o || !n || !l) return "";
2541
+ const { xs: s, ys: a, endPts: o, flags: h } = e;
2542
+ if (!s || !a || !o || !h) return "";
2548
2543
  let c = "", u = 0;
2549
- for (let d = 0; d < n.length; d++) {
2550
- const f = n[d];
2544
+ for (let d = 0; d < o.length; d++) {
2545
+ const f = o[d];
2551
2546
  if (!(f < u)) {
2552
2547
  if (f >= u) {
2553
- const g = t + s[u] * i, p = r - o[u] * i;
2554
- c += `M${g.toFixed(2)},${p.toFixed(2)}`;
2555
- let _ = u + 1;
2556
- for (; _ <= f; )
2557
- if ((l[_] & 1) !== 0) {
2558
- const C = t + s[_] * i, v = r - o[_] * i;
2559
- c += `L${C.toFixed(2)},${v.toFixed(2)}`, _++;
2548
+ const g = t + s[u] * i, _ = r - a[u] * i;
2549
+ c += `M${g.toFixed(2)},${_.toFixed(2)}`;
2550
+ let p = u + 1;
2551
+ for (; p <= f; )
2552
+ if ((h[p] & 1) !== 0) {
2553
+ const C = t + s[p] * i, v = r - a[p] * i;
2554
+ c += `L${C.toFixed(2)},${v.toFixed(2)}`, p++;
2560
2555
  } else {
2561
- const C = t + s[_] * i, v = r - o[_] * i;
2562
- let w = _ + 1 > f ? u : _ + 1;
2563
- if ((l[w] & 1) !== 0) {
2564
- const R = t + s[w] * i, y = r - o[w] * i;
2565
- c += `Q${C.toFixed(2)},${v.toFixed(2)} ${R.toFixed(2)},${y.toFixed(2)}`, _ = w + 1;
2556
+ const C = t + s[p] * i, v = r - a[p] * i;
2557
+ let w = p + 1 > f ? u : p + 1;
2558
+ if ((h[w] & 1) !== 0) {
2559
+ const R = t + s[w] * i, S = r - a[w] * i;
2560
+ c += `Q${C.toFixed(2)},${v.toFixed(2)} ${R.toFixed(2)},${S.toFixed(2)}`, p = w + 1;
2566
2561
  } else {
2567
- const R = t + s[w] * i, y = r - o[w] * i, P = (C + R) / 2, M = (v + y) / 2;
2568
- c += `Q${C.toFixed(2)},${v.toFixed(2)} ${P.toFixed(2)},${M.toFixed(2)}`, _ = w;
2562
+ const R = t + s[w] * i, S = r - a[w] * i, P = (C + R) / 2, D = (v + S) / 2;
2563
+ c += `Q${C.toFixed(2)},${v.toFixed(2)} ${P.toFixed(2)},${D.toFixed(2)}`, p = w;
2569
2564
  }
2570
2565
  }
2571
2566
  c += "Z";
@@ -2586,18 +2581,18 @@ class Ae {
2586
2581
  */
2587
2582
  generateCharacterPath(e, t, r, i, s) {
2588
2583
  try {
2589
- const o = e.codePointAt(0) || 0, n = this.getGlyphIndex(t, o);
2590
- if (n === 0)
2584
+ const a = e.codePointAt(0) || 0, o = this.getGlyphIndex(t, a);
2585
+ if (o === 0)
2591
2586
  return this.createEmptyPath();
2592
- let l = null;
2587
+ let h = null;
2593
2588
  try {
2594
- t.glyf && t.glyf[n] !== null ? l = t.glyf[n] : m && m.T && m.T.glyf && m.T.glyf._parseGlyf && (l = m.T.glyf._parseGlyf(t, n), t.glyf && l && (t.glyf[n] = l));
2589
+ t.glyf && t.glyf[o] !== null ? h = t.glyf[o] : m && m.T && m.T.glyf && m.T.glyf._parseGlyf && (h = m.T.glyf._parseGlyf(t, o), t.glyf && h && (t.glyf[o] = h));
2595
2590
  } catch (c) {
2596
- console.warn(`Failed to parse glyph ${n}:`, c);
2591
+ console.warn(`Failed to parse glyph ${o}:`, c);
2597
2592
  }
2598
- return l ? this.createGlyphPath(t, l, r, i, s) : this.createEmptyPath();
2599
- } catch (o) {
2600
- return console.warn(`Failed to generate path for character "${e}":`, o), this.createEmptyPath();
2593
+ return h ? this.createGlyphPath(t, h, r, i, s) : this.createEmptyPath();
2594
+ } catch (a) {
2595
+ return console.warn(`Failed to generate path for character "${e}":`, a), this.createEmptyPath();
2601
2596
  }
2602
2597
  }
2603
2598
  /**
@@ -2612,19 +2607,19 @@ class Ae {
2612
2607
  * @param advanceWidth Character advance width
2613
2608
  * @returns SVG path data string or null if generation fails
2614
2609
  */
2615
- generatePositionedCharacterPath(e, t, r, i, s, o, n, l) {
2610
+ generatePositionedCharacterPath(e, t, r, i, s, a, o, h) {
2616
2611
  try {
2617
- const c = n / t.head.unitsPerEm, u = l * c, d = r + (s - u) / 2, f = i + (o + n * 0.7) / 2;
2618
- return this.generateCharacterPath(e, t, d, f, n).toSVG() || null;
2612
+ const c = o / t.head.unitsPerEm, u = h * c, d = r + (s - u) / 2, f = i + (a + o * 0.7) / 2;
2613
+ return this.generateCharacterPath(e, t, d, f, o).toSVG() || null;
2619
2614
  } catch (c) {
2620
2615
  return console.warn(`Failed to generate positioned character path for "${e}":`, c), null;
2621
2616
  }
2622
2617
  }
2623
2618
  }
2624
- class Me {
2619
+ class De {
2625
2620
  constructor() {
2626
- a(this, "pathGenerator");
2627
- this.pathGenerator = new Ae();
2621
+ n(this, "pathGenerator");
2622
+ this.pathGenerator = new Me();
2628
2623
  }
2629
2624
  /**
2630
2625
  * Generates the SVG header with metadata
@@ -2676,12 +2671,12 @@ class Me {
2676
2671
  * @returns Transform attribute string or empty string
2677
2672
  */
2678
2673
  generateTransformAttribute(e, t) {
2679
- const { transform: r, position: i } = e, s = i.cellX + t.cellWidth / 2, o = i.cellY + t.cellHeight / 2, n = [];
2674
+ const { transform: r, position: i } = e, s = i.cellX + t.cellWidth / 2, a = i.cellY + t.cellHeight / 2, o = [];
2680
2675
  if (r.flipHorizontal || r.flipVertical) {
2681
- const l = r.flipHorizontal ? -1 : 1, c = r.flipVertical ? -1 : 1;
2682
- n.push(`translate(${s} ${o})`), n.push(`scale(${l} ${c})`), n.push(`translate(${-s} ${-o})`);
2676
+ const h = r.flipHorizontal ? -1 : 1, c = r.flipVertical ? -1 : 1;
2677
+ o.push(`translate(${s} ${a})`), o.push(`scale(${h} ${c})`), o.push(`translate(${-s} ${-a})`);
2683
2678
  }
2684
- return r.rotation && n.push(`rotate(${r.rotation} ${s} ${o})`), n.length ? ` transform="${n.join(" ")}"` : "";
2679
+ return r.rotation && o.push(`rotate(${r.rotation} ${s} ${a})`), o.length ? ` transform="${o.join(" ")}"` : "";
2685
2680
  }
2686
2681
  /**
2687
2682
  * Generates background rectangle for a cell
@@ -2710,7 +2705,7 @@ class Me {
2710
2705
  const s = r.characters[e.charIndex];
2711
2706
  if (!s)
2712
2707
  return "";
2713
- const o = this.pathGenerator.generatePositionedCharacterPath(
2708
+ const a = this.pathGenerator.generatePositionedCharacterPath(
2714
2709
  s.character,
2715
2710
  r.font,
2716
2711
  e.position.cellX,
@@ -2720,12 +2715,12 @@ class Me {
2720
2715
  r.fontSize,
2721
2716
  s.advanceWidth
2722
2717
  );
2723
- if (!o)
2718
+ if (!a)
2724
2719
  return "";
2725
- const n = this.rgbaToColorString(e.primaryColor);
2720
+ const o = this.rgbaToColorString(e.primaryColor);
2726
2721
  return i.drawMode === "stroke" ? `
2727
- <path id="${`path-${e.charIndex}-${e.position.cellX}-${e.position.cellY}`.replace(/\./g, "-")}" d="${o}" stroke="${n}" stroke-width="${i.strokeWidth}" fill="none" />` : `
2728
- <path d="${o}" fill="${n}" />`;
2722
+ <path id="${`path-${e.charIndex}-${e.position.cellX}-${e.position.cellY}`.replace(/\./g, "-")}" d="${a}" stroke="${o}" stroke-width="${i.strokeWidth}" fill="none" />` : `
2723
+ <path d="${a}" fill="${o}" />`;
2729
2724
  }
2730
2725
  /**
2731
2726
  * Generates complete SVG content for a single cell
@@ -2738,10 +2733,10 @@ class Me {
2738
2733
  generateCellContent(e, t, r, i) {
2739
2734
  let s = "";
2740
2735
  s += this.generateCellBackground(e, t, i);
2741
- const o = this.generateTransformAttribute(e, t), n = this.generateCharacterPath(e, t, r, i);
2742
- return n && (o ? (s += `
2743
- <g${o}>`, s += n, s += `
2744
- </g>`) : s += n), s;
2736
+ const a = this.generateTransformAttribute(e, t), o = this.generateCharacterPath(e, t, r, i);
2737
+ return o && (a ? (s += `
2738
+ <g${a}>`, s += o, s += `
2739
+ </g>`) : s += o), s;
2745
2740
  }
2746
2741
  /**
2747
2742
  * Generates the complete SVG content from cell data
@@ -2755,8 +2750,8 @@ class Me {
2755
2750
  let s = this.generateSVGHeader(t);
2756
2751
  s += this.generateBackground(t, i), s += `
2757
2752
  <g id="ascii-cells">`;
2758
- for (const o of e)
2759
- s += this.generateCellContent(o, t, r, i);
2753
+ for (const a of e)
2754
+ s += this.generateCellContent(a, t, r, i);
2760
2755
  return s += this.generateSVGFooter(), s;
2761
2756
  }
2762
2757
  /**
@@ -2801,10 +2796,10 @@ class Ie extends N {
2801
2796
  }
2802
2797
  class Y {
2803
2798
  constructor() {
2804
- a(this, "dataExtractor");
2805
- a(this, "contentGenerator");
2806
- a(this, "fileHandler");
2807
- this.dataExtractor = new De(), this.contentGenerator = new Me(), this.fileHandler = new Ie();
2799
+ n(this, "dataExtractor");
2800
+ n(this, "contentGenerator");
2801
+ n(this, "fileHandler");
2802
+ this.dataExtractor = new Ae(), this.contentGenerator = new De(), this.fileHandler = new Ie();
2808
2803
  }
2809
2804
  /**
2810
2805
  * Applies default values to SVG export options
@@ -2829,13 +2824,13 @@ class Y {
2829
2824
  const r = this.applyDefaultOptions(t), i = this.dataExtractor.extractFramebufferData(e.pipeline), s = this.dataExtractor.extractSVGCellData(
2830
2825
  i,
2831
2826
  e.grid
2832
- ), o = this.contentGenerator.generateSVGContent(
2827
+ ), a = this.contentGenerator.generateSVGContent(
2833
2828
  s,
2834
2829
  e.grid,
2835
2830
  e.font,
2836
2831
  r
2837
2832
  );
2838
- return this.contentGenerator.optimizeSVGContent(o);
2833
+ return this.contentGenerator.optimizeSVGContent(a);
2839
2834
  }
2840
2835
  /**
2841
2836
  * Exports SVG content to a downloadable file
@@ -2851,7 +2846,7 @@ class Y {
2851
2846
  }
2852
2847
  }
2853
2848
  }
2854
- class Pe extends H {
2849
+ class Pe extends X {
2855
2850
  /**
2856
2851
  * Extracts character data for TXT generation
2857
2852
  * @param framebufferData Framebuffer pixel data
@@ -2861,17 +2856,17 @@ class Pe extends H {
2861
2856
  * @returns 2D array of characters (rows x columns)
2862
2857
  */
2863
2858
  extractCharacterGrid(e, t, r, i = " ") {
2864
- var n;
2859
+ var o;
2865
2860
  const s = [];
2866
- let o = 0;
2867
- for (let l = 0; l < t.rows; l++) {
2861
+ let a = 0;
2862
+ for (let h = 0; h < t.rows; h++) {
2868
2863
  const c = [];
2869
2864
  for (let u = 0; u < t.cols; u++) {
2870
- const d = o * 4, f = this.getCharacterIndex(
2865
+ const d = a * 4, f = this.getCharacterIndex(
2871
2866
  e.characterPixels,
2872
2867
  d
2873
- ), g = ((n = r.characters[f]) == null ? void 0 : n.character) || i;
2874
- c.push(g), o++;
2868
+ ), g = ((o = r.characters[f]) == null ? void 0 : o.character) || i;
2869
+ c.push(g), a++;
2875
2870
  }
2876
2871
  s.push(c);
2877
2872
  }
@@ -2888,8 +2883,8 @@ class Be {
2888
2883
  generateTXTContent(e, t) {
2889
2884
  const r = [];
2890
2885
  for (const s of e) {
2891
- let o = s.join("");
2892
- t.preserveTrailingSpaces || (o = o.replace(/\s+$/, "")), r.push(o);
2886
+ let a = s.join("");
2887
+ t.preserveTrailingSpaces || (a = a.replace(/\s+$/, "")), r.push(a);
2893
2888
  }
2894
2889
  const i = t.lineEnding === "crlf" ? `\r
2895
2890
  ` : `
@@ -2923,9 +2918,9 @@ class Ge extends N {
2923
2918
  }
2924
2919
  class j {
2925
2920
  constructor() {
2926
- a(this, "dataExtractor");
2927
- a(this, "contentGenerator");
2928
- a(this, "fileHandler");
2921
+ n(this, "dataExtractor");
2922
+ n(this, "contentGenerator");
2923
+ n(this, "fileHandler");
2929
2924
  this.dataExtractor = new Pe(), this.contentGenerator = new Be(), this.fileHandler = new Ge();
2930
2925
  }
2931
2926
  /**
@@ -2972,7 +2967,7 @@ class j {
2972
2967
  }
2973
2968
  }
2974
2969
  }
2975
- class Ve extends H {
2970
+ class Ve extends X {
2976
2971
  /**
2977
2972
  * Captures the current state of the textmode canvas as image data
2978
2973
  * @param canvas The canvas data containing the rendered textmode graphics
@@ -2984,8 +2979,8 @@ class Ve extends H {
2984
2979
  const i = e.canvas;
2985
2980
  if (t === 1 && r === "transparent")
2986
2981
  return i;
2987
- const s = document.createElement("canvas"), o = s.getContext("2d"), n = Math.round(i.width * t), l = Math.round(i.height * t);
2988
- return s.width = n, s.height = l, r !== "transparent" && (o.fillStyle = r, o.fillRect(0, 0, n, l)), o.imageSmoothingEnabled = !1, o.drawImage(
2982
+ const s = document.createElement("canvas"), a = s.getContext("2d"), o = Math.round(i.width * t), h = Math.round(i.height * t);
2983
+ return s.width = o, s.height = h, r !== "transparent" && (a.fillStyle = r, a.fillRect(0, 0, o, h)), a.imageSmoothingEnabled = !1, a.drawImage(
2989
2984
  i,
2990
2985
  0,
2991
2986
  0,
@@ -2993,8 +2988,8 @@ class Ve extends H {
2993
2988
  i.height,
2994
2989
  0,
2995
2990
  0,
2996
- n,
2997
- l
2991
+ o,
2992
+ h
2998
2993
  ), s;
2999
2994
  }
3000
2995
  }
@@ -3017,10 +3012,10 @@ class ke {
3017
3012
  */
3018
3013
  async generateImageBlob(e, t) {
3019
3014
  return new Promise((r, i) => {
3020
- const s = this.getMimeType(t.format), o = (n) => {
3021
- n ? r(n) : i(new Error(`Failed to generate ${t.format.toUpperCase()} blob`));
3015
+ const s = this.getMimeType(t.format), a = (o) => {
3016
+ o ? r(o) : i(new Error(`Failed to generate ${t.format.toUpperCase()} blob`));
3022
3017
  };
3023
- t.format === "png" ? e.toBlob(o, s) : e.toBlob(o, s, t.quality);
3018
+ t.format === "png" ? e.toBlob(a, s) : e.toBlob(a, s, t.quality);
3024
3019
  });
3025
3020
  }
3026
3021
  /**
@@ -3115,9 +3110,9 @@ class ze extends N {
3115
3110
  }
3116
3111
  class $e {
3117
3112
  constructor() {
3118
- a(this, "dataExtractor");
3119
- a(this, "contentGenerator");
3120
- a(this, "fileHandler");
3113
+ n(this, "dataExtractor");
3114
+ n(this, "contentGenerator");
3115
+ n(this, "fileHandler");
3121
3116
  this.dataExtractor = new Ve(), this.contentGenerator = new ke(), this.fileHandler = new ze();
3122
3117
  }
3123
3118
  /**
@@ -3204,38 +3199,37 @@ class $e {
3204
3199
  class I {
3205
3200
  constructor(e = null, t = {}) {
3206
3201
  /** The element to capture content from (optional for standalone mode) */
3207
- a(this, "captureSource");
3202
+ n(this, "captureSource");
3208
3203
  /** Our WebGL overlay canvas manager */
3209
- a(this, "textmodeCanvas");
3204
+ n(this, "textmodeCanvas");
3210
3205
  /** Core WebGL renderer */
3211
- a(this, "_renderer");
3212
- a(this, "_canvasFramebuffer");
3213
- a(this, "_font");
3214
- a(this, "_grid");
3215
- a(this, "resizeObserver");
3206
+ n(this, "_renderer");
3207
+ n(this, "_canvasFramebuffer");
3208
+ n(this, "_font");
3209
+ n(this, "_grid");
3210
+ n(this, "resizeObserver");
3216
3211
  // Auto-rendering properties
3217
- a(this, "_mode");
3218
- a(this, "_frameRateLimit");
3219
- a(this, "animationFrameId", null);
3220
- a(this, "lastFrameTime", 0);
3221
- a(this, "frameInterval");
3222
- a(this, "_isLooping", !0);
3223
- a(this, "_frameRate", 0);
3224
- a(this, "lastRenderTime", 0);
3225
- a(this, "_frameCount", 0);
3212
+ n(this, "_mode");
3213
+ n(this, "_frameRateLimit");
3214
+ n(this, "animationFrameId", null);
3215
+ n(this, "lastFrameTime", 0);
3216
+ n(this, "frameInterval");
3217
+ n(this, "_isLooping", !0);
3218
+ n(this, "_frameRate", 0);
3219
+ n(this, "lastRenderTime", 0);
3220
+ n(this, "_frameCount", 0);
3226
3221
  // Frame rate measurement smoothing
3227
- a(this, "frameTimeHistory", []);
3228
- a(this, "frameTimeHistorySize", 10);
3229
- a(this, "_pipeline");
3222
+ n(this, "frameTimeHistory", []);
3223
+ n(this, "frameTimeHistorySize", 10);
3224
+ n(this, "_pipeline");
3225
+ n(this, "_isDisposed", !1);
3230
3226
  // Standalone canvas properties
3231
- a(this, "_standalone", !1);
3232
- a(this, "_drawCallback", () => {
3227
+ n(this, "_standalone", !1);
3228
+ n(this, "_drawCallback", () => {
3233
3229
  });
3234
- a(this, "_resizedCallback", () => {
3230
+ n(this, "_resizedCallback", () => {
3235
3231
  });
3236
- // Destroy state
3237
- a(this, "_isDestroyed", !1);
3238
- a(this, "_windowResizeListener", null);
3232
+ n(this, "_windowResizeListener", null);
3239
3233
  this.captureSource = e, this._standalone = e === null, this._mode = t.renderMode ?? "auto", this._frameRateLimit = t.frameRate ?? 60, this.frameInterval = 1e3 / this._frameRateLimit;
3240
3234
  }
3241
3235
  /**
@@ -3247,10 +3241,10 @@ class I {
3247
3241
  static async create(e = null, t = {}) {
3248
3242
  const r = new I(e, t), i = r._standalone ? t : void 0;
3249
3243
  r.textmodeCanvas = new be(r.captureSource, r._standalone, i), r._renderer = new fe(r.textmodeCanvas.getWebGLContext());
3250
- let s, o;
3251
- r._standalone ? (s = t.width || 800, o = t.height || 600) : (s = r.textmodeCanvas.width || 800, o = r.textmodeCanvas.height || 600), r._canvasFramebuffer = r._renderer.createFramebuffer(s, o), r._font = new xe(r._renderer, t.fontSize ?? 16), await r._font.initialize(t.fontSource);
3252
- const n = r._font.maxGlyphDimensions;
3253
- return r._grid = new ve(r.textmodeCanvas.canvas, n.width, n.height), r._pipeline = new Ue(r._renderer, r._font, r._grid), r.setupEventListeners(), r.startAutoRendering(), r;
3244
+ let s, a;
3245
+ r._standalone ? (s = t.width || 800, a = t.height || 600) : (s = r.textmodeCanvas.width || 800, a = r.textmodeCanvas.height || 600), r._canvasFramebuffer = r._renderer.createFramebuffer(s, a), r._font = new xe(r._renderer, t.fontSize ?? 16), await r._font.initialize(t.fontSource);
3246
+ const o = r._font.maxGlyphDimensions;
3247
+ return r._grid = new ve(r.textmodeCanvas.canvas, o.width, o.height), r._pipeline = new Ue(r._renderer, r._font, r._grid), r.setupEventListeners(), r.startAutoRendering(), r;
3254
3248
  }
3255
3249
  setupEventListeners() {
3256
3250
  this._windowResizeListener = () => {
@@ -3477,11 +3471,7 @@ class I {
3477
3471
  * ```
3478
3472
  */
3479
3473
  render() {
3480
- if (this._isDestroyed) {
3481
- console.warn("Cannot render: Textmodifier instance has been destroyed");
3482
- return;
3483
- }
3484
- if (this.measureFrameRate(), this._frameCount++, !this._canvasFramebuffer || !this._renderer || !this._pipeline) {
3474
+ if (this.measureFrameRate(), this._frameCount++, this._isDisposed) {
3485
3475
  console.warn("Cannot render: Required resources have been disposed");
3486
3476
  return;
3487
3477
  }
@@ -3498,17 +3488,15 @@ class I {
3498
3488
  * Start automatic rendering
3499
3489
  */
3500
3490
  startAutoRendering() {
3501
- if (this._mode !== "auto" || this._isDestroyed || !this._isLooping) return;
3491
+ if (this._mode !== "auto" || !this._isLooping) return;
3502
3492
  this.lastFrameTime = performance.now();
3503
3493
  const e = (t) => {
3504
- if (this._isDestroyed)
3505
- return;
3506
3494
  if (!this._isLooping) {
3507
3495
  this.animationFrameId = null;
3508
3496
  return;
3509
3497
  }
3510
3498
  const r = t - this.lastFrameTime;
3511
- r >= this.frameInterval && (this.render(), this.lastFrameTime = t - r % this.frameInterval), !this._isDestroyed && this._isLooping && (this.animationFrameId = requestAnimationFrame(e));
3499
+ r >= this.frameInterval && (this.render(), this.lastFrameTime = t - r % this.frameInterval), this._isLooping && (this.animationFrameId = requestAnimationFrame(e));
3512
3500
  };
3513
3501
  this.animationFrameId = requestAnimationFrame(e);
3514
3502
  }
@@ -3517,7 +3505,6 @@ class I {
3517
3505
  * Uses a rolling average for smoother frame rate reporting
3518
3506
  */
3519
3507
  measureFrameRate() {
3520
- if (this._isDestroyed) return;
3521
3508
  const e = performance.now();
3522
3509
  if (this.lastRenderTime > 0) {
3523
3510
  const t = e - this.lastRenderTime;
@@ -3558,10 +3545,6 @@ class I {
3558
3545
  * ```
3559
3546
  */
3560
3547
  renderMode(e) {
3561
- if (this._isDestroyed) {
3562
- console.warn("Cannot change render mode: Textmodifier instance has been destroyed");
3563
- return;
3564
- }
3565
3548
  this._mode !== e && (this.stopAutoRendering(), this._mode = e, e === "auto" && this._isLooping && this.startAutoRendering());
3566
3549
  }
3567
3550
  /**
@@ -3613,10 +3596,6 @@ class I {
3613
3596
  * ```
3614
3597
  */
3615
3598
  noLoop() {
3616
- if (this._isDestroyed) {
3617
- console.warn("Cannot stop loop: Textmodifier instance has been destroyed");
3618
- return;
3619
- }
3620
3599
  this._isLooping && (this._isLooping = !1, this.animationFrameId && (cancelAnimationFrame(this.animationFrameId), this.animationFrameId = null));
3621
3600
  }
3622
3601
  /**
@@ -3646,10 +3625,6 @@ class I {
3646
3625
  * ```
3647
3626
  */
3648
3627
  loop() {
3649
- if (this._isDestroyed) {
3650
- console.warn("Cannot start loop: Textmodifier instance has been destroyed");
3651
- return;
3652
- }
3653
3628
  this._isLooping || (this._isLooping = !0, this._mode === "auto" && this.startAutoRendering());
3654
3629
  }
3655
3630
  /**
@@ -3681,7 +3656,7 @@ class I {
3681
3656
  * ```
3682
3657
  */
3683
3658
  isLooping() {
3684
- return this._isDestroyed ? !1 : this._mode === "auto" && this._isLooping;
3659
+ return this._mode === "auto" && this._isLooping;
3685
3660
  }
3686
3661
  /**
3687
3662
  * Set the font size used for rendering.
@@ -4198,6 +4173,14 @@ class I {
4198
4173
  createShader(e, t) {
4199
4174
  return this._renderer.createShader(e, t);
4200
4175
  }
4176
+ /**
4177
+ * Create a filter shader program from a fragment source code.
4178
+ * @param fragmentSource The GLSL source code for the fragment shader.
4179
+ * @returns The created filter shader program for use in `textmode.js`.
4180
+ */
4181
+ createFilterShader(e) {
4182
+ return this._renderer.createFilterShader(e);
4183
+ }
4201
4184
  /**
4202
4185
  * Set the current shader for rendering.
4203
4186
  * @param shader The shader program to use for rendering.
@@ -4241,49 +4224,44 @@ class I {
4241
4224
  * ```
4242
4225
  */
4243
4226
  destroy() {
4244
- this._isDestroyed || (this._isDestroyed = !0, this.stopAutoRendering(), this._windowResizeListener && (window.removeEventListener("resize", this._windowResizeListener), this._windowResizeListener = null), this.resizeObserver && (this.resizeObserver.disconnect(), this.resizeObserver = null), this._pipeline && !this._pipeline.isDisposed && this._pipeline.dispose(), this._font && !this._font.isDisposed && this._font.dispose(), this._grid && !this._grid.isDisposed && this._grid.dispose(), this._canvasFramebuffer && !this._canvasFramebuffer.isDisposed && this._canvasFramebuffer.dispose(), this._renderer && !this._renderer.isDisposed && this._renderer.dispose(), this.textmodeCanvas && !this.textmodeCanvas.isDisposed && this.textmodeCanvas.dispose(), this.captureSource = null, this.textmodeCanvas = null, this._renderer = null, this._canvasFramebuffer = null, this._font = null, this._grid = null, this._pipeline = null, this.resizeObserver = null, this._drawCallback = () => {
4227
+ this._isDisposed = !0, this.stopAutoRendering(), this._windowResizeListener && (window.removeEventListener("resize", this._windowResizeListener), this._windowResizeListener = null), this.resizeObserver && (this.resizeObserver.disconnect(), this.resizeObserver = null), this._pipeline.dispose(), this._font.dispose(), this._grid.dispose(), this._canvasFramebuffer.dispose(), this._renderer.dispose(), this.textmodeCanvas.dispose(), this.captureSource = null, this.textmodeCanvas = null, this._renderer = null, this._canvasFramebuffer = null, this._font = null, this._grid = null, this._pipeline = null, this.resizeObserver = null, this._drawCallback = () => {
4245
4228
  }, this._resizedCallback = () => {
4246
- }, this.animationFrameId = null, this.lastFrameTime = 0, this.lastRenderTime = 0, this._frameCount = 0, this._frameRate = 0, this.frameTimeHistory = [], this._isLooping = !1);
4229
+ }, this.animationFrameId = null, this.lastFrameTime = 0, this.lastRenderTime = 0, this._frameCount = 0, this._frameRate = 0, this.frameTimeHistory = [], this._isLooping = !1;
4247
4230
  }
4248
4231
  /** Get the current grid object used for rendering. */
4249
4232
  get grid() {
4250
- if (this._isDestroyed)
4251
- throw new Error("Cannot access grid: Textmodifier instance has been destroyed");
4252
4233
  return this._grid;
4253
4234
  }
4254
4235
  /** Get the current font object used for rendering. */
4255
4236
  get font() {
4256
- if (this._isDestroyed)
4257
- throw new Error("Cannot access font: Textmodifier instance has been destroyed");
4258
4237
  return this._font;
4259
4238
  }
4260
4239
  /** Get the current rendering mode.*/
4261
4240
  get mode() {
4262
- if (this._isDestroyed)
4263
- throw new Error("Cannot access mode: Textmodifier instance has been destroyed");
4264
4241
  return this._mode;
4265
4242
  }
4266
4243
  /** Get the current textmode conversion pipeline. */
4267
4244
  get pipeline() {
4268
- if (this._isDestroyed)
4269
- throw new Error("Cannot access pipeline: Textmodifier instance has been destroyed");
4270
4245
  return this._pipeline;
4271
4246
  }
4272
4247
  /** Get the current frame count. */
4273
4248
  get frameCount() {
4274
- return this._isDestroyed ? 0 : this._frameCount;
4249
+ return this._frameCount;
4250
+ }
4251
+ set frameCount(e) {
4252
+ this._frameCount = e;
4275
4253
  }
4276
4254
  /** Get the width of the canvas. */
4277
4255
  get width() {
4278
- return this._isDestroyed ? 0 : this.textmodeCanvas.width;
4256
+ return this.textmodeCanvas.width;
4279
4257
  }
4280
4258
  /** Get the height of the canvas. */
4281
4259
  get height() {
4282
- return this._isDestroyed ? 0 : this.textmodeCanvas.height;
4260
+ return this.textmodeCanvas.height;
4283
4261
  }
4284
- /** Check if this Textmodifier instance has been destroyed. */
4285
- get isDestroyed() {
4286
- return this._isDestroyed;
4262
+ /** Check if the instance has been disposed/destroyed. */
4263
+ get isDisposed() {
4264
+ return this._isDisposed;
4287
4265
  }
4288
4266
  }
4289
4267
  class O {
@@ -4376,26 +4354,26 @@ class O {
4376
4354
  * ```
4377
4355
  */
4378
4356
  static get version() {
4379
- return "0.1.4-beta.2";
4357
+ return "0.1.4-beta.5";
4380
4358
  }
4381
4359
  constructor() {
4382
4360
  throw new Error("Textmode is a static class and cannot be instantiated.");
4383
4361
  }
4384
4362
  }
4385
- const He = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
4363
+ const Xe = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
4386
4364
  __proto__: null
4387
4365
  }, Symbol.toStringTag, { value: "Module" })), Ne = O.create, Oe = O.setErrorLevel, We = O.version;
4388
4366
  export {
4389
4367
  be as TextmodeCanvas,
4390
4368
  Ue as TextmodeConversionPipeline,
4391
- ne as TextmodeErrorLevel,
4369
+ oe as TextmodeErrorLevel,
4392
4370
  xe as TextmodeFont,
4393
4371
  ve as TextmodeGrid,
4394
4372
  I as Textmodifier,
4395
- Xe as converters,
4373
+ He as converters,
4396
4374
  Ne as create,
4397
4375
  O as default,
4398
- He as export,
4376
+ Xe as export,
4399
4377
  Oe as setErrorLevel,
4400
4378
  O as textmode,
4401
4379
  We as version