UNPKG

evotars

Version:

Show animated characters on stream

1,334 lines 92.5 kB
import { E as b, U as pt, T as pe, O as q, M as U, N as Fe, c as Me, w as L, j as R, P as gt, t as Re, K as k, L as H, b as Q, B as D, I, Q as mt, V as xt, a as _t, W as re, X as z, R as V, Y as bt, Z as M, _ as E, $ as yt, q as B, a0 as Tt, D as $, a1 as wt, a2 as Z, a3 as vt, m as St, a4 as Ct, a5 as se, n as ge, e as P, a6 as Bt } from "./index-BYnkzXxX.js"; import { U as Y, T as A, R as ne, S as Ae, i as ae, b as ke, c as Ue, j as Ge, e as Pt, r as ze, o as Ft, n as He, a as Mt, g as Rt, k as At, m as kt, B as Ie } from "./colorToUniform-CPC7AZcR.js"; import { C as W } from "./CanvasPool-BP3W-ghP.js"; import { g as Ut } from "./getBatchSamplersUniformGroup-jycmuB9s.js"; class We { /** * Initialize the plugin with scope of application instance * @static * @private * @param {object} [options] - See application options */ static init(e) { Object.defineProperty( this, "resizeTo", /** * The HTML element or window to automatically resize the * renderer's view element to match width and height. * @member {Window|HTMLElement} * @name resizeTo * @memberof app.Application# */ { set(t) { globalThis.removeEventListener("resize", this.queueResize), this._resizeTo = t, t && (globalThis.addEventListener("resize", this.queueResize), this.resize()); }, get() { return this._resizeTo; } } ), this.queueResize = () => { this._resizeTo && (this._cancelResize(), this._resizeId = requestAnimationFrame(() => this.resize())); }, this._cancelResize = () => { this._resizeId && (cancelAnimationFrame(this._resizeId), this._resizeId = null); }, this.resize = () => { if (!this._resizeTo) return; this._cancelResize(); let t, r; if (this._resizeTo === globalThis.window) t = globalThis.innerWidth, r = globalThis.innerHeight; else { const { clientWidth: s, clientHeight: n } = this._resizeTo; t = s, r = n; } this.renderer.resize(t, r), this.render(); }, this._resizeId = null, this._resizeTo = null, this.resizeTo = e.resizeTo || null; } /** * Clean up the ticker, scoped to application * @static * @private */ static destroy() { globalThis.removeEventListener("resize", this.queueResize), this._cancelResize(), this._cancelResize = null, this.queueResize = null, this.resizeTo = null, this.resize = null; } } We.extension = b.Application; class Oe { /** * Initialize the plugin with scope of application instance * @static * @private * @param {object} [options] - See application options */ static init(e) { e = Object.assign({ autoStart: !0, sharedTicker: !1 }, e), Object.defineProperty( this, "ticker", { set(t) { this._ticker && this._ticker.remove(this.render, this), this._ticker = t, t && t.add(this.render, this, pt.LOW); }, get() { return this._ticker; } } ), this.stop = () => { this._ticker.stop(); }, this.start = () => { this._ticker.start(); }, this._ticker = null, this.ticker = e.sharedTicker ? pe.shared : new pe(), e.autoStart && this.start(); } /** * Clean up the ticker, scoped to application. * @static * @private */ static destroy() { if (this._ticker) { const e = this._ticker; this.ticker = null, e.destroy(); } } } Oe.extension = b.Application; class De { constructor(e) { this._renderer = e; } push(e, t, r) { this._renderer.renderPipes.batch.break(r), r.add({ renderPipeId: "filter", canBundle: !1, action: "pushFilter", container: t, filterEffect: e }); } pop(e, t, r) { this._renderer.renderPipes.batch.break(r), r.add({ renderPipeId: "filter", action: "popFilter", canBundle: !1 }); } execute(e) { e.action === "pushFilter" ? this._renderer.filter.push(e) : e.action === "popFilter" && this._renderer.filter.pop(); } destroy() { this._renderer = null; } } De.extension = { type: [ b.WebGLPipes, b.WebGPUPipes, b.CanvasPipes ], name: "filter" }; const Gt = new U(); function zt(i, e) { return e.clear(), Le(i, e), e.isValid || e.set(0, 0, 0, 0), i.renderGroup ? e.applyMatrix(i.renderGroup.localTransform) : e.applyMatrix(i.parentRenderGroup.worldTransform), e; } function Le(i, e) { if (i.localDisplayStatus !== 7 || !i.measurable) return; const t = !!i.effects.length; let r = e; if ((i.renderGroup || t) && (r = q.get().clear()), i.boundsArea) e.addRect(i.boundsArea, i.worldTransform); else { if (i.renderPipeId) { const n = i.bounds; r.addFrame( n.minX, n.minY, n.maxX, n.maxY, i.groupTransform ); } const s = i.children; for (let n = 0; n < s.length; n++) Le(s[n], r); } if (t) { let s = !1; for (let n = 0; n < i.effects.length; n++) i.effects[n].addBounds && (s || (s = !0, r.applyMatrix(i.parentRenderGroup.worldTransform)), i.effects[n].addBounds(r, !0)); s && (r.applyMatrix(i.parentRenderGroup.worldTransform.copyTo(Gt).invert()), e.addBounds(r, i.relativeGroupTransform)), e.addBounds(r), q.return(r); } else i.renderGroup && (e.addBounds(r, i.relativeGroupTransform), q.return(r)); } function Ht(i, e) { e.clear(); const t = e.matrix; for (let r = 0; r < i.length; r++) { const s = i[r]; s.globalDisplayStatus < 7 || (e.matrix = s.worldTransform, s.addBounds(e)); } return e.matrix = t, e; } const It = new Fe({ attributes: { aPosition: { buffer: new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), location: 0, format: "float32x2", stride: 2 * 4, offset: 0 } }, indexBuffer: new Uint32Array([0, 1, 2, 0, 2, 3]) }); class Ee { constructor(e) { this._filterStackIndex = 0, this._filterStack = [], this._filterGlobalUniforms = new Y({ uInputSize: { value: new Float32Array(4), type: "vec4<f32>" }, uInputPixel: { value: new Float32Array(4), type: "vec4<f32>" }, uInputClamp: { value: new Float32Array(4), type: "vec4<f32>" }, uOutputFrame: { value: new Float32Array(4), type: "vec4<f32>" }, uGlobalFrame: { value: new Float32Array(4), type: "vec4<f32>" }, uOutputTexture: { value: new Float32Array(4), type: "vec4<f32>" } }), this._globalFilterBindGroup = new Me({}), this.renderer = e; } /** * The back texture of the currently active filter. Requires the filter to have `blendRequired` set to true. * @readonly */ get activeBackTexture() { var e; return (e = this._activeFilterData) == null ? void 0 : e.backTexture; } push(e) { var f; const t = this.renderer, r = e.filterEffect.filters; this._filterStack[this._filterStackIndex] || (this._filterStack[this._filterStackIndex] = this._getFilterData()); const s = this._filterStack[this._filterStackIndex]; if (this._filterStackIndex++, r.length === 0) { s.skip = !0; return; } const n = s.bounds; e.renderables ? Ht(e.renderables, n) : e.filterEffect.filterArea ? (n.clear(), n.addRect(e.filterEffect.filterArea), n.applyMatrix(e.container.worldTransform)) : zt(e.container, n); const a = t.renderTarget.rootRenderTarget.colorTexture.source; let o = a._resolution, c = 0, l = a.antialias, h = !1, d = !1; for (let p = 0; p < r.length; p++) { const g = r[p]; if (o = Math.min(o, g.resolution), c += g.padding, g.antialias !== "inherit" && (g.antialias === "on" ? l = !0 : l = !1), !!!(g.compatibleRenderers & t.type)) { d = !1; break; } if (g.blendRequired && !(((f = t.backBuffer) == null ? void 0 : f.useBackBuffer) ?? !0)) { L("Blend filter requires backBuffer on WebGL renderer to be enabled. Set `useBackBuffer: true` in the renderer options."), d = !1; break; } d = g.enabled || d, h = h || g.blendRequired; } if (!d) { s.skip = !0; return; } const u = t.renderTarget.rootViewPort; if (n.scale(o).fitBounds(0, u.width, 0, u.height).scale(1 / o).pad(c).ceil(), !n.isPositive) { s.skip = !0; return; } s.skip = !1, s.bounds = n, s.blendRequired = h, s.container = e.container, s.filterEffect = e.filterEffect, s.previousRenderSurface = t.renderTarget.renderSurface, s.inputTexture = A.getOptimalTexture( n.width, n.height, o, l ), t.renderTarget.bind(s.inputTexture, !0), t.globalUniforms.push({ offset: n }); } pop() { const e = this.renderer; this._filterStackIndex--; const t = this._filterStack[this._filterStackIndex]; if (t.skip) return; this._activeFilterData = t; const r = t.inputTexture, s = t.bounds; let n = R.EMPTY; if (e.renderTarget.finishRenderPass(), t.blendRequired) { const o = this._filterStackIndex > 0 ? this._filterStack[this._filterStackIndex - 1].bounds : null, c = e.renderTarget.getRenderTarget(t.previousRenderSurface); n = this.getBackTexture(c, s, o); } t.backTexture = n; const a = t.filterEffect.filters; if (this._globalFilterBindGroup.setResource(r.source.style, 2), this._globalFilterBindGroup.setResource(n.source, 3), e.globalUniforms.pop(), a.length === 1) a[0].apply(this, r, t.previousRenderSurface, !1), A.returnTexture(r); else { let o = t.inputTexture, c = A.getOptimalTexture( s.width, s.height, o.source._resolution, !1 ), l = 0; for (l = 0; l < a.length - 1; ++l) { a[l].apply(this, o, c, !0); const d = o; o = c, c = d; } a[l].apply(this, o, t.previousRenderSurface, !1), A.returnTexture(o), A.returnTexture(c); } t.blendRequired && A.returnTexture(n); } getBackTexture(e, t, r) { const s = e.colorTexture.source._resolution, n = A.getOptimalTexture( t.width, t.height, s, !1 ); let a = t.minX, o = t.minY; r && (a -= r.minX, o -= r.minY), a = Math.floor(a * s), o = Math.floor(o * s); const c = Math.ceil(t.width * s), l = Math.ceil(t.height * s); return this.renderer.renderTarget.copyToTexture( e, n, { x: a, y: o }, { width: c, height: l }, { x: 0, y: 0 } ), n; } applyFilter(e, t, r, s) { const n = this.renderer, a = this._filterStack[this._filterStackIndex], o = a.bounds, c = gt.shared, h = a.previousRenderSurface === r; let d = this.renderer.renderTarget.rootRenderTarget.colorTexture.source._resolution, u = this._filterStackIndex - 1; for (; u > 0 && this._filterStack[u].skip; ) --u; u > 0 && (d = this._filterStack[u].inputTexture.source._resolution); const f = this._filterGlobalUniforms, p = f.uniforms, g = p.uOutputFrame, m = p.uInputSize, x = p.uInputPixel, _ = p.uInputClamp, y = p.uGlobalFrame, T = p.uOutputTexture; if (h) { let v = this._filterStackIndex; for (; v > 0; ) { v--; const S = this._filterStack[this._filterStackIndex - 1]; if (!S.skip) { c.x = S.bounds.minX, c.y = S.bounds.minY; break; } } g[0] = o.minX - c.x, g[1] = o.minY - c.y; } else g[0] = 0, g[1] = 0; g[2] = t.frame.width, g[3] = t.frame.height, m[0] = t.source.width, m[1] = t.source.height, m[2] = 1 / m[0], m[3] = 1 / m[1], x[0] = t.source.pixelWidth, x[1] = t.source.pixelHeight, x[2] = 1 / x[0], x[3] = 1 / x[1], _[0] = 0.5 * x[2], _[1] = 0.5 * x[3], _[2] = t.frame.width * m[2] - 0.5 * x[2], _[3] = t.frame.height * m[3] - 0.5 * x[3]; const w = this.renderer.renderTarget.rootRenderTarget.colorTexture; y[0] = c.x * d, y[1] = c.y * d, y[2] = w.source.width * d, y[3] = w.source.height * d; const F = this.renderer.renderTarget.getRenderTarget(r); if (n.renderTarget.bind(r, !!s), r instanceof R ? (T[0] = r.frame.width, T[1] = r.frame.height) : (T[0] = F.width, T[1] = F.height), T[2] = F.isRoot ? -1 : 1, f.update(), n.renderPipes.uniformBatch) { const v = n.renderPipes.uniformBatch.getUboResource(f); this._globalFilterBindGroup.setResource(v, 0); } else this._globalFilterBindGroup.setResource(f, 0); this._globalFilterBindGroup.setResource(t.source, 1), this._globalFilterBindGroup.setResource(t.source.style, 2), e.groups[0] = this._globalFilterBindGroup, n.encoder.draw({ geometry: It, shader: e, state: e._state, topology: "triangle-list" }), n.type === ne.WEBGL && n.renderTarget.finishRenderPass(); } _getFilterData() { return { skip: !1, inputTexture: null, bounds: new Re(), container: null, filterEffect: null, blendRequired: !1, previousRenderSurface: null }; } /** * Multiply _input normalized coordinates_ to this matrix to get _sprite texture normalized coordinates_. * * Use `outputMatrix * vTextureCoord` in the shader. * @param outputMatrix - The matrix to output to. * @param {Sprite} sprite - The sprite to map to. * @returns The mapped matrix. */ calculateSpriteMatrix(e, t) { const r = this._activeFilterData, s = e.set( r.inputTexture._source.width, 0, 0, r.inputTexture._source.height, r.bounds.minX, r.bounds.minY ), n = t.worldTransform.copyTo(U.shared); return n.invert(), s.prepend(n), s.scale( 1 / t.texture.frame.width, 1 / t.texture.frame.height ), s.translate(t.anchor.x, t.anchor.y), s; } } Ee.extension = { type: [ b.WebGLSystem, b.WebGPUSystem ], name: "filter" }; const $e = class Ye extends Fe { constructor(...e) { let t = e[0] ?? {}; t instanceof Float32Array && (k(H, "use new MeshGeometry({ positions, uvs, indices }) instead"), t = { positions: t, uvs: e[1], indices: e[2] }), t = { ...Ye.defaultOptions, ...t }; const r = t.positions || new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), s = t.uvs || new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), n = t.indices || new Uint32Array([0, 1, 2, 0, 2, 3]), a = t.shrinkBuffersToFit, o = new Q({ data: r, label: "attribute-mesh-positions", shrinkToFit: a, usage: D.VERTEX | D.COPY_DST }), c = new Q({ data: s, label: "attribute-mesh-uvs", shrinkToFit: a, usage: D.VERTEX | D.COPY_DST }), l = new Q({ data: n, label: "index-mesh-buffer", shrinkToFit: a, usage: D.INDEX | D.COPY_DST }); super({ attributes: { aPosition: { buffer: o, format: "float32x2", stride: 2 * 4, offset: 0 }, aUV: { buffer: c, format: "float32x2", stride: 2 * 4, offset: 0 } }, indexBuffer: l, topology: t.topology }), this.batchMode = "auto"; } /** The positions of the mesh. */ get positions() { return this.attributes.aPosition.buffer.data; } set positions(e) { this.attributes.aPosition.buffer.data = e; } /** The UVs of the mesh. */ get uvs() { return this.attributes.aUV.buffer.data; } set uvs(e) { this.attributes.aUV.buffer.data = e; } /** The indices of the mesh. */ get indices() { return this.indexBuffer.data; } set indices(e) { this.indexBuffer.data = e; } }; $e.defaultOptions = { topology: "triangle-list", shrinkBuffersToFit: !1 }; let oe = $e; function K(i, e) { if (i.texture === R.WHITE && !i.fill) return I.shared.setValue(i.color).toHex(); if (i.fill) { if (i.fill instanceof mt) { const t = i.fill, r = e.createPattern(t.texture.source.resource, "repeat"), s = t.transform.copyTo(U.shared); return s.scale( t.texture.frame.width, t.texture.frame.height ), r.setTransform(s), r; } else if (i.fill instanceof xt) { const t = i.fill; if (t.type === "linear") { const r = e.createLinearGradient( t.x0, t.y0, t.x1, t.y1 ); return t.gradientStops.forEach((s) => { r.addColorStop(s.offset, I.shared.setValue(s.color).toHex()); }), r; } } } else { const t = e.createPattern(i.texture.source.resource, "repeat"), r = i.matrix.copyTo(U.shared); return r.scale(i.texture.frame.width, i.texture.frame.height), t.setTransform(r), t; } return L("FillStyle not recognised", i), "red"; } class Xe extends _t { constructor() { super(...arguments), this.chars = /* @__PURE__ */ Object.create(null), this.lineHeight = 0, this.fontFamily = "", this.fontMetrics = { fontSize: 0, ascent: 0, descent: 0 }, this.baseLineOffset = 0, this.distanceField = { type: "none", range: 0 }, this.pages = [], this.baseMeasurementFontSize = 100, this.baseRenderedFontSize = 100; } /** * The name of the font face. * @deprecated since 8.0.0 Use `fontFamily` instead. */ get font() { return k(H, "BitmapFont.font is deprecated, please use BitmapFont.fontFamily instead."), this.fontFamily; } /** * The map of base page textures (i.e., sheets of glyphs). * @deprecated since 8.0.0 Use `pages` instead. */ get pageTextures() { return k(H, "BitmapFont.pageTextures is deprecated, please use BitmapFont.pages instead."), this.pages; } /** * The size of the font face in pixels. * @deprecated since 8.0.0 Use `fontMetrics.fontSize` instead. */ get size() { return k(H, "BitmapFont.size is deprecated, please use BitmapFont.fontMetrics.fontSize instead."), this.fontMetrics.fontSize; } /** * The kind of distance field for this font or "none". * @deprecated since 8.0.0 Use `distanceField.type` instead. */ get distanceFieldRange() { return k(H, "BitmapFont.distanceFieldRange is deprecated, please use BitmapFont.distanceField.range instead."), this.distanceField.range; } /** * The range of the distance field in pixels. * @deprecated since 8.0.0 Use `distanceField.range` instead. */ get distanceFieldType() { return k(H, "BitmapFont.distanceFieldType is deprecated, please use BitmapFont.distanceField.type instead."), this.distanceField.type; } destroy(e = !1) { this.emit("destroy", this), this.removeAllListeners(); for (const t in this.chars) this.chars[t].texture.destroy(); this.chars = null, e && (this.pages.forEach((t) => t.texture.destroy(!0)), this.pages = null); } } function je(i) { if (i === "") return []; typeof i == "string" && (i = [i]); const e = []; for (let t = 0, r = i.length; t < r; t++) { const s = i[t]; if (Array.isArray(s)) { if (s.length !== 2) throw new Error(`[BitmapFont]: Invalid character range length, expecting 2 got ${s.length}.`); if (s[0].length === 0 || s[1].length === 0) throw new Error("[BitmapFont]: Invalid character delimiter."); const n = s[0].charCodeAt(0), a = s[1].charCodeAt(0); if (a < n) throw new Error("[BitmapFont]: Invalid character range."); for (let o = n, c = a; o <= c; o++) e.push(String.fromCharCode(o)); } else e.push(...Array.from(s)); } if (e.length === 0) throw new Error("[BitmapFont]: Empty set when resolving characters."); return e; } class me extends Xe { /** * @param options - The options for the dynamic bitmap font. */ constructor(e) { super(), this.resolution = 1, this.pages = [], this._padding = 4, this._measureCache = /* @__PURE__ */ Object.create(null), this._currentChars = [], this._currentX = 0, this._currentY = 0, this._currentPageIndex = -1, this._skipKerning = !1; const t = e, r = t.style.clone(); t.overrideFill && (r._fill.color = 16777215, r._fill.alpha = 1, r._fill.texture = R.WHITE, r._fill.fill = null); const s = r.fontSize; r.fontSize = this.baseMeasurementFontSize; const n = re(r); t.overrideSize ? r._stroke && (r._stroke.width *= this.baseRenderedFontSize / s) : r.fontSize = this.baseRenderedFontSize = s, this._style = r, this._skipKerning = t.skipKerning ?? !1, this.resolution = t.resolution ?? 1, this._padding = t.padding ?? 4, this.fontMetrics = z.measureFont(n), this.lineHeight = r.lineHeight || this.fontMetrics.fontSize || r.fontSize; } ensureCharacters(e) { var g, m; const t = je(e).filter((x) => !this._currentChars.includes(x)).filter((x, _, y) => y.indexOf(x) === _); if (!t.length) return; this._currentChars = [...this._currentChars, ...t]; let r; this._currentPageIndex === -1 ? r = this._nextPage() : r = this.pages[this._currentPageIndex]; let { canvas: s, context: n } = r.canvasAndContext, a = r.texture.source; const o = this._style; let c = this._currentX, l = this._currentY; const h = this.baseRenderedFontSize / this.baseMeasurementFontSize, d = this._padding * h, u = o.fontStyle === "italic" ? 2 : 1; let f = 0, p = !1; for (let x = 0; x < t.length; x++) { const _ = t[x], y = z.measureText(_, o, s, !1); y.lineHeight = y.height; const T = u * y.width * h, w = y.height * h, F = T + d * 2, v = w + d * 2; if (p = !1, _ !== ` ` && _ !== "\r" && _ !== " " && _ !== " " && (p = !0, f = Math.ceil(Math.max(v, f))), c + F > 512 && (l += f, f = v, c = 0, l + f > 512)) { a.update(); const G = this._nextPage(); s = G.canvasAndContext.canvas, n = G.canvasAndContext.context, a = G.texture.source, l = 0; } const S = T / h - (((g = o.dropShadow) == null ? void 0 : g.distance) ?? 0) - (((m = o._stroke) == null ? void 0 : m.width) ?? 0); if (this.chars[_] = { id: _.codePointAt(0), xOffset: -this._padding, yOffset: -this._padding, xAdvance: S, kerning: {} }, p) { this._drawGlyph( n, y, c + d, l + d, h, o ); const G = a.width * h, O = a.height * h, N = new V( c / G * a.width, l / O * a.height, F / G * a.width, v / O * a.height ); this.chars[_].texture = new R({ source: a, frame: N }), c += Math.ceil(F); } } a.update(), this._currentX = c, this._currentY = l, this._skipKerning && this._applyKerning(t, n); } /** * @deprecated since 8.0.0 * The map of base page textures (i.e., sheets of glyphs). */ get pageTextures() { return k(H, "BitmapFont.pageTextures is deprecated, please use BitmapFont.pages instead."), this.pages; } _applyKerning(e, t) { const r = this._measureCache; for (let s = 0; s < e.length; s++) { const n = e[s]; for (let a = 0; a < this._currentChars.length; a++) { const o = this._currentChars[a]; let c = r[n]; c || (c = r[n] = t.measureText(n).width); let l = r[o]; l || (l = r[o] = t.measureText(o).width); let h = t.measureText(n + o).width, d = h - (c + l); d && (this.chars[n].kerning[o] = d), h = t.measureText(n + o).width, d = h - (c + l), d && (this.chars[o].kerning[n] = d); } } } _nextPage() { this._currentPageIndex++; const e = this.resolution, t = W.getOptimalCanvasAndContext(512, 512, e); this._setupContext(t.context, this._style, e); const r = e * (this.baseRenderedFontSize / this.baseMeasurementFontSize), s = new R({ source: new bt({ resource: t.canvas, resolution: r, alphaMode: "premultiply-alpha-on-upload" }) }), n = { canvasAndContext: t, texture: s }; return this.pages[this._currentPageIndex] = n, n; } // canvas style! _setupContext(e, t, r) { t.fontSize = this.baseRenderedFontSize, e.scale(r, r), e.font = re(t), t.fontSize = this.baseMeasurementFontSize, e.textBaseline = t.textBaseline; const s = t._stroke, n = (s == null ? void 0 : s.width) ?? 0; if (s && (e.lineWidth = n, e.lineJoin = s.join, e.miterLimit = s.miterLimit, e.strokeStyle = K(s, e)), t._fill && (e.fillStyle = K(t._fill, e)), t.dropShadow) { const a = t.dropShadow, o = I.shared.setValue(a.color).toArray(), c = a.blur * r, l = a.distance * r; e.shadowColor = `rgba(${o[0] * 255},${o[1] * 255},${o[2] * 255},${a.alpha})`, e.shadowBlur = c, e.shadowOffsetX = Math.cos(a.angle) * l, e.shadowOffsetY = Math.sin(a.angle) * l; } else e.shadowColor = "black", e.shadowBlur = 0, e.shadowOffsetX = 0, e.shadowOffsetY = 0; } _drawGlyph(e, t, r, s, n, a) { const o = t.text, c = t.fontProperties, l = a._stroke, h = ((l == null ? void 0 : l.width) ?? 0) * n, d = r + h / 2, u = s - h / 2, f = c.descent * n, p = t.lineHeight * n; a.stroke && h && e.strokeText(o, d, u + p - f), a._fill && e.fillText(o, d, u + p - f); } destroy() { super.destroy(); for (let e = 0; e < this.pages.length; e++) { const { canvasAndContext: t, texture: r } = this.pages[e]; W.returnCanvasAndContext(t), r.destroy(!0); } this.pages = null; } } function Ve(i, e, t) { const r = { width: 0, height: 0, offsetY: 0, scale: e.fontSize / t.baseMeasurementFontSize, lines: [{ width: 0, charPositions: [], spaceWidth: 0, spacesIndex: [], chars: [] }] }; r.offsetY = t.baseLineOffset; let s = r.lines[0], n = null, a = !0; const o = { spaceWord: !1, width: 0, start: 0, index: 0, // use index to not modify the array as we use it a lot! positions: [], chars: [] }, c = (f) => { const p = s.width; for (let g = 0; g < o.index; g++) { const m = f.positions[g]; s.chars.push(f.chars[g]), s.charPositions.push(m + p); } s.width += f.width, a = !1, o.width = 0, o.index = 0, o.chars.length = 0; }, l = () => { let f = s.chars.length - 1, p = s.chars[f]; for (; p === " "; ) s.width -= t.chars[p].xAdvance, p = s.chars[--f]; r.width = Math.max(r.width, s.width), s = { width: 0, charPositions: [], chars: [], spaceWidth: 0, spacesIndex: [] }, a = !0, r.lines.push(s), r.height += t.lineHeight; }, h = t.baseMeasurementFontSize / e.fontSize, d = e.letterSpacing * h, u = e.wordWrapWidth * h; for (let f = 0; f < i.length + 1; f++) { let p; const g = f === i.length; g || (p = i[f]); const m = t.chars[p] || t.chars[" "]; if (/(?:\s)/.test(p) || p === "\r" || p === ` ` || g) { if (!a && e.wordWrap && s.width + o.width - d > u ? (l(), c(o), g || s.charPositions.push(0)) : (o.start = s.width, c(o), g || s.charPositions.push(0)), p === "\r" || p === ` `) s.width !== 0 && l(); else if (!g) { const T = m.xAdvance + (m.kerning[n] || 0) + d; s.width += T, s.spaceWidth = T, s.spacesIndex.push(s.charPositions.length), s.chars.push(p); } } else { const y = m.kerning[n] || 0, T = m.xAdvance + y + d; o.positions[o.index++] = o.width + y, o.chars.push(p), o.width += T; } n = p; } return l(), e.align === "center" ? Wt(r) : e.align === "right" ? Ot(r) : e.align === "justify" && Dt(r), r; } function Wt(i) { for (let e = 0; e < i.lines.length; e++) { const t = i.lines[e], r = i.width / 2 - t.width / 2; for (let s = 0; s < t.charPositions.length; s++) t.charPositions[s] += r; } } function Ot(i) { for (let e = 0; e < i.lines.length; e++) { const t = i.lines[e], r = i.width - t.width; for (let s = 0; s < t.charPositions.length; s++) t.charPositions[s] += r; } } function Dt(i) { const e = i.width; for (let t = 0; t < i.lines.length; t++) { const r = i.lines[t]; let s = 0, n = r.spacesIndex[s++], a = 0; const o = r.spacesIndex.length, l = (e - r.width) / o; for (let h = 0; h < r.charPositions.length; h++) h === n && (n = r.spacesIndex[s++], a += l), r.charPositions[h] += a; } } class Lt { constructor() { this.ALPHA = [["a", "z"], ["A", "Z"], " "], this.NUMERIC = [["0", "9"]], this.ALPHANUMERIC = [["a", "z"], ["A", "Z"], ["0", "9"], " "], this.ASCII = [[" ", "~"]], this.defaultOptions = { chars: this.ALPHANUMERIC, resolution: 1, padding: 4, skipKerning: !1 }; } /** * Get a font for the specified text and style. * @param text - The text to get the font for * @param style - The style to use */ getFont(e, t) { var a; let r = `${t.fontFamily}-bitmap`, s = !0; if (t._fill.fill && (r += t._fill.fill.uid, s = !1), !M.has(r)) { const o = new me({ style: t, overrideFill: s, overrideSize: !0, ...this.defaultOptions }); o.once("destroy", () => M.remove(r)), M.set( r, o ); } const n = M.get(r); return (a = n.ensureCharacters) == null || a.call(n, e), n; } /** * Get the layout of a text for the specified style. * @param text - The text to get the layout for * @param style - The style to use */ getLayout(e, t) { const r = this.getFont(e, t); return Ve([...e], t, r); } /** * Measure the text using the specified style. * @param text - The text to measure * @param style - The style to use */ measureText(e, t) { return this.getLayout(e, t); } // eslint-disable-next-line max-len install(...e) { var l, h, d, u; let t = e[0]; typeof t == "string" && (t = { name: t, style: e[1], chars: (l = e[2]) == null ? void 0 : l.chars, resolution: (h = e[2]) == null ? void 0 : h.resolution, padding: (d = e[2]) == null ? void 0 : d.padding, skipKerning: (u = e[2]) == null ? void 0 : u.skipKerning }, k(H, "BitmapFontManager.install(name, style, options) is deprecated, use BitmapFontManager.install({name, style, ...options})")); const r = t == null ? void 0 : t.name; if (!r) throw new Error("[BitmapFontManager] Property `name` is required."); t = { ...this.defaultOptions, ...t }; const s = t.style, n = s instanceof E ? s : new E(s), a = n._fill.fill !== null && n._fill.fill !== void 0, o = new me({ style: n, overrideFill: a, skipKerning: t.skipKerning, padding: t.padding, resolution: t.resolution, overrideSize: !1 }), c = je(t.chars); return o.ensureCharacters(c.join("")), M.set(`${r}-bitmap`, o), o.once("destroy", () => M.remove(`${r}-bitmap`)), o; } /** * Uninstalls a bitmap font from the cache. * @param {string} name - The name of the bitmap font to uninstall. */ uninstall(e) { const t = `${e}-bitmap`, r = M.get(t); r && (M.remove(t), r.destroy()); } } const ie = new Lt(); function Et(i) { const e = i._stroke, t = i._fill, s = [`div { ${[ `color: ${I.shared.setValue(t.color).toHex()}`, `font-size: ${i.fontSize}px`, `font-family: ${i.fontFamily}`, `font-weight: ${i.fontWeight}`, `font-style: ${i.fontStyle}`, `font-variant: ${i.fontVariant}`, `letter-spacing: ${i.letterSpacing}px`, `text-align: ${i.align}`, `padding: ${i.padding}px`, `white-space: ${i.whiteSpace === "pre" && i.wordWrap ? "pre-wrap" : i.whiteSpace}`, ...i.lineHeight ? [`line-height: ${i.lineHeight}px`] : [], ...i.wordWrap ? [ `word-wrap: ${i.breakWords ? "break-all" : "break-word"}`, `max-width: ${i.wordWrapWidth}px` ] : [], ...e ? [Ne(e)] : [], ...i.dropShadow ? [Ke(i.dropShadow)] : [], ...i.cssOverrides ].join(";")} }`]; return $t(i.tagStyles, s), s.join(" "); } function Ke(i) { const e = I.shared.setValue(i.color).setAlpha(i.alpha).toHexa(), t = Math.round(Math.cos(i.angle) * i.distance), r = Math.round(Math.sin(i.angle) * i.distance), s = `${t}px ${r}px`; return i.blur > 0 ? `text-shadow: ${s} ${i.blur}px ${e}` : `text-shadow: ${s} ${e}`; } function Ne(i) { return [ `-webkit-text-stroke-width: ${i.width}px`, `-webkit-text-stroke-color: ${I.shared.setValue(i.color).toHex()}`, `text-stroke-width: ${i.width}px`, `text-stroke-color: ${I.shared.setValue(i.color).toHex()}`, "paint-order: stroke" ].join(";"); } const xe = { fontSize: "font-size: {{VALUE}}px", fontFamily: "font-family: {{VALUE}}", fontWeight: "font-weight: {{VALUE}}", fontStyle: "font-style: {{VALUE}}", fontVariant: "font-variant: {{VALUE}}", letterSpacing: "letter-spacing: {{VALUE}}px", align: "text-align: {{VALUE}}", padding: "padding: {{VALUE}}px", whiteSpace: "white-space: {{VALUE}}", lineHeight: "line-height: {{VALUE}}px", wordWrapWidth: "max-width: {{VALUE}}px" }, _e = { fill: (i) => `color: ${I.shared.setValue(i).toHex()}`, breakWords: (i) => `word-wrap: ${i ? "break-all" : "break-word"}`, stroke: Ne, dropShadow: Ke }; function $t(i, e) { for (const t in i) { const r = i[t], s = []; for (const n in r) _e[n] ? s.push(_e[n](r[n])) : xe[n] && s.push(xe[n].replace("{{VALUE}}", r[n])); e.push(`${t} { ${s.join(";")} }`); } } class ce extends E { constructor(e = {}) { super(e), this._cssOverrides = [], this.cssOverrides ?? (this.cssOverrides = e.cssOverrides), this.tagStyles = e.tagStyles ?? {}; } /** List of style overrides that will be applied to the HTML text. */ set cssOverrides(e) { this._cssOverrides = e instanceof Array ? e : [e], this.update(); } get cssOverrides() { return this._cssOverrides; } _generateKey() { return this._styleKey = yt(this) + this._cssOverrides.join("-"), this._styleKey; } update() { this._cssStyle = null, super.update(); } /** * Creates a new HTMLTextStyle object with the same values as this one. * @returns New cloned HTMLTextStyle object */ clone() { return new ce({ align: this.align, breakWords: this.breakWords, dropShadow: this.dropShadow, fill: this._fill, fontFamily: this.fontFamily, fontSize: this.fontSize, fontStyle: this.fontStyle, fontVariant: this.fontVariant, fontWeight: this.fontWeight, letterSpacing: this.letterSpacing, lineHeight: this.lineHeight, padding: this.padding, stroke: this._stroke, whiteSpace: this.whiteSpace, wordWrap: this.wordWrap, wordWrapWidth: this.wordWrapWidth, cssOverrides: this.cssOverrides }); } get cssStyle() { return this._cssStyle || (this._cssStyle = Et(this)), this._cssStyle; } /** * Add a style override, this can be any CSS property * it will override any built-in style. This is the * property and the value as a string (e.g., `color: red`). * This will override any other internal style. * @param {string} value - CSS style(s) to add. * @example * style.addOverride('background-color: red'); */ addOverride(...e) { const t = e.filter((r) => !this.cssOverrides.includes(r)); t.length > 0 && (this.cssOverrides.push(...t), this.update()); } /** * Remove any overrides that match the value. * @param {string} value - CSS style to remove. * @example * style.removeOverride('background-color: red'); */ removeOverride(...e) { const t = e.filter((r) => this.cssOverrides.includes(r)); t.length > 0 && (this.cssOverrides = this.cssOverrides.filter((r) => !t.includes(r)), this.update()); } set fill(e) { typeof e != "string" && typeof e != "number" && L("[HTMLTextStyle] only color fill is not supported by HTMLText"), super.fill = e; } set stroke(e) { e && typeof e != "string" && typeof e != "number" && L("[HTMLTextStyle] only color stroke is not supported by HTMLText"), super.stroke = e; } } const be = "http://www.w3.org/2000/svg", ye = "http://www.w3.org/1999/xhtml"; class qe { constructor() { this.svgRoot = document.createElementNS(be, "svg"), this.foreignObject = document.createElementNS(be, "foreignObject"), this.domElement = document.createElementNS(ye, "div"), this.styleElement = document.createElementNS(ye, "style"), this.image = new Image(); const { foreignObject: e, svgRoot: t, styleElement: r, domElement: s } = this; e.setAttribute("width", "10000"), e.setAttribute("height", "10000"), e.style.overflow = "hidden", t.appendChild(e), e.appendChild(r), e.appendChild(s); } } let Te; function Yt(i, e, t, r) { r = r || Te || (Te = new qe()); const { domElement: s, styleElement: n, svgRoot: a } = r; s.innerHTML = `<style>${e.cssStyle}</style><div>${i}</div>`, s.setAttribute("style", "transform-origin: top left; display: inline-block"), t && (n.textContent = t), document.body.appendChild(a); const o = s.getBoundingClientRect(); a.remove(); const c = z.measureFont(e.fontStyle).descent; return { width: o.width, height: o.height + c }; } class Qe { constructor(e, t) { this.state = Ae.for2d(), this._graphicsBatchesHash = /* @__PURE__ */ Object.create(null), this.renderer = e, this._adaptor = t, this._adaptor.init(); } validateRenderable(e) { const t = e.context, r = !!this._graphicsBatchesHash[e.uid], s = this.renderer.graphicsContext.updateGpuContext(t); return !!(s.isBatchable || r !== s.isBatchable); } addRenderable(e, t) { const r = this.renderer.graphicsContext.updateGpuContext(e.context); e._didGraphicsUpdate && (e._didGraphicsUpdate = !1, this._rebuild(e)), r.isBatchable ? this._addToBatcher(e, t) : (this.renderer.renderPipes.batch.break(t), t.add(e)); } updateRenderable(e) { const t = this._graphicsBatchesHash[e.uid]; if (t) for (let r = 0; r < t.length; r++) { const s = t[r]; s.batcher.updateElement(s); } } destroyRenderable(e) { this._graphicsBatchesHash[e.uid] && this._removeBatchForRenderable(e.uid); } execute(e) { if (!e.isRenderable) return; const t = this.renderer, r = e.context; if (!t.graphicsContext.getGpuContext(r).batches.length) return; const n = r.customShader || this._adaptor.shader; this.state.blendMode = e.groupBlendMode; const a = n.resources.localUniforms.uniforms; a.uTransformMatrix = e.groupTransform, a.uRound = t._roundPixels | e._roundPixels, ae( e.groupColorAlpha, a.uColor, 0 ), this._adaptor.execute(this, e); } _rebuild(e) { const t = !!this._graphicsBatchesHash[e.uid], r = this.renderer.graphicsContext.updateGpuContext(e.context); t && this._removeBatchForRenderable(e.uid), r.isBatchable && this._initBatchesForRenderable(e), e.batched = r.isBatchable; } _addToBatcher(e, t) { const r = this.renderer.renderPipes.batch, s = this._getBatchesForRenderable(e); for (let n = 0; n < s.length; n++) { const a = s[n]; r.addToBatch(a, t); } } _getBatchesForRenderable(e) { return this._graphicsBatchesHash[e.uid] || this._initBatchesForRenderable(e); } _initBatchesForRenderable(e) { const t = e.context, r = this.renderer.graphicsContext.getGpuContext(t), s = this.renderer._roundPixels | e._roundPixels, n = r.batches.map((a) => { const o = B.get(Tt); return a.copyTo(o), o.renderable = e, o.roundPixels = s, o; }); return this._graphicsBatchesHash[e.uid] === void 0 && e.on("destroyed", () => { this.destroyRenderable(e); }), this._graphicsBatchesHash[e.uid] = n, n; } _removeBatchForRenderable(e) { this._graphicsBatchesHash[e].forEach((t) => { B.return(t); }), this._graphicsBatchesHash[e] = null; } destroy() { this.renderer = null, this._adaptor.destroy(), this._adaptor = null, this.state = null; for (const e in this._graphicsBatchesHash) this._removeBatchForRenderable(e); this._graphicsBatchesHash = null; } } Qe.extension = { type: [ b.WebGLPipes, b.WebGPUPipes, b.CanvasPipes ], name: "graphics" }; const Ze = class Je extends oe { constructor(...e) { super({}); let t = e[0] ?? {}; typeof t == "number" && (k(H, "PlaneGeometry constructor changed please use { width, height, verticesX, verticesY } instead"), t = { width: t, height: e[1], verticesX: e[2], verticesY: e[3] }), this.build(t); } /** * Refreshes plane coordinates * @param options - Options to be applied to plane geometry */ build(e) { e = { ...Je.defaultOptions, ...e }, this.verticesX = this.verticesX ?? e.verticesX, this.verticesY = this.verticesY ?? e.verticesY, this.width = this.width ?? e.width, this.height = this.height ?? e.height; const t = this.verticesX * this.verticesY, r = [], s = [], n = [], a = this.verticesX - 1, o = this.verticesY - 1, c = this.width / a, l = this.height / o; for (let d = 0; d < t; d++) { const u = d % this.verticesX, f = d / this.verticesX | 0; r.push(u * c, f * l), s.push(u / a, f / o); } const h = a * o; for (let d = 0; d < h; d++) { const u = d % a, f = d / a | 0, p = f * this.verticesX + u, g = f * this.verticesX + u + 1, m = (f + 1) * this.verticesX + u, x = (f + 1) * this.verticesX + u + 1; n.push( p, g, m, g, x, m ); } this.buffers[0].data = new Float32Array(r), this.buffers[1].data = new Float32Array(s), this.indexBuffer.data = new Uint32Array(n), this.buffers[0].update(), this.buffers[1].update(), this.indexBuffer.update(); } }; Ze.defaultOptions = { width: 100, height: 100, verticesX: 10, verticesY: 10 }; let Xt = Ze; class he { constructor() { this.batcher = null, this.batch = null, this.roundPixels = 0, this._uvUpdateId = -1, this._textureMatrixUpdateId = -1; } get blendMode() { return this.mesh.groupBlendMode; } reset() { this.mesh = null, this.texture = null, this.batcher = null, this.batch = null; } packIndex(e, t, r) { const s = this.geometry.indices; for (let n = 0; n < s.length; n++) e[t++] = s[n] + r; } packAttributes(e, t, r, s) { const n = this.mesh, a = this.geometry, o = n.groupTransform, c = s << 16 | this.roundPixels & 65535, l = o.a, h = o.b, d = o.c, u = o.d, f = o.tx, p = o.ty, g = a.positions, m = a.getBuffer("aUV"), x = m.data; let _ = x; const y = this.texture.textureMatrix; y.isSimple || (_ = this._transformedUvs, (this._textureMatrixUpdateId !== y._updateID || this._uvUpdateId !== m._updateID) && ((!_ || _.length < x.length) && (_ = this._transformedUvs = new Float32Array(x.length)), this._textureMatrixUpdateId = y._updateID, this._uvUpdateId = m._updateID, y.multiplyUvs(x, _))); const T = n.groupColorAlpha; for (let w = 0; w < g.length; w += 2) { const F = g[w], v = g[w + 1]; e[r] = l * F + d * v + f, e[r + 1] = h * F + u * v + p, e[r + 2] = _[w], e[r + 3] = _[w + 1], t[r + 4] = T, t[r + 5] = c, r += 6; } } get vertexSize() { return this.geometry.positions.length / 2; } get indexSize() { return this.geometry.indices.length; } } class et { constructor(e, t) { this.localUniforms = new Y({ uTransformMatrix: { value: new U(), type: "mat3x3<f32>" }, uColor: { value: new Float32Array([1, 1, 1, 1]), type: "vec4<f32>" }, uRound: { value: 0, type: "f32" } }), this.localUniformsBindGroup = new Me({ 0: this.localUniforms }), this._meshDataHash = /* @__PURE__ */ Object.create(null), this._gpuBatchableMeshHash = /* @__PURE__ */ Object.create(null), this.renderer = e, this._adaptor = t, this._adaptor.init(); } validateRenderable(e) { const t = this._getMeshData(e), r = t.batched, s = e.batched; if (t.batched = s, r !== s) return !0; if (s) { const n = e._geometry; if (n.indices.length !== t.indexSize || n.positions.length !== t.vertexSize) return t.indexSize = n.indices.length, t.vertexSize = n.positions.length, !0; const a = this._getBatchableMesh(e), o = e.texture; if (a.texture._source !== o._source && a.texture._source !== o._source) return !a.batcher.checkAndUpdateTexture(a, o); } return !1; } addRenderable(e, t) { const r = this.renderer.renderPipes.batch, { batched: s } = this._getMeshData(e); if (s) { const n = this._getBatchableMesh(e); n.texture = e._texture, n.geometry = e._geometry, r.addToBatch(n); } else r.break(t), t.add({ renderPipeId: "mesh", mesh: e }); } updateRenderable(e) { if (e.batched) { const t = this._gpuBatchableMeshHash[e.uid]; t.texture = e._texture, t.geometry = e._geometry, t.batcher.updateElement(t); } } destroyRenderable(e) { this._meshDataHash[e.uid] = null; const t = this._gpuBatchableMeshHash[e.uid]; t && (B.return(t), this._gpuBatchableMeshHash[e.uid] = null); } execute({ mesh: e }) { if (!e.isRenderable) return; e.state.blendMode = e.groupBlendMode; const t = this.localUniforms; t.uniforms.uTransformMatrix = e.groupTransform, t.uniforms.uRound = this.renderer._roundPixels | e._roundPixels, t.update(), ae( e.groupColorAlpha, t.uniforms.uColor, 0 ), this._adaptor.execute(this, e); } _getMeshData(e) { return this._meshDataHash[e.uid] || this._initMeshData(e); } _initMeshData(e) { var t, r; return this._meshDataHash[e.uid] = { batched: e.batched, indexSize: (t = e._geometry.indices) == null ? void 0 : t.length, vertexSize: (r = e._geometry.positions) == null ? void 0 : r.length }, e.on("destroyed", () => { this.destroyRenderable(e); }), this._meshDataHash[e.uid]; } _getBatchableMesh(e) { return this._gpuBatchableMeshHash[e.uid] || this._initBatchableMesh(e); } _initBatchableMesh(e) { const t = B.get(he); return t.mesh = e, t.texture = e._texture, t.roundPixels = this.renderer._roundPixels | e._roundPixels, this._gpuBatchableMeshHash[e.uid] = t, t.mesh = e, t; } destroy() { for (const e in this._gpuBatchableMeshHash) this._gpuBatchableMeshHash[e] && B.return(this._gpuBatchableMeshHash[e]); this._gpuBatchableMeshHash = null, this._meshDataHash = null, this.localUniforms = null, this.localUniformsBindGroup = null, this._adaptor.destroy(), this._adaptor = null, this.renderer = null; } } et.extension = { type: [ b.WebGLPipes, b.WebGPUPipes, b.CanvasPipes ], name: "mesh" }; const tt = class rt extends Xt { constructor(e = {}) { e = { ...rt.defaultOptions, ...e }, super({ width: e.width, height: e.height, verticesX: 4, verticesY: 4 }), this.update(e); } /** * Updates the NineSliceGeometry with the options. * @param options - The options of the NineSliceGeometry. */ update(e) { this.width = e.width ?? this.width, this.height = e.height ?? this.height, this._originalWidth = e.originalWidth ?? this._originalWidth, this._originalHeight = e.originalHeight ?? this._originalHeight, this._leftWidth = e.leftWidth ?? this._leftWidth, this._rightWidth = e.rightWidth ?? this._rightWidth, this._topHeight = e.topHeight ?? this._topHeight, this._bottomHeight = e.bottomHeight ?? this._bottomHeight, this.updateUvs(), this.updatePositions(); } /** Updates the positions of the vertices. */ updatePositions() { const e = this.positions, t = this._leftWidth + this._rightWidth, r = this.width > t ? 1 : this.width / t, s = this._topHeight + this._bottomHeight, n = this.height > s ? 1 : this.height / s, a = Math.min(r, n); e[9] = e[11] = e[13] = e[15] = this._topHeight * a, e[17] = e[19] = e[21] = e[23] = this.height - this._bottomHeight * a, e[25] = e[27] = e[29] = e[31] = this.height, e[2] = e[10] = e[18] = e[26] = this._leftWidth * a, e[4] = e[12] = e[20] = e[28] = this.width - this._rightWidth * a, e[6] = e[14] = e[22] = e[30] = this.width, this.getBuffer("aPosition").update(); } /** Updates the UVs of the vertices. */ updateUvs() { const e = this.uvs; e[0] = e[8] = e[16] = e[24] = 0, e[1] = e[3] = e[5] = e[7] = 0, e[6] = e[14] = e[22] = e[30] = 1, e[25] = e[27] = e[29] = e[31] = 1; const t = 1 / this._originalWidth, r = 1 / this._originalHeight; e[2] = e[10] = e[18] = e[26] = t * this._leftWidth, e[9] = e[11] = e[13] = e[15] = r * this._topHeight, e[4] = e[12] = e[20] = e[28] = 1 - t * this._rightWidth, e[17] = e[19] = e[21] = e[23] = 1 - r * this._bottomHeight, this.getBuffer("aUV").update(); } }; tt.defaultOptions = { /** The width of the NineSlicePlane, setting this will actually modify the vertices and UV's of this plane. */ width: 100, /** The height of the NineSlicePlane, setting this will actually modify the vertices and UV's of this plane. */ height: 100, /** The width of the left column. */ leftWidth: 10, /** The height of the top row. */ topHeight: 10, /** The width of the right column. */ rightWidth: 10, /** The height of the bottom row. */ bottomHeight: 10, /** The original width of the texture */ originalWidth: 100, /** The original height of the texture */ originalHeight: 100 }; let jt = tt; class st { constructor(e) { this._gpuSpriteHash = /* @__PURE__ */ Object.create(null), this._renderer = e; } addRenderable(e, t) { const r = this._getGpuSprite(e); e._didSpriteUpdate && this._updateBatchableSprite(e, r), this._renderer.renderPipes.batch.addToBatch(r); } updateRenderable(e) { const t = this._gpuSpriteHash[e.uid]; e._didSpriteUpdate && this._updateBatchableSprite(e, t), t.batcher.updateElement(t); } validateRenderable(e) { const t = e._texture, r = this._getGpuSprite(e); return r.texture._source !== t._source ? !r.batcher.checkAndUpdateTexture(r, t) : !1; } destroyRenderable(e) { const t = this._gpuSpriteHash[e.uid]; B.return(t), this._gpuSpriteHash[e.uid] = null; } _updateBatchableSprite(e, t) { e._didSpriteUpdate = !1, t.geometry.update(e), t.texture = e._texture; } _getGpuSprite(e) { return this._gpuSpriteHash[e.uid] || this._initGPUSprite(e); } _initGPUSprite(e) { const t = new he(); return t.geometry = new jt(), t.mesh = e, t.texture = e._texture, t.roundPixels = this._renderer._roundPixels | e._roundPixels, this._gpuSpr