textmode.js 0.1.7 → 0.1.8-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1292,8 +1292,8 @@ const lA = (E) => class extends E {
1292
1292
  };
1293
1293
  class Y {
1294
1294
  Ce(A) {
1295
- const t = A.get("brightness"), e = t == null ? void 0 : t.characterFramebuffer, r = t == null ? void 0 : t.primaryColorFramebuffer, B = t == null ? void 0 : t.secondaryColorFramebuffer, s = t == null ? void 0 : t.transformFramebuffer, i = t == null ? void 0 : t.rotationFramebuffer;
1296
- return e == null || e.loadPixels(), r == null || r.loadPixels(), B == null || B.loadPixels(), s == null || s.loadPixels(), i == null || i.loadPixels(), { characterPixels: (e == null ? void 0 : e.pixels) || new Uint8Array(0), primaryColorPixels: (r == null ? void 0 : r.pixels) || new Uint8Array(0), secondaryColorPixels: (B == null ? void 0 : B.pixels) || new Uint8Array(0), transformPixels: (s == null ? void 0 : s.pixels) || new Uint8Array(0), rotationPixels: (i == null ? void 0 : i.pixels) || new Uint8Array(0) };
1295
+ const t = A.characterFramebuffer, e = A.primaryColorFramebuffer, r = A.secondaryColorFramebuffer, B = A.transformFramebuffer, s = A.rotationFramebuffer;
1296
+ return t == null || t.loadPixels(), e == null || e.loadPixels(), r == null || r.loadPixels(), B == null || B.loadPixels(), s == null || s.loadPixels(), { characterPixels: (t == null ? void 0 : t.pixels) || new Uint8Array(0), primaryColorPixels: (e == null ? void 0 : e.pixels) || new Uint8Array(0), secondaryColorPixels: (r == null ? void 0 : r.pixels) || new Uint8Array(0), transformPixels: (B == null ? void 0 : B.pixels) || new Uint8Array(0), rotationPixels: (s == null ? void 0 : s.pixels) || new Uint8Array(0) };
1297
1297
  }
1298
1298
  ce(A, t) {
1299
1299
  return A[t] + (A[t + 1] << 8);
@@ -1665,10 +1665,10 @@ class xA {
1665
1665
  }
1666
1666
  const bA = (E) => class extends E {
1667
1667
  toString(A = {}) {
1668
- return new H().AB(this, A);
1668
+ return new H().AB({ pipeline: this.oB, grid: this.zt, font: this.et }, A);
1669
1669
  }
1670
1670
  saveStrings(A = {}) {
1671
- new H().Xe(this, A);
1671
+ new H().Xe({ pipeline: this.oB, grid: this.zt, font: this.et }, A);
1672
1672
  }
1673
1673
  toSVG(A = {}) {
1674
1674
  return new k().je(this, A);
@@ -740,10 +740,10 @@ class ht {
740
740
  h(this, "fe");
741
741
  h(this, "de", "UrsaFont");
742
742
  h(this, "me");
743
- h(this, "ge");
744
743
  h(this, "pe");
744
+ h(this, "ge");
745
745
  h(this, "_e");
746
- this.he = e, this.me = new it(), this.ge = new ot(t), this.pe = new nt(), this._e = new at();
746
+ this.he = e, this.me = new it(), this.pe = new ot(t), this.ge = new nt(), this._e = new at();
747
747
  }
748
748
  async ve(t) {
749
749
  let e;
@@ -757,8 +757,8 @@ class ht {
757
757
  }
758
758
  we(t) {
759
759
  if (t === void 0) return this.he;
760
- this.he = t, this.ue = this.pe.calculateMaxGlyphDimensions(this.ne.map((r) => r.character), this.he, this.de);
761
- const e = this.ge.createTextureAtlas(this.ne, this.ue, this.he, this.de);
760
+ this.he = t, this.ue = this.ge.calculateMaxGlyphDimensions(this.ne.map((r) => r.character), this.he, this.de);
761
+ const e = this.pe.createTextureAtlas(this.ne, this.ue, this.he, this.de);
762
762
  this.ae = e.framebuffer, this.le = e.columns, this.ce = e.rows;
763
763
  }
764
764
  async Ce(t) {
@@ -780,8 +780,8 @@ class ht {
780
780
  }
781
781
  async be() {
782
782
  const t = this.me.extractCharacters(this.oe), e = this.me.filterProblematicCharacters(t);
783
- this.ne = this._e.createCharacterObjects(e, this.oe), this.ue = this.pe.calculateMaxGlyphDimensions(e, this.he, this.de);
784
- const r = this.ge.createTextureAtlas(this.ne, this.ue, this.he, this.de);
783
+ this.ne = this._e.createCharacterObjects(e, this.oe), this.ue = this.ge.calculateMaxGlyphDimensions(e, this.he, this.de);
784
+ const r = this.pe.createTextureAtlas(this.ne, this.ue, this.he, this.de);
785
785
  this.ae = r.framebuffer, this.le = r.columns, this.ce = r.rows;
786
786
  }
787
787
  getCharacterColor(t) {
@@ -1170,14 +1170,14 @@ class ft {
1170
1170
  h(this, "ur");
1171
1171
  h(this, "dr");
1172
1172
  h(this, "mr");
1173
- h(this, "gr");
1174
1173
  h(this, "pr");
1174
+ h(this, "gr");
1175
1175
  h(this, "We");
1176
1176
  h(this, "Ne");
1177
1177
  h(this, "Xe");
1178
1178
  h(this, "qe");
1179
1179
  h(this, "Ye");
1180
- this.Zt = t, this.oe = e, this.je = r, this.pr = this.Zt.zt(Z, "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);float flippedRow=(u_charsetDimensions.y-1.0)-float(charRow);vec2 charCoord=vec2(float(charCol),flippedRow)/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);}"), this.dr = new I(t, e, r), this.mr = new U(t, e, r), this.ur = [this.dr, this.mr], this.We = this.Zt.Et(r.cols, r.rows), this.Ne = this.Zt.Et(r.cols, r.rows), this.Xe = this.Zt.Et(r.cols, r.rows), this.qe = this.Zt.Et(r.cols, r.rows), this.Ye = this.Zt.Et(r.cols, r.rows), this.gr = this.Zt.Et(this.je.width, this.je.height);
1180
+ this.Zt = t, this.oe = e, this.je = r, this.gr = this.Zt.zt(Z, "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);float flippedRow=(u_charsetDimensions.y-1.0)-float(charRow);vec2 charCoord=vec2(float(charCol),flippedRow)/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);}"), this.dr = new I(t, e, r), this.mr = new U(t, e, r), this.ur = [this.dr, this.mr], this.We = this.Zt.Et(r.cols, r.rows), this.Ne = this.Zt.Et(r.cols, r.rows), this.Xe = this.Zt.Et(r.cols, r.rows), this.qe = this.Zt.Et(r.cols, r.rows), this.Ye = this.Zt.Et(r.cols, r.rows), this.pr = this.Zt.Et(this.je.width, this.je.height);
1181
1181
  }
1182
1182
  _r(t) {
1183
1183
  for (const r of this.ur) r.options.enabled && r instanceof k && r.cr(t);
@@ -1186,7 +1186,7 @@ class ft {
1186
1186
  for (const i of this.ur) i.options.enabled && this.Zt.Ot(s(i), 0, 0);
1187
1187
  r.end();
1188
1188
  };
1189
- e(this.We, (r) => r.characterFramebuffer), e(this.Ne, (r) => r.primaryColorFramebuffer), e(this.Xe, (r) => r.secondaryColorFramebuffer), e(this.qe, (r) => r.rotationFramebuffer), e(this.Ye, (r) => r.transformFramebuffer), this.gr.begin(), this.Zt.Bt(), this.Zt.yt(this.pr), this.Zt.Pt("u_characterTexture", this.oe.fontFramebuffer), this.Zt.Pt("u_charsetDimensions", [this.oe.textureColumns, this.oe.textureRows]), this.Zt.Pt("u_asciiCharacterTexture", this.We.texture), this.Zt.Pt("u_primaryColorTexture", this.Ne.texture), this.Zt.Pt("u_secondaryColorTexture", this.Xe.texture), this.Zt.Pt("u_transformTexture", this.Ye.texture), this.Zt.Pt("u_rotationTexture", this.qe.texture), this.Zt.Pt("u_captureTexture", t.texture), this.Zt.Pt("u_backgroundMode", !1), this.Zt.Pt("u_captureDimensions", [t.width, t.height]), this.Zt.Pt("u_gridCellDimensions", [this.je.cols, this.je.rows]), this.Zt.Pt("u_gridPixelDimensions", [this.je.width, this.je.height]), this.Zt.Ut(0, 0, this.gr.width, this.gr.height), this.gr.end();
1189
+ e(this.We, (r) => r.characterFramebuffer), e(this.Ne, (r) => r.primaryColorFramebuffer), e(this.Xe, (r) => r.secondaryColorFramebuffer), e(this.qe, (r) => r.rotationFramebuffer), e(this.Ye, (r) => r.transformFramebuffer), this.pr.begin(), this.Zt.Bt(), this.Zt.yt(this.gr), this.Zt.Pt("u_characterTexture", this.oe.fontFramebuffer), this.Zt.Pt("u_charsetDimensions", [this.oe.textureColumns, this.oe.textureRows]), this.Zt.Pt("u_asciiCharacterTexture", this.We.texture), this.Zt.Pt("u_primaryColorTexture", this.Ne.texture), this.Zt.Pt("u_secondaryColorTexture", this.Xe.texture), this.Zt.Pt("u_transformTexture", this.Ye.texture), this.Zt.Pt("u_rotationTexture", this.qe.texture), this.Zt.Pt("u_captureTexture", t.texture), this.Zt.Pt("u_backgroundMode", !1), this.Zt.Pt("u_captureDimensions", [t.width, t.height]), this.Zt.Pt("u_gridCellDimensions", [this.je.cols, this.je.rows]), this.Zt.Pt("u_gridPixelDimensions", [this.je.width, this.je.height]), this.Zt.Ut(0, 0, this.pr.width, this.pr.height), this.pr.end();
1190
1190
  }
1191
1191
  add(t) {
1192
1192
  if (!C.p(t === "brightness" || t === "custom", 'Converter type must be either "brightness" or "custom".', { method: "add", providedValue: t })) return;
@@ -1199,7 +1199,7 @@ class ft {
1199
1199
  C.p(e !== -1, "Converter instance not found in pipeline.", { method: "remove", providedValue: t, convertersCount: this.ur.length }) && this.ur.splice(e, 1);
1200
1200
  }
1201
1201
  Pe() {
1202
- this.gr.resize(this.je.width, this.je.height);
1202
+ this.pr.resize(this.je.width, this.je.height);
1203
1203
  const t = this.je.cols, e = this.je.rows;
1204
1204
  this.We.resize(t, e), this.Ne.resize(t, e), this.Xe.resize(t, e), this.qe.resize(t, e), this.Ye.resize(t, e);
1205
1205
  for (const r of this.ur) r.Pe();
@@ -1215,10 +1215,10 @@ class ft {
1215
1215
  }
1216
1216
  P() {
1217
1217
  for (const t of this.ur) t.P();
1218
- this.We.P(), this.Ne.P(), this.Xe.P(), this.qe.P(), this.Ye.P(), this.gr.P(), this.pr.P();
1218
+ this.We.P(), this.Ne.P(), this.Xe.P(), this.qe.P(), this.Ye.P(), this.pr.P(), this.gr.P();
1219
1219
  }
1220
1220
  get texture() {
1221
- return this.gr;
1221
+ return this.pr;
1222
1222
  }
1223
1223
  get characterFramebuffer() {
1224
1224
  return this.We;
@@ -1291,8 +1291,8 @@ const gt = (a) => class extends a {
1291
1291
  };
1292
1292
  class j {
1293
1293
  vr(t) {
1294
- const e = t.get("brightness"), r = e == null ? void 0 : e.characterFramebuffer, s = e == null ? void 0 : e.primaryColorFramebuffer, i = e == null ? void 0 : e.secondaryColorFramebuffer, o = e == null ? void 0 : e.transformFramebuffer, n = e == null ? void 0 : e.rotationFramebuffer;
1295
- return r == null || r.loadPixels(), s == null || s.loadPixels(), i == null || i.loadPixels(), o == null || o.loadPixels(), n == null || n.loadPixels(), { characterPixels: (r == null ? void 0 : r.pixels) || new Uint8Array(0), primaryColorPixels: (s == null ? void 0 : s.pixels) || new Uint8Array(0), secondaryColorPixels: (i == null ? void 0 : i.pixels) || new Uint8Array(0), transformPixels: (o == null ? void 0 : o.pixels) || new Uint8Array(0), rotationPixels: (n == null ? void 0 : n.pixels) || new Uint8Array(0) };
1294
+ const e = t.characterFramebuffer, r = t.primaryColorFramebuffer, s = t.secondaryColorFramebuffer, i = t.transformFramebuffer, o = t.rotationFramebuffer;
1295
+ return e == null || e.loadPixels(), r == null || r.loadPixels(), s == null || s.loadPixels(), i == null || i.loadPixels(), o == null || o.loadPixels(), { characterPixels: (e == null ? void 0 : e.pixels) || new Uint8Array(0), primaryColorPixels: (r == null ? void 0 : r.pixels) || new Uint8Array(0), secondaryColorPixels: (s == null ? void 0 : s.pixels) || new Uint8Array(0), transformPixels: (i == null ? void 0 : i.pixels) || new Uint8Array(0), rotationPixels: (o == null ? void 0 : o.pixels) || new Uint8Array(0) };
1296
1296
  }
1297
1297
  br(t, e) {
1298
1298
  return t[e] + (t[e + 1] << 8);
@@ -1639,21 +1639,21 @@ class Pt {
1639
1639
  Zr(t) {
1640
1640
  return { format: t.format ?? "png", quality: t.quality ?? 1, scale: t.scale ?? 1, backgroundColor: t.backgroundColor ?? "transparent" };
1641
1641
  }
1642
- gs(t) {
1642
+ ps(t) {
1643
1643
  if (console.log("Validating image export options:", t), !this.Qr.ds(t.format)) throw Error(`Saving '${t.format}' files is not supported`);
1644
1644
  if (t.quality < 0 || t.quality > 1) throw Error("Image quality must be between 0.0 and 1.0");
1645
1645
  if (t.scale <= 0) throw Error("Scale factor must be greater than 0");
1646
1646
  t.scale > 10 && console.warn("Large scale factors may result in very large files and slow performance"), t.format === "jpg" && t.backgroundColor === "transparent" && (t.backgroundColor = "black");
1647
1647
  }
1648
- ps(t, e = {}) {
1648
+ gs(t, e = {}) {
1649
1649
  const r = this.Zr(e);
1650
- if (this.gs(r), r.scale === 1 && r.backgroundColor === "transparent") return this.Yr.hs(t.canvas, r);
1650
+ if (this.ps(r), r.scale === 1 && r.backgroundColor === "transparent") return this.Yr.hs(t.canvas, r);
1651
1651
  const s = this.qr.ns(t, r.scale, r.backgroundColor);
1652
1652
  return this.Yr.hs(s, r);
1653
1653
  }
1654
1654
  async cs(t, e = {}) {
1655
1655
  const r = this.Zr(e);
1656
- if (this.gs(r), r.scale === 1 && r.backgroundColor === "transparent") return await this.Yr.cs(t.canvas, r);
1656
+ if (this.ps(r), r.scale === 1 && r.backgroundColor === "transparent") return await this.Yr.cs(t.canvas, r);
1657
1657
  const s = this.qr.ns(t, r.scale, r.backgroundColor);
1658
1658
  return await this.Yr.cs(s, r);
1659
1659
  }
@@ -1664,10 +1664,10 @@ class Pt {
1664
1664
  }
1665
1665
  const Rt = (a) => class extends a {
1666
1666
  toString(t = {}) {
1667
- return new Y().ss(this, t);
1667
+ return new Y().ss({ pipeline: this._s, grid: this.je, font: this.oe }, t);
1668
1668
  }
1669
1669
  saveStrings(t = {}) {
1670
- new Y().es(this, t);
1670
+ new Y().es({ pipeline: this._s, grid: this.je, font: this.oe }, t);
1671
1671
  }
1672
1672
  toSVG(t = {}) {
1673
1673
  return new V().Jr(this, t);
@@ -43,7 +43,7 @@ void main() {\r
43
43
  \r
44
44
  gl_Position = vec4(pos, 0.0, 1.0);\r
45
45
  }\r
46
- `,hA={enabled:!0,characters:" .:-=+*%@#",characterColor:[1,1,1,1],characterColorMode:"sampled",cellColor:[0,0,0,1],cellColorMode:"fixed",invert:!1,rotation:[0,0,0,255],flipHorizontally:!1,flipVertically:!1,brightnessRange:[0,255]};class k extends z{constructor(r,B,i){super(r,B,i,{...hA});g(this,"Be");g(this,"Qe");g(this,"se");g(this,"re");g(this,"ie");g(this,"Ee");this.Be=new x(r.context,F,"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);}}"),this.Qe=new x(r.context,F,"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);}}"),this.re=new x(r.context,F,"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);}}"),this.ie=new x(r.context,F,"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);}}"),this.se=new x(r.context,F,"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);}"),this.Ee=this.WA.TA(this.zt.cols,this.zt.rows)}ge(r){const B=this.zt.cols,i=this.zt.rows;this.Ee.begin(),this.WA.OA(),this.WA.IA(this.Be),this.WA.GA("u_sketchTexture",r),this.WA.GA("u_gridCellDimensions",[B,i]),this.WA.GA("u_brightnessRange",this.h.brightnessRange),this.WA.FA(0,0,B,i),this.Ee.end(),this.Lt.begin(),this.WA.OA(),this.WA.IA(this.Qe),this.WA.GA("u_sampleTexture",this.Ee),this.WA.GA("u_fillColor",this.h.characterColor),this.WA.GA("u_useFixedColor",this.h.characterColorMode==="fixed"),this.WA.FA(0,0,B,i),this.Lt.end(),this.Kt.begin(),this.WA.OA(),this.WA.IA(this.Qe),this.WA.GA("u_sampleTexture",this.Ee),this.WA.GA("u_fillColor",this.h.cellColor),this.WA.GA("u_useFixedColor",this.h.cellColorMode==="fixed"),this.WA.FA(0,0,B,i),this.Kt.end(),this.jt.begin(),this.WA.OA(),this.WA.IA(this.re),this.WA.GA("u_sampleTexture",this.Ee),this.WA.GA("u_invert",this.h.invert),this.WA.GA("u_flipHorizontally",this.h.flipHorizontally),this.WA.GA("u_flipVertically",this.h.flipVertically),this.WA.FA(0,0,B,i),this.jt.end(),this.Wt.begin(),this.WA.OA(),this.WA.IA(this.ie),this.WA.GA("u_sampleTexture",this.Ee),this.WA.GA("u_rotationColor",this.h.rotation),this.WA.FA(0,0,B,i),this.Wt.end(),this.Jt.begin(),this.WA.OA(),this.WA.IA(this.se),this.WA.GA("u_colorSampleFramebuffer",this.Ee),this.WA.GA("u_charPaletteTexture",this.Xt.texture),this.WA.GA("u_charPaletteSize",[this.Xt.colors.length,1]),this.WA.GA("u_brightnessRange",this.h.brightnessRange),this.WA.FA(0,0,B,i),this.Jt.end()}$t(){super.$t(),this.Ee.resize(this.zt.cols,this.zt.rows)}brightnessRange(r){f.C(Array.isArray(r)&&r.length===2&&r.every(B=>typeof B=="number"&&B>=0&&B<=255),"Brightness range must be an array of two numbers between 0 and 255.",{method:"brightnessRange",providedValue:r})&&(this.h.brightnessRange=r)}}const lA=Object.freeze(Object.defineProperty({__proto__:null,TextmodeBrightnessConverter:k,TextmodeConverter:R,TextmodeFeatureConverter:z},Symbol.toStringTag,{value:"Module"}));class AA{constructor(e,r,B){g(this,"WA");g(this,"et");g(this,"zt");g(this,"oe");g(this,"ne");g(this,"ae");g(this,"he");g(this,"De");g(this,"Jt");g(this,"Lt");g(this,"Kt");g(this,"Wt");g(this,"jt");this.WA=e,this.et=r,this.zt=B,this.De=this.WA.yA(W,"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);float flippedRow=(u_charsetDimensions.y-1.0)-float(charRow);vec2 charCoord=vec2(float(charCol),flippedRow)/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);}"),this.ne=new k(e,r,B),this.ae=new R(e,r,B),this.oe=[this.ne,this.ae],this.Jt=this.WA.TA(B.cols,B.rows),this.Lt=this.WA.TA(B.cols,B.rows),this.Kt=this.WA.TA(B.cols,B.rows),this.Wt=this.WA.TA(B.cols,B.rows),this.jt=this.WA.TA(B.cols,B.rows),this.he=this.WA.TA(this.zt.width,this.zt.height)}le(e){for(const B of this.oe)B.options.enabled&&B instanceof z&&B.ge(e);const r=(B,i)=>{B.begin(),this.WA.OA();for(const s of this.oe)s.options.enabled&&this.WA.kA(i(s),0,0);B.end()};r(this.Jt,B=>B.characterFramebuffer),r(this.Lt,B=>B.primaryColorFramebuffer),r(this.Kt,B=>B.secondaryColorFramebuffer),r(this.Wt,B=>B.rotationFramebuffer),r(this.jt,B=>B.transformFramebuffer),this.he.begin(),this.WA.OA(),this.WA.IA(this.De),this.WA.GA("u_characterTexture",this.et.fontFramebuffer),this.WA.GA("u_charsetDimensions",[this.et.textureColumns,this.et.textureRows]),this.WA.GA("u_asciiCharacterTexture",this.Jt.texture),this.WA.GA("u_primaryColorTexture",this.Lt.texture),this.WA.GA("u_secondaryColorTexture",this.Kt.texture),this.WA.GA("u_transformTexture",this.jt.texture),this.WA.GA("u_rotationTexture",this.Wt.texture),this.WA.GA("u_captureTexture",e.texture),this.WA.GA("u_backgroundMode",!1),this.WA.GA("u_captureDimensions",[e.width,e.height]),this.WA.GA("u_gridCellDimensions",[this.zt.cols,this.zt.rows]),this.WA.GA("u_gridPixelDimensions",[this.zt.width,this.zt.height]),this.WA.FA(0,0,this.he.width,this.he.height),this.he.end()}add(e){if(!f.C(e==="brightness"||e==="custom",'Converter type must be either "brightness" or "custom".',{method:"add",providedValue:e}))return;let r;return r=e==="brightness"?new k(this.WA,this.et,this.zt):new R(this.WA,this.et,this.zt),this.oe.push(r),r}remove(e){if(!f.C(e instanceof R,"Parameter must be a TextmodeConverter instance.",{method:"remove",providedValue:e}))return;const r=this.oe.indexOf(e);f.C(r!==-1,"Converter instance not found in pipeline.",{method:"remove",providedValue:e,convertersCount:this.oe.length})&&this.oe.splice(r,1)}$t(){this.he.resize(this.zt.width,this.zt.height);const e=this.zt.cols,r=this.zt.rows;this.Jt.resize(e,r),this.Lt.resize(e,r),this.Kt.resize(e,r),this.Wt.resize(e,r),this.jt.resize(e,r);for(const B of this.oe)B.$t()}hasEnabledConverters(){return this.oe.some(e=>e.options.enabled)}disable(){for(const e of this.oe)e.disable()}enable(){for(const e of this.oe)e.enable()}S(){for(const e of this.oe)e.S();this.Jt.S(),this.Lt.S(),this.Kt.S(),this.Wt.S(),this.jt.S(),this.he.S(),this.De.S()}get texture(){return this.he}get characterFramebuffer(){return this.Jt}get primaryColorFramebuffer(){return this.Lt}get secondaryColorFramebuffer(){return this.Kt}get rotationFramebuffer(){return this.Wt}get transformFramebuffer(){return this.jt}get brightness(){return this.ne}get custom(){return this.ae}}const cA=o=>class extends o{fill(e,r,B,i){this.WA.wA(e,r,B,i)}stroke(e,r,B,i){this.WA.fA(e,r,B,i)}strokeWeight(e){this.WA.dA(e)}noStroke(){this.WA.mA()}noFill(){this.WA.pA()}rotate(e){this.WA._A(e)}push(){this.WA.vA()}pop(){this.WA.bA()}rect(e,r,B=1,i=1){this.WA.FA(e,r,B,i)}line(e,r,B,i){this.WA.$A(e,r,B,i)}background(e,r=e,B=e,i=255){this.WA.SA(e,r,B,i)}createShader(e,r){return this.WA.yA(e,r)}createFilterShader(e){return this.WA.MA(e)}shader(e){this.WA.IA(e)}setUniform(e,r){this.WA.GA(e,r)}};class H{Ce(e){const r=e.get("brightness"),B=r==null?void 0:r.characterFramebuffer,i=r==null?void 0:r.primaryColorFramebuffer,s=r==null?void 0:r.secondaryColorFramebuffer,E=r==null?void 0:r.transformFramebuffer,Q=r==null?void 0:r.rotationFramebuffer;return B==null||B.loadPixels(),i==null||i.loadPixels(),s==null||s.loadPixels(),E==null||E.loadPixels(),Q==null||Q.loadPixels(),{characterPixels:(B==null?void 0:B.pixels)||new Uint8Array(0),primaryColorPixels:(i==null?void 0:i.pixels)||new Uint8Array(0),secondaryColorPixels:(s==null?void 0:s.pixels)||new Uint8Array(0),transformPixels:(E==null?void 0:E.pixels)||new Uint8Array(0),rotationPixels:(Q==null?void 0:Q.pixels)||new Uint8Array(0)}}ce(e,r){return e[r]+(e[r+1]<<8)}ue(e,r){return{r:e[r],g:e[r+1],b:e[r+2],a:e[r+3]}}}class ${Pe(e,r){return new Blob([e],{type:r})}Ie(e,r,B){try{const i=this.Pe(e,B),s=URL.createObjectURL(i),E=document.createElement("a");E.href=s,E.download=r,E.style.display="none",E.rel="noopener",document.body.appendChild(E),E.click(),document.body.removeChild(E),URL.revokeObjectURL(s)}catch(i){throw console.error("Failed to download file:",i),Error("File download failed: "+(i instanceof Error?i.message:"Unknown error"))}}we(){return new Date().toISOString().slice(0,19).replace(/:/g,"-")}fe(){const e=new Date;return{date:e.toISOString().split("T")[0],time:e.toTimeString().split(" ")[0].replace(/:/g,"-")}}de(e){return e.replace(/[<>:"/\\|?*]/g,"_").replace(/\s+/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").substring(0,255)}me(){return"'textmode-export'-"+this.we()}}class CA extends H{pe(e,r,B){const i=e[B]===255,s=e[B+1]===255,E=e[B+2]===255,Q=r[B],n=r[B+1];return{isInverted:i,flipHorizontal:s,flipVertical:E,rotation:Math.round(360*(Q+n/255)/255*100)/100}}_e(e,r,B){return{x:e,y:r,cellX:e*B.cellWidth,cellY:r*B.cellHeight}}ve(e,r){const B=[];let i=0;for(let s=0;s<r.rows;s++)for(let E=0;E<r.cols;E++){const Q=4*i,n=this.ce(e.characterPixels,Q);let a=this.ue(e.primaryColorPixels,Q),h=this.ue(e.secondaryColorPixels,Q);const l=this.pe(e.transformPixels,e.rotationPixels,Q);if(l.isInverted){const P=a;a=h,h=P}const c=this._e(E,s,r);B.push({charIndex:n,primaryColor:a,secondaryColor:h,transform:l,position:c}),i++}return B}}class DA{tt(e,r){const B=e.cmap;for(const i of B.tables)if(i.format===4){for(let s=0;s<i.startCount.length;s++)if(r>=i.startCount[s]&&r<=i.endCount[s]){if(i.idRangeOffset[s]===0)return r+i.idDelta[s]&65535;{const E=i.idRangeOffset[s]/2+(r-i.startCount[s])-(i.startCount.length-s);if(E>=0&&E<i.glyphIdArray.length){const Q=i.glyphIdArray[E];if(Q!==0)return Q+i.idDelta[s]&65535}}}}return 0}be(e,r,B,i,s){const E=s/e.head.unitsPerEm;return{getBoundingBox:()=>({x1:B+r.xMin*E,y1:i+-r.yMax*E,x2:B+r.xMax*E,y2:i+-r.yMin*E}),toSVG:()=>this.xe(r,B,i,E)}}xe(e,r,B,i){if(!e||!e.xs)return"";const{xs:s,ys:E,endPts:Q,flags:n}=e;if(!(s&&E&&Q&&n))return"";let a="",h=0;for(let l=0;l<Q.length;l++){const c=Q[l];if(!(c<h)){if(c>=h){const P=r+s[h]*i,d=B-E[h]*i;a+=`M${P.toFixed(2)},${d.toFixed(2)}`;let D=h+1;for(;D<=c;)if(1&n[D]){const w=r+s[D]*i,p=B-E[D]*i;a+=`L${w.toFixed(2)},${p.toFixed(2)}`,D++}else{const w=r+s[D]*i,p=B-E[D]*i;let m=D+1>c?h:D+1;if(1&n[m]){const y=r+s[m]*i,_=B-E[m]*i;a+=`Q${w.toFixed(2)},${p.toFixed(2)} ${y.toFixed(2)},${_.toFixed(2)}`,D=m+1}else{const y=(w+(r+s[m]*i))/2,_=(p+(B-E[m]*i))/2;a+=`Q${w.toFixed(2)},${p.toFixed(2)} ${y.toFixed(2)},${_.toFixed(2)}`,D=m}}a+="Z"}h=c+1}}return a}ye(e,r,B,i,s){const E=e.codePointAt(0)||0,Q=this.tt(r,E);let n=null;return r.glyf&&r.glyf[Q]!==null?n=r.glyf[Q]:C&&C.T&&C.T.glyf&&C.T.glyf.VA&&(n=C.T.glyf.VA(r,Q),r.glyf&&n&&(r.glyf[Q]=n)),this.be(r,n,B,i,s)}Me(e,r,B,i,s,E,Q,n){const a=B+(s-n*(Q/r.head.unitsPerEm))/2,h=i+(E+.7*Q)/2;return this.ye(e,r,a,h,Q).toSVG()||null}}class uA{constructor(){g(this,"Ge");this.Ge=new DA}Fe(e){return`<?xml version="1.0" encoding="UTF-8" standalone="no"?>
46
+ `,hA={enabled:!0,characters:" .:-=+*%@#",characterColor:[1,1,1,1],characterColorMode:"sampled",cellColor:[0,0,0,1],cellColorMode:"fixed",invert:!1,rotation:[0,0,0,255],flipHorizontally:!1,flipVertically:!1,brightnessRange:[0,255]};class k extends z{constructor(r,B,i){super(r,B,i,{...hA});g(this,"Be");g(this,"Qe");g(this,"se");g(this,"re");g(this,"ie");g(this,"Ee");this.Be=new x(r.context,F,"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);}}"),this.Qe=new x(r.context,F,"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);}}"),this.re=new x(r.context,F,"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);}}"),this.ie=new x(r.context,F,"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);}}"),this.se=new x(r.context,F,"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);}"),this.Ee=this.WA.TA(this.zt.cols,this.zt.rows)}ge(r){const B=this.zt.cols,i=this.zt.rows;this.Ee.begin(),this.WA.OA(),this.WA.IA(this.Be),this.WA.GA("u_sketchTexture",r),this.WA.GA("u_gridCellDimensions",[B,i]),this.WA.GA("u_brightnessRange",this.h.brightnessRange),this.WA.FA(0,0,B,i),this.Ee.end(),this.Lt.begin(),this.WA.OA(),this.WA.IA(this.Qe),this.WA.GA("u_sampleTexture",this.Ee),this.WA.GA("u_fillColor",this.h.characterColor),this.WA.GA("u_useFixedColor",this.h.characterColorMode==="fixed"),this.WA.FA(0,0,B,i),this.Lt.end(),this.Kt.begin(),this.WA.OA(),this.WA.IA(this.Qe),this.WA.GA("u_sampleTexture",this.Ee),this.WA.GA("u_fillColor",this.h.cellColor),this.WA.GA("u_useFixedColor",this.h.cellColorMode==="fixed"),this.WA.FA(0,0,B,i),this.Kt.end(),this.jt.begin(),this.WA.OA(),this.WA.IA(this.re),this.WA.GA("u_sampleTexture",this.Ee),this.WA.GA("u_invert",this.h.invert),this.WA.GA("u_flipHorizontally",this.h.flipHorizontally),this.WA.GA("u_flipVertically",this.h.flipVertically),this.WA.FA(0,0,B,i),this.jt.end(),this.Wt.begin(),this.WA.OA(),this.WA.IA(this.ie),this.WA.GA("u_sampleTexture",this.Ee),this.WA.GA("u_rotationColor",this.h.rotation),this.WA.FA(0,0,B,i),this.Wt.end(),this.Jt.begin(),this.WA.OA(),this.WA.IA(this.se),this.WA.GA("u_colorSampleFramebuffer",this.Ee),this.WA.GA("u_charPaletteTexture",this.Xt.texture),this.WA.GA("u_charPaletteSize",[this.Xt.colors.length,1]),this.WA.GA("u_brightnessRange",this.h.brightnessRange),this.WA.FA(0,0,B,i),this.Jt.end()}$t(){super.$t(),this.Ee.resize(this.zt.cols,this.zt.rows)}brightnessRange(r){f.C(Array.isArray(r)&&r.length===2&&r.every(B=>typeof B=="number"&&B>=0&&B<=255),"Brightness range must be an array of two numbers between 0 and 255.",{method:"brightnessRange",providedValue:r})&&(this.h.brightnessRange=r)}}const lA=Object.freeze(Object.defineProperty({__proto__:null,TextmodeBrightnessConverter:k,TextmodeConverter:R,TextmodeFeatureConverter:z},Symbol.toStringTag,{value:"Module"}));class AA{constructor(e,r,B){g(this,"WA");g(this,"et");g(this,"zt");g(this,"oe");g(this,"ne");g(this,"ae");g(this,"he");g(this,"De");g(this,"Jt");g(this,"Lt");g(this,"Kt");g(this,"Wt");g(this,"jt");this.WA=e,this.et=r,this.zt=B,this.De=this.WA.yA(W,"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);float flippedRow=(u_charsetDimensions.y-1.0)-float(charRow);vec2 charCoord=vec2(float(charCol),flippedRow)/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);}"),this.ne=new k(e,r,B),this.ae=new R(e,r,B),this.oe=[this.ne,this.ae],this.Jt=this.WA.TA(B.cols,B.rows),this.Lt=this.WA.TA(B.cols,B.rows),this.Kt=this.WA.TA(B.cols,B.rows),this.Wt=this.WA.TA(B.cols,B.rows),this.jt=this.WA.TA(B.cols,B.rows),this.he=this.WA.TA(this.zt.width,this.zt.height)}le(e){for(const B of this.oe)B.options.enabled&&B instanceof z&&B.ge(e);const r=(B,i)=>{B.begin(),this.WA.OA();for(const s of this.oe)s.options.enabled&&this.WA.kA(i(s),0,0);B.end()};r(this.Jt,B=>B.characterFramebuffer),r(this.Lt,B=>B.primaryColorFramebuffer),r(this.Kt,B=>B.secondaryColorFramebuffer),r(this.Wt,B=>B.rotationFramebuffer),r(this.jt,B=>B.transformFramebuffer),this.he.begin(),this.WA.OA(),this.WA.IA(this.De),this.WA.GA("u_characterTexture",this.et.fontFramebuffer),this.WA.GA("u_charsetDimensions",[this.et.textureColumns,this.et.textureRows]),this.WA.GA("u_asciiCharacterTexture",this.Jt.texture),this.WA.GA("u_primaryColorTexture",this.Lt.texture),this.WA.GA("u_secondaryColorTexture",this.Kt.texture),this.WA.GA("u_transformTexture",this.jt.texture),this.WA.GA("u_rotationTexture",this.Wt.texture),this.WA.GA("u_captureTexture",e.texture),this.WA.GA("u_backgroundMode",!1),this.WA.GA("u_captureDimensions",[e.width,e.height]),this.WA.GA("u_gridCellDimensions",[this.zt.cols,this.zt.rows]),this.WA.GA("u_gridPixelDimensions",[this.zt.width,this.zt.height]),this.WA.FA(0,0,this.he.width,this.he.height),this.he.end()}add(e){if(!f.C(e==="brightness"||e==="custom",'Converter type must be either "brightness" or "custom".',{method:"add",providedValue:e}))return;let r;return r=e==="brightness"?new k(this.WA,this.et,this.zt):new R(this.WA,this.et,this.zt),this.oe.push(r),r}remove(e){if(!f.C(e instanceof R,"Parameter must be a TextmodeConverter instance.",{method:"remove",providedValue:e}))return;const r=this.oe.indexOf(e);f.C(r!==-1,"Converter instance not found in pipeline.",{method:"remove",providedValue:e,convertersCount:this.oe.length})&&this.oe.splice(r,1)}$t(){this.he.resize(this.zt.width,this.zt.height);const e=this.zt.cols,r=this.zt.rows;this.Jt.resize(e,r),this.Lt.resize(e,r),this.Kt.resize(e,r),this.Wt.resize(e,r),this.jt.resize(e,r);for(const B of this.oe)B.$t()}hasEnabledConverters(){return this.oe.some(e=>e.options.enabled)}disable(){for(const e of this.oe)e.disable()}enable(){for(const e of this.oe)e.enable()}S(){for(const e of this.oe)e.S();this.Jt.S(),this.Lt.S(),this.Kt.S(),this.Wt.S(),this.jt.S(),this.he.S(),this.De.S()}get texture(){return this.he}get characterFramebuffer(){return this.Jt}get primaryColorFramebuffer(){return this.Lt}get secondaryColorFramebuffer(){return this.Kt}get rotationFramebuffer(){return this.Wt}get transformFramebuffer(){return this.jt}get brightness(){return this.ne}get custom(){return this.ae}}const cA=o=>class extends o{fill(e,r,B,i){this.WA.wA(e,r,B,i)}stroke(e,r,B,i){this.WA.fA(e,r,B,i)}strokeWeight(e){this.WA.dA(e)}noStroke(){this.WA.mA()}noFill(){this.WA.pA()}rotate(e){this.WA._A(e)}push(){this.WA.vA()}pop(){this.WA.bA()}rect(e,r,B=1,i=1){this.WA.FA(e,r,B,i)}line(e,r,B,i){this.WA.$A(e,r,B,i)}background(e,r=e,B=e,i=255){this.WA.SA(e,r,B,i)}createShader(e,r){return this.WA.yA(e,r)}createFilterShader(e){return this.WA.MA(e)}shader(e){this.WA.IA(e)}setUniform(e,r){this.WA.GA(e,r)}};class H{Ce(e){const r=e.characterFramebuffer,B=e.primaryColorFramebuffer,i=e.secondaryColorFramebuffer,s=e.transformFramebuffer,E=e.rotationFramebuffer;return r==null||r.loadPixels(),B==null||B.loadPixels(),i==null||i.loadPixels(),s==null||s.loadPixels(),E==null||E.loadPixels(),{characterPixels:(r==null?void 0:r.pixels)||new Uint8Array(0),primaryColorPixels:(B==null?void 0:B.pixels)||new Uint8Array(0),secondaryColorPixels:(i==null?void 0:i.pixels)||new Uint8Array(0),transformPixels:(s==null?void 0:s.pixels)||new Uint8Array(0),rotationPixels:(E==null?void 0:E.pixels)||new Uint8Array(0)}}ce(e,r){return e[r]+(e[r+1]<<8)}ue(e,r){return{r:e[r],g:e[r+1],b:e[r+2],a:e[r+3]}}}class ${Pe(e,r){return new Blob([e],{type:r})}Ie(e,r,B){try{const i=this.Pe(e,B),s=URL.createObjectURL(i),E=document.createElement("a");E.href=s,E.download=r,E.style.display="none",E.rel="noopener",document.body.appendChild(E),E.click(),document.body.removeChild(E),URL.revokeObjectURL(s)}catch(i){throw console.error("Failed to download file:",i),Error("File download failed: "+(i instanceof Error?i.message:"Unknown error"))}}we(){return new Date().toISOString().slice(0,19).replace(/:/g,"-")}fe(){const e=new Date;return{date:e.toISOString().split("T")[0],time:e.toTimeString().split(" ")[0].replace(/:/g,"-")}}de(e){return e.replace(/[<>:"/\\|?*]/g,"_").replace(/\s+/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").substring(0,255)}me(){return"'textmode-export'-"+this.we()}}class CA extends H{pe(e,r,B){const i=e[B]===255,s=e[B+1]===255,E=e[B+2]===255,Q=r[B],n=r[B+1];return{isInverted:i,flipHorizontal:s,flipVertical:E,rotation:Math.round(360*(Q+n/255)/255*100)/100}}_e(e,r,B){return{x:e,y:r,cellX:e*B.cellWidth,cellY:r*B.cellHeight}}ve(e,r){const B=[];let i=0;for(let s=0;s<r.rows;s++)for(let E=0;E<r.cols;E++){const Q=4*i,n=this.ce(e.characterPixels,Q);let a=this.ue(e.primaryColorPixels,Q),h=this.ue(e.secondaryColorPixels,Q);const l=this.pe(e.transformPixels,e.rotationPixels,Q);if(l.isInverted){const P=a;a=h,h=P}const c=this._e(E,s,r);B.push({charIndex:n,primaryColor:a,secondaryColor:h,transform:l,position:c}),i++}return B}}class DA{tt(e,r){const B=e.cmap;for(const i of B.tables)if(i.format===4){for(let s=0;s<i.startCount.length;s++)if(r>=i.startCount[s]&&r<=i.endCount[s]){if(i.idRangeOffset[s]===0)return r+i.idDelta[s]&65535;{const E=i.idRangeOffset[s]/2+(r-i.startCount[s])-(i.startCount.length-s);if(E>=0&&E<i.glyphIdArray.length){const Q=i.glyphIdArray[E];if(Q!==0)return Q+i.idDelta[s]&65535}}}}return 0}be(e,r,B,i,s){const E=s/e.head.unitsPerEm;return{getBoundingBox:()=>({x1:B+r.xMin*E,y1:i+-r.yMax*E,x2:B+r.xMax*E,y2:i+-r.yMin*E}),toSVG:()=>this.xe(r,B,i,E)}}xe(e,r,B,i){if(!e||!e.xs)return"";const{xs:s,ys:E,endPts:Q,flags:n}=e;if(!(s&&E&&Q&&n))return"";let a="",h=0;for(let l=0;l<Q.length;l++){const c=Q[l];if(!(c<h)){if(c>=h){const P=r+s[h]*i,d=B-E[h]*i;a+=`M${P.toFixed(2)},${d.toFixed(2)}`;let D=h+1;for(;D<=c;)if(1&n[D]){const w=r+s[D]*i,p=B-E[D]*i;a+=`L${w.toFixed(2)},${p.toFixed(2)}`,D++}else{const w=r+s[D]*i,p=B-E[D]*i;let m=D+1>c?h:D+1;if(1&n[m]){const y=r+s[m]*i,_=B-E[m]*i;a+=`Q${w.toFixed(2)},${p.toFixed(2)} ${y.toFixed(2)},${_.toFixed(2)}`,D=m+1}else{const y=(w+(r+s[m]*i))/2,_=(p+(B-E[m]*i))/2;a+=`Q${w.toFixed(2)},${p.toFixed(2)} ${y.toFixed(2)},${_.toFixed(2)}`,D=m}}a+="Z"}h=c+1}}return a}ye(e,r,B,i,s){const E=e.codePointAt(0)||0,Q=this.tt(r,E);let n=null;return r.glyf&&r.glyf[Q]!==null?n=r.glyf[Q]:C&&C.T&&C.T.glyf&&C.T.glyf.VA&&(n=C.T.glyf.VA(r,Q),r.glyf&&n&&(r.glyf[Q]=n)),this.be(r,n,B,i,s)}Me(e,r,B,i,s,E,Q,n){const a=B+(s-n*(Q/r.head.unitsPerEm))/2,h=i+(E+.7*Q)/2;return this.ye(e,r,a,h,Q).toSVG()||null}}class uA{constructor(){g(this,"Ge");this.Ge=new DA}Fe(e){return`<?xml version="1.0" encoding="UTF-8" standalone="no"?>
47
47
  <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
48
48
  <svg width="${e.width}" height="${e.height}" viewBox="0 0 ${e.width} ${e.height}"
49
49
  xmlns="http://www.w3.org/2000/svg" version="1.1">
@@ -61,4 +61,4 @@ void main() {\r
61
61
  <g id="ascii-cells">`;for(const E of e)s+=this.Ue(E,r,B,i);return s+=this.Ye(),s}Ve(e){return e.replace(/<path[^>]*d=""[^>]*\/>/g,"").replace(/\n\s*\n/g,`
62
62
  `).replace(/[ \t]+$/gm,"")}}class PA extends ${Re(e){return this.Pe(e,"image/svg+xml;charset=utf-8")}He(e,r){this.Ie(e,this.de(r)+".svg","image/svg+xml;charset=utf-8")}ze(e,r){this.He(e,r||this.me())}}class tA{constructor(){g(this,"Je");g(this,"Le");g(this,"Ke");this.Je=new CA,this.Le=new uA,this.Ke=new PA}We(e){return{includeBackgroundRectangles:e.includeBackgroundRectangles??!0,drawMode:e.drawMode??"fill",strokeWidth:e.strokeWidth??1,backgroundColor:e.backgroundColor??[0,0,0,0]}}je(e,r={}){const B=this.We(r),i=this.Je.Ce(e.pipeline),s=this.Je.ve(i,e.grid),E=this.Le.ke(s,e.grid,e.font,B);return this.Le.Ve(E)}ze(e,r={}){const B=this.je(e,r),i=r.filename||this.Ke.me();this.Ke.ze(B,i)}}class IA extends H{Ze(e,r,B,i=" "){var Q;const s=[];let E=0;for(let n=0;n<r.rows;n++){const a=[];for(let h=0;h<r.cols;h++){const l=4*E,c=this.ce(e.characterPixels,l),P=((Q=B.characters[c])==null?void 0:Q.character)||i;a.push(P),E++}s.push(a)}return s}}class dA{Ne(e,r){const B=[];for(const s of e){let E=s.join("");r.preserveTrailingSpaces||(E=E.replace(/\s+$/,"")),B.push(E)}const i=r.lineEnding==="crlf"?`\r
63
63
  `:`
64
- `;return B.join(i)}}class fA extends ${Xe(e,r){const B=this.qe(r);this.Ie(e,B,"text/plain;charset=utf-8")}qe(e){let r=this.de(e);return r===".txt"||r.length<=4?this.me():r}}class eA{constructor(){g(this,"Je");g(this,"Le");g(this,"Ke");this.Je=new IA,this.Le=new dA,this.Ke=new fA}We(e){return{preserveTrailingSpaces:e.preserveTrailingSpaces??!1,lineEnding:e.lineEnding??"lf",emptyCharacter:e.emptyCharacter??" "}}AB(e,r={}){const B=this.We(r),i=this.Je.Ce(e.pipeline),s=this.Je.Ze(i,e.grid,e.font,B.emptyCharacter);return this.Le.Ne(s,B)}Xe(e,r={}){const B=this.AB(e,r),i=r.filename||this.Ke.me();this.Ke.Xe(B,i)}}class wA extends H{tB(e,r=1,B="transparent"){const i=e.canvas;if(r===1&&B==="transparent")return i;const s=document.createElement("canvas"),E=s.getContext("2d"),Q=Math.round(i.width*r),n=Math.round(i.height*r);return s.width=Q,s.height=n,B!=="transparent"&&(E.fillStyle=B,E.fillRect(0,0,Q,n)),E.imageSmoothingEnabled=!1,E.drawImage(i,0,0,i.width,i.height,0,0,Q,n),s}}class mA{eB(e,r){const B=this.BB(r.format);return r.format==="png"?e.toDataURL(B):e.toDataURL(B,r.quality)}async QB(e,r){return new Promise((B,i)=>{const s=this.BB(r.format),E=Q=>{Q?B(Q):i(Error(`Failed to generate ${r.format.toUpperCase()} blob`))};r.format==="png"?e.toBlob(E,s):e.toBlob(E,s,r.quality)})}BB(e){switch(e){case"png":return"image/png";case"jpg":return"image/jpeg";case"webp":return"image/webp";default:throw Error("Unsupported image format: "+e)}}}const pA={png:"image/png",jpg:"image/jpeg",webp:"image/webp"},rA={png:".png",jpg:".jpg",webp:".webp"};class xA extends ${sB(e,r,B){this.rB(e,this.de(r)+rA[B])}rB(e,r){const B=URL.createObjectURL(e);try{const i=document.createElement("a");i.href=B,i.download=r,i.style.display="none",i.rel="noopener",document.body.appendChild(i),i.click(),document.body.removeChild(i)}finally{URL.revokeObjectURL(B)}}iB(e){return e in pA&&e in rA}}class bA{constructor(){g(this,"Je");g(this,"Le");g(this,"Ke");this.Je=new wA,this.Le=new mA,this.Ke=new xA}We(e){return{format:e.format??"png",quality:e.quality??1,scale:e.scale??1,backgroundColor:e.backgroundColor??"transparent"}}EB(e){if(console.log("Validating image export options:",e),!this.Ke.iB(e.format))throw Error(`Saving '${e.format}' files is not supported`);if(e.quality<0||e.quality>1)throw Error("Image quality must be between 0.0 and 1.0");if(e.scale<=0)throw Error("Scale factor must be greater than 0");e.scale>10&&console.warn("Large scale factors may result in very large files and slow performance"),e.format==="jpg"&&e.backgroundColor==="transparent"&&(e.backgroundColor="black")}gB(e,r={}){const B=this.We(r);if(this.EB(B),B.scale===1&&B.backgroundColor==="transparent")return this.Le.eB(e.canvas,B);const i=this.Je.tB(e,B.scale,B.backgroundColor);return this.Le.eB(i,B)}async QB(e,r={}){const B=this.We(r);if(this.EB(B),B.scale===1&&B.backgroundColor==="transparent")return await this.Le.QB(e.canvas,B);const i=this.Je.tB(e,B.scale,B.backgroundColor);return await this.Le.QB(i,B)}async sB(e,r={}){const B=await this.QB(e,r),i=r.format??"png",s=r.filename||this.Ke.me();this.Ke.sB(B,s,i)}}const vA=o=>class extends o{toString(e={}){return new eA().AB(this,e)}saveStrings(e={}){new eA().Xe(this,e)}toSVG(e={}){return new tA().je(this,e)}saveSVG(e={}){new tA().ze(this,e)}async saveCanvas(e,r="png",B={}){await new bA().sB(this.bt,{...B,filename:e,format:r})}},yA=o=>class extends o{async loadFont(e){return this.et.It(e).then(()=>{const r=this.et.maxGlyphDimensions;this.zt.Gt(r.width,r.height),this.oB.$t()})}fontSize(e){if(!f.C(typeof e=="number"&&e>0,"Font size must be a positive number greater than 0.",{method:"fontSize",providedValue:e})||this.et.fontSize===e)return;this.et.Pt(e);const r=this.et.maxGlyphDimensions;this.zt.Gt(r.width,r.height),this.oB.$t(),this.WA.UA()}},_A=o=>class extends o{addConverter(e){return this.oB.add(e)}removeConverter(e){this.oB.remove(e)}};class TA{constructor(){g(this,"WA");g(this,"et");g(this,"oB");g(this,"bt");g(this,"zt")}}class J extends function(r,...B){return B.reduce((i,s)=>s(i),r)}(TA,cA,vA,yA,_A){constructor(r=null,B={}){super();g(this,"St");g(this,"nB");g(this,"Ut");g(this,"aB");g(this,"hB");g(this,"DB",null);g(this,"lB",0);g(this,"CB");g(this,"cB",!0);g(this,"uB",0);g(this,"PB",0);g(this,"IB",0);g(this,"wB",[]);g(this,"fB",10);g(this,"dB",!1);g(this,"mB",!1);g(this,"pB",()=>{});g(this,"_B",()=>{});g(this,"vB");this.St=r,this.mB=r===null,this.aB=B.renderMode??"auto",this.hB=B.frameRate??60,this.CB=1e3/this.hB}static async create(r=null,B={}){const i=new this(r,B),s=i.mB?B:void 0;let E,Q;i.bt=new q(i.captureSource,i.mB,s),i.WA=new EA(i.bt.Rt()),i.mB?(E=B.width||800,Q=B.height||600):(E=i.bt.width||800,Q=i.bt.height||600),i.nB=i.WA.TA(E,Q),i.et=new j(i.WA,B.fontSize??16),await i.et.Ct(B.fontSource);const n=i.et.maxGlyphDimensions;return i.zt=new Z(i.bt.canvas,n.width,n.height),i.oB=new AA(i.WA,i.et,i.zt),i.bB(),i.xB(),i}bB(){this.vB=()=>{this.mB?this._B():this.yB()},window.addEventListener("resize",this.vB),window.ResizeObserver&&this.St&&!this.mB&&(this.Ut=new ResizeObserver(()=>{this.yB()}),this.Ut.observe(this.St))}render(){this.MB(),this.IB++,this.dB?console.warn("Cannot render: Required resources have been disposed"):(this.mB?(this.nB.begin(),this.pB(),this.nB.end()):this.nB.update(this.St),this.oB.hasEnabledConverters()?(this.oB.le(this.nB),this.WA.SA(0),this.WA.kA(this.oB.texture,this.zt.offsetX,this.zt.offsetY,this.oB.texture.width,this.oB.texture.height)):(this.WA.OA(),this.WA.kA(this.nB,this.zt.offsetX,this.zt.offsetY,this.nB.width,this.nB.height)))}yB(){this.bt.$t(),this.nB.resize(this.bt.width,this.bt.height),this.zt.$t(),this.oB.$t(),this.WA.UA(),this.aB!=="manual"&&this.render()}xB(){if(this.aB!=="auto"||!this.cB)return;this.lB=performance.now();const r=B=>{if(!this.cB)return void(this.DB=null);const i=B-this.lB;i>=this.CB&&(this.render(),this.lB=B-i%this.CB),this.cB&&(this.DB=requestAnimationFrame(r))};this.DB=requestAnimationFrame(r)}MB(){const r=performance.now();if(this.PB>0){const B=r-this.PB;this.wB.push(B),this.wB.length>this.fB&&this.wB.shift();const i=this.wB.reduce((s,E)=>s+E,0)/this.wB.length;this.uB=1e3/i}this.PB=r}GB(){this.DB&&(cancelAnimationFrame(this.DB),this.DB=null)}renderMode(r){this.aB!==r&&(this.GB(),this.aB=r,r==="auto"&&this.cB&&this.xB())}frameRate(r){if(r===void 0)return this.uB;this.hB=r,this.CB=1e3/r,this.aB==="auto"&&this.cB&&(this.GB(),this.xB())}noLoop(){this.cB&&(this.cB=!1,this.DB&&(cancelAnimationFrame(this.DB),this.DB=null))}loop(){this.cB||(this.cB=!0,this.aB==="auto"&&this.xB())}redraw(r=1){if(f.C(typeof r=="number"&&r>0&&Number.isInteger(r),"Redraw count must be a positive integer.",{method:"redraw",providedValue:r}))for(let B=0;B<r;B++)this.render()}isLooping(){return this.aB==="auto"&&this.cB}draw(r){this.pB=r}windowResized(r){this._B=r}resizeCanvas(r,B){this.bt.$t(r,B),this.nB.resize(this.bt.width,this.bt.height),this.zt.$t(),this.oB.$t(),this.WA.UA(),this.aB!=="manual"&&this.render()}destroy(){this.dB||(this.GB(),window.removeEventListener("resize",this.vB),this.Ut&&this.Ut.disconnect(),this.oB.S(),this.et.S(),this.nB.S(),this.WA.S(),this.dB=!0)}get grid(){return this.zt}get font(){return this.et}get mode(){return this.aB}get pipeline(){return this.oB}get frameCount(){return this.IB}set frameCount(r){this.IB=r}get width(){return this.bt.width}get height(){return this.bt.height}get canvas(){return this.bt}get isDisposed(){return this.dB}}class Y{static async create(e,r={}){if(e instanceof HTMLCanvasElement||e instanceof HTMLVideoElement)return J.create(e,r);{const B=e||{};return J.create(null,B)}}static setErrorLevel(e){f.u(e)}static get version(){return"0.1.7"}}const GA=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"})),MA=Y.create,RA=Y.setErrorLevel,FA=Y.version;I.TextmodeCanvas=q,I.TextmodeConversionPipeline=AA,I.TextmodeErrorLevel=b,I.TextmodeFont=j,I.TextmodeGrid=Z,I.Textmodifier=J,I.converters=lA,I.create=MA,I.export=GA,I.setErrorLevel=RA,I.textmode=Y,I.version=FA,Object.defineProperty(I,Symbol.toStringTag,{value:"Module"})},typeof exports=="object"&&typeof module<"u"?t(exports):typeof define=="function"&&define.amd?define(["exports"],t):t((A=typeof globalThis<"u"?globalThis:A||self).textmode={});
64
+ `;return B.join(i)}}class fA extends ${Xe(e,r){const B=this.qe(r);this.Ie(e,B,"text/plain;charset=utf-8")}qe(e){let r=this.de(e);return r===".txt"||r.length<=4?this.me():r}}class eA{constructor(){g(this,"Je");g(this,"Le");g(this,"Ke");this.Je=new IA,this.Le=new dA,this.Ke=new fA}We(e){return{preserveTrailingSpaces:e.preserveTrailingSpaces??!1,lineEnding:e.lineEnding??"lf",emptyCharacter:e.emptyCharacter??" "}}AB(e,r={}){const B=this.We(r),i=this.Je.Ce(e.pipeline),s=this.Je.Ze(i,e.grid,e.font,B.emptyCharacter);return this.Le.Ne(s,B)}Xe(e,r={}){const B=this.AB(e,r),i=r.filename||this.Ke.me();this.Ke.Xe(B,i)}}class wA extends H{tB(e,r=1,B="transparent"){const i=e.canvas;if(r===1&&B==="transparent")return i;const s=document.createElement("canvas"),E=s.getContext("2d"),Q=Math.round(i.width*r),n=Math.round(i.height*r);return s.width=Q,s.height=n,B!=="transparent"&&(E.fillStyle=B,E.fillRect(0,0,Q,n)),E.imageSmoothingEnabled=!1,E.drawImage(i,0,0,i.width,i.height,0,0,Q,n),s}}class mA{eB(e,r){const B=this.BB(r.format);return r.format==="png"?e.toDataURL(B):e.toDataURL(B,r.quality)}async QB(e,r){return new Promise((B,i)=>{const s=this.BB(r.format),E=Q=>{Q?B(Q):i(Error(`Failed to generate ${r.format.toUpperCase()} blob`))};r.format==="png"?e.toBlob(E,s):e.toBlob(E,s,r.quality)})}BB(e){switch(e){case"png":return"image/png";case"jpg":return"image/jpeg";case"webp":return"image/webp";default:throw Error("Unsupported image format: "+e)}}}const pA={png:"image/png",jpg:"image/jpeg",webp:"image/webp"},rA={png:".png",jpg:".jpg",webp:".webp"};class xA extends ${sB(e,r,B){this.rB(e,this.de(r)+rA[B])}rB(e,r){const B=URL.createObjectURL(e);try{const i=document.createElement("a");i.href=B,i.download=r,i.style.display="none",i.rel="noopener",document.body.appendChild(i),i.click(),document.body.removeChild(i)}finally{URL.revokeObjectURL(B)}}iB(e){return e in pA&&e in rA}}class bA{constructor(){g(this,"Je");g(this,"Le");g(this,"Ke");this.Je=new wA,this.Le=new mA,this.Ke=new xA}We(e){return{format:e.format??"png",quality:e.quality??1,scale:e.scale??1,backgroundColor:e.backgroundColor??"transparent"}}EB(e){if(console.log("Validating image export options:",e),!this.Ke.iB(e.format))throw Error(`Saving '${e.format}' files is not supported`);if(e.quality<0||e.quality>1)throw Error("Image quality must be between 0.0 and 1.0");if(e.scale<=0)throw Error("Scale factor must be greater than 0");e.scale>10&&console.warn("Large scale factors may result in very large files and slow performance"),e.format==="jpg"&&e.backgroundColor==="transparent"&&(e.backgroundColor="black")}gB(e,r={}){const B=this.We(r);if(this.EB(B),B.scale===1&&B.backgroundColor==="transparent")return this.Le.eB(e.canvas,B);const i=this.Je.tB(e,B.scale,B.backgroundColor);return this.Le.eB(i,B)}async QB(e,r={}){const B=this.We(r);if(this.EB(B),B.scale===1&&B.backgroundColor==="transparent")return await this.Le.QB(e.canvas,B);const i=this.Je.tB(e,B.scale,B.backgroundColor);return await this.Le.QB(i,B)}async sB(e,r={}){const B=await this.QB(e,r),i=r.format??"png",s=r.filename||this.Ke.me();this.Ke.sB(B,s,i)}}const vA=o=>class extends o{toString(e={}){return new eA().AB({pipeline:this.oB,grid:this.zt,font:this.et},e)}saveStrings(e={}){new eA().Xe({pipeline:this.oB,grid:this.zt,font:this.et},e)}toSVG(e={}){return new tA().je(this,e)}saveSVG(e={}){new tA().ze(this,e)}async saveCanvas(e,r="png",B={}){await new bA().sB(this.bt,{...B,filename:e,format:r})}},yA=o=>class extends o{async loadFont(e){return this.et.It(e).then(()=>{const r=this.et.maxGlyphDimensions;this.zt.Gt(r.width,r.height),this.oB.$t()})}fontSize(e){if(!f.C(typeof e=="number"&&e>0,"Font size must be a positive number greater than 0.",{method:"fontSize",providedValue:e})||this.et.fontSize===e)return;this.et.Pt(e);const r=this.et.maxGlyphDimensions;this.zt.Gt(r.width,r.height),this.oB.$t(),this.WA.UA()}},_A=o=>class extends o{addConverter(e){return this.oB.add(e)}removeConverter(e){this.oB.remove(e)}};class TA{constructor(){g(this,"WA");g(this,"et");g(this,"oB");g(this,"bt");g(this,"zt")}}class J extends function(r,...B){return B.reduce((i,s)=>s(i),r)}(TA,cA,vA,yA,_A){constructor(r=null,B={}){super();g(this,"St");g(this,"nB");g(this,"Ut");g(this,"aB");g(this,"hB");g(this,"DB",null);g(this,"lB",0);g(this,"CB");g(this,"cB",!0);g(this,"uB",0);g(this,"PB",0);g(this,"IB",0);g(this,"wB",[]);g(this,"fB",10);g(this,"dB",!1);g(this,"mB",!1);g(this,"pB",()=>{});g(this,"_B",()=>{});g(this,"vB");this.St=r,this.mB=r===null,this.aB=B.renderMode??"auto",this.hB=B.frameRate??60,this.CB=1e3/this.hB}static async create(r=null,B={}){const i=new this(r,B),s=i.mB?B:void 0;let E,Q;i.bt=new q(i.captureSource,i.mB,s),i.WA=new EA(i.bt.Rt()),i.mB?(E=B.width||800,Q=B.height||600):(E=i.bt.width||800,Q=i.bt.height||600),i.nB=i.WA.TA(E,Q),i.et=new j(i.WA,B.fontSize??16),await i.et.Ct(B.fontSource);const n=i.et.maxGlyphDimensions;return i.zt=new Z(i.bt.canvas,n.width,n.height),i.oB=new AA(i.WA,i.et,i.zt),i.bB(),i.xB(),i}bB(){this.vB=()=>{this.mB?this._B():this.yB()},window.addEventListener("resize",this.vB),window.ResizeObserver&&this.St&&!this.mB&&(this.Ut=new ResizeObserver(()=>{this.yB()}),this.Ut.observe(this.St))}render(){this.MB(),this.IB++,this.dB?console.warn("Cannot render: Required resources have been disposed"):(this.mB?(this.nB.begin(),this.pB(),this.nB.end()):this.nB.update(this.St),this.oB.hasEnabledConverters()?(this.oB.le(this.nB),this.WA.SA(0),this.WA.kA(this.oB.texture,this.zt.offsetX,this.zt.offsetY,this.oB.texture.width,this.oB.texture.height)):(this.WA.OA(),this.WA.kA(this.nB,this.zt.offsetX,this.zt.offsetY,this.nB.width,this.nB.height)))}yB(){this.bt.$t(),this.nB.resize(this.bt.width,this.bt.height),this.zt.$t(),this.oB.$t(),this.WA.UA(),this.aB!=="manual"&&this.render()}xB(){if(this.aB!=="auto"||!this.cB)return;this.lB=performance.now();const r=B=>{if(!this.cB)return void(this.DB=null);const i=B-this.lB;i>=this.CB&&(this.render(),this.lB=B-i%this.CB),this.cB&&(this.DB=requestAnimationFrame(r))};this.DB=requestAnimationFrame(r)}MB(){const r=performance.now();if(this.PB>0){const B=r-this.PB;this.wB.push(B),this.wB.length>this.fB&&this.wB.shift();const i=this.wB.reduce((s,E)=>s+E,0)/this.wB.length;this.uB=1e3/i}this.PB=r}GB(){this.DB&&(cancelAnimationFrame(this.DB),this.DB=null)}renderMode(r){this.aB!==r&&(this.GB(),this.aB=r,r==="auto"&&this.cB&&this.xB())}frameRate(r){if(r===void 0)return this.uB;this.hB=r,this.CB=1e3/r,this.aB==="auto"&&this.cB&&(this.GB(),this.xB())}noLoop(){this.cB&&(this.cB=!1,this.DB&&(cancelAnimationFrame(this.DB),this.DB=null))}loop(){this.cB||(this.cB=!0,this.aB==="auto"&&this.xB())}redraw(r=1){if(f.C(typeof r=="number"&&r>0&&Number.isInteger(r),"Redraw count must be a positive integer.",{method:"redraw",providedValue:r}))for(let B=0;B<r;B++)this.render()}isLooping(){return this.aB==="auto"&&this.cB}draw(r){this.pB=r}windowResized(r){this._B=r}resizeCanvas(r,B){this.bt.$t(r,B),this.nB.resize(this.bt.width,this.bt.height),this.zt.$t(),this.oB.$t(),this.WA.UA(),this.aB!=="manual"&&this.render()}destroy(){this.dB||(this.GB(),window.removeEventListener("resize",this.vB),this.Ut&&this.Ut.disconnect(),this.oB.S(),this.et.S(),this.nB.S(),this.WA.S(),this.dB=!0)}get grid(){return this.zt}get font(){return this.et}get mode(){return this.aB}get pipeline(){return this.oB}get frameCount(){return this.IB}set frameCount(r){this.IB=r}get width(){return this.bt.width}get height(){return this.bt.height}get canvas(){return this.bt}get isDisposed(){return this.dB}}class Y{static async create(e,r={}){if(e instanceof HTMLCanvasElement||e instanceof HTMLVideoElement)return J.create(e,r);{const B=e||{};return J.create(null,B)}}static setErrorLevel(e){f.u(e)}static get version(){return"0.1.7"}}const GA=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"})),MA=Y.create,RA=Y.setErrorLevel,FA=Y.version;I.TextmodeCanvas=q,I.TextmodeConversionPipeline=AA,I.TextmodeErrorLevel=b,I.TextmodeFont=j,I.TextmodeGrid=Z,I.Textmodifier=J,I.converters=lA,I.create=MA,I.export=GA,I.setErrorLevel=RA,I.textmode=Y,I.version=FA,Object.defineProperty(I,Symbol.toStringTag,{value:"Module"})},typeof exports=="object"&&typeof module<"u"?t(exports):typeof define=="function"&&define.amd?define(["exports"],t):t((A=typeof globalThis<"u"?globalThis:A||self).textmode={});
@@ -4,7 +4,7 @@ var Bt=Object.defineProperty;var kt=(C,x,R)=>x in C?Bt(C,x,{enumerable:!0,config
4
4
  - ${o}: ${x.o(n)}`}return i+=`
5
5
 
6
6
  `,i+="↓".repeat(24)+`
7
- `,i}static o(r){if(r===null)return"null";if(r===void 0)return"undefined";if(typeof r=="string")return`"${r}"`;if(typeof r=="number"||typeof r=="boolean")return r+"";if(Array.isArray(r))return r.length===0?"[]":r.length<=5?`[${r.map(s=>x.o(s)).join(", ")}]`:`[${r.slice(0,3).map(s=>x.o(s)).join(", ")}, ... +${r.length-3} more]`;if(typeof r=="object"){const s=Object.keys(r);return s.length===0?"{}":s.length<=3?`{ ${s.map(i=>`${i}: ${x.o(r[i])}`).join(", ")} }`:`{ ${s.slice(0,2).map(i=>`${i}: ${x.o(r[i])}`).join(", ")}, ... +${s.length-2} more }`}return r+""}}var R=(l=>(l[l.SILENT=0]="SILENT",l[l.WARNING=1]="WARNING",l[l.ERROR=2]="ERROR",l[l.THROW=3]="THROW",l))(R||{});const M=class M{constructor(){c(this,"l",{globalLevel:3})}static u(){return M.h||(M.h=new M),M.h}m(r,s){const i="%c[textmode.js] Oops! (╯°□°)╯︵ Something went wrong in your code.",o="color: #f44336; font-weight: bold; background: #ffebee; padding: 2px 6px; border-radius: 3px;";switch(this.l.globalLevel){case 0:return!1;case 1:return console.group(i,o),console.warn(x.i(r,s)),console.groupEnd(),!1;case 2:return console.group(i,o),console.error(x.i(r,s)),console.groupEnd(),!1;default:throw new x(r,s)}}p(r,s,i){return!!r||(this.m(s,i),!1)}_(r){this.l.globalLevel=r}};c(M,"h",null);let O=M;const y=O.u(),X=new WeakMap;function B(l,r){X.set(l,r)}function W(l){return X.get(l)}class H{constructor(r,s,i=s,o={}){c(this,"v");c(this,"C");c(this,"$");c(this,"F");c(this,"D");c(this,"l");c(this,"M",null);c(this,"S",null);this.v=r,this.F=s,this.D=i,this.l={filter:"nearest",wrap:"clamp",format:"rgba",type:"unsigned_byte",...o},this.$=this.R(),this.C=r.createFramebuffer(),this.V()}k(r){const{v:s}=this,i=s.getParameter(s.FRAMEBUFFER_BINDING);s.bindFramebuffer(s.FRAMEBUFFER,this.C);try{return r()}finally{s.bindFramebuffer(s.FRAMEBUFFER,i)}}R(){const{v:r}=this,s=r.createTexture();r.bindTexture(r.TEXTURE_2D,s);const i=this.l.filter==="linear"?r.LINEAR:r.NEAREST,o=this.l.wrap==="repeat"?r.REPEAT:r.CLAMP_TO_EDGE;return r.texParameteri(r.TEXTURE_2D,r.TEXTURE_MIN_FILTER,i),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_MAG_FILTER,i),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_WRAP_S,o),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_WRAP_T,o),this.I(),s}I(){const{v:r}=this,s=this.l.type==="float"?r.FLOAT:r.UNSIGNED_BYTE;r.texImage2D(r.TEXTURE_2D,0,r.RGBA,this.F,this.D,0,r.RGBA,s,null)}V(){const{v:r}=this;r.bindFramebuffer(r.FRAMEBUFFER,this.C),r.framebufferTexture2D(r.FRAMEBUFFER,r.COLOR_ATTACHMENT0,r.TEXTURE_2D,this.$,0),r.bindFramebuffer(r.FRAMEBUFFER,null)}update(r){const{v:s}=this;s.bindTexture(s.TEXTURE_2D,this.$),s.pixelStorei(s.UNPACK_FLIP_Y_WEBGL,1),s.texImage2D(s.TEXTURE_2D,0,s.RGBA,s.RGBA,s.UNSIGNED_BYTE,r),s.bindTexture(s.TEXTURE_2D,null)}updatePixels(r,s,i){const{v:o}=this;o.bindTexture(o.TEXTURE_2D,this.$),o.texImage2D(o.TEXTURE_2D,0,o.RGBA,s,i,0,o.RGBA,o.UNSIGNED_BYTE,r),o.bindTexture(o.TEXTURE_2D,null)}resize(r,s){const{v:i}=this;this.F=r,this.D=s,this.S=null,i.bindTexture(i.TEXTURE_2D,this.$),this.I(),i.bindTexture(i.TEXTURE_2D,null)}begin(){const{v:r}=this;this.M={framebuffer:r.getParameter(r.FRAMEBUFFER_BINDING),viewport:r.getParameter(r.VIEWPORT)},r.bindFramebuffer(r.FRAMEBUFFER,this.C),r.viewport(0,0,this.F,this.D),B(r,[0,0,this.F,this.D])}end(){if(!this.M)return;const{v:r}=this;r.bindFramebuffer(r.FRAMEBUFFER,this.M.framebuffer),r.viewport(...this.M.viewport),B(r,this.M.viewport),this.M=null}loadPixels(){const{v:r}=this;this.S||(this.S=new Uint8Array(this.F*this.D*4)),this.k(()=>{r.readPixels(0,0,this.F,this.D,r.RGBA,r.UNSIGNED_BYTE,this.S)})}get(r,s,i,o){const{v:n}=this;if(r===void 0&&s===void 0){const a=new Uint8Array(this.F*this.D*4);return this.k(()=>(n.readPixels(0,0,this.F,this.D,n.RGBA,n.UNSIGNED_BYTE,a),a))}if(i===void 0&&o===void 0){(r<0||s<0||r>=this.F||s>=this.D)&&(console.warn("The x and y values passed to Framebuffer.get are outside of its range and will be clamped."),r=Math.max(0,Math.min(r,this.F-1)),s=Math.max(0,Math.min(s,this.D-1)));const a=new Uint8Array(4);return this.k(()=>(n.readPixels(r,s,1,1,n.RGBA,n.UNSIGNED_BYTE,a),[a[0],a[1],a[2],a[3]]))}{r=Math.max(0,Math.min(r,this.F-1)),s=Math.max(0,Math.min(s,this.D-1)),i=Math.max(1,Math.min(i,this.F-r)),o=Math.max(1,Math.min(o,this.D-s));const a=new Uint8Array(i*o*4);return this.k(()=>(n.readPixels(r,s,i,o,n.RGBA,n.UNSIGNED_BYTE,a),a))}}P(){this.C&&this.v.deleteFramebuffer(this.C),this.$&&this.v.deleteTexture(this.$)}get framebuffer(){return this.C}get texture(){return this.$}get width(){return this.F}get height(){return this.D}get pixels(){return this.S}}class P{constructor(r,s,i){c(this,"v");c(this,"U");c(this,"A",new Map);c(this,"G",new Map);c(this,"L",0);c(this,"O");this.v=r,this.U=this.H(s,i),this.O=r.getParameter(r.MAX_TEXTURE_IMAGE_UNITS),this.j()}j(){const r=this.v.getProgramParameter(this.U,this.v.ACTIVE_UNIFORMS);for(let s=0;s<r;s++){const i=this.v.getActiveUniform(this.U,s);if(i){const o=this.v.getUniformLocation(this.U,i.name);o&&(this.A.set(i.name,o),this.G.set(i.name,i.type))}}}H(r,s){const i=this.W(this.v.VERTEX_SHADER,r),o=this.W(this.v.FRAGMENT_SHADER,s),n=this.v.createProgram();if(this.v.attachShader(n,i),this.v.attachShader(n,o),this.v.linkProgram(n),!this.v.getProgramParameter(n,this.v.LINK_STATUS)){const a=this.v.getProgramInfoLog(n);throw Error("Shader program link error: "+a)}return this.v.deleteShader(i),this.v.deleteShader(o),n}W(r,s){const i=this.v.createShader(r);if(this.v.shaderSource(i,s),this.v.compileShader(i),!this.v.getShaderParameter(i,this.v.COMPILE_STATUS)){const o=this.v.getShaderInfoLog(i);throw this.v.deleteShader(i),Error("Shader compilation error: "+o)}return i}N(){this.v.useProgram(this.U),this.X()}setUniform(r,s){const i=this.A.get(r);if(i)if(typeof s=="number")this.q(r)?this.v.uniform1i(i,Math.floor(s)):this.v.uniform1f(i,s);else if(typeof s=="boolean")this.v.uniform1i(i,s?1:0);else if(Array.isArray(s))switch(s.length){case 2:this.v.uniform2f(i,s[0],s[1]);break;case 3:this.v.uniform3f(i,s[0],s[1],s[2]);break;case 4:this.v.uniform4f(i,s[0],s[1],s[2],s[3]);break;default:console.warn(`Unsupported array length ${s.length} for uniform '${r}'`)}else if(s instanceof WebGLTexture){const o=this.Y();this.v.uniform1i(i,o),this.v.activeTexture(this.v.TEXTURE0+o),this.v.bindTexture(this.v.TEXTURE_2D,s)}else if(s instanceof H){const o=this.Y();this.v.uniform1i(i,o),this.v.activeTexture(this.v.TEXTURE0+o),this.v.bindTexture(this.v.TEXTURE_2D,s.texture)}else console.warn(`Unsupported uniform type for '${r}':`,typeof s)}Y(){return this.L>=this.O&&console.warn(`Exceeded maximum texture units (${this.O}). Texture may not render correctly.`),this.L++}q(r){const s=this.G.get(r);return!!s&&(s===this.v.INT||s===this.v.INT_VEC2||s===this.v.INT_VEC3||s===this.v.INT_VEC4||s===this.v.SAMPLER_2D||s===this.v.SAMPLER_CUBE)}get glProgram(){return this.U}P(){this.v.deleteProgram(this.U)}X(){this.L=0}}class q{constructor(r){c(this,"v");c(this,"Z",null);c(this,"J",16);c(this,"K",new Map);this.v=r}tt(){if(this.Z)return;const r=this.v;this.Z=r.createBuffer(),r.bindBuffer(r.ARRAY_BUFFER,this.Z)}et(){const r=this.v,s=r.getParameter(r.CURRENT_PROGRAM);let i=this.K.get(s);return i||(i={a_position:r.getAttribLocation(s,"a_position"),a_texCoord:r.getAttribLocation(s,"a_texCoord")},this.K.set(s,i)),r.enableVertexAttribArray(i.a_position),r.vertexAttribPointer(i.a_position,2,r.FLOAT,!1,this.J,0),r.enableVertexAttribArray(i.a_texCoord),r.vertexAttribPointer(i.a_texCoord,2,r.FLOAT,!1,this.J,8),{positionLoc:i.a_position,texLoc:i.a_texCoord}}rt(r,s){const i=this.v;i.disableVertexAttribArray(r),i.disableVertexAttribArray(s)}st(r,s){const i=this.v,o=W(i)||[0,0,i.canvas.width,i.canvas.height];return{nx:r/o[2]*2-1,ny:1-s/o[3]*2}}it(r,s,i,o){const n=this.v;this.tt(),n.bindBuffer(n.ARRAY_BUFFER,this.Z);const a=new Float32Array([r,o,0,0,i,o,1,0,r,s,0,1,r,s,0,1,i,o,1,0,i,s,1,1]);n.bufferData(n.ARRAY_BUFFER,a,n.DYNAMIC_DRAW)}P(){this.Z&&this.v.deleteBuffer(this.Z)}}class ot extends q{constructor(r){super(r)}ot(r,s,i,o){const n=this.st(r,s),a=this.st(r+i,s+o);this.it(n.nx,n.ny,a.nx,a.ny);const h=this.et();this.v.drawArrays(this.v.TRIANGLES,0,6),this.rt(h.positionLoc,h.texLoc)}nt(r,s,i,o,n){this.ot(r,s,i,n),this.ot(r+i-n,s,n,o),this.ot(r,s+o-n,i,n),this.ot(r,s,n,o)}}class nt extends q{constructor(r){super(r)}ht(r,s,i,o,n){const a=i-r,h=o-s,u=Math.hypot(a,h);if(u===0){const f=n/2,g=this.st(r-f,s-f),p=this.st(r+f,s+f);this.it(g.nx,g.ny,p.nx,p.ny)}else{const f=-h/u,g=a/u,p=n/2,b=r+f*p,w=s+g*p,v=r-f*p,_=s-g*p,E=i+f*p,T=o+g*p,F=i-f*p,A=o-g*p,L=this.st(b,w),D=this.st(v,_),U=this.st(E,T),it=this.st(F,A),I=this.v;this.tt(),I.bindBuffer(I.ARRAY_BUFFER,this.Z);const It=new Float32Array([L.nx,L.ny,0,0,D.nx,D.ny,0,1,U.nx,U.ny,1,0,D.nx,D.ny,0,1,it.nx,it.ny,1,1,U.nx,U.ny,1,0]);I.bufferData(I.ARRAY_BUFFER,It,I.DYNAMIC_DRAW)}const d=this.et();this.v.drawArrays(this.v.TRIANGLES,0,6),this.rt(d.positionLoc,d.texLoc)}}var k="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);}";class at{constructor(r){c(this,"v");c(this,"lt");c(this,"ct");c(this,"ut",null);c(this,"ft");c(this,"dt");c(this,"gt",[1,1,1,1]);c(this,"_t",!0);c(this,"vt",[0,0,0,1]);c(this,"xt",1);c(this,"bt",!0);c(this,"wt",0);c(this,"Ct",[]);this.v=r,this.lt=new P(this.v,k,"precision lowp float;uniform sampler2D u_texture;varying vec2 v_uv;void main(){gl_FragColor=texture2D(u_texture,v_uv);}"),this.ct=new P(this.v,k,"precision lowp float;uniform vec4 u_color;void main(){gl_FragColor=u_color;}"),this.ft=new ot(this.v),this.dt=new nt(this.v),this.v.enable(this.v.BLEND),this.v.blendEquation(this.v.FUNC_ADD),this.v.blendFunc(this.v.ONE,this.v.ONE_MINUS_SRC_ALPHA),B(this.v,[0,0,this.v.canvas.width,this.v.canvas.height])}yt(r){this.ut!==r&&(this.ut=r,r.N())}$t(r,s,i,o){if(this._t=!0,s===void 0&&i===void 0&&o===void 0){const n=r/255;this.gt=[n,n,n,1]}else if(i!==void 0&&o===void 0)this.gt=[r/255,s/255,i/255,1];else{if(i===void 0||o===void 0)throw Error("Invalid fill parameters. Use fill(gray), fill(r,g,b), or fill(r,g,b,a)");this.gt=[r/255,s/255,i/255,o/255]}}Ft(r,s,i,o){if(this.bt=!0,s===void 0&&i===void 0&&o===void 0){const n=r/255;this.vt=[n,n,n,1]}else if(i!==void 0&&o===void 0)this.vt=[r/255,s/255,i/255,1];else{if(i===void 0||o===void 0)throw Error("Invalid stroke parameters. Use stroke(gray), stroke(r,g,b), or stroke(r,g,b,a)");this.vt=[r/255,s/255,i/255,o/255]}}Tt(r){if(r<0)throw Error("Stroke weight must be non-negative");this.xt=r}Dt(){this.bt=!1}Mt(){this._t=!1}St(r){this.wt=r}Rt(){this.Ct.push({fillColor:[...this.gt],fillMode:this._t,strokeColor:[...this.vt],strokeWeight:this.xt,strokeMode:this.bt,rotation:this.wt})}Vt(){const r=this.Ct.pop();r?(this.gt=r.fillColor,this._t=r.fillMode,this.vt=r.strokeColor,this.xt=r.strokeWeight,this.bt=r.strokeMode,this.wt=r.rotation):console.warn("pop() called without matching push()")}kt(){this.ut=null,this.Ct=[],this.wt=0}zt(r,s){return new P(this.v,r,s)}It(r){return new P(this.v,k,r)}Pt(r,s){this.ut.setUniform(r,s)}Ut(r,s,i,o){if(this.ut!==null){const{centerX:g,centerY:p,radians:b,aspectRatio:w}=this.At(r,s,i,o);return this.Pt("u_rotation",b),this.Pt("u_center",[g,p]),this.Pt("u_aspectRatio",w),this.ft.ot(r,s,i,o),void(this.ut=null)}const n=this.ct;let a=0,h=0,u=0,d=1;const f=this.At(r,s,i,o);a=f.centerX,h=f.centerY,u=f.radians,d=f.aspectRatio,this._t&&(this.yt(n),this.Pt("u_color",this.gt),this.Pt("u_rotation",u),this.Pt("u_center",[a,h]),this.Pt("u_aspectRatio",d),this.ft.ot(r,s,i,o)),this.bt&&this.xt>0&&(this.yt(n),this.Pt("u_color",this.vt),this.Pt("u_rotation",u),this.Pt("u_center",[a,h]),this.Pt("u_aspectRatio",d),this.ft.nt(r,s,i,o,this.xt)),this.ut=null}Gt(r,s,i,o){if(this.ut!==null){const v=(r+i)/2,_=(s+o)/2,E=Math.abs(i-r)||1,T=Math.abs(o-s)||1,{centerX:F,centerY:A,radians:L,aspectRatio:D}=this.At(v-E/2,_-T/2,E,T);this.Pt("u_rotation",L),this.Pt("u_center",[F,A]),this.Pt("u_aspectRatio",D);const U=this.xt>0?this.xt:1;return this.dt.ht(r,s,i,o,U),void(this.ut=null)}if(!this.bt||this.xt<=0)return;const n=this.ct,a=(r+i)/2,h=(s+o)/2,u=Math.abs(i-r)||1,d=Math.abs(o-s)||1,f=this.wt!==0;let g=0,p=0,b=0,w=1;if(f){const v=this.At(a-u/2,h-d/2,u,d);g=v.centerX,p=v.centerY,b=v.radians,w=v.aspectRatio}this.yt(n),this.Pt("u_color",this.vt),f&&(this.Pt("u_rotation",b),this.Pt("u_center",[g,p]),this.Pt("u_aspectRatio",w)),this.dt.ht(r,s,i,o,this.xt)}At(r,s,i,o){const n=W(this.v)||[0,0,this.v.canvas.width,this.v.canvas.height],a=n[2],h=n[3],u=a/h;return{centerX:(r+i/2)/a*2-1,centerY:1-(s+o/2)/h*2,radians:this.wt*Math.PI/180,aspectRatio:u}}Et(r,s,i={}){return new H(this.v,r,s,i)}Lt(r,s=r,i=r,o=255){this.Ot(r/255,s/255,i/255,o/255)}Ot(r=0,s=0,i=0,o=0){this.v.clearColor(r,s,i,o),this.v.clear(this.v.COLOR_BUFFER_BIT)}Bt(){this.v.viewport(0,0,this.v.canvas.width,this.v.canvas.height),B(this.v,[0,0,this.v.canvas.width,this.v.canvas.height])}get context(){return this.v}P(){this.lt.P(),this.ct.P(),this.ft.P(),this.dt.P()}Ht(r,s,i,o,n){const a=this.v,h=o??r.width,u=n??r.height;this.yt(this.lt),this.Pt("u_texture",r.texture);const d=this.At(s,i,h,u);this.Pt("u_rotation",d.radians),this.Pt("u_center",[d.centerX,d.centerY]),this.Pt("u_aspectRatio",d.aspectRatio),this.ft.ot(s,i,h,u),a.bindTexture(a.TEXTURE_2D,null),this.ut=null}}var S,m={parse:function(l){var r=function(s,i,o,n){var a=m.T,h={cmap:a.cmap,head:a.head,hhea:a.hhea,maxp:a.maxp,hmtx:a.hmtx,loca:a.loca,glyf:a.glyf},u={_data:s,_index:i,_offset:o};for(var d in h){var f=m.findTable(s,d,o);if(f){var g=f[0],p=n[g];p==null&&(p=h[d].parseTab(s,g,f[1],u)),u[d]=n[g]=p}}return u}(new Uint8Array(l),0,0,{});return[r]},findTable:function(l,r,s){for(var i=m.B,o=i.readUshort(l,s+4),n=s+12,a=0;a<o;a++){var h=i.readASCII(l,n,4);i.readUint(l,n+4);var u=i.readUint(l,n+8),d=i.readUint(l,n+12);if(h==r)return[u,d];n+=16}return null},T:{}};m.B={readShort:function(l,r){return m.B.t.uint16[0]=l[r]<<8|l[r+1],m.B.t.int16[0]},readUshort:function(l,r){return l[r]<<8|l[r+1]},readUshorts:function(l,r,s){for(var i=[],o=0;o<s;o++)i.push(m.B.readUshort(l,r+2*o));return i},readUint:function(l,r){var s=m.B.t.uint8;return s[3]=l[r],s[2]=l[r+1],s[1]=l[r+2],s[0]=l[r+3],m.B.t.uint32[0]},readASCII:function(l,r,s){for(var i="",o=0;o<s;o++)i+=String.fromCharCode(l[r+o]);return i},t:(S=new ArrayBuffer(8),{uint8:new Uint8Array(S),int16:new Int16Array(S),uint16:new Uint16Array(S),uint32:new Uint32Array(S)})},m.T.cmap={parseTab:function(l,r,s){var i={tables:[],ids:{},off:r};l=new Uint8Array(l.buffer,r,s),r=0;var o=m.B,n=o.readUshort,a=m.T.cmap;n(l,r);var h=n(l,r+=2);r+=2;for(var u=[],d=0;d<h;d++){var f=n(l,r),g=n(l,r+=2);r+=2;var p=o.readUint(l,r);r+=4;var b="p"+f+"e"+g,w=u.indexOf(p);if(w==-1){w=i.tables.length;var v={};u.push(p);var _=v.format=n(l,p);_==4?v=a.parse4(l,p,v):_==12&&(v=a.parse12(l,p,v)),i.tables.push(v)}i.ids[b]!=null&&console.log("multiple tables for one platform+encoding: "+b),i.ids[b]=w}return i},parse4:function(l,r,s){var i=m.B,o=i.readUshort,n=i.readUshorts,a=r,h=o(l,r+=2);o(l,r+=2);var u=o(l,r+=2);r+=2;var d=u>>>1;s.searchRange=o(l,r),r+=2,s.entrySelector=o(l,r),r+=2,s.rangeShift=o(l,r),r+=2,s.endCount=n(l,r,d),r+=2*d,r+=2,s.startCount=n(l,r,d),r+=2*d,s.idDelta=[];for(var f=0;f<d;f++)s.idDelta.push(i.readShort(l,r)),r+=2;return s.idRangeOffset=n(l,r,d),r+=2*d,s.glyphIdArray=n(l,r,a+h-r>>1),s},parse12:function(l,r,s){var i=m.B.readUint;i(l,r+=4),i(l,r+=4);var o=3*i(l,r+=4);r+=4;for(var n=s.groups=new Uint32Array(o),a=0;a<o;a+=3)n[a]=i(l,r+(a<<2)),n[a+1]=i(l,r+(a<<2)+4),n[a+2]=i(l,r+(a<<2)+8);return s}},m.T.head={parseTab:function(l,r,s){var i=m.B,o={};return r+=18,o.unitsPerEm=i.readUshort(l,r),r+=2,r+=16,o.xMin=i.readShort(l,r),r+=2,o.yMin=i.readShort(l,r),r+=2,o.xMax=i.readShort(l,r),r+=2,o.yMax=i.readShort(l,r),r+=2,r+=6,o.indexToLocFormat=i.readShort(l,r),o}},m.T.hhea={parseTab:function(l,r,s){var i=m.B,o={};r+=4;for(var n=["ascender","descender","lineGap","advanceWidthMax","minLeftSideBearing","minRightSideBearing","xMaxExtent","caretSlopeRise","caretSlopeRun","caretOffset","res0","res1","res2","res3","metricDataFormat","numberOfHMetrics"],a=0;a<n.length;a++){var h=n[a],u=h=="advanceWidthMax"||h=="numberOfHMetrics"?i.readUshort:i.readShort;o[h]=u(l,r+2*a)}return o}},m.T.hmtx={parseTab:function(l,r,s,i){for(var o=m.B,n=[],a=[],h=i.maxp.numGlyphs,u=i.hhea.numberOfHMetrics,d=0,f=0,g=0;g<u;)d=o.readUshort(l,r+(g<<2)),f=o.readShort(l,r+(g<<2)+2),n.push(d),a.push(f),g++;for(;g<h;)n.push(d),a.push(f),g++;return{aWidth:n,lsBearing:a}}},m.T.maxp={parseTab:function(l,r,s){var i=m.B,o=i.readUshort,n={};return i.readUint(l,r),r+=4,n.numGlyphs=o(l,r),r+=2,n}},m.T.loca={parseTab:function(l,r,s,i){var o=m.B,n=[],a=i.head.indexToLocFormat,h=i.maxp.numGlyphs+1;if(a==0)for(var u=0;u<h;u++)n.push(o.readUshort(l,r+(u<<1))<<1);if(a==1)for(u=0;u<h;u++)n.push(o.readUint(l,r+(u<<2)));return n}},m.T.glyf={parseTab:function(l,r,s,i){for(var o=[],n=i.maxp.numGlyphs,a=0;a<n;a++)o.push(null);return o},jt:function(l,r){var s=m.B,i=l._data,o=l.loca;if(o[r]==o[r+1])return null;var n=m.findTable(i,"glyf",l._offset)[0]+o[r],a={};if(a.noc=s.readShort(i,n),n+=2,a.xMin=s.readShort(i,n),n+=2,a.yMin=s.readShort(i,n),n+=2,a.xMax=s.readShort(i,n),n+=2,a.yMax=s.readShort(i,n),n+=2,a.xMin>=a.xMax||a.yMin>=a.yMax)return null;if(a.noc>0){a.endPts=[];for(var h=0;h<a.noc;h++)a.endPts.push(s.readUshort(i,n)),n+=2;var u=s.readUshort(i,n);if(n+=2,i.length-n<u)return null;n+=u;var d=a.endPts[a.noc-1]+1;for(a.flags=[],h=0;h<d;h++){var f=i[n];if(n++,a.flags.push(f),8&f){var g=i[n];n++;for(var p=0;p<g;p++)a.flags.push(f),h++}}for(a.xs=[],h=0;h<d;h++){var b=!!(2&a.flags[h]),w=!!(16&a.flags[h]);b?(a.xs.push(w?i[n]:-i[n]),n++):w?a.xs.push(0):(a.xs.push(s.readShort(i,n)),n+=2)}for(a.ys=[],h=0;h<d;h++)b=!!(4&a.flags[h]),w=!!(32&a.flags[h]),b?(a.ys.push(w?i[n]:-i[n]),n++):w?a.ys.push(0):(a.ys.push(s.readShort(i,n)),n+=2);var v=0,_=0;for(h=0;h<d;h++)v+=a.xs[h],_+=a.ys[h],a.xs[h]=v,a.ys[h]=_}else a.parts=[];return a}},typeof module<"u"&&module.exports?module.exports=m:typeof window<"u"&&(window.Typr=m);class ht{extractCharacters(r){var i;const s=[];return(i=r==null?void 0:r.cmap)!=null&&i.tables?(r.cmap.tables.forEach(o=>{if(o.format===4){const n=this.Wt(o);s.push(...n)}else if(o.format===12){const n=this.Nt(o);s.push(...n)}}),[...new Set(s)]):[]}Wt(r){const s=[];if(!(r.startCount&&r.endCount&&r.idRangeOffset&&r.idDelta))return s;for(let i=0;i<r.startCount.length;i++){const o=r.startCount[i],n=r.endCount[i];if(o!==65535||n!==65535){for(let a=o;a<=n;a++)if(this.Xt(r,a,i)>0){const h=String.fromCodePoint(a);s.push(h)}}}return s}Nt(r){const s=[];if(!r.groups)return s;for(let i=0;i<r.groups.length;i+=3){const o=r.groups[i],n=r.groups[i+1],a=r.groups[i+2];for(let h=o;h<=n;h++)if(a+(h-o)>0){const u=String.fromCodePoint(h);s.push(u)}}return s}Xt(r,s,i){if(r.idRangeOffset[i]===0)return s+r.idDelta[i]&65535;{const o=r.idRangeOffset[i]/2+(s-r.startCount[i])-(r.startCount.length-i);if(o>=0&&r.glyphIdArray&&o<r.glyphIdArray.length){const n=r.glyphIdArray[o];if(n!==0)return n+r.idDelta[i]&65535}}return 0}filterProblematicCharacters(r){return r.filter(s=>this.qt(s))}qt(r){const s=r.codePointAt(0)||0;return!(s>=0&&s<=31&&s!==9&&s!==10&&s!==13||s>=127&&s<=159)}}class lt{constructor(r){c(this,"Yt");c(this,"Qt");c(this,"Zt");this.Zt=r,this.Yt=document.createElement("canvas"),this.Qt=this.Yt.getContext("2d",{willReadFrequently:!0,alpha:!1})}createTextureAtlas(r,s,i,o){const n=r.length,a=Math.ceil(Math.sqrt(n)),h=Math.ceil(n/a),u=s.width*a,d=s.height*h;this.Jt(u,d,i,o),this.Kt(r,s,a,i),this.te();const f=this.Zt.Et(u,d,{filter:"nearest"});return f.update(this.Yt),{framebuffer:f,columns:a,rows:h}}Jt(r,s,i,o){this.Yt.width=r,this.Yt.height=s,this.Yt.style.width=r+"px",this.Yt.style.height=r+"px",this.Qt.imageSmoothingEnabled=!1,this.Yt.style.imageRendering="pixelated",this.Qt.fillStyle="black",this.Qt.fillRect(0,0,r,s),this.Qt.font=`${i}px ${o}`,this.Qt.textBaseline="top",this.Qt.textAlign="left",this.Qt.fillStyle="white"}Kt(r,s,i,o){for(let n=0;n<r.length;n++){const a=n%i,h=Math.floor(n/i),u=a*s.width+.5*s.width,d=h*s.height+.5*s.height,f=Math.round(u-.5*s.width),g=Math.round(d-.5*o);this.Qt.fillText(r[n].character,f,g)}}te(r=128){const s=this.Qt.getImageData(0,0,this.Yt.width,this.Yt.height),i=s.data;for(let o=0;o<i.length;o+=4){const n=.299*i[o]+.587*i[o+1]+.114*i[o+2]>r+32?255:0;i[o]=n,i[o+1]=n,i[o+2]=n}this.Qt.putImageData(s,0,0)}}class ct{constructor(){c(this,"ee");c(this,"re");this.ee=document.createElement("canvas"),this.re=this.ee.getContext("2d")}calculateMaxGlyphDimensions(r,s,i){this.re.font=`${s}px ${i}`;let o=0,n=0;for(const a of r){const h=this.re.measureText(a);o=Math.max(o,h.width),n=Math.max(n,h.actualBoundingBoxAscent+h.actualBoundingBoxDescent)}return{width:o,height:n}}}class ut{createCharacterObjects(r,s){return r.map((i,o)=>{const n=i.codePointAt(0)||0,a=this.se(o);let h=0;if(s.hmtx&&s.hmtx.aWidth){const u=this.ie(s,n);u>0&&s.hmtx.aWidth[u]!==void 0&&(h=s.hmtx.aWidth[u])}return{character:i,unicode:n,color:a,advanceWidth:h}})}ie(r,s){const i=r.cmap;if(!i||!i.tables)return 0;for(const o of i.tables)if(o.format===4){for(let n=0;n<o.startCount.length;n++)if(s>=o.startCount[n]&&s<=o.endCount[n]){if(o.idRangeOffset[n]===0)return s+o.idDelta[n]&65535;{const a=o.idRangeOffset[n]/2+(s-o.startCount[n])-(o.startCount.length-n);if(a>=0&&a<o.glyphIdArray.length){const h=o.glyphIdArray[a];if(h!==0)return h+o.idDelta[n]&65535}}}}return 0}se(r){return[r%256,Math.floor(r/256)%256,Math.floor(r/65536)%256]}getCharacterColor(r,s){if(!y.p(typeof r=="string","Character must be a string.",{method:"getCharacterColor",providedValue:r}))return[0,0,0];const i=s.find(o=>o.character===r);return i?i.color:[0,0,0]}getCharacterColors(r,s){return y.p(typeof r=="string"&&r.length>0,"Characters must be a string with at least one character.",{method:"getCharacterColors",providedValue:r})?r.split("").map(i=>this.getCharacterColor(i,s)||[0,0,0]):[[0,0,0]]}}class Q{constructor(r,s=16){c(this,"oe");c(this,"ne",[]);c(this,"ae");c(this,"he",16);c(this,"le",0);c(this,"ce",0);c(this,"ue",{width:0,height:0});c(this,"fe");c(this,"de","UrsaFont");c(this,"me");c(this,"pe");c(this,"ge");c(this,"_e");this.he=s,this.me=new ht,this.pe=new lt(r),this.ge=new ct,this._e=new ut}async ve(r){let s;if(!r)throw new x("Embedded font not available. This appears to be a minified build - please provide `fontSource`.");{const i=await fetch(r);if(!i.ok)throw new x(`Failed to load font file: ${i.status} ${i.statusText}`);s=await i.arrayBuffer()}await this.xe(s),this.oe=m.parse(s)[0],await this.be()}we(r){if(r===void 0)return this.he;this.he=r,this.ue=this.ge.calculateMaxGlyphDimensions(this.ne.map(i=>i.character),this.he,this.de);const s=this.pe.createTextureAtlas(this.ne,this.ue,this.he,this.de);this.ae=s.framebuffer,this.le=s.columns,this.ce=s.rows}async Ce(r){try{const s=await fetch(r);if(!s.ok)throw new x(`Failed to load font file: ${s.status} ${s.statusText}`);const i=await s.arrayBuffer();await this.xe(i);const o=m.parse(i);if(!o||o.length===0)throw Error("Failed to parse font file");this.oe=o[0],await this.be()}catch(s){throw new x("Failed to load font: "+(s instanceof Error?s.message:"Unknown error"),s)}}async xe(r){const s=Date.now();this.de=this.de==="UrsaFont"?"UrsaFont":"CustomFont_"+s,this.fe=new FontFace(this.de,r),await this.fe.load(),document.fonts.add(this.fe)}async be(){const r=this.me.extractCharacters(this.oe),s=this.me.filterProblematicCharacters(r);this.ne=this._e.createCharacterObjects(s,this.oe),this.ue=this.ge.calculateMaxGlyphDimensions(s,this.he,this.de);const i=this.pe.createTextureAtlas(this.ne,this.ue,this.he,this.de);this.ae=i.framebuffer,this.le=i.columns,this.ce=i.rows}getCharacterColor(r){return this._e.getCharacterColor(r,this.ne)}getCharacterColors(r){return this._e.getCharacterColors(r,this.ne)}hasAllCharacters(r){if(typeof r!="string"||r.length===0)return!1;const s=new Set(this.ne.map(i=>i.character));for(const i of r)if(!s.has(i))return!1;return!0}P(){this.ae.P(),document.fonts.delete(this.fe)}get fontFramebuffer(){return this.ae}get characters(){return this.ne}get textureColumns(){return this.le}get textureRows(){return this.ce}get maxGlyphDimensions(){return this.ue}get fontSize(){return this.he}get font(){return this.oe}}class J{constructor(r,s,i){c(this,"ye");c(this,"$e");c(this,"F");c(this,"D");c(this,"Fe");c(this,"Te");c(this,"De",!1);c(this,"Me");c(this,"Se");c(this,"Re");this.Me=r,this.Se=s,this.Re=i,this.kt()}kt(){this.De||(this.ye=Math.floor(this.Me.width/this.Se),this.$e=Math.floor(this.Me.height/this.Re)),this.Ve()}Ve(){this.F=this.ye*this.Se,this.D=this.$e*this.Re,this.Fe=Math.floor((this.Me.width-this.F)/2),this.Te=Math.floor((this.Me.height-this.D)/2)}ke(r,s){this.Se=r,this.Re=s,this.kt()}ze(r,s){this.De=!0,this.ye=r,this.$e=s,this.Ve()}Ie(){this.De=!1,this.kt()}Pe(){this.De?this.Ve():this.kt()}Ue(r){if(r===void 0)return this.De;this.De=r}get cellWidth(){return this.Se}get cellHeight(){return this.Re}get cols(){return this.ye}get rows(){return this.$e}get width(){return this.F}get height(){return this.D}get offsetX(){return this.Fe}get offsetY(){return this.Te}}class K{constructor(r,s=!1,i={}){c(this,"Me");c(this,"Ae");c(this,"Ge");c(this,"Ee");c(this,"onTransformChange");this.Ae=r,this.Ge=s,this.Me=this.Le(i.width,i.height),s&&this.setupTransformObserver()}Le(r,s){var o;const i=document.createElement("canvas");if(i.className="textmodeCanvas",i.style.imageRendering="pixelated",this.Ge)i.width=r||800,i.height=s||600,document.body.appendChild(i);else{const n=this.Ae.getBoundingClientRect();let a=Math.round(n.width),h=Math.round(n.height);if(this.Ae instanceof HTMLVideoElement){const f=this.Ae;(a===0||h===0)&&f.videoWidth>0&&f.videoHeight>0&&(a=f.videoWidth,h=f.videoHeight)}i.width=a,i.height=h,i.style.position="absolute",i.style.pointerEvents="none";const u=window.getComputedStyle(this.Ae);let d=parseInt(u.zIndex||"0",10);isNaN(d)&&(d=0),i.style.zIndex=""+(d+1),this.Oe(i),(o=this.Ae.parentNode)==null||o.insertBefore(i,this.Ae.nextSibling)}return i}Oe(r){const s=this.Ae.getBoundingClientRect();let i=this.Ae.offsetParent;if(i&&i!==document.body){const o=i.getBoundingClientRect();r.style.top=s.top-o.top+"px",r.style.left=s.left-o.left+"px"}else r.style.top=s.top+window.scrollY+"px",r.style.left=s.left+window.scrollX+"px"}Pe(r,s){if(this.Ge)this.Me.width=r??this.Me.width,this.Me.height=s??this.Me.height;else{const i=this.Ae.getBoundingClientRect();let o=Math.round(i.width),n=Math.round(i.height);if(this.Ae instanceof HTMLVideoElement){const a=this.Ae;(o===0||n===0)&&a.videoWidth>0&&a.videoHeight>0&&(o=a.videoWidth,n=a.videoHeight)}this.Me.width=o,this.Me.height=n,this.Oe(this.Me)}}Be(){const r={alpha:!1,premultipliedAlpha:!1,preserveDrawingBuffer:!0,antialias:!1,depth:!1,stencil:!1,powerPreference:"high-performance"},s=this.Me.getContext("webgl2",r)||this.Me.getContext("webgl",r);if(!s)throw new x("WebGL context could not be created. Ensure your browser supports WebGL.");return s}setupTransformObserver(){this.Ee=new ResizeObserver(r=>{for(const s of r){const i=s.contentRect;!this.onTransformChange||Math.round(i.width)===this.Me.width&&Math.round(i.height)===this.Me.height||this.onTransformChange()}}),this.Ee.observe(this.Me)}P(){this.Ee&&this.Ee.disconnect();const r=this.Me.getContext("webgl")||this.Me.getContext("webgl2");if(r){const s=r.getExtension("WEBGL_lose_context");s&&s.loseContext()}this.Me.parentNode&&this.Me.parentNode.removeChild(this.Me)}get canvas(){return this.Me}get width(){return this.Me.width}get height(){return this.Me.height}}class Z{constructor(r,s,i,o={}){c(this,"Zt");c(this,"He");c(this,"je");c(this,"We");c(this,"Ne");c(this,"Xe");c(this,"qe");c(this,"Ye");c(this,"l");this.Zt=r,this.He=s,this.je=i,this.l=o;const n=this.je.cols,a=this.je.rows;this.We=this.Zt.Et(n,a),this.Ne=this.Zt.Et(n,a),this.Xe=this.Zt.Et(n,a),this.qe=this.Zt.Et(n,a),this.Ye=this.Zt.Et(n,a)}Pe(){const r=this.je.cols,s=this.je.rows;this.We.resize(r,s),this.Ne.resize(r,s),this.Xe.resize(r,s),this.qe.resize(r,s),this.Ye.resize(r,s)}enabled(r){this.l.enabled=r}enable(){this.enabled(!0)}disable(){this.enabled(!1)}P(){this.We.P(),this.Ne.P(),this.Xe.P(),this.qe.P(),this.Ye.P()}get characterFramebuffer(){return this.We}get primaryColorFramebuffer(){return this.Ne}get secondaryColorFramebuffer(){return this.Xe}get rotationFramebuffer(){return this.qe}get transformFramebuffer(){return this.Ye}get options(){return this.l}}class dt{constructor(r,s){c(this,"C");c(this,"Zt");c(this,"Qe");this.Zt=r,this.Qe=s;const i=Math.max(this.Qe.length,1);this.C=this.Zt.Et(i,1),this.Ze()}Ze(){const r=this.Qe.length;this.C.width!==r&&this.C.resize(r,1);const s=new Uint8Array(1*r*4);for(let i=0;i<r;i++){const o=this.Qe[i],n=4*i;s[n]=o[0],s[n+1]=o[1],s[n+2]=o[2],s[n+3]=255}this.C.updatePixels(s,r,1)}setColors(r){this.Qe=r,this.Ze()}get colors(){return this.Qe}get framebuffer(){return this.C}get texture(){return this.C.texture}}class N extends Z{constructor(s,i,o,n={}){super(s,i,o,n);c(this,"Je");this.Je=new dt(this.Zt,this.He.getCharacterColors(" .:-=+*%@#"))}characters(s){y.p(this.He.hasAllCharacters(s),"One or more characters do not exist in the current font.",{method:"characters",providedValue:s})&&(this.l.characters=s,this.Je.setColors(this.He.getCharacterColors(s)))}characterColor(s,i,o,n=255){const a=this.Ke(s,"characterColor",i,o,n);a&&(this.l.characterColor=a)}characterColorMode(s){this.tr(s,"characterColorMode")}cellColor(s,i,o,n=255){const a=this.Ke(s,"cellColor",i,o,n);a&&(this.l.cellColor=a)}cellColorMode(s){this.tr(s,"cellColorMode")}invert(s){this.er(s,"invert","Invert")}rotation(s){if(!y.p(typeof s=="number","Rotation angle must be a number.",{method:"rotation",providedValue:s}))return;(s%=360)<0&&(s+=360);const i=255*s/360,o=Math.floor(i)/255,n=Math.round(i-o);this.l.rotation=[o,n,0,1]}flipHorizontally(s){this.er(s,"flipHorizontally","Flip horizontally")}flipVertically(s){this.er(s,"flipVertically","Flip vertically")}Ke(s,i,o,n,a=255){let h,u,d,f;if(typeof s=="string"){const g=this.rr(s);if(!g)return y.p(!1,"Invalid hex color format. Use '#FF0000', '#F00', 'FF0000', or 'F00'.",{method:i,providedValue:s}),null;[h,u,d,f]=g}else if(h=s,u=o!==void 0?o:s,d=n!==void 0?n:s,f=a,!y.p([h,u,d,f].every(g=>g>=0&&g<=255),i.charAt(0).toUpperCase()+i.slice(1)+" color values must be between 0 and 255",{method:i,providedValues:{r:h,g:u,b:d,a:f}}))return null;return[h/255,u/255,d/255,f/255]}tr(s,i){y.p(["sampled","fixed"].includes(s),"Invalid color mode. Must be 'sampled' or 'fixed'.",{method:i,providedValue:s})&&(this.l[i]=s)}er(s,i,o){y.p(typeof s=="boolean"||typeof s=="number"&&Number.isInteger(s),o+" must be a boolean value or an integer (0 for false, any other number for true).",{method:i,providedValue:s})&&(this.l[i]=!!s)}rr(s){return s=s.replace(/^#/,""),/^[0-9A-Fa-f]{3}$|^[0-9A-Fa-f]{6}$/.test(s)?(s.length===3&&(s=s.split("").map(i=>i+i).join("")),[parseInt(s.slice(0,2),16),parseInt(s.slice(2,4),16),parseInt(s.slice(4,6),16),255]):null}}const $=`attribute vec2 a_position;\r
7
+ `,i}static o(r){if(r===null)return"null";if(r===void 0)return"undefined";if(typeof r=="string")return`"${r}"`;if(typeof r=="number"||typeof r=="boolean")return r+"";if(Array.isArray(r))return r.length===0?"[]":r.length<=5?`[${r.map(s=>x.o(s)).join(", ")}]`:`[${r.slice(0,3).map(s=>x.o(s)).join(", ")}, ... +${r.length-3} more]`;if(typeof r=="object"){const s=Object.keys(r);return s.length===0?"{}":s.length<=3?`{ ${s.map(i=>`${i}: ${x.o(r[i])}`).join(", ")} }`:`{ ${s.slice(0,2).map(i=>`${i}: ${x.o(r[i])}`).join(", ")}, ... +${s.length-2} more }`}return r+""}}var R=(l=>(l[l.SILENT=0]="SILENT",l[l.WARNING=1]="WARNING",l[l.ERROR=2]="ERROR",l[l.THROW=3]="THROW",l))(R||{});const M=class M{constructor(){c(this,"l",{globalLevel:3})}static u(){return M.h||(M.h=new M),M.h}m(r,s){const i="%c[textmode.js] Oops! (╯°□°)╯︵ Something went wrong in your code.",o="color: #f44336; font-weight: bold; background: #ffebee; padding: 2px 6px; border-radius: 3px;";switch(this.l.globalLevel){case 0:return!1;case 1:return console.group(i,o),console.warn(x.i(r,s)),console.groupEnd(),!1;case 2:return console.group(i,o),console.error(x.i(r,s)),console.groupEnd(),!1;default:throw new x(r,s)}}p(r,s,i){return!!r||(this.m(s,i),!1)}_(r){this.l.globalLevel=r}};c(M,"h",null);let O=M;const _=O.u(),X=new WeakMap;function B(l,r){X.set(l,r)}function W(l){return X.get(l)}class H{constructor(r,s,i=s,o={}){c(this,"v");c(this,"C");c(this,"$");c(this,"F");c(this,"D");c(this,"l");c(this,"M",null);c(this,"S",null);this.v=r,this.F=s,this.D=i,this.l={filter:"nearest",wrap:"clamp",format:"rgba",type:"unsigned_byte",...o},this.$=this.R(),this.C=r.createFramebuffer(),this.V()}k(r){const{v:s}=this,i=s.getParameter(s.FRAMEBUFFER_BINDING);s.bindFramebuffer(s.FRAMEBUFFER,this.C);try{return r()}finally{s.bindFramebuffer(s.FRAMEBUFFER,i)}}R(){const{v:r}=this,s=r.createTexture();r.bindTexture(r.TEXTURE_2D,s);const i=this.l.filter==="linear"?r.LINEAR:r.NEAREST,o=this.l.wrap==="repeat"?r.REPEAT:r.CLAMP_TO_EDGE;return r.texParameteri(r.TEXTURE_2D,r.TEXTURE_MIN_FILTER,i),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_MAG_FILTER,i),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_WRAP_S,o),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_WRAP_T,o),this.I(),s}I(){const{v:r}=this,s=this.l.type==="float"?r.FLOAT:r.UNSIGNED_BYTE;r.texImage2D(r.TEXTURE_2D,0,r.RGBA,this.F,this.D,0,r.RGBA,s,null)}V(){const{v:r}=this;r.bindFramebuffer(r.FRAMEBUFFER,this.C),r.framebufferTexture2D(r.FRAMEBUFFER,r.COLOR_ATTACHMENT0,r.TEXTURE_2D,this.$,0),r.bindFramebuffer(r.FRAMEBUFFER,null)}update(r){const{v:s}=this;s.bindTexture(s.TEXTURE_2D,this.$),s.pixelStorei(s.UNPACK_FLIP_Y_WEBGL,1),s.texImage2D(s.TEXTURE_2D,0,s.RGBA,s.RGBA,s.UNSIGNED_BYTE,r),s.bindTexture(s.TEXTURE_2D,null)}updatePixels(r,s,i){const{v:o}=this;o.bindTexture(o.TEXTURE_2D,this.$),o.texImage2D(o.TEXTURE_2D,0,o.RGBA,s,i,0,o.RGBA,o.UNSIGNED_BYTE,r),o.bindTexture(o.TEXTURE_2D,null)}resize(r,s){const{v:i}=this;this.F=r,this.D=s,this.S=null,i.bindTexture(i.TEXTURE_2D,this.$),this.I(),i.bindTexture(i.TEXTURE_2D,null)}begin(){const{v:r}=this;this.M={framebuffer:r.getParameter(r.FRAMEBUFFER_BINDING),viewport:r.getParameter(r.VIEWPORT)},r.bindFramebuffer(r.FRAMEBUFFER,this.C),r.viewport(0,0,this.F,this.D),B(r,[0,0,this.F,this.D])}end(){if(!this.M)return;const{v:r}=this;r.bindFramebuffer(r.FRAMEBUFFER,this.M.framebuffer),r.viewport(...this.M.viewport),B(r,this.M.viewport),this.M=null}loadPixels(){const{v:r}=this;this.S||(this.S=new Uint8Array(this.F*this.D*4)),this.k(()=>{r.readPixels(0,0,this.F,this.D,r.RGBA,r.UNSIGNED_BYTE,this.S)})}get(r,s,i,o){const{v:n}=this;if(r===void 0&&s===void 0){const a=new Uint8Array(this.F*this.D*4);return this.k(()=>(n.readPixels(0,0,this.F,this.D,n.RGBA,n.UNSIGNED_BYTE,a),a))}if(i===void 0&&o===void 0){(r<0||s<0||r>=this.F||s>=this.D)&&(console.warn("The x and y values passed to Framebuffer.get are outside of its range and will be clamped."),r=Math.max(0,Math.min(r,this.F-1)),s=Math.max(0,Math.min(s,this.D-1)));const a=new Uint8Array(4);return this.k(()=>(n.readPixels(r,s,1,1,n.RGBA,n.UNSIGNED_BYTE,a),[a[0],a[1],a[2],a[3]]))}{r=Math.max(0,Math.min(r,this.F-1)),s=Math.max(0,Math.min(s,this.D-1)),i=Math.max(1,Math.min(i,this.F-r)),o=Math.max(1,Math.min(o,this.D-s));const a=new Uint8Array(i*o*4);return this.k(()=>(n.readPixels(r,s,i,o,n.RGBA,n.UNSIGNED_BYTE,a),a))}}P(){this.C&&this.v.deleteFramebuffer(this.C),this.$&&this.v.deleteTexture(this.$)}get framebuffer(){return this.C}get texture(){return this.$}get width(){return this.F}get height(){return this.D}get pixels(){return this.S}}class P{constructor(r,s,i){c(this,"v");c(this,"U");c(this,"A",new Map);c(this,"G",new Map);c(this,"L",0);c(this,"O");this.v=r,this.U=this.H(s,i),this.O=r.getParameter(r.MAX_TEXTURE_IMAGE_UNITS),this.j()}j(){const r=this.v.getProgramParameter(this.U,this.v.ACTIVE_UNIFORMS);for(let s=0;s<r;s++){const i=this.v.getActiveUniform(this.U,s);if(i){const o=this.v.getUniformLocation(this.U,i.name);o&&(this.A.set(i.name,o),this.G.set(i.name,i.type))}}}H(r,s){const i=this.W(this.v.VERTEX_SHADER,r),o=this.W(this.v.FRAGMENT_SHADER,s),n=this.v.createProgram();if(this.v.attachShader(n,i),this.v.attachShader(n,o),this.v.linkProgram(n),!this.v.getProgramParameter(n,this.v.LINK_STATUS)){const a=this.v.getProgramInfoLog(n);throw Error("Shader program link error: "+a)}return this.v.deleteShader(i),this.v.deleteShader(o),n}W(r,s){const i=this.v.createShader(r);if(this.v.shaderSource(i,s),this.v.compileShader(i),!this.v.getShaderParameter(i,this.v.COMPILE_STATUS)){const o=this.v.getShaderInfoLog(i);throw this.v.deleteShader(i),Error("Shader compilation error: "+o)}return i}N(){this.v.useProgram(this.U),this.X()}setUniform(r,s){const i=this.A.get(r);if(i)if(typeof s=="number")this.q(r)?this.v.uniform1i(i,Math.floor(s)):this.v.uniform1f(i,s);else if(typeof s=="boolean")this.v.uniform1i(i,s?1:0);else if(Array.isArray(s))switch(s.length){case 2:this.v.uniform2f(i,s[0],s[1]);break;case 3:this.v.uniform3f(i,s[0],s[1],s[2]);break;case 4:this.v.uniform4f(i,s[0],s[1],s[2],s[3]);break;default:console.warn(`Unsupported array length ${s.length} for uniform '${r}'`)}else if(s instanceof WebGLTexture){const o=this.Y();this.v.uniform1i(i,o),this.v.activeTexture(this.v.TEXTURE0+o),this.v.bindTexture(this.v.TEXTURE_2D,s)}else if(s instanceof H){const o=this.Y();this.v.uniform1i(i,o),this.v.activeTexture(this.v.TEXTURE0+o),this.v.bindTexture(this.v.TEXTURE_2D,s.texture)}else console.warn(`Unsupported uniform type for '${r}':`,typeof s)}Y(){return this.L>=this.O&&console.warn(`Exceeded maximum texture units (${this.O}). Texture may not render correctly.`),this.L++}q(r){const s=this.G.get(r);return!!s&&(s===this.v.INT||s===this.v.INT_VEC2||s===this.v.INT_VEC3||s===this.v.INT_VEC4||s===this.v.SAMPLER_2D||s===this.v.SAMPLER_CUBE)}get glProgram(){return this.U}P(){this.v.deleteProgram(this.U)}X(){this.L=0}}class q{constructor(r){c(this,"v");c(this,"Z",null);c(this,"J",16);c(this,"K",new Map);this.v=r}tt(){if(this.Z)return;const r=this.v;this.Z=r.createBuffer(),r.bindBuffer(r.ARRAY_BUFFER,this.Z)}et(){const r=this.v,s=r.getParameter(r.CURRENT_PROGRAM);let i=this.K.get(s);return i||(i={a_position:r.getAttribLocation(s,"a_position"),a_texCoord:r.getAttribLocation(s,"a_texCoord")},this.K.set(s,i)),r.enableVertexAttribArray(i.a_position),r.vertexAttribPointer(i.a_position,2,r.FLOAT,!1,this.J,0),r.enableVertexAttribArray(i.a_texCoord),r.vertexAttribPointer(i.a_texCoord,2,r.FLOAT,!1,this.J,8),{positionLoc:i.a_position,texLoc:i.a_texCoord}}rt(r,s){const i=this.v;i.disableVertexAttribArray(r),i.disableVertexAttribArray(s)}st(r,s){const i=this.v,o=W(i)||[0,0,i.canvas.width,i.canvas.height];return{nx:r/o[2]*2-1,ny:1-s/o[3]*2}}it(r,s,i,o){const n=this.v;this.tt(),n.bindBuffer(n.ARRAY_BUFFER,this.Z);const a=new Float32Array([r,o,0,0,i,o,1,0,r,s,0,1,r,s,0,1,i,o,1,0,i,s,1,1]);n.bufferData(n.ARRAY_BUFFER,a,n.DYNAMIC_DRAW)}P(){this.Z&&this.v.deleteBuffer(this.Z)}}class ot extends q{constructor(r){super(r)}ot(r,s,i,o){const n=this.st(r,s),a=this.st(r+i,s+o);this.it(n.nx,n.ny,a.nx,a.ny);const h=this.et();this.v.drawArrays(this.v.TRIANGLES,0,6),this.rt(h.positionLoc,h.texLoc)}nt(r,s,i,o,n){this.ot(r,s,i,n),this.ot(r+i-n,s,n,o),this.ot(r,s+o-n,i,n),this.ot(r,s,n,o)}}class nt extends q{constructor(r){super(r)}ht(r,s,i,o,n){const a=i-r,h=o-s,u=Math.hypot(a,h);if(u===0){const f=n/2,g=this.st(r-f,s-f),p=this.st(r+f,s+f);this.it(g.nx,g.ny,p.nx,p.ny)}else{const f=-h/u,g=a/u,p=n/2,b=r+f*p,w=s+g*p,v=r-f*p,y=s-g*p,E=i+f*p,T=o+g*p,F=i-f*p,A=o-g*p,L=this.st(b,w),D=this.st(v,y),U=this.st(E,T),it=this.st(F,A),I=this.v;this.tt(),I.bindBuffer(I.ARRAY_BUFFER,this.Z);const It=new Float32Array([L.nx,L.ny,0,0,D.nx,D.ny,0,1,U.nx,U.ny,1,0,D.nx,D.ny,0,1,it.nx,it.ny,1,1,U.nx,U.ny,1,0]);I.bufferData(I.ARRAY_BUFFER,It,I.DYNAMIC_DRAW)}const d=this.et();this.v.drawArrays(this.v.TRIANGLES,0,6),this.rt(d.positionLoc,d.texLoc)}}var k="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);}";class at{constructor(r){c(this,"v");c(this,"lt");c(this,"ct");c(this,"ut",null);c(this,"ft");c(this,"dt");c(this,"gt",[1,1,1,1]);c(this,"_t",!0);c(this,"vt",[0,0,0,1]);c(this,"xt",1);c(this,"bt",!0);c(this,"wt",0);c(this,"Ct",[]);this.v=r,this.lt=new P(this.v,k,"precision lowp float;uniform sampler2D u_texture;varying vec2 v_uv;void main(){gl_FragColor=texture2D(u_texture,v_uv);}"),this.ct=new P(this.v,k,"precision lowp float;uniform vec4 u_color;void main(){gl_FragColor=u_color;}"),this.ft=new ot(this.v),this.dt=new nt(this.v),this.v.enable(this.v.BLEND),this.v.blendEquation(this.v.FUNC_ADD),this.v.blendFunc(this.v.ONE,this.v.ONE_MINUS_SRC_ALPHA),B(this.v,[0,0,this.v.canvas.width,this.v.canvas.height])}yt(r){this.ut!==r&&(this.ut=r,r.N())}$t(r,s,i,o){if(this._t=!0,s===void 0&&i===void 0&&o===void 0){const n=r/255;this.gt=[n,n,n,1]}else if(i!==void 0&&o===void 0)this.gt=[r/255,s/255,i/255,1];else{if(i===void 0||o===void 0)throw Error("Invalid fill parameters. Use fill(gray), fill(r,g,b), or fill(r,g,b,a)");this.gt=[r/255,s/255,i/255,o/255]}}Ft(r,s,i,o){if(this.bt=!0,s===void 0&&i===void 0&&o===void 0){const n=r/255;this.vt=[n,n,n,1]}else if(i!==void 0&&o===void 0)this.vt=[r/255,s/255,i/255,1];else{if(i===void 0||o===void 0)throw Error("Invalid stroke parameters. Use stroke(gray), stroke(r,g,b), or stroke(r,g,b,a)");this.vt=[r/255,s/255,i/255,o/255]}}Tt(r){if(r<0)throw Error("Stroke weight must be non-negative");this.xt=r}Dt(){this.bt=!1}Mt(){this._t=!1}St(r){this.wt=r}Rt(){this.Ct.push({fillColor:[...this.gt],fillMode:this._t,strokeColor:[...this.vt],strokeWeight:this.xt,strokeMode:this.bt,rotation:this.wt})}Vt(){const r=this.Ct.pop();r?(this.gt=r.fillColor,this._t=r.fillMode,this.vt=r.strokeColor,this.xt=r.strokeWeight,this.bt=r.strokeMode,this.wt=r.rotation):console.warn("pop() called without matching push()")}kt(){this.ut=null,this.Ct=[],this.wt=0}zt(r,s){return new P(this.v,r,s)}It(r){return new P(this.v,k,r)}Pt(r,s){this.ut.setUniform(r,s)}Ut(r,s,i,o){if(this.ut!==null){const{centerX:g,centerY:p,radians:b,aspectRatio:w}=this.At(r,s,i,o);return this.Pt("u_rotation",b),this.Pt("u_center",[g,p]),this.Pt("u_aspectRatio",w),this.ft.ot(r,s,i,o),void(this.ut=null)}const n=this.ct;let a=0,h=0,u=0,d=1;const f=this.At(r,s,i,o);a=f.centerX,h=f.centerY,u=f.radians,d=f.aspectRatio,this._t&&(this.yt(n),this.Pt("u_color",this.gt),this.Pt("u_rotation",u),this.Pt("u_center",[a,h]),this.Pt("u_aspectRatio",d),this.ft.ot(r,s,i,o)),this.bt&&this.xt>0&&(this.yt(n),this.Pt("u_color",this.vt),this.Pt("u_rotation",u),this.Pt("u_center",[a,h]),this.Pt("u_aspectRatio",d),this.ft.nt(r,s,i,o,this.xt)),this.ut=null}Gt(r,s,i,o){if(this.ut!==null){const v=(r+i)/2,y=(s+o)/2,E=Math.abs(i-r)||1,T=Math.abs(o-s)||1,{centerX:F,centerY:A,radians:L,aspectRatio:D}=this.At(v-E/2,y-T/2,E,T);this.Pt("u_rotation",L),this.Pt("u_center",[F,A]),this.Pt("u_aspectRatio",D);const U=this.xt>0?this.xt:1;return this.dt.ht(r,s,i,o,U),void(this.ut=null)}if(!this.bt||this.xt<=0)return;const n=this.ct,a=(r+i)/2,h=(s+o)/2,u=Math.abs(i-r)||1,d=Math.abs(o-s)||1,f=this.wt!==0;let g=0,p=0,b=0,w=1;if(f){const v=this.At(a-u/2,h-d/2,u,d);g=v.centerX,p=v.centerY,b=v.radians,w=v.aspectRatio}this.yt(n),this.Pt("u_color",this.vt),f&&(this.Pt("u_rotation",b),this.Pt("u_center",[g,p]),this.Pt("u_aspectRatio",w)),this.dt.ht(r,s,i,o,this.xt)}At(r,s,i,o){const n=W(this.v)||[0,0,this.v.canvas.width,this.v.canvas.height],a=n[2],h=n[3],u=a/h;return{centerX:(r+i/2)/a*2-1,centerY:1-(s+o/2)/h*2,radians:this.wt*Math.PI/180,aspectRatio:u}}Et(r,s,i={}){return new H(this.v,r,s,i)}Lt(r,s=r,i=r,o=255){this.Ot(r/255,s/255,i/255,o/255)}Ot(r=0,s=0,i=0,o=0){this.v.clearColor(r,s,i,o),this.v.clear(this.v.COLOR_BUFFER_BIT)}Bt(){this.v.viewport(0,0,this.v.canvas.width,this.v.canvas.height),B(this.v,[0,0,this.v.canvas.width,this.v.canvas.height])}get context(){return this.v}P(){this.lt.P(),this.ct.P(),this.ft.P(),this.dt.P()}Ht(r,s,i,o,n){const a=this.v,h=o??r.width,u=n??r.height;this.yt(this.lt),this.Pt("u_texture",r.texture);const d=this.At(s,i,h,u);this.Pt("u_rotation",d.radians),this.Pt("u_center",[d.centerX,d.centerY]),this.Pt("u_aspectRatio",d.aspectRatio),this.ft.ot(s,i,h,u),a.bindTexture(a.TEXTURE_2D,null),this.ut=null}}var S,m={parse:function(l){var r=function(s,i,o,n){var a=m.T,h={cmap:a.cmap,head:a.head,hhea:a.hhea,maxp:a.maxp,hmtx:a.hmtx,loca:a.loca,glyf:a.glyf},u={_data:s,_index:i,_offset:o};for(var d in h){var f=m.findTable(s,d,o);if(f){var g=f[0],p=n[g];p==null&&(p=h[d].parseTab(s,g,f[1],u)),u[d]=n[g]=p}}return u}(new Uint8Array(l),0,0,{});return[r]},findTable:function(l,r,s){for(var i=m.B,o=i.readUshort(l,s+4),n=s+12,a=0;a<o;a++){var h=i.readASCII(l,n,4);i.readUint(l,n+4);var u=i.readUint(l,n+8),d=i.readUint(l,n+12);if(h==r)return[u,d];n+=16}return null},T:{}};m.B={readShort:function(l,r){return m.B.t.uint16[0]=l[r]<<8|l[r+1],m.B.t.int16[0]},readUshort:function(l,r){return l[r]<<8|l[r+1]},readUshorts:function(l,r,s){for(var i=[],o=0;o<s;o++)i.push(m.B.readUshort(l,r+2*o));return i},readUint:function(l,r){var s=m.B.t.uint8;return s[3]=l[r],s[2]=l[r+1],s[1]=l[r+2],s[0]=l[r+3],m.B.t.uint32[0]},readASCII:function(l,r,s){for(var i="",o=0;o<s;o++)i+=String.fromCharCode(l[r+o]);return i},t:(S=new ArrayBuffer(8),{uint8:new Uint8Array(S),int16:new Int16Array(S),uint16:new Uint16Array(S),uint32:new Uint32Array(S)})},m.T.cmap={parseTab:function(l,r,s){var i={tables:[],ids:{},off:r};l=new Uint8Array(l.buffer,r,s),r=0;var o=m.B,n=o.readUshort,a=m.T.cmap;n(l,r);var h=n(l,r+=2);r+=2;for(var u=[],d=0;d<h;d++){var f=n(l,r),g=n(l,r+=2);r+=2;var p=o.readUint(l,r);r+=4;var b="p"+f+"e"+g,w=u.indexOf(p);if(w==-1){w=i.tables.length;var v={};u.push(p);var y=v.format=n(l,p);y==4?v=a.parse4(l,p,v):y==12&&(v=a.parse12(l,p,v)),i.tables.push(v)}i.ids[b]!=null&&console.log("multiple tables for one platform+encoding: "+b),i.ids[b]=w}return i},parse4:function(l,r,s){var i=m.B,o=i.readUshort,n=i.readUshorts,a=r,h=o(l,r+=2);o(l,r+=2);var u=o(l,r+=2);r+=2;var d=u>>>1;s.searchRange=o(l,r),r+=2,s.entrySelector=o(l,r),r+=2,s.rangeShift=o(l,r),r+=2,s.endCount=n(l,r,d),r+=2*d,r+=2,s.startCount=n(l,r,d),r+=2*d,s.idDelta=[];for(var f=0;f<d;f++)s.idDelta.push(i.readShort(l,r)),r+=2;return s.idRangeOffset=n(l,r,d),r+=2*d,s.glyphIdArray=n(l,r,a+h-r>>1),s},parse12:function(l,r,s){var i=m.B.readUint;i(l,r+=4),i(l,r+=4);var o=3*i(l,r+=4);r+=4;for(var n=s.groups=new Uint32Array(o),a=0;a<o;a+=3)n[a]=i(l,r+(a<<2)),n[a+1]=i(l,r+(a<<2)+4),n[a+2]=i(l,r+(a<<2)+8);return s}},m.T.head={parseTab:function(l,r,s){var i=m.B,o={};return r+=18,o.unitsPerEm=i.readUshort(l,r),r+=2,r+=16,o.xMin=i.readShort(l,r),r+=2,o.yMin=i.readShort(l,r),r+=2,o.xMax=i.readShort(l,r),r+=2,o.yMax=i.readShort(l,r),r+=2,r+=6,o.indexToLocFormat=i.readShort(l,r),o}},m.T.hhea={parseTab:function(l,r,s){var i=m.B,o={};r+=4;for(var n=["ascender","descender","lineGap","advanceWidthMax","minLeftSideBearing","minRightSideBearing","xMaxExtent","caretSlopeRise","caretSlopeRun","caretOffset","res0","res1","res2","res3","metricDataFormat","numberOfHMetrics"],a=0;a<n.length;a++){var h=n[a],u=h=="advanceWidthMax"||h=="numberOfHMetrics"?i.readUshort:i.readShort;o[h]=u(l,r+2*a)}return o}},m.T.hmtx={parseTab:function(l,r,s,i){for(var o=m.B,n=[],a=[],h=i.maxp.numGlyphs,u=i.hhea.numberOfHMetrics,d=0,f=0,g=0;g<u;)d=o.readUshort(l,r+(g<<2)),f=o.readShort(l,r+(g<<2)+2),n.push(d),a.push(f),g++;for(;g<h;)n.push(d),a.push(f),g++;return{aWidth:n,lsBearing:a}}},m.T.maxp={parseTab:function(l,r,s){var i=m.B,o=i.readUshort,n={};return i.readUint(l,r),r+=4,n.numGlyphs=o(l,r),r+=2,n}},m.T.loca={parseTab:function(l,r,s,i){var o=m.B,n=[],a=i.head.indexToLocFormat,h=i.maxp.numGlyphs+1;if(a==0)for(var u=0;u<h;u++)n.push(o.readUshort(l,r+(u<<1))<<1);if(a==1)for(u=0;u<h;u++)n.push(o.readUint(l,r+(u<<2)));return n}},m.T.glyf={parseTab:function(l,r,s,i){for(var o=[],n=i.maxp.numGlyphs,a=0;a<n;a++)o.push(null);return o},jt:function(l,r){var s=m.B,i=l._data,o=l.loca;if(o[r]==o[r+1])return null;var n=m.findTable(i,"glyf",l._offset)[0]+o[r],a={};if(a.noc=s.readShort(i,n),n+=2,a.xMin=s.readShort(i,n),n+=2,a.yMin=s.readShort(i,n),n+=2,a.xMax=s.readShort(i,n),n+=2,a.yMax=s.readShort(i,n),n+=2,a.xMin>=a.xMax||a.yMin>=a.yMax)return null;if(a.noc>0){a.endPts=[];for(var h=0;h<a.noc;h++)a.endPts.push(s.readUshort(i,n)),n+=2;var u=s.readUshort(i,n);if(n+=2,i.length-n<u)return null;n+=u;var d=a.endPts[a.noc-1]+1;for(a.flags=[],h=0;h<d;h++){var f=i[n];if(n++,a.flags.push(f),8&f){var g=i[n];n++;for(var p=0;p<g;p++)a.flags.push(f),h++}}for(a.xs=[],h=0;h<d;h++){var b=!!(2&a.flags[h]),w=!!(16&a.flags[h]);b?(a.xs.push(w?i[n]:-i[n]),n++):w?a.xs.push(0):(a.xs.push(s.readShort(i,n)),n+=2)}for(a.ys=[],h=0;h<d;h++)b=!!(4&a.flags[h]),w=!!(32&a.flags[h]),b?(a.ys.push(w?i[n]:-i[n]),n++):w?a.ys.push(0):(a.ys.push(s.readShort(i,n)),n+=2);var v=0,y=0;for(h=0;h<d;h++)v+=a.xs[h],y+=a.ys[h],a.xs[h]=v,a.ys[h]=y}else a.parts=[];return a}},typeof module<"u"&&module.exports?module.exports=m:typeof window<"u"&&(window.Typr=m);class ht{extractCharacters(r){var i;const s=[];return(i=r==null?void 0:r.cmap)!=null&&i.tables?(r.cmap.tables.forEach(o=>{if(o.format===4){const n=this.Wt(o);s.push(...n)}else if(o.format===12){const n=this.Nt(o);s.push(...n)}}),[...new Set(s)]):[]}Wt(r){const s=[];if(!(r.startCount&&r.endCount&&r.idRangeOffset&&r.idDelta))return s;for(let i=0;i<r.startCount.length;i++){const o=r.startCount[i],n=r.endCount[i];if(o!==65535||n!==65535){for(let a=o;a<=n;a++)if(this.Xt(r,a,i)>0){const h=String.fromCodePoint(a);s.push(h)}}}return s}Nt(r){const s=[];if(!r.groups)return s;for(let i=0;i<r.groups.length;i+=3){const o=r.groups[i],n=r.groups[i+1],a=r.groups[i+2];for(let h=o;h<=n;h++)if(a+(h-o)>0){const u=String.fromCodePoint(h);s.push(u)}}return s}Xt(r,s,i){if(r.idRangeOffset[i]===0)return s+r.idDelta[i]&65535;{const o=r.idRangeOffset[i]/2+(s-r.startCount[i])-(r.startCount.length-i);if(o>=0&&r.glyphIdArray&&o<r.glyphIdArray.length){const n=r.glyphIdArray[o];if(n!==0)return n+r.idDelta[i]&65535}}return 0}filterProblematicCharacters(r){return r.filter(s=>this.qt(s))}qt(r){const s=r.codePointAt(0)||0;return!(s>=0&&s<=31&&s!==9&&s!==10&&s!==13||s>=127&&s<=159)}}class lt{constructor(r){c(this,"Yt");c(this,"Qt");c(this,"Zt");this.Zt=r,this.Yt=document.createElement("canvas"),this.Qt=this.Yt.getContext("2d",{willReadFrequently:!0,alpha:!1})}createTextureAtlas(r,s,i,o){const n=r.length,a=Math.ceil(Math.sqrt(n)),h=Math.ceil(n/a),u=s.width*a,d=s.height*h;this.Jt(u,d,i,o),this.Kt(r,s,a,i),this.te();const f=this.Zt.Et(u,d,{filter:"nearest"});return f.update(this.Yt),{framebuffer:f,columns:a,rows:h}}Jt(r,s,i,o){this.Yt.width=r,this.Yt.height=s,this.Yt.style.width=r+"px",this.Yt.style.height=r+"px",this.Qt.imageSmoothingEnabled=!1,this.Yt.style.imageRendering="pixelated",this.Qt.fillStyle="black",this.Qt.fillRect(0,0,r,s),this.Qt.font=`${i}px ${o}`,this.Qt.textBaseline="top",this.Qt.textAlign="left",this.Qt.fillStyle="white"}Kt(r,s,i,o){for(let n=0;n<r.length;n++){const a=n%i,h=Math.floor(n/i),u=a*s.width+.5*s.width,d=h*s.height+.5*s.height,f=Math.round(u-.5*s.width),g=Math.round(d-.5*o);this.Qt.fillText(r[n].character,f,g)}}te(r=128){const s=this.Qt.getImageData(0,0,this.Yt.width,this.Yt.height),i=s.data;for(let o=0;o<i.length;o+=4){const n=.299*i[o]+.587*i[o+1]+.114*i[o+2]>r+32?255:0;i[o]=n,i[o+1]=n,i[o+2]=n}this.Qt.putImageData(s,0,0)}}class ct{constructor(){c(this,"ee");c(this,"re");this.ee=document.createElement("canvas"),this.re=this.ee.getContext("2d")}calculateMaxGlyphDimensions(r,s,i){this.re.font=`${s}px ${i}`;let o=0,n=0;for(const a of r){const h=this.re.measureText(a);o=Math.max(o,h.width),n=Math.max(n,h.actualBoundingBoxAscent+h.actualBoundingBoxDescent)}return{width:o,height:n}}}class ut{createCharacterObjects(r,s){return r.map((i,o)=>{const n=i.codePointAt(0)||0,a=this.se(o);let h=0;if(s.hmtx&&s.hmtx.aWidth){const u=this.ie(s,n);u>0&&s.hmtx.aWidth[u]!==void 0&&(h=s.hmtx.aWidth[u])}return{character:i,unicode:n,color:a,advanceWidth:h}})}ie(r,s){const i=r.cmap;if(!i||!i.tables)return 0;for(const o of i.tables)if(o.format===4){for(let n=0;n<o.startCount.length;n++)if(s>=o.startCount[n]&&s<=o.endCount[n]){if(o.idRangeOffset[n]===0)return s+o.idDelta[n]&65535;{const a=o.idRangeOffset[n]/2+(s-o.startCount[n])-(o.startCount.length-n);if(a>=0&&a<o.glyphIdArray.length){const h=o.glyphIdArray[a];if(h!==0)return h+o.idDelta[n]&65535}}}}return 0}se(r){return[r%256,Math.floor(r/256)%256,Math.floor(r/65536)%256]}getCharacterColor(r,s){if(!_.p(typeof r=="string","Character must be a string.",{method:"getCharacterColor",providedValue:r}))return[0,0,0];const i=s.find(o=>o.character===r);return i?i.color:[0,0,0]}getCharacterColors(r,s){return _.p(typeof r=="string"&&r.length>0,"Characters must be a string with at least one character.",{method:"getCharacterColors",providedValue:r})?r.split("").map(i=>this.getCharacterColor(i,s)||[0,0,0]):[[0,0,0]]}}class Q{constructor(r,s=16){c(this,"oe");c(this,"ne",[]);c(this,"ae");c(this,"he",16);c(this,"le",0);c(this,"ce",0);c(this,"ue",{width:0,height:0});c(this,"fe");c(this,"de","UrsaFont");c(this,"me");c(this,"pe");c(this,"ge");c(this,"_e");this.he=s,this.me=new ht,this.pe=new lt(r),this.ge=new ct,this._e=new ut}async ve(r){let s;if(!r)throw new x("Embedded font not available. This appears to be a minified build - please provide `fontSource`.");{const i=await fetch(r);if(!i.ok)throw new x(`Failed to load font file: ${i.status} ${i.statusText}`);s=await i.arrayBuffer()}await this.xe(s),this.oe=m.parse(s)[0],await this.be()}we(r){if(r===void 0)return this.he;this.he=r,this.ue=this.ge.calculateMaxGlyphDimensions(this.ne.map(i=>i.character),this.he,this.de);const s=this.pe.createTextureAtlas(this.ne,this.ue,this.he,this.de);this.ae=s.framebuffer,this.le=s.columns,this.ce=s.rows}async Ce(r){try{const s=await fetch(r);if(!s.ok)throw new x(`Failed to load font file: ${s.status} ${s.statusText}`);const i=await s.arrayBuffer();await this.xe(i);const o=m.parse(i);if(!o||o.length===0)throw Error("Failed to parse font file");this.oe=o[0],await this.be()}catch(s){throw new x("Failed to load font: "+(s instanceof Error?s.message:"Unknown error"),s)}}async xe(r){const s=Date.now();this.de=this.de==="UrsaFont"?"UrsaFont":"CustomFont_"+s,this.fe=new FontFace(this.de,r),await this.fe.load(),document.fonts.add(this.fe)}async be(){const r=this.me.extractCharacters(this.oe),s=this.me.filterProblematicCharacters(r);this.ne=this._e.createCharacterObjects(s,this.oe),this.ue=this.ge.calculateMaxGlyphDimensions(s,this.he,this.de);const i=this.pe.createTextureAtlas(this.ne,this.ue,this.he,this.de);this.ae=i.framebuffer,this.le=i.columns,this.ce=i.rows}getCharacterColor(r){return this._e.getCharacterColor(r,this.ne)}getCharacterColors(r){return this._e.getCharacterColors(r,this.ne)}hasAllCharacters(r){if(typeof r!="string"||r.length===0)return!1;const s=new Set(this.ne.map(i=>i.character));for(const i of r)if(!s.has(i))return!1;return!0}P(){this.ae.P(),document.fonts.delete(this.fe)}get fontFramebuffer(){return this.ae}get characters(){return this.ne}get textureColumns(){return this.le}get textureRows(){return this.ce}get maxGlyphDimensions(){return this.ue}get fontSize(){return this.he}get font(){return this.oe}}class J{constructor(r,s,i){c(this,"ye");c(this,"$e");c(this,"F");c(this,"D");c(this,"Fe");c(this,"Te");c(this,"De",!1);c(this,"Me");c(this,"Se");c(this,"Re");this.Me=r,this.Se=s,this.Re=i,this.kt()}kt(){this.De||(this.ye=Math.floor(this.Me.width/this.Se),this.$e=Math.floor(this.Me.height/this.Re)),this.Ve()}Ve(){this.F=this.ye*this.Se,this.D=this.$e*this.Re,this.Fe=Math.floor((this.Me.width-this.F)/2),this.Te=Math.floor((this.Me.height-this.D)/2)}ke(r,s){this.Se=r,this.Re=s,this.kt()}ze(r,s){this.De=!0,this.ye=r,this.$e=s,this.Ve()}Ie(){this.De=!1,this.kt()}Pe(){this.De?this.Ve():this.kt()}Ue(r){if(r===void 0)return this.De;this.De=r}get cellWidth(){return this.Se}get cellHeight(){return this.Re}get cols(){return this.ye}get rows(){return this.$e}get width(){return this.F}get height(){return this.D}get offsetX(){return this.Fe}get offsetY(){return this.Te}}class K{constructor(r,s=!1,i={}){c(this,"Me");c(this,"Ae");c(this,"Ge");c(this,"Ee");c(this,"onTransformChange");this.Ae=r,this.Ge=s,this.Me=this.Le(i.width,i.height),s&&this.setupTransformObserver()}Le(r,s){var o;const i=document.createElement("canvas");if(i.className="textmodeCanvas",i.style.imageRendering="pixelated",this.Ge)i.width=r||800,i.height=s||600,document.body.appendChild(i);else{const n=this.Ae.getBoundingClientRect();let a=Math.round(n.width),h=Math.round(n.height);if(this.Ae instanceof HTMLVideoElement){const f=this.Ae;(a===0||h===0)&&f.videoWidth>0&&f.videoHeight>0&&(a=f.videoWidth,h=f.videoHeight)}i.width=a,i.height=h,i.style.position="absolute",i.style.pointerEvents="none";const u=window.getComputedStyle(this.Ae);let d=parseInt(u.zIndex||"0",10);isNaN(d)&&(d=0),i.style.zIndex=""+(d+1),this.Oe(i),(o=this.Ae.parentNode)==null||o.insertBefore(i,this.Ae.nextSibling)}return i}Oe(r){const s=this.Ae.getBoundingClientRect();let i=this.Ae.offsetParent;if(i&&i!==document.body){const o=i.getBoundingClientRect();r.style.top=s.top-o.top+"px",r.style.left=s.left-o.left+"px"}else r.style.top=s.top+window.scrollY+"px",r.style.left=s.left+window.scrollX+"px"}Pe(r,s){if(this.Ge)this.Me.width=r??this.Me.width,this.Me.height=s??this.Me.height;else{const i=this.Ae.getBoundingClientRect();let o=Math.round(i.width),n=Math.round(i.height);if(this.Ae instanceof HTMLVideoElement){const a=this.Ae;(o===0||n===0)&&a.videoWidth>0&&a.videoHeight>0&&(o=a.videoWidth,n=a.videoHeight)}this.Me.width=o,this.Me.height=n,this.Oe(this.Me)}}Be(){const r={alpha:!1,premultipliedAlpha:!1,preserveDrawingBuffer:!0,antialias:!1,depth:!1,stencil:!1,powerPreference:"high-performance"},s=this.Me.getContext("webgl2",r)||this.Me.getContext("webgl",r);if(!s)throw new x("WebGL context could not be created. Ensure your browser supports WebGL.");return s}setupTransformObserver(){this.Ee=new ResizeObserver(r=>{for(const s of r){const i=s.contentRect;!this.onTransformChange||Math.round(i.width)===this.Me.width&&Math.round(i.height)===this.Me.height||this.onTransformChange()}}),this.Ee.observe(this.Me)}P(){this.Ee&&this.Ee.disconnect();const r=this.Me.getContext("webgl")||this.Me.getContext("webgl2");if(r){const s=r.getExtension("WEBGL_lose_context");s&&s.loseContext()}this.Me.parentNode&&this.Me.parentNode.removeChild(this.Me)}get canvas(){return this.Me}get width(){return this.Me.width}get height(){return this.Me.height}}class Z{constructor(r,s,i,o={}){c(this,"Zt");c(this,"He");c(this,"je");c(this,"We");c(this,"Ne");c(this,"Xe");c(this,"qe");c(this,"Ye");c(this,"l");this.Zt=r,this.He=s,this.je=i,this.l=o;const n=this.je.cols,a=this.je.rows;this.We=this.Zt.Et(n,a),this.Ne=this.Zt.Et(n,a),this.Xe=this.Zt.Et(n,a),this.qe=this.Zt.Et(n,a),this.Ye=this.Zt.Et(n,a)}Pe(){const r=this.je.cols,s=this.je.rows;this.We.resize(r,s),this.Ne.resize(r,s),this.Xe.resize(r,s),this.qe.resize(r,s),this.Ye.resize(r,s)}enabled(r){this.l.enabled=r}enable(){this.enabled(!0)}disable(){this.enabled(!1)}P(){this.We.P(),this.Ne.P(),this.Xe.P(),this.qe.P(),this.Ye.P()}get characterFramebuffer(){return this.We}get primaryColorFramebuffer(){return this.Ne}get secondaryColorFramebuffer(){return this.Xe}get rotationFramebuffer(){return this.qe}get transformFramebuffer(){return this.Ye}get options(){return this.l}}class dt{constructor(r,s){c(this,"C");c(this,"Zt");c(this,"Qe");this.Zt=r,this.Qe=s;const i=Math.max(this.Qe.length,1);this.C=this.Zt.Et(i,1),this.Ze()}Ze(){const r=this.Qe.length;this.C.width!==r&&this.C.resize(r,1);const s=new Uint8Array(1*r*4);for(let i=0;i<r;i++){const o=this.Qe[i],n=4*i;s[n]=o[0],s[n+1]=o[1],s[n+2]=o[2],s[n+3]=255}this.C.updatePixels(s,r,1)}setColors(r){this.Qe=r,this.Ze()}get colors(){return this.Qe}get framebuffer(){return this.C}get texture(){return this.C.texture}}class N extends Z{constructor(s,i,o,n={}){super(s,i,o,n);c(this,"Je");this.Je=new dt(this.Zt,this.He.getCharacterColors(" .:-=+*%@#"))}characters(s){_.p(this.He.hasAllCharacters(s),"One or more characters do not exist in the current font.",{method:"characters",providedValue:s})&&(this.l.characters=s,this.Je.setColors(this.He.getCharacterColors(s)))}characterColor(s,i,o,n=255){const a=this.Ke(s,"characterColor",i,o,n);a&&(this.l.characterColor=a)}characterColorMode(s){this.tr(s,"characterColorMode")}cellColor(s,i,o,n=255){const a=this.Ke(s,"cellColor",i,o,n);a&&(this.l.cellColor=a)}cellColorMode(s){this.tr(s,"cellColorMode")}invert(s){this.er(s,"invert","Invert")}rotation(s){if(!_.p(typeof s=="number","Rotation angle must be a number.",{method:"rotation",providedValue:s}))return;(s%=360)<0&&(s+=360);const i=255*s/360,o=Math.floor(i)/255,n=Math.round(i-o);this.l.rotation=[o,n,0,1]}flipHorizontally(s){this.er(s,"flipHorizontally","Flip horizontally")}flipVertically(s){this.er(s,"flipVertically","Flip vertically")}Ke(s,i,o,n,a=255){let h,u,d,f;if(typeof s=="string"){const g=this.rr(s);if(!g)return _.p(!1,"Invalid hex color format. Use '#FF0000', '#F00', 'FF0000', or 'F00'.",{method:i,providedValue:s}),null;[h,u,d,f]=g}else if(h=s,u=o!==void 0?o:s,d=n!==void 0?n:s,f=a,!_.p([h,u,d,f].every(g=>g>=0&&g<=255),i.charAt(0).toUpperCase()+i.slice(1)+" color values must be between 0 and 255",{method:i,providedValues:{r:h,g:u,b:d,a:f}}))return null;return[h/255,u/255,d/255,f/255]}tr(s,i){_.p(["sampled","fixed"].includes(s),"Invalid color mode. Must be 'sampled' or 'fixed'.",{method:i,providedValue:s})&&(this.l[i]=s)}er(s,i,o){_.p(typeof s=="boolean"||typeof s=="number"&&Number.isInteger(s),o+" must be a boolean value or an integer (0 for false, any other number for true).",{method:i,providedValue:s})&&(this.l[i]=!!s)}rr(s){return s=s.replace(/^#/,""),/^[0-9A-Fa-f]{3}$|^[0-9A-Fa-f]{6}$/.test(s)?(s.length===3&&(s=s.split("").map(i=>i+i).join("")),[parseInt(s.slice(0,2),16),parseInt(s.slice(2,4),16),parseInt(s.slice(4,6),16),255]):null}}const $=`attribute vec2 a_position;\r
8
8
  attribute vec2 a_texCoord;\r
9
9
  varying vec2 v_uv;\r
10
10
  \r
@@ -42,7 +42,7 @@ void main() {\r
42
42
  \r
43
43
  gl_Position = vec4(pos, 0.0, 1.0);\r
44
44
  }\r
45
- `,ft={enabled:!0,characters:" .:-=+*%@#",characterColor:[1,1,1,1],characterColorMode:"sampled",cellColor:[0,0,0,1],cellColorMode:"fixed",invert:!1,rotation:[0,0,0,255],flipHorizontally:!1,flipVertically:!1,brightnessRange:[0,255]};class z extends N{constructor(s,i,o){super(s,i,o,{...ft});c(this,"sr");c(this,"ir");c(this,"nr");c(this,"ar");c(this,"hr");c(this,"lr");this.sr=new P(s.context,$,"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);}}"),this.ir=new P(s.context,$,"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);}}"),this.ar=new P(s.context,$,"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);}}"),this.hr=new P(s.context,$,"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);}}"),this.nr=new P(s.context,$,"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);}"),this.lr=this.Zt.Et(this.je.cols,this.je.rows)}cr(s){const i=this.je.cols,o=this.je.rows;this.lr.begin(),this.Zt.Ot(),this.Zt.yt(this.sr),this.Zt.Pt("u_sketchTexture",s),this.Zt.Pt("u_gridCellDimensions",[i,o]),this.Zt.Pt("u_brightnessRange",this.l.brightnessRange),this.Zt.Ut(0,0,i,o),this.lr.end(),this.Ne.begin(),this.Zt.Ot(),this.Zt.yt(this.ir),this.Zt.Pt("u_sampleTexture",this.lr),this.Zt.Pt("u_fillColor",this.l.characterColor),this.Zt.Pt("u_useFixedColor",this.l.characterColorMode==="fixed"),this.Zt.Ut(0,0,i,o),this.Ne.end(),this.Xe.begin(),this.Zt.Ot(),this.Zt.yt(this.ir),this.Zt.Pt("u_sampleTexture",this.lr),this.Zt.Pt("u_fillColor",this.l.cellColor),this.Zt.Pt("u_useFixedColor",this.l.cellColorMode==="fixed"),this.Zt.Ut(0,0,i,o),this.Xe.end(),this.Ye.begin(),this.Zt.Ot(),this.Zt.yt(this.ar),this.Zt.Pt("u_sampleTexture",this.lr),this.Zt.Pt("u_invert",this.l.invert),this.Zt.Pt("u_flipHorizontally",this.l.flipHorizontally),this.Zt.Pt("u_flipVertically",this.l.flipVertically),this.Zt.Ut(0,0,i,o),this.Ye.end(),this.qe.begin(),this.Zt.Ot(),this.Zt.yt(this.hr),this.Zt.Pt("u_sampleTexture",this.lr),this.Zt.Pt("u_rotationColor",this.l.rotation),this.Zt.Ut(0,0,i,o),this.qe.end(),this.We.begin(),this.Zt.Ot(),this.Zt.yt(this.nr),this.Zt.Pt("u_colorSampleFramebuffer",this.lr),this.Zt.Pt("u_charPaletteTexture",this.Je.texture),this.Zt.Pt("u_charPaletteSize",[this.Je.colors.length,1]),this.Zt.Pt("u_brightnessRange",this.l.brightnessRange),this.Zt.Ut(0,0,i,o),this.We.end()}Pe(){super.Pe(),this.lr.resize(this.je.cols,this.je.rows)}brightnessRange(s){y.p(Array.isArray(s)&&s.length===2&&s.every(i=>typeof i=="number"&&i>=0&&i<=255),"Brightness range must be an array of two numbers between 0 and 255.",{method:"brightnessRange",providedValue:s})&&(this.l.brightnessRange=s)}}const gt=Object.freeze(Object.defineProperty({__proto__:null,TextmodeBrightnessConverter:z,TextmodeConverter:Z,TextmodeFeatureConverter:N},Symbol.toStringTag,{value:"Module"}));class tt{constructor(r,s,i){c(this,"Zt");c(this,"oe");c(this,"je");c(this,"ur");c(this,"dr");c(this,"mr");c(this,"pr");c(this,"gr");c(this,"We");c(this,"Ne");c(this,"Xe");c(this,"qe");c(this,"Ye");this.Zt=r,this.oe=s,this.je=i,this.gr=this.Zt.zt(k,"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);float flippedRow=(u_charsetDimensions.y-1.0)-float(charRow);vec2 charCoord=vec2(float(charCol),flippedRow)/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);}"),this.dr=new z(r,s,i),this.mr=new Z(r,s,i),this.ur=[this.dr,this.mr],this.We=this.Zt.Et(i.cols,i.rows),this.Ne=this.Zt.Et(i.cols,i.rows),this.Xe=this.Zt.Et(i.cols,i.rows),this.qe=this.Zt.Et(i.cols,i.rows),this.Ye=this.Zt.Et(i.cols,i.rows),this.pr=this.Zt.Et(this.je.width,this.je.height)}_r(r){for(const i of this.ur)i.options.enabled&&i instanceof N&&i.cr(r);const s=(i,o)=>{i.begin(),this.Zt.Ot();for(const n of this.ur)n.options.enabled&&this.Zt.Ht(o(n),0,0);i.end()};s(this.We,i=>i.characterFramebuffer),s(this.Ne,i=>i.primaryColorFramebuffer),s(this.Xe,i=>i.secondaryColorFramebuffer),s(this.qe,i=>i.rotationFramebuffer),s(this.Ye,i=>i.transformFramebuffer),this.pr.begin(),this.Zt.Ot(),this.Zt.yt(this.gr),this.Zt.Pt("u_characterTexture",this.oe.fontFramebuffer),this.Zt.Pt("u_charsetDimensions",[this.oe.textureColumns,this.oe.textureRows]),this.Zt.Pt("u_asciiCharacterTexture",this.We.texture),this.Zt.Pt("u_primaryColorTexture",this.Ne.texture),this.Zt.Pt("u_secondaryColorTexture",this.Xe.texture),this.Zt.Pt("u_transformTexture",this.Ye.texture),this.Zt.Pt("u_rotationTexture",this.qe.texture),this.Zt.Pt("u_captureTexture",r.texture),this.Zt.Pt("u_backgroundMode",!1),this.Zt.Pt("u_captureDimensions",[r.width,r.height]),this.Zt.Pt("u_gridCellDimensions",[this.je.cols,this.je.rows]),this.Zt.Pt("u_gridPixelDimensions",[this.je.width,this.je.height]),this.Zt.Ut(0,0,this.pr.width,this.pr.height),this.pr.end()}add(r){if(!y.p(r==="brightness"||r==="custom",'Converter type must be either "brightness" or "custom".',{method:"add",providedValue:r}))return;let s;return s=r==="brightness"?new z(this.Zt,this.oe,this.je):new Z(this.Zt,this.oe,this.je),this.ur.push(s),s}remove(r){if(!y.p(r instanceof Z,"Parameter must be a TextmodeConverter instance.",{method:"remove",providedValue:r}))return;const s=this.ur.indexOf(r);y.p(s!==-1,"Converter instance not found in pipeline.",{method:"remove",providedValue:r,convertersCount:this.ur.length})&&this.ur.splice(s,1)}Pe(){this.pr.resize(this.je.width,this.je.height);const r=this.je.cols,s=this.je.rows;this.We.resize(r,s),this.Ne.resize(r,s),this.Xe.resize(r,s),this.qe.resize(r,s),this.Ye.resize(r,s);for(const i of this.ur)i.Pe()}hasEnabledConverters(){return this.ur.some(r=>r.options.enabled)}disable(){for(const r of this.ur)r.disable()}enable(){for(const r of this.ur)r.enable()}P(){for(const r of this.ur)r.P();this.We.P(),this.Ne.P(),this.Xe.P(),this.qe.P(),this.Ye.P(),this.pr.P(),this.gr.P()}get texture(){return this.pr}get characterFramebuffer(){return this.We}get primaryColorFramebuffer(){return this.Ne}get secondaryColorFramebuffer(){return this.Xe}get rotationFramebuffer(){return this.qe}get transformFramebuffer(){return this.Ye}get brightness(){return this.dr}get custom(){return this.mr}}const pt=l=>class extends l{fill(r,s,i,o){this.Zt.$t(r,s,i,o)}stroke(r,s,i,o){this.Zt.Ft(r,s,i,o)}strokeWeight(r){this.Zt.Tt(r)}noStroke(){this.Zt.Dt()}noFill(){this.Zt.Mt()}rotate(r){this.Zt.St(r)}push(){this.Zt.Rt()}pop(){this.Zt.Vt()}rect(r,s,i=1,o=1){this.Zt.Ut(r,s,i,o)}line(r,s,i,o){this.Zt.Gt(r,s,i,o)}background(r,s=r,i=r,o=255){this.Zt.Lt(r,s,i,o)}createShader(r,s){return this.Zt.zt(r,s)}createFilterShader(r){return this.Zt.It(r)}shader(r){this.Zt.yt(r)}setUniform(r,s){this.Zt.Pt(r,s)}};class V{vr(r){const s=r.get("brightness"),i=s==null?void 0:s.characterFramebuffer,o=s==null?void 0:s.primaryColorFramebuffer,n=s==null?void 0:s.secondaryColorFramebuffer,a=s==null?void 0:s.transformFramebuffer,h=s==null?void 0:s.rotationFramebuffer;return i==null||i.loadPixels(),o==null||o.loadPixels(),n==null||n.loadPixels(),a==null||a.loadPixels(),h==null||h.loadPixels(),{characterPixels:(i==null?void 0:i.pixels)||new Uint8Array(0),primaryColorPixels:(o==null?void 0:o.pixels)||new Uint8Array(0),secondaryColorPixels:(n==null?void 0:n.pixels)||new Uint8Array(0),transformPixels:(a==null?void 0:a.pixels)||new Uint8Array(0),rotationPixels:(h==null?void 0:h.pixels)||new Uint8Array(0)}}br(r,s){return r[s]+(r[s+1]<<8)}wr(r,s){return{r:r[s],g:r[s+1],b:r[s+2],a:r[s+3]}}}class Y{Cr(r,s){return new Blob([r],{type:s})}yr(r,s,i){try{const o=this.Cr(r,i),n=URL.createObjectURL(o),a=document.createElement("a");a.href=n,a.download=s,a.style.display="none",a.rel="noopener",document.body.appendChild(a),a.click(),document.body.removeChild(a),URL.revokeObjectURL(n)}catch(o){throw console.error("Failed to download file:",o),Error("File download failed: "+(o instanceof Error?o.message:"Unknown error"))}}$r(){return new Date().toISOString().slice(0,19).replace(/:/g,"-")}Fr(){const r=new Date;return{date:r.toISOString().split("T")[0],time:r.toTimeString().split(" ")[0].replace(/:/g,"-")}}Tr(r){return r.replace(/[<>:"/\\|?*]/g,"_").replace(/\s+/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").substring(0,255)}Dr(){return"'textmode-export'-"+this.$r()}}class mt extends V{Mr(r,s,i){const o=r[i]===255,n=r[i+1]===255,a=r[i+2]===255,h=s[i],u=s[i+1];return{isInverted:o,flipHorizontal:n,flipVertical:a,rotation:Math.round(360*(h+u/255)/255*100)/100}}Sr(r,s,i){return{x:r,y:s,cellX:r*i.cellWidth,cellY:s*i.cellHeight}}Rr(r,s){const i=[];let o=0;for(let n=0;n<s.rows;n++)for(let a=0;a<s.cols;a++){const h=4*o,u=this.br(r.characterPixels,h);let d=this.wr(r.primaryColorPixels,h),f=this.wr(r.secondaryColorPixels,h);const g=this.Mr(r.transformPixels,r.rotationPixels,h);if(g.isInverted){const b=d;d=f,f=b}const p=this.Sr(a,n,s);i.push({charIndex:u,primaryColor:d,secondaryColor:f,transform:g,position:p}),o++}return i}}class vt{ie(r,s){const i=r.cmap;for(const o of i.tables)if(o.format===4){for(let n=0;n<o.startCount.length;n++)if(s>=o.startCount[n]&&s<=o.endCount[n]){if(o.idRangeOffset[n]===0)return s+o.idDelta[n]&65535;{const a=o.idRangeOffset[n]/2+(s-o.startCount[n])-(o.startCount.length-n);if(a>=0&&a<o.glyphIdArray.length){const h=o.glyphIdArray[a];if(h!==0)return h+o.idDelta[n]&65535}}}}return 0}Vr(r,s,i,o,n){const a=n/r.head.unitsPerEm;return{getBoundingBox:()=>({x1:i+s.xMin*a,y1:o+-s.yMax*a,x2:i+s.xMax*a,y2:o+-s.yMin*a}),toSVG:()=>this.kr(s,i,o,a)}}kr(r,s,i,o){if(!r||!r.xs)return"";const{xs:n,ys:a,endPts:h,flags:u}=r;if(!(n&&a&&h&&u))return"";let d="",f=0;for(let g=0;g<h.length;g++){const p=h[g];if(!(p<f)){if(p>=f){const b=s+n[f]*o,w=i-a[f]*o;d+=`M${b.toFixed(2)},${w.toFixed(2)}`;let v=f+1;for(;v<=p;)if(1&u[v]){const _=s+n[v]*o,E=i-a[v]*o;d+=`L${_.toFixed(2)},${E.toFixed(2)}`,v++}else{const _=s+n[v]*o,E=i-a[v]*o;let T=v+1>p?f:v+1;if(1&u[T]){const F=s+n[T]*o,A=i-a[T]*o;d+=`Q${_.toFixed(2)},${E.toFixed(2)} ${F.toFixed(2)},${A.toFixed(2)}`,v=T+1}else{const F=(_+(s+n[T]*o))/2,A=(E+(i-a[T]*o))/2;d+=`Q${_.toFixed(2)},${E.toFixed(2)} ${F.toFixed(2)},${A.toFixed(2)}`,v=T}}d+="Z"}f=p+1}}return d}zr(r,s,i,o,n){const a=r.codePointAt(0)||0,h=this.ie(s,a);let u=null;return s.glyf&&s.glyf[h]!==null?u=s.glyf[h]:m&&m.T&&m.T.glyf&&m.T.glyf.jt&&(u=m.T.glyf.jt(s,h),s.glyf&&u&&(s.glyf[h]=u)),this.Vr(s,u,i,o,n)}Ir(r,s,i,o,n,a,h,u){const d=i+(n-u*(h/s.head.unitsPerEm))/2,f=o+(a+.7*h)/2;return this.zr(r,s,d,f,h).toSVG()||null}}class xt{constructor(){c(this,"Pr");this.Pr=new vt}Ur(r){return`<?xml version="1.0" encoding="UTF-8" standalone="no"?>
45
+ `,ft={enabled:!0,characters:" .:-=+*%@#",characterColor:[1,1,1,1],characterColorMode:"sampled",cellColor:[0,0,0,1],cellColorMode:"fixed",invert:!1,rotation:[0,0,0,255],flipHorizontally:!1,flipVertically:!1,brightnessRange:[0,255]};class z extends N{constructor(s,i,o){super(s,i,o,{...ft});c(this,"sr");c(this,"ir");c(this,"nr");c(this,"ar");c(this,"hr");c(this,"lr");this.sr=new P(s.context,$,"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);}}"),this.ir=new P(s.context,$,"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);}}"),this.ar=new P(s.context,$,"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);}}"),this.hr=new P(s.context,$,"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);}}"),this.nr=new P(s.context,$,"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);}"),this.lr=this.Zt.Et(this.je.cols,this.je.rows)}cr(s){const i=this.je.cols,o=this.je.rows;this.lr.begin(),this.Zt.Ot(),this.Zt.yt(this.sr),this.Zt.Pt("u_sketchTexture",s),this.Zt.Pt("u_gridCellDimensions",[i,o]),this.Zt.Pt("u_brightnessRange",this.l.brightnessRange),this.Zt.Ut(0,0,i,o),this.lr.end(),this.Ne.begin(),this.Zt.Ot(),this.Zt.yt(this.ir),this.Zt.Pt("u_sampleTexture",this.lr),this.Zt.Pt("u_fillColor",this.l.characterColor),this.Zt.Pt("u_useFixedColor",this.l.characterColorMode==="fixed"),this.Zt.Ut(0,0,i,o),this.Ne.end(),this.Xe.begin(),this.Zt.Ot(),this.Zt.yt(this.ir),this.Zt.Pt("u_sampleTexture",this.lr),this.Zt.Pt("u_fillColor",this.l.cellColor),this.Zt.Pt("u_useFixedColor",this.l.cellColorMode==="fixed"),this.Zt.Ut(0,0,i,o),this.Xe.end(),this.Ye.begin(),this.Zt.Ot(),this.Zt.yt(this.ar),this.Zt.Pt("u_sampleTexture",this.lr),this.Zt.Pt("u_invert",this.l.invert),this.Zt.Pt("u_flipHorizontally",this.l.flipHorizontally),this.Zt.Pt("u_flipVertically",this.l.flipVertically),this.Zt.Ut(0,0,i,o),this.Ye.end(),this.qe.begin(),this.Zt.Ot(),this.Zt.yt(this.hr),this.Zt.Pt("u_sampleTexture",this.lr),this.Zt.Pt("u_rotationColor",this.l.rotation),this.Zt.Ut(0,0,i,o),this.qe.end(),this.We.begin(),this.Zt.Ot(),this.Zt.yt(this.nr),this.Zt.Pt("u_colorSampleFramebuffer",this.lr),this.Zt.Pt("u_charPaletteTexture",this.Je.texture),this.Zt.Pt("u_charPaletteSize",[this.Je.colors.length,1]),this.Zt.Pt("u_brightnessRange",this.l.brightnessRange),this.Zt.Ut(0,0,i,o),this.We.end()}Pe(){super.Pe(),this.lr.resize(this.je.cols,this.je.rows)}brightnessRange(s){_.p(Array.isArray(s)&&s.length===2&&s.every(i=>typeof i=="number"&&i>=0&&i<=255),"Brightness range must be an array of two numbers between 0 and 255.",{method:"brightnessRange",providedValue:s})&&(this.l.brightnessRange=s)}}const gt=Object.freeze(Object.defineProperty({__proto__:null,TextmodeBrightnessConverter:z,TextmodeConverter:Z,TextmodeFeatureConverter:N},Symbol.toStringTag,{value:"Module"}));class tt{constructor(r,s,i){c(this,"Zt");c(this,"oe");c(this,"je");c(this,"ur");c(this,"dr");c(this,"mr");c(this,"pr");c(this,"gr");c(this,"We");c(this,"Ne");c(this,"Xe");c(this,"qe");c(this,"Ye");this.Zt=r,this.oe=s,this.je=i,this.gr=this.Zt.zt(k,"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);float flippedRow=(u_charsetDimensions.y-1.0)-float(charRow);vec2 charCoord=vec2(float(charCol),flippedRow)/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);}"),this.dr=new z(r,s,i),this.mr=new Z(r,s,i),this.ur=[this.dr,this.mr],this.We=this.Zt.Et(i.cols,i.rows),this.Ne=this.Zt.Et(i.cols,i.rows),this.Xe=this.Zt.Et(i.cols,i.rows),this.qe=this.Zt.Et(i.cols,i.rows),this.Ye=this.Zt.Et(i.cols,i.rows),this.pr=this.Zt.Et(this.je.width,this.je.height)}_r(r){for(const i of this.ur)i.options.enabled&&i instanceof N&&i.cr(r);const s=(i,o)=>{i.begin(),this.Zt.Ot();for(const n of this.ur)n.options.enabled&&this.Zt.Ht(o(n),0,0);i.end()};s(this.We,i=>i.characterFramebuffer),s(this.Ne,i=>i.primaryColorFramebuffer),s(this.Xe,i=>i.secondaryColorFramebuffer),s(this.qe,i=>i.rotationFramebuffer),s(this.Ye,i=>i.transformFramebuffer),this.pr.begin(),this.Zt.Ot(),this.Zt.yt(this.gr),this.Zt.Pt("u_characterTexture",this.oe.fontFramebuffer),this.Zt.Pt("u_charsetDimensions",[this.oe.textureColumns,this.oe.textureRows]),this.Zt.Pt("u_asciiCharacterTexture",this.We.texture),this.Zt.Pt("u_primaryColorTexture",this.Ne.texture),this.Zt.Pt("u_secondaryColorTexture",this.Xe.texture),this.Zt.Pt("u_transformTexture",this.Ye.texture),this.Zt.Pt("u_rotationTexture",this.qe.texture),this.Zt.Pt("u_captureTexture",r.texture),this.Zt.Pt("u_backgroundMode",!1),this.Zt.Pt("u_captureDimensions",[r.width,r.height]),this.Zt.Pt("u_gridCellDimensions",[this.je.cols,this.je.rows]),this.Zt.Pt("u_gridPixelDimensions",[this.je.width,this.je.height]),this.Zt.Ut(0,0,this.pr.width,this.pr.height),this.pr.end()}add(r){if(!_.p(r==="brightness"||r==="custom",'Converter type must be either "brightness" or "custom".',{method:"add",providedValue:r}))return;let s;return s=r==="brightness"?new z(this.Zt,this.oe,this.je):new Z(this.Zt,this.oe,this.je),this.ur.push(s),s}remove(r){if(!_.p(r instanceof Z,"Parameter must be a TextmodeConverter instance.",{method:"remove",providedValue:r}))return;const s=this.ur.indexOf(r);_.p(s!==-1,"Converter instance not found in pipeline.",{method:"remove",providedValue:r,convertersCount:this.ur.length})&&this.ur.splice(s,1)}Pe(){this.pr.resize(this.je.width,this.je.height);const r=this.je.cols,s=this.je.rows;this.We.resize(r,s),this.Ne.resize(r,s),this.Xe.resize(r,s),this.qe.resize(r,s),this.Ye.resize(r,s);for(const i of this.ur)i.Pe()}hasEnabledConverters(){return this.ur.some(r=>r.options.enabled)}disable(){for(const r of this.ur)r.disable()}enable(){for(const r of this.ur)r.enable()}P(){for(const r of this.ur)r.P();this.We.P(),this.Ne.P(),this.Xe.P(),this.qe.P(),this.Ye.P(),this.pr.P(),this.gr.P()}get texture(){return this.pr}get characterFramebuffer(){return this.We}get primaryColorFramebuffer(){return this.Ne}get secondaryColorFramebuffer(){return this.Xe}get rotationFramebuffer(){return this.qe}get transformFramebuffer(){return this.Ye}get brightness(){return this.dr}get custom(){return this.mr}}const pt=l=>class extends l{fill(r,s,i,o){this.Zt.$t(r,s,i,o)}stroke(r,s,i,o){this.Zt.Ft(r,s,i,o)}strokeWeight(r){this.Zt.Tt(r)}noStroke(){this.Zt.Dt()}noFill(){this.Zt.Mt()}rotate(r){this.Zt.St(r)}push(){this.Zt.Rt()}pop(){this.Zt.Vt()}rect(r,s,i=1,o=1){this.Zt.Ut(r,s,i,o)}line(r,s,i,o){this.Zt.Gt(r,s,i,o)}background(r,s=r,i=r,o=255){this.Zt.Lt(r,s,i,o)}createShader(r,s){return this.Zt.zt(r,s)}createFilterShader(r){return this.Zt.It(r)}shader(r){this.Zt.yt(r)}setUniform(r,s){this.Zt.Pt(r,s)}};class V{vr(r){const s=r.characterFramebuffer,i=r.primaryColorFramebuffer,o=r.secondaryColorFramebuffer,n=r.transformFramebuffer,a=r.rotationFramebuffer;return s==null||s.loadPixels(),i==null||i.loadPixels(),o==null||o.loadPixels(),n==null||n.loadPixels(),a==null||a.loadPixels(),{characterPixels:(s==null?void 0:s.pixels)||new Uint8Array(0),primaryColorPixels:(i==null?void 0:i.pixels)||new Uint8Array(0),secondaryColorPixels:(o==null?void 0:o.pixels)||new Uint8Array(0),transformPixels:(n==null?void 0:n.pixels)||new Uint8Array(0),rotationPixels:(a==null?void 0:a.pixels)||new Uint8Array(0)}}br(r,s){return r[s]+(r[s+1]<<8)}wr(r,s){return{r:r[s],g:r[s+1],b:r[s+2],a:r[s+3]}}}class Y{Cr(r,s){return new Blob([r],{type:s})}yr(r,s,i){try{const o=this.Cr(r,i),n=URL.createObjectURL(o),a=document.createElement("a");a.href=n,a.download=s,a.style.display="none",a.rel="noopener",document.body.appendChild(a),a.click(),document.body.removeChild(a),URL.revokeObjectURL(n)}catch(o){throw console.error("Failed to download file:",o),Error("File download failed: "+(o instanceof Error?o.message:"Unknown error"))}}$r(){return new Date().toISOString().slice(0,19).replace(/:/g,"-")}Fr(){const r=new Date;return{date:r.toISOString().split("T")[0],time:r.toTimeString().split(" ")[0].replace(/:/g,"-")}}Tr(r){return r.replace(/[<>:"/\\|?*]/g,"_").replace(/\s+/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").substring(0,255)}Dr(){return"'textmode-export'-"+this.$r()}}class mt extends V{Mr(r,s,i){const o=r[i]===255,n=r[i+1]===255,a=r[i+2]===255,h=s[i],u=s[i+1];return{isInverted:o,flipHorizontal:n,flipVertical:a,rotation:Math.round(360*(h+u/255)/255*100)/100}}Sr(r,s,i){return{x:r,y:s,cellX:r*i.cellWidth,cellY:s*i.cellHeight}}Rr(r,s){const i=[];let o=0;for(let n=0;n<s.rows;n++)for(let a=0;a<s.cols;a++){const h=4*o,u=this.br(r.characterPixels,h);let d=this.wr(r.primaryColorPixels,h),f=this.wr(r.secondaryColorPixels,h);const g=this.Mr(r.transformPixels,r.rotationPixels,h);if(g.isInverted){const b=d;d=f,f=b}const p=this.Sr(a,n,s);i.push({charIndex:u,primaryColor:d,secondaryColor:f,transform:g,position:p}),o++}return i}}class vt{ie(r,s){const i=r.cmap;for(const o of i.tables)if(o.format===4){for(let n=0;n<o.startCount.length;n++)if(s>=o.startCount[n]&&s<=o.endCount[n]){if(o.idRangeOffset[n]===0)return s+o.idDelta[n]&65535;{const a=o.idRangeOffset[n]/2+(s-o.startCount[n])-(o.startCount.length-n);if(a>=0&&a<o.glyphIdArray.length){const h=o.glyphIdArray[a];if(h!==0)return h+o.idDelta[n]&65535}}}}return 0}Vr(r,s,i,o,n){const a=n/r.head.unitsPerEm;return{getBoundingBox:()=>({x1:i+s.xMin*a,y1:o+-s.yMax*a,x2:i+s.xMax*a,y2:o+-s.yMin*a}),toSVG:()=>this.kr(s,i,o,a)}}kr(r,s,i,o){if(!r||!r.xs)return"";const{xs:n,ys:a,endPts:h,flags:u}=r;if(!(n&&a&&h&&u))return"";let d="",f=0;for(let g=0;g<h.length;g++){const p=h[g];if(!(p<f)){if(p>=f){const b=s+n[f]*o,w=i-a[f]*o;d+=`M${b.toFixed(2)},${w.toFixed(2)}`;let v=f+1;for(;v<=p;)if(1&u[v]){const y=s+n[v]*o,E=i-a[v]*o;d+=`L${y.toFixed(2)},${E.toFixed(2)}`,v++}else{const y=s+n[v]*o,E=i-a[v]*o;let T=v+1>p?f:v+1;if(1&u[T]){const F=s+n[T]*o,A=i-a[T]*o;d+=`Q${y.toFixed(2)},${E.toFixed(2)} ${F.toFixed(2)},${A.toFixed(2)}`,v=T+1}else{const F=(y+(s+n[T]*o))/2,A=(E+(i-a[T]*o))/2;d+=`Q${y.toFixed(2)},${E.toFixed(2)} ${F.toFixed(2)},${A.toFixed(2)}`,v=T}}d+="Z"}f=p+1}}return d}zr(r,s,i,o,n){const a=r.codePointAt(0)||0,h=this.ie(s,a);let u=null;return s.glyf&&s.glyf[h]!==null?u=s.glyf[h]:m&&m.T&&m.T.glyf&&m.T.glyf.jt&&(u=m.T.glyf.jt(s,h),s.glyf&&u&&(s.glyf[h]=u)),this.Vr(s,u,i,o,n)}Ir(r,s,i,o,n,a,h,u){const d=i+(n-u*(h/s.head.unitsPerEm))/2,f=o+(a+.7*h)/2;return this.zr(r,s,d,f,h).toSVG()||null}}class xt{constructor(){c(this,"Pr");this.Pr=new vt}Ur(r){return`<?xml version="1.0" encoding="UTF-8" standalone="no"?>
46
46
  <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
47
47
  <svg width="${r.width}" height="${r.height}" viewBox="0 0 ${r.width} ${r.height}"
48
48
  xmlns="http://www.w3.org/2000/svg" version="1.1">
@@ -60,4 +60,4 @@ void main() {\r
60
60
  <g id="ascii-cells">`;for(const a of r)n+=this.Br(a,s,i,o);return n+=this.Ar(),n}jr(r){return r.replace(/<path[^>]*d=""[^>]*\/>/g,"").replace(/\n\s*\n/g,`
61
61
  `).replace(/[ \t]+$/gm,"")}}class bt extends Y{Wr(r){return this.Cr(r,"image/svg+xml;charset=utf-8")}Nr(r,s){this.yr(r,this.Tr(s)+".svg","image/svg+xml;charset=utf-8")}Xr(r,s){this.Nr(r,s||this.Dr())}}class et{constructor(){c(this,"qr");c(this,"Yr");c(this,"Qr");this.qr=new mt,this.Yr=new xt,this.Qr=new bt}Zr(r){return{includeBackgroundRectangles:r.includeBackgroundRectangles??!0,drawMode:r.drawMode??"fill",strokeWidth:r.strokeWidth??1,backgroundColor:r.backgroundColor??[0,0,0,0]}}Jr(r,s={}){const i=this.Zr(s),o=this.qr.vr(r.pipeline),n=this.qr.Rr(o,r.grid),a=this.Yr.Hr(n,r.grid,r.font,i);return this.Yr.jr(a)}Xr(r,s={}){const i=this.Jr(r,s),o=s.filename||this.Qr.Dr();this.Qr.Xr(i,o)}}class Ct extends V{Kr(r,s,i,o=" "){var h;const n=[];let a=0;for(let u=0;u<s.rows;u++){const d=[];for(let f=0;f<s.cols;f++){const g=4*a,p=this.br(r.characterPixels,g),b=((h=i.characters[p])==null?void 0:h.character)||o;d.push(b),a++}n.push(d)}return n}}class wt{ts(r,s){const i=[];for(const n of r){let a=n.join("");s.preserveTrailingSpaces||(a=a.replace(/\s+$/,"")),i.push(a)}const o=s.lineEnding==="crlf"?`\r
62
62
  `:`
63
- `;return i.join(o)}}class yt extends Y{es(r,s){const i=this.rs(s);this.yr(r,i,"text/plain;charset=utf-8")}rs(r){let s=this.Tr(r);return s===".txt"||s.length<=4?this.Dr():s}}class rt{constructor(){c(this,"qr");c(this,"Yr");c(this,"Qr");this.qr=new Ct,this.Yr=new wt,this.Qr=new yt}Zr(r){return{preserveTrailingSpaces:r.preserveTrailingSpaces??!1,lineEnding:r.lineEnding??"lf",emptyCharacter:r.emptyCharacter??" "}}ss(r,s={}){const i=this.Zr(s),o=this.qr.vr(r.pipeline),n=this.qr.Kr(o,r.grid,r.font,i.emptyCharacter);return this.Yr.ts(n,i)}es(r,s={}){const i=this.ss(r,s),o=s.filename||this.Qr.Dr();this.Qr.es(i,o)}}class _t extends V{ns(r,s=1,i="transparent"){const o=r.canvas;if(s===1&&i==="transparent")return o;const n=document.createElement("canvas"),a=n.getContext("2d"),h=Math.round(o.width*s),u=Math.round(o.height*s);return n.width=h,n.height=u,i!=="transparent"&&(a.fillStyle=i,a.fillRect(0,0,h,u)),a.imageSmoothingEnabled=!1,a.drawImage(o,0,0,o.width,o.height,0,0,h,u),n}}class Tt{hs(r,s){const i=this.ls(s.format);return s.format==="png"?r.toDataURL(i):r.toDataURL(i,s.quality)}async cs(r,s){return new Promise((i,o)=>{const n=this.ls(s.format),a=h=>{h?i(h):o(Error(`Failed to generate ${s.format.toUpperCase()} blob`))};s.format==="png"?r.toBlob(a,n):r.toBlob(a,n,s.quality)})}ls(r){switch(r){case"png":return"image/png";case"jpg":return"image/jpeg";case"webp":return"image/webp";default:throw Error("Unsupported image format: "+r)}}}const Et={png:"image/png",jpg:"image/jpeg",webp:"image/webp"},st={png:".png",jpg:".jpg",webp:".webp"};class Pt extends Y{us(r,s,i){this.fs(r,this.Tr(s)+st[i])}fs(r,s){const i=URL.createObjectURL(r);try{const o=document.createElement("a");o.href=i,o.download=s,o.style.display="none",o.rel="noopener",document.body.appendChild(o),o.click(),document.body.removeChild(o)}finally{URL.revokeObjectURL(i)}}ds(r){return r in Et&&r in st}}class Rt{constructor(){c(this,"qr");c(this,"Yr");c(this,"Qr");this.qr=new _t,this.Yr=new Tt,this.Qr=new Pt}Zr(r){return{format:r.format??"png",quality:r.quality??1,scale:r.scale??1,backgroundColor:r.backgroundColor??"transparent"}}ps(r){if(console.log("Validating image export options:",r),!this.Qr.ds(r.format))throw Error(`Saving '${r.format}' files is not supported`);if(r.quality<0||r.quality>1)throw Error("Image quality must be between 0.0 and 1.0");if(r.scale<=0)throw Error("Scale factor must be greater than 0");r.scale>10&&console.warn("Large scale factors may result in very large files and slow performance"),r.format==="jpg"&&r.backgroundColor==="transparent"&&(r.backgroundColor="black")}gs(r,s={}){const i=this.Zr(s);if(this.ps(i),i.scale===1&&i.backgroundColor==="transparent")return this.Yr.hs(r.canvas,i);const o=this.qr.ns(r,i.scale,i.backgroundColor);return this.Yr.hs(o,i)}async cs(r,s={}){const i=this.Zr(s);if(this.ps(i),i.scale===1&&i.backgroundColor==="transparent")return await this.Yr.cs(r.canvas,i);const o=this.qr.ns(r,i.scale,i.backgroundColor);return await this.Yr.cs(o,i)}async us(r,s={}){const i=await this.cs(r,s),o=s.format??"png",n=s.filename||this.Qr.Dr();this.Qr.us(i,n,o)}}const Mt=l=>class extends l{toString(r={}){return new rt().ss(this,r)}saveStrings(r={}){new rt().es(this,r)}toSVG(r={}){return new et().Jr(this,r)}saveSVG(r={}){new et().Xr(this,r)}async saveCanvas(r,s="png",i={}){await new Rt().us(this.Me,{...i,filename:r,format:s})}},Ft=l=>class extends l{async loadFont(r){return this.oe.Ce(r).then(()=>{const s=this.oe.maxGlyphDimensions;this.je.ke(s.width,s.height),this._s.Pe()})}fontSize(r){if(!y.p(typeof r=="number"&&r>0,"Font size must be a positive number greater than 0.",{method:"fontSize",providedValue:r})||this.oe.fontSize===r)return;this.oe.we(r);const s=this.oe.maxGlyphDimensions;this.je.ke(s.width,s.height),this._s.Pe(),this.Zt.Bt()}},At=l=>class extends l{addConverter(r){return this._s.add(r)}removeConverter(r){this._s.remove(r)}};class Dt{constructor(){c(this,"Zt");c(this,"oe");c(this,"_s");c(this,"Me");c(this,"je")}}class G extends function(s,...i){return i.reduce((o,n)=>n(o),s)}(Dt,pt,Mt,Ft,At){constructor(s=null,i={}){super();c(this,"Ae");c(this,"vs");c(this,"Ee");c(this,"bs");c(this,"ws");c(this,"Cs",null);c(this,"$s",0);c(this,"Fs");c(this,"Ts",!0);c(this,"Ds",0);c(this,"Ms",0);c(this,"Ss",0);c(this,"Rs",[]);c(this,"Vs",10);c(this,"ks",!1);c(this,"zs",!1);c(this,"Is",()=>{});c(this,"Ps",()=>{});c(this,"Us");this.Ae=s,this.zs=s===null,this.bs=i.renderMode??"auto",this.ws=i.frameRate??60,this.Fs=1e3/this.ws}static async create(s=null,i={}){const o=new this(s,i),n=o.zs?i:void 0;let a,h;o.Me=new K(o.captureSource,o.zs,n),o.Zt=new at(o.Me.Be()),o.zs?(a=i.width||800,h=i.height||600):(a=o.Me.width||800,h=o.Me.height||600),o.vs=o.Zt.Et(a,h),o.oe=new Q(o.Zt,i.fontSize??16),await o.oe.ve(i.fontSource);const u=o.oe.maxGlyphDimensions;return o.je=new J(o.Me.canvas,u.width,u.height),o._s=new tt(o.Zt,o.oe,o.je),o.As(),o.Gs(),o}As(){this.Us=()=>{this.zs?this.Ps():this.Es()},window.addEventListener("resize",this.Us),window.ResizeObserver&&this.Ae&&!this.zs&&(this.Ee=new ResizeObserver(()=>{this.Es()}),this.Ee.observe(this.Ae))}render(){this.Ls(),this.Ss++,this.ks?console.warn("Cannot render: Required resources have been disposed"):(this.zs?(this.vs.begin(),this.Is(),this.vs.end()):this.vs.update(this.Ae),this._s.hasEnabledConverters()?(this._s._r(this.vs),this.Zt.Lt(0),this.Zt.Ht(this._s.texture,this.je.offsetX,this.je.offsetY,this._s.texture.width,this._s.texture.height)):(this.Zt.Ot(),this.Zt.Ht(this.vs,this.je.offsetX,this.je.offsetY,this.vs.width,this.vs.height)))}Es(){this.Me.Pe(),this.vs.resize(this.Me.width,this.Me.height),this.je.Pe(),this._s.Pe(),this.Zt.Bt(),this.bs!=="manual"&&this.render()}Gs(){if(this.bs!=="auto"||!this.Ts)return;this.$s=performance.now();const s=i=>{if(!this.Ts)return void(this.Cs=null);const o=i-this.$s;o>=this.Fs&&(this.render(),this.$s=i-o%this.Fs),this.Ts&&(this.Cs=requestAnimationFrame(s))};this.Cs=requestAnimationFrame(s)}Ls(){const s=performance.now();if(this.Ms>0){const i=s-this.Ms;this.Rs.push(i),this.Rs.length>this.Vs&&this.Rs.shift();const o=this.Rs.reduce((n,a)=>n+a,0)/this.Rs.length;this.Ds=1e3/o}this.Ms=s}Os(){this.Cs&&(cancelAnimationFrame(this.Cs),this.Cs=null)}renderMode(s){this.bs!==s&&(this.Os(),this.bs=s,s==="auto"&&this.Ts&&this.Gs())}frameRate(s){if(s===void 0)return this.Ds;this.ws=s,this.Fs=1e3/s,this.bs==="auto"&&this.Ts&&(this.Os(),this.Gs())}noLoop(){this.Ts&&(this.Ts=!1,this.Cs&&(cancelAnimationFrame(this.Cs),this.Cs=null))}loop(){this.Ts||(this.Ts=!0,this.bs==="auto"&&this.Gs())}redraw(s=1){if(y.p(typeof s=="number"&&s>0&&Number.isInteger(s),"Redraw count must be a positive integer.",{method:"redraw",providedValue:s}))for(let i=0;i<s;i++)this.render()}isLooping(){return this.bs==="auto"&&this.Ts}draw(s){this.Is=s}windowResized(s){this.Ps=s}resizeCanvas(s,i){this.Me.Pe(s,i),this.vs.resize(this.Me.width,this.Me.height),this.je.Pe(),this._s.Pe(),this.Zt.Bt(),this.bs!=="manual"&&this.render()}destroy(){this.ks||(this.Os(),window.removeEventListener("resize",this.Us),this.Ee&&this.Ee.disconnect(),this._s.P(),this.oe.P(),this.vs.P(),this.Zt.P(),this.ks=!0)}get grid(){return this.je}get font(){return this.oe}get mode(){return this.bs}get pipeline(){return this._s}get frameCount(){return this.Ss}set frameCount(s){this.Ss=s}get width(){return this.Me.width}get height(){return this.Me.height}get canvas(){return this.Me}get isDisposed(){return this.ks}}class j{static async create(r,s={}){if(r instanceof HTMLCanvasElement||r instanceof HTMLVideoElement)return G.create(r,s);{const i=r||{};return G.create(null,i)}}static setErrorLevel(r){y._(r)}static get version(){return"0.1.7"}}const Ut=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"})),St=j.create,Zt=j.setErrorLevel,$t=j.version;C.TextmodeCanvas=K,C.TextmodeConversionPipeline=tt,C.TextmodeErrorLevel=R,C.TextmodeFont=Q,C.TextmodeGrid=J,C.Textmodifier=G,C.converters=gt,C.create=St,C.export=Ut,C.setErrorLevel=Zt,C.textmode=j,C.version=$t,Object.defineProperty(C,Symbol.toStringTag,{value:"Module"})},typeof exports=="object"&&typeof module<"u"?e(exports):typeof define=="function"&&define.amd?define(["exports"],e):e((t=typeof globalThis<"u"?globalThis:t||self).textmode={});
63
+ `;return i.join(o)}}class _t extends Y{es(r,s){const i=this.rs(s);this.yr(r,i,"text/plain;charset=utf-8")}rs(r){let s=this.Tr(r);return s===".txt"||s.length<=4?this.Dr():s}}class rt{constructor(){c(this,"qr");c(this,"Yr");c(this,"Qr");this.qr=new Ct,this.Yr=new wt,this.Qr=new _t}Zr(r){return{preserveTrailingSpaces:r.preserveTrailingSpaces??!1,lineEnding:r.lineEnding??"lf",emptyCharacter:r.emptyCharacter??" "}}ss(r,s={}){const i=this.Zr(s),o=this.qr.vr(r.pipeline),n=this.qr.Kr(o,r.grid,r.font,i.emptyCharacter);return this.Yr.ts(n,i)}es(r,s={}){const i=this.ss(r,s),o=s.filename||this.Qr.Dr();this.Qr.es(i,o)}}class yt extends V{ns(r,s=1,i="transparent"){const o=r.canvas;if(s===1&&i==="transparent")return o;const n=document.createElement("canvas"),a=n.getContext("2d"),h=Math.round(o.width*s),u=Math.round(o.height*s);return n.width=h,n.height=u,i!=="transparent"&&(a.fillStyle=i,a.fillRect(0,0,h,u)),a.imageSmoothingEnabled=!1,a.drawImage(o,0,0,o.width,o.height,0,0,h,u),n}}class Tt{hs(r,s){const i=this.ls(s.format);return s.format==="png"?r.toDataURL(i):r.toDataURL(i,s.quality)}async cs(r,s){return new Promise((i,o)=>{const n=this.ls(s.format),a=h=>{h?i(h):o(Error(`Failed to generate ${s.format.toUpperCase()} blob`))};s.format==="png"?r.toBlob(a,n):r.toBlob(a,n,s.quality)})}ls(r){switch(r){case"png":return"image/png";case"jpg":return"image/jpeg";case"webp":return"image/webp";default:throw Error("Unsupported image format: "+r)}}}const Et={png:"image/png",jpg:"image/jpeg",webp:"image/webp"},st={png:".png",jpg:".jpg",webp:".webp"};class Pt extends Y{us(r,s,i){this.fs(r,this.Tr(s)+st[i])}fs(r,s){const i=URL.createObjectURL(r);try{const o=document.createElement("a");o.href=i,o.download=s,o.style.display="none",o.rel="noopener",document.body.appendChild(o),o.click(),document.body.removeChild(o)}finally{URL.revokeObjectURL(i)}}ds(r){return r in Et&&r in st}}class Rt{constructor(){c(this,"qr");c(this,"Yr");c(this,"Qr");this.qr=new yt,this.Yr=new Tt,this.Qr=new Pt}Zr(r){return{format:r.format??"png",quality:r.quality??1,scale:r.scale??1,backgroundColor:r.backgroundColor??"transparent"}}ps(r){if(console.log("Validating image export options:",r),!this.Qr.ds(r.format))throw Error(`Saving '${r.format}' files is not supported`);if(r.quality<0||r.quality>1)throw Error("Image quality must be between 0.0 and 1.0");if(r.scale<=0)throw Error("Scale factor must be greater than 0");r.scale>10&&console.warn("Large scale factors may result in very large files and slow performance"),r.format==="jpg"&&r.backgroundColor==="transparent"&&(r.backgroundColor="black")}gs(r,s={}){const i=this.Zr(s);if(this.ps(i),i.scale===1&&i.backgroundColor==="transparent")return this.Yr.hs(r.canvas,i);const o=this.qr.ns(r,i.scale,i.backgroundColor);return this.Yr.hs(o,i)}async cs(r,s={}){const i=this.Zr(s);if(this.ps(i),i.scale===1&&i.backgroundColor==="transparent")return await this.Yr.cs(r.canvas,i);const o=this.qr.ns(r,i.scale,i.backgroundColor);return await this.Yr.cs(o,i)}async us(r,s={}){const i=await this.cs(r,s),o=s.format??"png",n=s.filename||this.Qr.Dr();this.Qr.us(i,n,o)}}const Mt=l=>class extends l{toString(r={}){return new rt().ss({pipeline:this._s,grid:this.je,font:this.oe},r)}saveStrings(r={}){new rt().es({pipeline:this._s,grid:this.je,font:this.oe},r)}toSVG(r={}){return new et().Jr(this,r)}saveSVG(r={}){new et().Xr(this,r)}async saveCanvas(r,s="png",i={}){await new Rt().us(this.Me,{...i,filename:r,format:s})}},Ft=l=>class extends l{async loadFont(r){return this.oe.Ce(r).then(()=>{const s=this.oe.maxGlyphDimensions;this.je.ke(s.width,s.height),this._s.Pe()})}fontSize(r){if(!_.p(typeof r=="number"&&r>0,"Font size must be a positive number greater than 0.",{method:"fontSize",providedValue:r})||this.oe.fontSize===r)return;this.oe.we(r);const s=this.oe.maxGlyphDimensions;this.je.ke(s.width,s.height),this._s.Pe(),this.Zt.Bt()}},At=l=>class extends l{addConverter(r){return this._s.add(r)}removeConverter(r){this._s.remove(r)}};class Dt{constructor(){c(this,"Zt");c(this,"oe");c(this,"_s");c(this,"Me");c(this,"je")}}class G extends function(s,...i){return i.reduce((o,n)=>n(o),s)}(Dt,pt,Mt,Ft,At){constructor(s=null,i={}){super();c(this,"Ae");c(this,"vs");c(this,"Ee");c(this,"bs");c(this,"ws");c(this,"Cs",null);c(this,"$s",0);c(this,"Fs");c(this,"Ts",!0);c(this,"Ds",0);c(this,"Ms",0);c(this,"Ss",0);c(this,"Rs",[]);c(this,"Vs",10);c(this,"ks",!1);c(this,"zs",!1);c(this,"Is",()=>{});c(this,"Ps",()=>{});c(this,"Us");this.Ae=s,this.zs=s===null,this.bs=i.renderMode??"auto",this.ws=i.frameRate??60,this.Fs=1e3/this.ws}static async create(s=null,i={}){const o=new this(s,i),n=o.zs?i:void 0;let a,h;o.Me=new K(o.captureSource,o.zs,n),o.Zt=new at(o.Me.Be()),o.zs?(a=i.width||800,h=i.height||600):(a=o.Me.width||800,h=o.Me.height||600),o.vs=o.Zt.Et(a,h),o.oe=new Q(o.Zt,i.fontSize??16),await o.oe.ve(i.fontSource);const u=o.oe.maxGlyphDimensions;return o.je=new J(o.Me.canvas,u.width,u.height),o._s=new tt(o.Zt,o.oe,o.je),o.As(),o.Gs(),o}As(){this.Us=()=>{this.zs?this.Ps():this.Es()},window.addEventListener("resize",this.Us),window.ResizeObserver&&this.Ae&&!this.zs&&(this.Ee=new ResizeObserver(()=>{this.Es()}),this.Ee.observe(this.Ae))}render(){this.Ls(),this.Ss++,this.ks?console.warn("Cannot render: Required resources have been disposed"):(this.zs?(this.vs.begin(),this.Is(),this.vs.end()):this.vs.update(this.Ae),this._s.hasEnabledConverters()?(this._s._r(this.vs),this.Zt.Lt(0),this.Zt.Ht(this._s.texture,this.je.offsetX,this.je.offsetY,this._s.texture.width,this._s.texture.height)):(this.Zt.Ot(),this.Zt.Ht(this.vs,this.je.offsetX,this.je.offsetY,this.vs.width,this.vs.height)))}Es(){this.Me.Pe(),this.vs.resize(this.Me.width,this.Me.height),this.je.Pe(),this._s.Pe(),this.Zt.Bt(),this.bs!=="manual"&&this.render()}Gs(){if(this.bs!=="auto"||!this.Ts)return;this.$s=performance.now();const s=i=>{if(!this.Ts)return void(this.Cs=null);const o=i-this.$s;o>=this.Fs&&(this.render(),this.$s=i-o%this.Fs),this.Ts&&(this.Cs=requestAnimationFrame(s))};this.Cs=requestAnimationFrame(s)}Ls(){const s=performance.now();if(this.Ms>0){const i=s-this.Ms;this.Rs.push(i),this.Rs.length>this.Vs&&this.Rs.shift();const o=this.Rs.reduce((n,a)=>n+a,0)/this.Rs.length;this.Ds=1e3/o}this.Ms=s}Os(){this.Cs&&(cancelAnimationFrame(this.Cs),this.Cs=null)}renderMode(s){this.bs!==s&&(this.Os(),this.bs=s,s==="auto"&&this.Ts&&this.Gs())}frameRate(s){if(s===void 0)return this.Ds;this.ws=s,this.Fs=1e3/s,this.bs==="auto"&&this.Ts&&(this.Os(),this.Gs())}noLoop(){this.Ts&&(this.Ts=!1,this.Cs&&(cancelAnimationFrame(this.Cs),this.Cs=null))}loop(){this.Ts||(this.Ts=!0,this.bs==="auto"&&this.Gs())}redraw(s=1){if(_.p(typeof s=="number"&&s>0&&Number.isInteger(s),"Redraw count must be a positive integer.",{method:"redraw",providedValue:s}))for(let i=0;i<s;i++)this.render()}isLooping(){return this.bs==="auto"&&this.Ts}draw(s){this.Is=s}windowResized(s){this.Ps=s}resizeCanvas(s,i){this.Me.Pe(s,i),this.vs.resize(this.Me.width,this.Me.height),this.je.Pe(),this._s.Pe(),this.Zt.Bt(),this.bs!=="manual"&&this.render()}destroy(){this.ks||(this.Os(),window.removeEventListener("resize",this.Us),this.Ee&&this.Ee.disconnect(),this._s.P(),this.oe.P(),this.vs.P(),this.Zt.P(),this.ks=!0)}get grid(){return this.je}get font(){return this.oe}get mode(){return this.bs}get pipeline(){return this._s}get frameCount(){return this.Ss}set frameCount(s){this.Ss=s}get width(){return this.Me.width}get height(){return this.Me.height}get canvas(){return this.Me}get isDisposed(){return this.ks}}class j{static async create(r,s={}){if(r instanceof HTMLCanvasElement||r instanceof HTMLVideoElement)return G.create(r,s);{const i=r||{};return G.create(null,i)}}static setErrorLevel(r){_._(r)}static get version(){return"0.1.7"}}const Ut=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"})),St=j.create,Zt=j.setErrorLevel,$t=j.version;C.TextmodeCanvas=K,C.TextmodeConversionPipeline=tt,C.TextmodeErrorLevel=R,C.TextmodeFont=Q,C.TextmodeGrid=J,C.Textmodifier=G,C.converters=gt,C.create=St,C.export=Ut,C.setErrorLevel=Zt,C.textmode=j,C.version=$t,Object.defineProperty(C,Symbol.toStringTag,{value:"Module"})},typeof exports=="object"&&typeof module<"u"?e(exports):typeof define=="function"&&define.amd?define(["exports"],e):e((t=typeof globalThis<"u"?globalThis:t||self).textmode={});
@@ -1,3 +1,4 @@
1
+ import type { TextmodeConversionPipeline } from '../../textmode/ConversionPipeline';
1
2
  import type { FramebufferData } from '../svg/types';
2
3
  /**
3
4
  * Base class for data extraction from textmode framebuffers.
@@ -9,7 +10,7 @@ export declare abstract class DataExtractor {
9
10
  * @param pipeline The conversion pipeline containing framebuffers
10
11
  * @returns Object containing all pixel data arrays
11
12
  */
12
- $extractFramebufferData(pipeline: any): FramebufferData;
13
+ $extractFramebufferData(pipeline: TextmodeConversionPipeline): FramebufferData;
13
14
  /**
14
15
  * Gets character index from character framebuffer pixels
15
16
  * @param characterPixels Character framebuffer pixel data
@@ -1,6 +1,5 @@
1
1
  import type { FramebufferData } from './types';
2
2
  import { DataExtractor } from '../base';
3
- import type { TextmodeFont, TextmodeGrid } from '../../index';
4
3
  /**
5
4
  * Extracts and processes data from framebuffers for TXT generation.
6
5
  * This class handles the conversion of raw pixel data into character arrays.
@@ -14,5 +13,7 @@ export declare class TXTDataExtractor extends DataExtractor {
14
13
  * @param emptyCharacter Character to use for empty cells
15
14
  * @returns 2D array of characters (rows x columns)
16
15
  */
17
- $extractCharacterGrid(framebufferData: FramebufferData, grid: TextmodeGrid, font: TextmodeFont, emptyCharacter?: string): string[][];
16
+ $extractCharacterGrid(framebufferData: FramebufferData, grid: any, // TextmodeGrid type - avoiding import to prevent circular dependency
17
+ font: any, // TextmodeFont type - avoiding import to prevent circular dependency
18
+ emptyCharacter?: string): string[][];
18
19
  }
@@ -1,4 +1,4 @@
1
- import type { TXTExportOptions } from './types';
1
+ import type { TXTExportOptions, TextmodeRenderingData } from './types';
2
2
  /**
3
3
  * Main TXT exporter for the textmode.js library.
4
4
  * Orchestrates the TXT export process by coordinating data extraction,
@@ -17,15 +17,15 @@ export declare class TXTExporter {
17
17
  private _applyDefaultOptions;
18
18
  /**
19
19
  * Generates TXT content from textmode rendering data without saving to file
20
- * @param textmodifier The textmodifier instance containing rendering data
20
+ * @param renderingData The textmode rendering data containing pipeline, grid, and font
21
21
  * @param options Export options (excluding filename)
22
22
  * @returns TXT content as string
23
23
  */
24
- $generateTXT(textmodifier: any, options?: Omit<TXTExportOptions, 'filename'>): string;
24
+ $generateTXT(renderingData: TextmodeRenderingData, options?: Omit<TXTExportOptions, 'filename'>): string;
25
25
  /**
26
26
  * Exports TXT content to a downloadable file
27
- * @param textmodifier The textmodifier instance containing rendering data
27
+ * @param renderingData The textmode rendering data containing pipeline, grid, and font
28
28
  * @param options Export options including filename
29
29
  */
30
- $saveTXT(textmodifier: any, options?: TXTExportOptions): void;
30
+ $saveTXT(renderingData: TextmodeRenderingData, options?: TXTExportOptions): void;
31
31
  }
@@ -39,6 +39,14 @@ export interface TXTGenerationOptions {
39
39
  lineEnding: 'lf' | 'crlf';
40
40
  emptyCharacter: string;
41
41
  }
42
+ /**
43
+ * Data required for textmode rendering export
44
+ */
45
+ export interface TextmodeRenderingData {
46
+ pipeline: any;
47
+ grid: any;
48
+ font: any;
49
+ }
42
50
  /**
43
51
  * Re-export shared types from SVG module that are also used by TXT exporter
44
52
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "textmode.js",
3
- "version": "0.1.7",
3
+ "version": "0.1.8-beta.1",
4
4
  "description": "Apply real-time ASCII conversion to any HTML canvas.",
5
5
  "type": "module",
6
6
  "types": "./dist/types/index.d.ts",