import { E as p, U as pt, T as pe, N as K, M as P, G as se, p as D, O as Ue, w as $, Q as B, f as A, P as gt, J as ie, V as Ge, W as xt, X as W, Y as w, Z as C, _ as O, B as M, $ as H, a0 as Z, a1 as mt, a2 as k, S as Y, a3 as j, a4 as b, a5 as _t, a6 as ne, g as ee, a7 as E, d as ae, c as bt, a8 as yt, a9 as Tt, aa as Fe, v as ke, ab as vt, ac as Ae, z as St, A as He, s as wt, ad as Ct, ae as Bt, x as Mt, y as Pt, F as Rt, af as Ut, ag as Gt, ah as te, ai as re, aj as De, D as ze, ak as V, R as ge, al as Ft, am as xe, an as me, e as y, ao as kt } from "./index-6BV7F4R3.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 = p.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 = p.Application; class Ve { 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; } } Ve.extension = { type: [ p.WebGLPipes, p.WebGPUPipes, p.CanvasPipes ], name: "filter" }; const At = new P(); function Ht(i, e) { return e.clear(), Ee(i, e), e.isValid || e.set(0, 0, 0, 0), i.renderGroup ? e.applyMatrix(i.renderGroup.localTransform) : e.applyMatrix(i.parentRenderGroup.worldTransform), e; } function Ee(i, e) { if (i.localDisplayStatus !== 7 || !i.measurable) return; const t = !!i.effects.length; let r = e; if ((i.renderGroup || t) && (r = K.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++) Ee(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(At).invert()), e.addBounds(r, i.relativeGroupTransform)), e.addBounds(r), K.return(r); } else i.renderGroup && (e.addBounds(r, i.relativeGroupTransform), K.return(r)); } function Dt(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 zt = new se({ attributes: { aPosition: { buffer: new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), format: "float32x2", stride: 2 * 4, offset: 0 } }, indexBuffer: new Uint32Array([0, 1, 2, 0, 2, 3]) }); class Ie { constructor(e) { this._filterStackIndex = 0, this._filterStack = [], this._filterGlobalUniforms = new D({ uInputSize: { value: new Float32Array(4), type: "vec4" }, uInputPixel: { value: new Float32Array(4), type: "vec4" }, uInputClamp: { value: new Float32Array(4), type: "vec4" }, uOutputFrame: { value: new Float32Array(4), type: "vec4" }, uGlobalFrame: { value: new Float32Array(4), type: "vec4" }, uOutputTexture: { value: new Float32Array(4), type: "vec4" } }), this._globalFilterBindGroup = new Ue({}), 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 g; 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 ? Dt(e.renderables, n) : e.filterEffect.filterArea ? (n.clear(), n.addRect(e.filterEffect.filterArea), n.applyMatrix(e.container.worldTransform)) : Ht(e.container, n); const a = t.renderTarget.renderTarget.colorTexture.source; let o = 1 / 0, l = 0, u = !0, c = !1, d = !1, h = !0; for (let x = 0; x < r.length; x++) { const f = r[x]; if (o = Math.min(o, f.resolution === "inherit" ? a._resolution : f.resolution), l += f.padding, f.antialias === "off" ? u = !1 : f.antialias === "inherit" && u && (u = a.antialias), f.clipToViewport || (h = !1), !!!(f.compatibleRenderers & t.type)) { d = !1; break; } if (f.blendRequired && !(((g = t.backBuffer) == null ? void 0 : g.useBackBuffer) ?? !0)) { $("Blend filter requires backBuffer on WebGL renderer to be enabled. Set `useBackBuffer: true` in the renderer options."), d = !1; break; } d = f.enabled || d, c = c || f.blendRequired; } if (!d) { s.skip = !0; return; } if (n.scale(o), h) { const x = t.renderTarget.rootViewPort; n.fitBounds(0, x.width, 0, x.height); } if (n.ceil().scale(1 / o).pad(l | 0), !n.isPositive) { s.skip = !0; return; } s.skip = !1, s.bounds = n, s.blendRequired = c, s.container = e.container, s.filterEffect = e.filterEffect, s.previousRenderSurface = t.renderTarget.renderSurface, s.inputTexture = B.getOptimalTexture( n.width, n.height, o, u ), 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 = A.EMPTY; if (e.renderTarget.finishRenderPass(), t.blendRequired) { const o = this._filterStackIndex > 0 ? this._filterStack[this._filterStackIndex - 1].bounds : null, l = e.renderTarget.getRenderTarget(t.previousRenderSurface); n = this.getBackTexture(l, 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), B.returnTexture(r); else { let o = t.inputTexture, l = B.getOptimalTexture( s.width, s.height, o.source._resolution, !1 ), u = 0; for (u = 0; u < a.length - 1; ++u) { a[u].apply(this, o, l, !0); const d = o; o = l, l = d; } a[u].apply(this, o, t.previousRenderSurface, !1), B.returnTexture(o), B.returnTexture(l); } t.blendRequired && B.returnTexture(n); } getBackTexture(e, t, r) { const s = e.colorTexture.source._resolution, n = B.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 l = Math.ceil(t.width * s), u = Math.ceil(t.height * s); return this.renderer.renderTarget.copyToTexture( e, n, { x: a, y: o }, { width: l, height: u }, { x: 0, y: 0 } ), n; } applyFilter(e, t, r, s) { const n = this.renderer, a = this._filterStack[this._filterStackIndex], o = a.bounds, l = gt.shared, c = a.previousRenderSurface === r; let d = this.renderer.renderTarget.rootRenderTarget.colorTexture.source._resolution, h = this._filterStackIndex - 1; for (; h > 0 && this._filterStack[h].skip; ) --h; h > 0 && (d = this._filterStack[h].inputTexture.source._resolution); const g = this._filterGlobalUniforms, x = g.uniforms, f = x.uOutputFrame, m = x.uInputSize, _ = x.uInputPixel, R = x.uInputClamp, T = x.uGlobalFrame, U = x.uOutputTexture; if (c) { let G = this._filterStackIndex; for (; G > 0; ) { G--; const F = this._filterStack[this._filterStackIndex - 1]; if (!F.skip) { l.x = F.bounds.minX, l.y = F.bounds.minY; break; } } f[0] = o.minX - l.x, f[1] = o.minY - l.y; } else f[0] = 0, f[1] = 0; f[2] = t.frame.width, f[3] = t.frame.height, m[0] = t.source.width, m[1] = t.source.height, m[2] = 1 / m[0], m[3] = 1 / m[1], _[0] = t.source.pixelWidth, _[1] = t.source.pixelHeight, _[2] = 1 / _[0], _[3] = 1 / _[1], R[0] = 0.5 * _[2], R[1] = 0.5 * _[3], R[2] = t.frame.width * m[2] - 0.5 * _[2], R[3] = t.frame.height * m[3] - 0.5 * _[3]; const z = this.renderer.renderTarget.rootRenderTarget.colorTexture; T[0] = l.x * d, T[1] = l.y * d, T[2] = z.source.width * d, T[3] = z.source.height * d; const S = this.renderer.renderTarget.getRenderTarget(r); if (n.renderTarget.bind(r, !!s), r instanceof A ? (U[0] = r.frame.width, U[1] = r.frame.height) : (U[0] = S.width, U[1] = S.height), U[2] = S.isRoot ? -1 : 1, g.update(), n.renderPipes.uniformBatch) { const G = n.renderPipes.uniformBatch.getUboResource(g); this._globalFilterBindGroup.setResource(G, 0); } else this._globalFilterBindGroup.setResource(g, 0); this._globalFilterBindGroup.setResource(t.source, 1), this._globalFilterBindGroup.setResource(t.source.style, 2), e.groups[0] = this._globalFilterBindGroup, n.encoder.draw({ geometry: zt, shader: e, state: e._state, topology: "triangle-list" }), n.type === ie.WEBGL && n.renderTarget.finishRenderPass(); } _getFilterData() { return { skip: !1, inputTexture: null, bounds: new Ge(), 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(P.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; } } Ie.extension = { type: [ p.WebGLSystem, p.WebGPUSystem ], name: "filter" }; class X extends xt { /** * @param options - Options for the Graphics. */ constructor(e) { e instanceof W && (e = { context: e }); const { context: t, roundPixels: r, ...s } = e || {}; super({ label: "Graphics", ...s }), this.renderPipeId = "graphics", t ? this._context = t : this._context = this._ownedContext = new W(), this._context.on("update", this.onViewUpdate, this), this.allowChildren = !1, this.roundPixels = r ?? !1; } set context(e) { e !== this._context && (this._context.off("update", this.onViewUpdate, this), this._context = e, this._context.on("update", this.onViewUpdate, this), this.onViewUpdate()); } get context() { return this._context; } /** * The local bounds of the graphic. * @type {rendering.Bounds} */ get bounds() { return this._context.bounds; } /** * Adds the bounds of this object to the bounds object. * @param bounds - The output bounds object. */ addBounds(e) { e.addBounds(this._context.bounds); } /** * Checks if the object contains the given point. * @param point - The point to check */ containsPoint(e) { return this._context.containsPoint(e); } /** * Destroys this graphics renderable and optionally its context. * @param options - Options parameter. A boolean will act as if all options * * If the context was created by this graphics and `destroy(false)` or `destroy()` is called * then the context will still be destroyed. * * If you want to explicitly not destroy this context that this graphics created, * then you should pass destroy({ context: false }) * * If the context was passed in as an argument to the constructor then it will not be destroyed * @param {boolean} [options.texture=false] - Should destroy the texture of the graphics context * @param {boolean} [options.textureSource=false] - Should destroy the texture source of the graphics context * @param {boolean} [options.context=false] - Should destroy the context */ destroy(e) { this._ownedContext && !e ? this._ownedContext.destroy(e) : (e === !0 || (e == null ? void 0 : e.context) === !0) && this._context.destroy(e), this._ownedContext = null, this._context = null, super.destroy(e); } _callContextMethod(e, t) { return this.context[e](...t), this; } // --------------------------------------- GraphicsContext methods --------------------------------------- /** * Sets the current fill style of the graphics context. The fill style can be a color, gradient, * pattern, or a more complex style defined by a FillStyle object. * @param {FillInput} args - The fill style to apply. This can be a simple color, a gradient or * pattern object, or a FillStyle or ConvertedFillStyle object. * @returns The instance of the current GraphicsContext for method chaining. */ setFillStyle(...e) { return this._callContextMethod("setFillStyle", e); } /** * Sets the current stroke style of the graphics context. Similar to fill styles, stroke styles can * encompass colors, gradients, patterns, or more detailed configurations via a StrokeStyle object. * @param {StrokeInput} args - The stroke style to apply. Can be defined as a color, a gradient or pattern, * or a StrokeStyle or ConvertedStrokeStyle object. * @returns The instance of the current GraphicsContext for method chaining. */ setStrokeStyle(...e) { return this._callContextMethod("setStrokeStyle", e); } fill(...e) { return this._callContextMethod("fill", e); } /** * Strokes the current path with the current stroke style. This method can take an optional * FillStyle parameter to define the stroke's appearance, including its color, width, and other properties. * @param {FillStyle} args - (Optional) The stroke style to apply. Can be defined as a simple color or a more * complex style object. If omitted, uses the current stroke style. * @returns The instance of the current GraphicsContext for method chaining. */ stroke(...e) { return this._callContextMethod("stroke", e); } texture(...e) { return this._callContextMethod("texture", e); } /** * Resets the current path. Any previous path and its commands are discarded and a new path is * started. This is typically called before beginning a new shape or series of drawing commands. * @returns The instance of the current GraphicsContext for method chaining. */ beginPath() { return this._callContextMethod("beginPath", []); } /** * Applies a cutout to the last drawn shape. This is used to create holes or complex shapes by * subtracting a path from the previously drawn path. If a hole is not completely in a shape, it will * fail to cut correctly! */ cut() { return this._callContextMethod("cut", []); } arc(...e) { return this._callContextMethod("arc", e); } arcTo(...e) { return this._callContextMethod("arcTo", e); } arcToSvg(...e) { return this._callContextMethod("arcToSvg", e); } bezierCurveTo(...e) { return this._callContextMethod("bezierCurveTo", e); } /** * Closes the current path by drawing a straight line back to the start. * If the shape is already closed or there are no points in the path, this method does nothing. * @returns The instance of the current object for chaining. */ closePath() { return this._callContextMethod("closePath", []); } ellipse(...e) { return this._callContextMethod("ellipse", e); } circle(...e) { return this._callContextMethod("circle", e); } path(...e) { return this._callContextMethod("path", e); } lineTo(...e) { return this._callContextMethod("lineTo", e); } moveTo(...e) { return this._callContextMethod("moveTo", e); } quadraticCurveTo(...e) { return this._callContextMethod("quadraticCurveTo", e); } rect(...e) { return this._callContextMethod("rect", e); } roundRect(...e) { return this._callContextMethod("roundRect", e); } poly(...e) { return this._callContextMethod("poly", e); } regularPoly(...e) { return this._callContextMethod("regularPoly", e); } roundPoly(...e) { return this._callContextMethod("roundPoly", e); } roundShape(...e) { return this._callContextMethod("roundShape", e); } filletRect(...e) { return this._callContextMethod("filletRect", e); } chamferRect(...e) { return this._callContextMethod("chamferRect", e); } star(...e) { return this._callContextMethod("star", e); } svg(...e) { return this._callContextMethod("svg", e); } restore(...e) { return this._callContextMethod("restore", e); } /** Saves the current graphics state, including transformations, fill styles, and stroke styles, onto a stack. */ save() { return this._callContextMethod("save", []); } /** * Returns the current transformation matrix of the graphics context. * @returns The current transformation matrix. */ getTransform() { return this.context.getTransform(); } /** * Resets the current transformation matrix to the identity matrix, effectively removing * any transformations (rotation, scaling, translation) previously applied. * @returns The instance of the current GraphicsContext for method chaining. */ resetTransform() { return this._callContextMethod("resetTransform", []); } rotateTransform(...e) { return this._callContextMethod("rotate", e); } scaleTransform(...e) { return this._callContextMethod("scale", e); } setTransform(...e) { return this._callContextMethod("setTransform", e); } transform(...e) { return this._callContextMethod("transform", e); } translateTransform(...e) { return this._callContextMethod("translate", e); } /** * Clears all drawing commands from the graphics context, effectively resetting it. This includes clearing the path, * and optionally resetting transformations to the identity matrix. * @returns The instance of the current GraphicsContext for method chaining. */ clear() { return this._callContextMethod("clear", []); } /** * The fill style to use. * @type {ConvertedFillStyle} */ get fillStyle() { return this._context.fillStyle; } set fillStyle(e) { this._context.fillStyle = e; } /** * The stroke style to use. * @type {ConvertedStrokeStyle} */ get strokeStyle() { return this._context.strokeStyle; } set strokeStyle(e) { this._context.strokeStyle = e; } /** * Creates a new Graphics object. * Note that only the context of the object is cloned, not its transform (position,scale,etc) * @param deep - Whether to create a deep clone of the graphics object. If false, the context * will be shared between the two objects (default false). If true, the context will be * cloned (recommended if you need to modify the context in any way). * @returns - A clone of the graphics object */ clone(e = !1) { return e ? new X(this._context.clone()) : (this._ownedContext = null, new X(this._context)); } // -------- v7 deprecations --------- /** * @param width * @param color * @param alpha * @deprecated since 8.0.0 Use {@link Graphics#setStrokeStyle} instead */ lineStyle(e, t, r) { w(C, "Graphics#lineStyle is no longer needed. Use Graphics#setStrokeStyle to set the stroke style."); const s = {}; return e && (s.width = e), t && (s.color = t), r && (s.alpha = r), this.context.strokeStyle = s, this; } /** * @param color * @param alpha * @deprecated since 8.0.0 Use {@link Graphics#fill} instead */ beginFill(e, t) { w(C, "Graphics#beginFill is no longer needed. Use Graphics#fill to fill the shape with the desired style."); const r = {}; return e && (r.color = e), t && (r.alpha = t), this.context.fillStyle = r, this; } /** * @deprecated since 8.0.0 Use {@link Graphics#fill} instead */ endFill() { w(C, "Graphics#endFill is no longer needed. Use Graphics#fill to fill the shape with the desired style."), this.context.fill(); const e = this.context.strokeStyle; return (e.width !== W.defaultStrokeStyle.width || e.color !== W.defaultStrokeStyle.color || e.alpha !== W.defaultStrokeStyle.alpha) && this.context.stroke(), this; } /** * @param {...any} args * @deprecated since 8.0.0 Use {@link Graphics#circle} instead */ drawCircle(...e) { return w(C, "Graphics#drawCircle has been renamed to Graphics#circle"), this._callContextMethod("circle", e); } /** * @param {...any} args * @deprecated since 8.0.0 Use {@link Graphics#ellipse} instead */ drawEllipse(...e) { return w(C, "Graphics#drawEllipse has been renamed to Graphics#ellipse"), this._callContextMethod("ellipse", e); } /** * @param {...any} args * @deprecated since 8.0.0 Use {@link Graphics#poly} instead */ drawPolygon(...e) { return w(C, "Graphics#drawPolygon has been renamed to Graphics#poly"), this._callContextMethod("poly", e); } /** * @param {...any} args * @deprecated since 8.0.0 Use {@link Graphics#rect} instead */ drawRect(...e) { return w(C, "Graphics#drawRect has been renamed to Graphics#rect"), this._callContextMethod("rect", e); } /** * @param {...any} args * @deprecated since 8.0.0 Use {@link Graphics#roundRect} instead */ drawRoundedRect(...e) { return w(C, "Graphics#drawRoundedRect has been renamed to Graphics#roundRect"), this._callContextMethod("roundRect", e); } /** * @param {...any} args * @deprecated since 8.0.0 Use {@link Graphics#star} instead */ drawStar(...e) { return w(C, "Graphics#drawStar has been renamed to Graphics#star"), this._callContextMethod("star", e); } } const Le = class $e extends se { constructor(...e) { let t = e[0] ?? {}; t instanceof Float32Array && (w(C, "use new MeshGeometry({ positions, uvs, indices }) instead"), t = { positions: t, uvs: e[1], indices: e[2] }), t = { ...$e.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 O({ data: r, label: "attribute-mesh-positions", shrinkToFit: a, usage: M.VERTEX | M.COPY_DST }), l = new O({ data: s, label: "attribute-mesh-uvs", shrinkToFit: a, usage: M.VERTEX | M.COPY_DST }), u = new O({ data: n, label: "index-mesh-buffer", shrinkToFit: a, usage: M.INDEX | M.COPY_DST }); super({ attributes: { aPosition: { buffer: o, format: "float32x2", stride: 2 * 4, offset: 0 }, aUV: { buffer: l, format: "float32x2", stride: 2 * 4, offset: 0 } }, indexBuffer: u, 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; } }; Le.defaultOptions = { topology: "triangle-list", shrinkBuffersToFit: !1 }; let oe = Le; function Wt(i) { const e = i._stroke, t = i._fill, s = [`div { ${[ `color: ${H.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 ? [Xe(e)] : [], ...i.dropShadow ? [Ye(i.dropShadow)] : [], ...i.cssOverrides ].join(";")} }`]; return Ot(i.tagStyles, s), s.join(" "); } function Ye(i) { const e = H.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 Xe(i) { return [ `-webkit-text-stroke-width: ${i.width}px`, `-webkit-text-stroke-color: ${H.shared.setValue(i.color).toHex()}`, `text-stroke-width: ${i.width}px`, `text-stroke-color: ${H.shared.setValue(i.color).toHex()}`, "paint-order: stroke" ].join(";"); } const _e = { 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" }, be = { fill: (i) => `color: ${H.shared.setValue(i).toHex()}`, breakWords: (i) => `word-wrap: ${i ? "break-all" : "break-word"}`, stroke: Xe, dropShadow: Ye }; function Ot(i, e) { for (const t in i) { const r = i[t], s = []; for (const n in r) be[n] ? s.push(be[n](r[n])) : _e[n] && s.push(_e[n].replace("{{VALUE}}", r[n])); e.push(`${t} { ${s.join(";")} }`); } } class le extends Z { 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 = mt(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 le({ align: this.align, breakWords: this.breakWords, dropShadow: this.dropShadow ? { ...this.dropShadow } : null, 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 = Wt(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" && $("[HTMLTextStyle] only color fill is not supported by HTMLText"), super.fill = e; } set stroke(e) { e && typeof e != "string" && typeof e != "number" && $("[HTMLTextStyle] only color stroke is not supported by HTMLText"), super.stroke = e; } } const ye = "http://www.w3.org/2000/svg", Te = "http://www.w3.org/1999/xhtml"; class je { constructor() { this.svgRoot = document.createElementNS(ye, "svg"), this.foreignObject = document.createElementNS(ye, "foreignObject"), this.domElement = document.createElementNS(Te, "div"), this.styleElement = document.createElementNS(Te, "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 ve; function Vt(i, e, t, r) { r = r || ve || (ve = new je()); const { domElement: s, styleElement: n, svgRoot: a } = r; s.innerHTML = `
${i}
`, 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 l = k.measureFont(e.fontStyle).descent, u = e.padding * 2; return { width: o.width - u, height: o.height + l - u }; } class Ke { constructor(e, t) { this.state = Y.for2d(), this._graphicsBatchesHash = /* @__PURE__ */ Object.create(null), this._destroyRenderableBound = this.destroyRenderable.bind(this), this.renderer = e, this._adaptor = t, this._adaptor.init(), this.renderer.renderableGC.addManagedHash(this, "_graphicsBatchesHash"); } 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.didViewUpdate && 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), e.off("destroyed", this._destroyRenderableBound); } 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, j( 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(_t); return a.copyTo(o), o.renderable = e, o.roundPixels = s, o; }); return this._graphicsBatchesHash[e.uid] === void 0 && e.on("destroyed", this._destroyRenderableBound), 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; } } Ke.extension = { type: [ p.WebGLPipes, p.WebGPUPipes, p.CanvasPipes ], name: "graphics" }; const Ne = class qe extends oe { constructor(...e) { super({}); let t = e[0] ?? {}; typeof t == "number" && (w(C, "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 = { ...qe.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, l = this.width / a, u = this.height / o; for (let d = 0; d < t; d++) { const h = d % this.verticesX, g = d / this.verticesX | 0; r.push(h * l, g * u), s.push(h / a, g / o); } const c = a * o; for (let d = 0; d < c; d++) { const h = d % a, g = d / a | 0, x = g * this.verticesX + h, f = g * this.verticesX + h + 1, m = (g + 1) * this.verticesX + h, _ = (g + 1) * this.verticesX + h + 1; n.push( x, f, m, f, _, 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(); } }; Ne.defaultOptions = { width: 100, height: 100, verticesX: 10, verticesY: 10 }; let Et = Ne; class de { constructor() { this.batcherName = "default", this.packAsQuad = !1, this.indexOffset = 0, this.attributeOffset = 0, this.roundPixels = 0, this._batcher = null, this._batch = null, this._uvUpdateId = -1, this._textureMatrixUpdateId = -1; } get blendMode() { return this.renderable.groupBlendMode; } reset() { this.renderable = null, this.texture = null, this._batcher = null, this._batch = null, this.geometry = null, this._uvUpdateId = -1, this._textureMatrixUpdateId = -1; } get uvs() { const t = this.geometry.getBuffer("aUV"), r = t.data; let s = r; const n = this.texture.textureMatrix; return n.isSimple || (s = this._transformedUvs, (this._textureMatrixUpdateId !== n._updateID || this._uvUpdateId !== t._updateID) && ((!s || s.length < r.length) && (s = this._transformedUvs = new Float32Array(r.length)), this._textureMatrixUpdateId = n._updateID, this._uvUpdateId = t._updateID, n.multiplyUvs(r, s))), s; } get positions() { return this.geometry.positions; } get indices() { return this.geometry.indices; } get color() { return this.renderable.groupColorAlpha; } get groupTransform() { return this.renderable.groupTransform; } get attributeSize() { return this.geometry.positions.length / 2; } get indexSize() { return this.geometry.indices.length; } } class Qe { constructor(e, t) { this.localUniforms = new D({ uTransformMatrix: { value: new P(), type: "mat3x3" }, uColor: { value: new Float32Array([1, 1, 1, 1]), type: "vec4" }, uRound: { value: 0, type: "f32" } }), this.localUniformsBindGroup = new Ue({ 0: this.localUniforms }), this._meshDataHash = /* @__PURE__ */ Object.create(null), this._gpuBatchableMeshHash = /* @__PURE__ */ Object.create(null), this._destroyRenderableBound = this.destroyRenderable.bind(this), this.renderer = e, this._adaptor = t, this._adaptor.init(), e.renderableGC.addManagedHash(this, "_gpuBatchableMeshHash"), e.renderableGC.addManagedHash(this, "_meshDataHash"); } 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, t); } else r.break(t), t.add(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), e.off("destroyed", this._destroyRenderableBound); } execute(e) { if (!e.isRenderable) return; e.state.blendMode = ne(e.groupBlendMode, e.texture._source); const t = this.localUniforms; t.uniforms.uTransformMatrix = e.groupTransform, t.uniforms.uRound = this.renderer._roundPixels | e._roundPixels, t.update(), j( 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._destroyRenderableBound), this._meshDataHash[e.uid]; } _getBatchableMesh(e) { return this._gpuBatchableMeshHash[e.uid] || this._initBatchableMesh(e); } _initBatchableMesh(e) { const t = b.get(de); return t.renderable = e, t.texture = e._texture, t.transform = e.groupTransform, t.roundPixels = this.renderer._roundPixels | e._roundPixels, this._gpuBatchableMeshHash[e.uid] = t, 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; } } Qe.extension = { type: [ p.WebGLPipes, p.WebGPUPipes, p.CanvasPipes ], name: "mesh" }; class It { execute(e, t) { const r = e.state, s = e.renderer, n = t.shader || e.defaultShader; n.resources.uTexture = t.texture._source, n.resources.uniforms = e.localUniforms; const a = s.gl, o = e.getBuffers(t); s.shader.bind(n), s.state.set(r), s.geometry.bind(o.geometry, n.glProgram); const u = o.geometry.indexBuffer.data.BYTES_PER_ELEMENT === 2 ? a.UNSIGNED_SHORT : a.UNSIGNED_INT; a.drawElements(a.TRIANGLES, t.particleChildren.length * 6, u, 0); } } class Lt { execute(e, t) { const r = e.renderer, s = t.shader || e.defaultShader; s.groups[0] = r.renderPipes.uniformBatch.getUniformBindGroup(e.localUniforms, !0), s.groups[1] = r.texture.getTextureBindGroup(t.texture); const n = e.state, a = e.getBuffers(t); r.encoder.draw({ geometry: a.geometry, shader: t.shader || e.defaultShader, state: n, size: t.particleChildren.length * 6 }); } } function Se(i, e = null) { const t = i * 6; if (t > 65535 ? e = e || new Uint32Array(t) : e = e || new Uint16Array(t), e.length !== t) throw new Error(`Out buffer length is incorrect, got ${e.length} and expected ${t}`); for (let r = 0, s = 0; r < t; r += 6, s += 4) e[r + 0] = s + 0, e[r + 1] = s + 1, e[r + 2] = s + 2, e[r + 3] = s + 0, e[r + 4] = s + 2, e[r + 5] = s + 3; return e; } function $t(i) { return { dynamicUpdate: we(i, !0), staticUpdate: we(i, !1) }; } function we(i, e) { const t = []; t.push(` var index = 0; for (let i = 0; i < ps.length; ++i) { const p = ps[i]; `); let r = 0; for (const n in i) { const a = i[n]; if (e !== a.dynamic) continue; t.push(`offset = index + ${r}`), t.push(a.code); const o = ee(a.format); r += o.stride / 4; } t.push(` index += stride * 4; } `), t.unshift(` var stride = ${r}; `); const s = t.join(` `); return new Function("ps", "f32v", "u32v", s); } class Yt { constructor(e) { this._size = 0, this._generateParticleUpdateCache = {}; const t = this._size = e.size ?? 1e3, r = e.properties; let s = 0, n = 0; for (const c in r) { const d = r[c], h = ee(d.format); d.dynamic ? n += h.stride : s += h.stride; } this._dynamicStride = n / 4, this._staticStride = s / 4, this.staticAttributeBuffer = new E(t * 4 * s), this.dynamicAttributeBuffer = new E(t * 4 * n), this.indexBuffer = Se(t); const a = new se(); let o = 0, l = 0; this._staticBuffer = new O({ data: new Float32Array(1), label: "static-particle-buffer", shrinkToFit: !1, usage: M.VERTEX | M.COPY_DST }), this._dynamicBuffer = new O({ data: new Float32Array(1), label: "dynamic-particle-buffer", shrinkToFit: !1, usage: M.VERTEX | M.COPY_DST }); for (const c in r) { const d = r[c], h = ee(d.format); d.dynamic ? (a.addAttribute(d.attributeName, { buffer: this._dynamicBuffer, stride: this._dynamicStride * 4, offset: o * 4, format: d.format }), o += h.size) : (a.addAttribute(d.attributeName, { buffer: this._staticBuffer, stride: this._staticStride * 4, offset: l * 4, format: d.format }), l += h.size); } a.addIndex(this.indexBuffer); const u = this.getParticleUpdate(r); this._dynamicUpload = u.dynamicUpdate, this._staticUpload = u.staticUpdate, this.geometry = a; } getParticleUpdate(e) { const t = Xt(e); return this._generateParticleUpdateCache[t] ? this._generateParticleUpdateCache[t] : (this._generateParticleUpdateCache[t] = this.generateParticleUpdate(e), this._generateParticleUpdateCache[t]); } generateParticleUpdate(e) { return $t(e); } update(e, t) { e.length > this._size && (t = !0, this._size = Math.max(e.length, this._size * 1.5 | 0), this.staticAttributeBuffer = new E(this._size * this._staticStride * 4 * 4), this.dynamicAttributeBuffer = new E(this._size * this._dynamicStride * 4 * 4), this.indexBuffer = Se(this._size), this.geometry.indexBuffer.setDataWithSize( this.indexBuffer, this.indexBuffer.byteLength, !0 )); const r = this.dynamicAttributeBuffer; if (this._dynamicUpload(e, r.float32View, r.uint32View), this._dynamicBuffer.setDataWithSize( this.dynamicAttributeBuffer.float32View, e.length * this._dynamicStride * 4, !0 ), t) { const s = this.staticAttributeBuffer; this._staticUpload(e, s.float32View, s.uint32View), this._staticBuffer.setDataWithSize( s.float32View, e.length * this._staticStride * 4, !0 ); } } destroy() { this._staticBuffer.destroy(), this._dynamicBuffer.destroy(), this.geometry.destroy(); } } function Xt(i) { const e = []; for (const t in i) { const r = i[t]; e.push(t, r.code, r.dynamic ? "d" : "s"); } return e.join("_"); } var jt = `varying vec2 vUV; varying vec4 vColor; uniform sampler2D uTexture; void main(void){ vec4 color = texture2D(uTexture, vUV) * vColor; gl_FragColor = color; }`, Kt = `attribute vec2 aVertex; attribute vec2 aUV; attribute vec4 aColor; attribute vec2 aPosition; attribute float aRotation; uniform mat3 uTranslationMatrix; uniform float uRound; uniform vec2 uResolution; uniform vec4 uColor; varying vec2 vUV; varying vec4 vColor; vec2 roundPixels(vec2 position, vec2 targetSize) { return (floor(((position * 0.5 + 0.5) * targetSize) + 0.5) / targetSize) * 2.0 - 1.0; } void main(void){ float cosRotation = cos(aRotation); float sinRotation = sin(aRotation); float x = aVertex.x * cosRotation - aVertex.y * sinRotation; float y = aVertex.x * sinRotation + aVertex.y * cosRotation; vec2 v = vec2(x, y); v = v + aPosition; gl_Position = vec4((uTranslationMatrix * vec3(v, 1.0)).xy, 0.0, 1.0); if(uRound == 1.0) { gl_Position.xy = roundPixels(gl_Position.xy, uResolution); } vUV = aUV; vColor = aColor * uColor; } `, Ce = ` struct ParticleUniforms { uProjectionMatrix:mat3x3, uResolution:vec2, uRoundPixels:f32, }; @group(0) @binding(0) var uniforms: ParticleUniforms; @group(1) @binding(0) var uTexture: texture_2d; @group(1) @binding(1) var uSampler : sampler; struct VSOutput { @builtin(position) position: vec4, @location(0) uv : vec2, @location(1) color : vec4, }; @vertex fn mainVertex( @location(0) aVertex: vec2, @location(1) aPosition: vec2, @location(2) aUV: vec2, @location(3) aColor: vec4, @location(4) aRotation: f32, ) -> VSOutput { let v = vec2( aVertex.x * cos(aRotation) - aVertex.y * sin(aRotation), aVertex.x * sin(aRotation) + aVertex.y * cos(aRotation) ) + aPosition; let position = vec4((uniforms.uProjectionMatrix * vec3(v, 1.0)).xy, 0.0, 1.0); return VSOutput( position, aUV, aColor, ); } @fragment fn mainFragment( @location(0) uv: vec2, @location(1) color: vec4, @builtin(position) position: vec4, ) -> @location(0) vec4 { var sample = textureSample(uTexture, uSampler, uv) * color; return sample; }`; class Nt extends ae { constructor() { const e = bt.from({ vertex: Kt, fragment: jt }), t = yt.from({ fragment: { source: Ce, entryPoint: "mainFragment" }, vertex: { source: Ce, entryPoint: "mainVertex" } }); super({ glProgram: e, gpuProgram: t, resources: { // this will be replaced with the texture from the particle container uTexture: A.WHITE.source, // this will be replaced with the texture style from the particle container uSampler: new Tt({}), // this will be replaced with the local uniforms from the particle container uniforms: { uTranslationMatrix: { value: new P(), type: "mat3x3" }, uColor: { value: new H(16777215), type: "vec4" }, uRound: { value: 1, type: "f32" }, uResolution: { value: [0, 0], type: "vec2" } } } }); } } class Je { /** * @param renderer - The renderer this sprite batch works for. * @param adaptor */ constructor(e, t) { this.state = Y.for2d(), this._gpuBufferHash = /* @__PURE__ */ Object.create(null), this._destroyRenderableBound = this.destroyRenderable.bind(this), this.localUniforms = new D({ uTranslationMatrix: { value: new P(), type: "mat3x3" }, uColor: { value: new Float32Array(4), type: "vec4" }, uRound: { value: 1, type: "f32" }, uResolution: { value: [0, 0], type: "vec2" } }), this.renderer = e, this.adaptor = t, this.defaultShader = new Nt(), this.state = Y.for2d(); } validateRenderable(e) { return !1; } addRenderable(e, t) { this.renderer.renderPipes.batch.break(t), t.add(e); } getBuffers(e) { return this._gpuBufferHash[e.uid] || this._initBuffer(e); } _initBuffer(e) { return this._gpuBufferHash[e.uid] = new Yt({ size: e.particleChildren.length, properties: e._properties }), e.on("destroyed", this._destroyRenderableBound), this._gpuBufferHash[e.uid]; } updateRenderable(e) { } destroyRenderable(e) { this._gpuBufferHash[e.uid].destroy(), this._gpuBufferHash[e.uid] = null, e.off("destroyed", this._destroyRenderableBound); } execute(e) { const t = e.particleChildren; if (t.length === 0) return; const r = this.renderer, s = this.getBuffers(e); e.texture || (e.texture = t[0].texture); const n = this.state; s.update(t, e._childrenDirty), e._childrenDirty = !1, n.blendMode = ne(e.blendMode, e.texture._source); const a = this.localUniforms.uniforms, o = a.uTranslationMatrix; e.worldTransform.copyTo(o), o.prepend(r.globalUniforms.globalUniformData.projectionMatrix), a.uResolution = r.globalUniforms.globalUniformData.resolution, a.uRound = r._roundPixels | e._roundPixels, j( e.groupColorAlpha, a.uColor, 0 ), this.adaptor.execute(this, e); } /** Destroys the ParticleRenderer. */ destroy() { this.defaultShader && (this.defaultShader.destroy(), this.defaultShader = null); } } class Ze extends Je { constructor(e) { super(e, new It()); } } Ze.extension = { type: [ p.WebGLPipes ], name: "particle" }; class et extends Je { constructor(e) { super(e, new Lt()); } } et.extension = { type: [ p.WebGPUPipes ], name: "particle" }; const tt = class rt extends Et { 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 qt = tt; class st { constructor(e) { this._gpuSpriteHash = /* @__PURE__ */ Object.create(null), this._destroyRenderableBound = this.destroyRenderable.bind(this), this._renderer = e, this._renderer.renderableGC.addManagedHash(this, "_gpuSpriteHash"); } addRenderable(e, t) { const r = this._getGpuSprite(e); e.didViewUpdate && this._updateBatchableSprite(e, r), this._renderer.renderPipes.batch.addToBatch(r, t); } updateRenderable(e) { const t = this._gpuSpriteHash[e.uid]; e.didViewUpdate && 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.geometry), b.return(t), this._gpuSpriteHash[e.uid] = null, e.off("destroyed", this._destroyRenderableBound); } _updateBatchableSprite(e, t) { t.geometry.update(e), t.texture = e._texture; } _getGpuSprite(e) { return this._gpuSpriteHash[e.uid] || this._initGPUSprite(e); } _initGPUSprite(e) { const t = b.get(de); return t.geometry = b.get(qt), t.renderable = e, t.transform = e.groupTransform, t.texture = e._texture, t.roundPixels = this._renderer._roundPixels | e._roundPixels, this._gpuSpriteHash[e.uid] = t, e.on("destroyed", this._destroyRenderableBound), t; } destroy() { for (const e in this._gpuSpriteHash) this._gpuSpriteHash[e].geometry.destroy(); this._gpuSpriteHash = null, this._renderer = null; } } st.extension = { type: [ p.WebGLPipes, p.WebGPUPipes, p.CanvasPipes ], name: "nineSliceSprite" }; const Qt = { name: "tiling-bit", vertex: { header: ( /* wgsl */ ` struct TilingUniforms { uMapCoord:mat3x3, uClampFrame:vec4, uClampOffset:vec2, uTextureTransform:mat3x3, uSizeAnchor:vec4 }; @group(2) @binding(0) var tilingUniforms: TilingUniforms; @group(2) @binding(1) var uTexture: texture_2d; @group(2) @binding(2) var uSampler: sampler; ` ), main: ( /* wgsl */ ` uv = (tilingUniforms.uTextureTransform * vec3(uv, 1.0)).xy; position = (position - tilingUniforms.uSizeAnchor.zw) * tilingUniforms.uSizeAnchor.xy; ` ) }, fragment: { header: ( /* wgsl */ ` struct TilingUniforms { uMapCoord:mat3x3, uClampFrame:vec4, uClampOffset:vec2, uTextureTransform:mat3x3, uSizeAnchor:vec4 }; @group(2) @binding(0) var tilingUniforms: TilingUniforms; @group(2) @binding(1) var uTexture: texture_2d; @group(2) @binding(2) var uSampler: sampler; ` ), main: ( /* wgsl */ ` var coord = vUV + ceil(tilingUniforms.uClampOffset - vUV); coord = (tilingUniforms.uMapCoord * vec3(coord, 1.0)).xy; var unclamped = coord; coord = clamp(coord, tilingUniforms.uClampFrame.xy, tilingUniforms.uClampFrame.zw); var bias = 0.; if(unclamped.x == coord.x && unclamped.y == coord.y) { bias = -32.; } outColor = textureSampleBias(uTexture, uSampler, coord, bias); ` ) } }, Jt = { name: "tiling-bit", vertex: { header: ( /* glsl */ ` uniform mat3 uTextureTransform; uniform vec4 uSizeAnchor; ` ), main: ( /* glsl */ ` uv = (uTextureTransform * vec3(aUV, 1.0)).xy; position = (position - uSizeAnchor.zw) * uSizeAnchor.xy; ` ) }, fragment: { header: ( /* glsl */ ` uniform sampler2D uTexture; uniform mat3 uMapCoord; uniform vec4 uClampFrame; uniform vec2 uClampOffset; ` ), main: ( /* glsl */ ` vec2 coord = vUV + ceil(uClampOffset - vUV); coord = (uMapCoord * vec3(coord, 1.0)).xy; vec2 unclamped = coord; coord = clamp(coord, uClampFrame.xy, uClampFrame.zw); outColor = texture(uTexture, coord, unclamped == coord ? 0.0 : -32.0);// lod-bias very negative to force lod 0 ` ) } }; let N, q; class Zt extends ae { constructor() { N ?? (N = Fe({ name: "tiling-sprite-shader", bits: [ vt, Qt, Ae ] })), q ?? (q = ke({ name: "tiling-sprite-shader", bits: [ St, Jt, He ] })); const e = new D({ uMapCoord: { value: new P(), type: "mat3x3" }, uClampFrame: { value: new Float32Array([0, 0, 1, 1]), type: "vec4" }, uClampOffset: { value: new Float32Array([0, 0]), type: "vec2" }, uTextureTransform: { value: new P(), type: "mat3x3" }, uSizeAnchor: { value: new Float32Array([100, 100, 0.5, 0.5]), type: "vec4" } }); super({ glProgram: q, gpuProgram: N, resources: { localUniforms: new D({ uTransformMatrix: { value: new P(), type: "mat3x3" }, uColor: { value: new Float32Array([1, 1, 1, 1]), type: "vec4" }, uRound: { value: 0, type: "f32" } }), tilingUniforms: e, uTexture: A.EMPTY.source, uSampler: A.EMPTY.source.style } }); } updateUniforms(e, t, r, s, n, a) { const o = this.resources.tilingUniforms, l = a.width, u = a.height, c = a.textureMatrix, d = o.uniforms.uTextureTransform; d.set( r.a * l / e, r.b * l / t, r.c * u / e, r.d * u / t, r.tx / e, r.ty / t ), d.invert(), o.uniforms.uMapCoord = c.mapCoord, o.uniforms.uClampFrame = c.uClampFrame, o.uniforms.uClampOffset = c.uClampOffset, o.uniforms.uTextureTransform = d, o.uniforms.uSizeAnchor[0] = e, o.uniforms.uSizeAnchor[1] = t, o.uniforms.uSizeAnchor[2] = s, o.uniforms.uSizeAnchor[3] = n, a && (this.resources.uTexture = a.source, this.resources.uSampler = a.source.style); } } class er extends oe { constructor() { super({ positions: new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), uvs: new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), indices: new Uint32Array([0, 1, 2, 0, 2, 3]) }); } } function tr(i, e) { const t = i.anchor.x, r = i.anchor.y; e[0] = -t * i.width, e[1] = -r * i.height, e[2] = (1 - t) * i.width, e[3] = -r * i.height, e[4] = (1 - t) * i.width, e[5] = (1 - r) * i.height, e[6] = -t * i.width, e[7] = (1 - r) * i.height; } function rr(i, e, t, r) { let s = 0; const n = i.length / e, a = r.a, o = r.b, l = r.c, u = r.d, c = r.tx, d = r.ty; for (t *= e; s < n; ) { const h = i[t], g = i[t + 1]; i[t] = a * h + l * g + c, i[t + 1] = o * h + u * g + d, t += e, s++; } } function sr(i, e) { const t = i.texture, r = t.frame.width, s = t.frame.height; let n = 0, a = 0; i._applyAnchorToTexture && (n = i.anchor.x, a = i.anchor.y), e[0] = e[6] = -n, e[2] = e[4] = 1 - n, e[1] = e[3] = -a, e[5] = e[7] = 1 - a; const o = P.shared; o.copyFrom(i._tileTransform.matrix), o.tx /= i.width, o.ty /= i.height, o.invert(), o.scale(i.width / r, i.height / s), rr(e, 2, 0, o); } const I = new er(); class it { constructor(e) { this._state = Y.default2d, this._tilingSpriteDataHash = /* @__PURE__ */ Object.create(null), this._destroyRenderableBound = this.destroyRenderable.bind(this), this._renderer = e, this._renderer.renderableGC.addManagedHash(this, "_tilingSpriteDataHash"); } validateRenderable(e) { const t = this._getTilingSpriteData(e), r = t.canBatch; this._updateCanBatch(e); const s = t.canBatch; if (s && s === r) { const { batchableMesh: n } = t; if (n && n.texture._source !== e.texture._source) return !n._batcher.checkAndUpdateTexture(n, e.texture); } return r !== s; } addRenderable(e, t) { const r = this._renderer.renderPipes.batch; this._updateCanBatch(e); const s = this._getTilingSpriteData(e), { geometry: n, canBatch: a } = s; if (a) { s.batchableMesh || (s.batchableMesh = new de()); const o = s.batchableMesh; e.didViewUpdate && (this._updateBatchableMesh(e), o.geometry = n, o.renderable = e, o.transform = e.groupTransform, o.texture = e._texture), o.roundPixels = this._renderer._roundPixels | e._roundPixels, r.addToBatch(o, t); } else r.break(t), s.shader || (s.shader = new Zt()), this.updateRenderable(e), t.add(e); } execute(e) { const { shader: t } = this._tilingSpriteDataHash[e.uid]; t.groups[0] = this._renderer.globalUniforms.bindGroup; const r = t.resources.localUniforms.uniforms; r.uTransformMatrix = e.groupTransform, r.uRound = this._renderer._roundPixels | e._roundPixels, j( e.groupColorAlpha, r.uColor, 0 ), this._state.blendMode = ne(e.groupBlendMode, e.texture._source), this._renderer.encoder.draw({ geometry: I, shader: t, state: this._state }); } updateRenderable(e) { const t = this._getTilingSpriteData(e), { canBatch: r } = t; if (r) { const { batchableMesh: s } = t; e.didViewUpdate && this._updateBatchableMesh(e), s._batcher.updateElement(s); } else if (e.didViewUpdate) { const { shader: s } = t; s.updateUniforms( e.width, e.height, e._tileTransform.matrix, e.anchor.x, e.anchor.y, e.texture ); } } destroyRenderable(e) { var r; const t = this._getTilingSpriteData(e); t.batchableMesh = null, (r = t.shader) == null || r.destroy(), this._tilingSpriteDataHash[e.uid] = null, e.off("destroyed", this._destroyRenderableBound); } _getTilingSpriteData(e) { return this._tilingSpriteDataHash[e.uid] || this._initTilingSpriteData(e); } _initTilingSpriteData(e) { const t = new oe({ indices: I.indices, positions: I.positions.slice(), uvs: I.uvs.slice() }); return this._tilingSpriteDataHash[e.uid] = { canBatch: !0, renderable: e, geometry: t }, e.on("destroyed", this._destroyRenderableBound), this._tilingSpriteDataHash[e.uid]; } _updateBatchableMesh(e) { const t = this._getTilingSpriteData(e), { geometry: r } = t, s = e.texture.source.style; s.addressMode !== "repeat" && (s.addressMode = "repeat", s.update()), sr(e, r.uvs), tr(e, r.positions); } destroy() { for (const e in this._tilingSpriteDataHash) this.destroyRenderable(this._tilingSpriteDataHash[e].renderable); this._tilingSpriteDataHash = null, this._renderer = null; } _updateCanBatch(e) { const t = this._getTilingSpriteData(e), r = e.texture; let s = !0; return this._renderer.type === ie.WEBGL && (s = this._renderer.context.supports.nonPowOf2wrapping), t.canBatch = r.textureMatrix.isSimple && (s || r.source.isPowerOfTwo), t.canBatch; } } it.extension = { type: [ p.WebGLPipes, p.WebGPUPipes, p.CanvasPipes ], name: "tilingSprite" }; const ir = { name: "local-uniform-msdf-bit", vertex: { header: ( /* wgsl */ ` struct LocalUniforms { uColor:vec4, uTransformMatrix:mat3x3, uDistance: f32, uRound:f32, } @group(2) @binding(0) var localUniforms : LocalUniforms; ` ), main: ( /* wgsl */ ` vColor *= localUniforms.uColor; modelMatrix *= localUniforms.uTransformMatrix; ` ), end: ( /* wgsl */ ` if(localUniforms.uRound == 1) { vPosition = vec4(roundPixels(vPosition.xy, globalUniforms.uResolution), vPosition.zw); } ` ) }, fragment: { header: ( /* wgsl */ ` struct LocalUniforms { uColor:vec4, uTransformMatrix:mat3x3, uDistance: f32 } @group(2) @binding(0) var localUniforms : LocalUniforms; ` ), main: ( /* wgsl */ ` outColor = vec4(calculateMSDFAlpha(outColor, localUniforms.uColor, localUniforms.uDistance)); ` ) } }, nr = { name: "local-uniform-msdf-bit", vertex: { header: ( /* glsl */ ` uniform mat3 uTransformMatrix; uniform vec4 uColor; uniform float uRound; ` ), main: ( /* glsl */ ` vColor *= uColor; modelMatrix *= uTransformMatrix; ` ), end: ( /* glsl */ ` if(uRound == 1.) { gl_Position.xy = roundPixels(gl_Position.xy, uResolution); } ` ) }, fragment: { header: ( /* glsl */ ` uniform float uDistance; ` ), main: ( /* glsl */ ` outColor = vec4(calculateMSDFAlpha(outColor, vColor, uDistance)); ` ) } }, ar = { name: "msdf-bit", fragment: { header: ( /* wgsl */ ` fn calculateMSDFAlpha(msdfColor:vec4, shapeColor:vec4, distance:f32) -> f32 { // MSDF var median = msdfColor.r + msdfColor.g + msdfColor.b - min(msdfColor.r, min(msdfColor.g, msdfColor.b)) - max(msdfColor.r, max(msdfColor.g, msdfColor.b)); // SDF median = min(median, msdfColor.a); var screenPxDistance = distance * (median - 0.5); var alpha = clamp(screenPxDistance + 0.5, 0.0, 1.0); if (median < 0.01) { alpha = 0.0; } else if (median > 0.99) { alpha = 1.0; } // Gamma correction for coverage-like alpha var luma: f32 = dot(shapeColor.rgb, vec3(0.299, 0.587, 0.114)); var gamma: f32 = mix(1.0, 1.0 / 2.2, luma); var coverage: f32 = pow(shapeColor.a * alpha, gamma); return coverage; } ` ) } }, or = { name: "msdf-bit", fragment: { header: ( /* glsl */ ` float calculateMSDFAlpha(vec4 msdfColor, vec4 shapeColor, float distance) { // MSDF float median = msdfColor.r + msdfColor.g + msdfColor.b - min(msdfColor.r, min(msdfColor.g, msdfColor.b)) - max(msdfColor.r, max(msdfColor.g, msdfColor.b)); // SDF median = min(median, msdfColor.a); float screenPxDistance = distance * (median - 0.5); float alpha = clamp(screenPxDistance + 0.5, 0.0, 1.0); if (median < 0.01) { alpha = 0.0; } else if (median > 0.99) { alpha = 1.0; } // Gamma correction for coverage-like alpha float luma = dot(shapeColor.rgb, vec3(0.299, 0.587, 0.114)); float gamma = mix(1.0, 1.0 / 2.2, luma); float coverage = pow(shapeColor.a * alpha, gamma); return coverage; } ` ) } }; let Q, J; class lr extends ae { constructor() { const e = new D({ uColor: { value: new Float32Array([1, 1, 1, 1]), type: "vec4" }, uTransformMatrix: { value: new P(), type: "mat3x3" }, uDistance: { value: 4, type: "f32" }, uRound: { value: 0, type: "f32" } }), t = wt(); Q ?? (Q = Fe({ name: "sdf-shader", bits: [ Ct, Bt(t), ir, ar, Ae ] })), J ?? (J = ke({ name: "sdf-shader", bits: [ Mt, Pt(t), nr, or, He ] })), super({ glProgram: J, gpuProgram: Q, resources: { localUniforms: e, batchSamplers: Rt(t) } }); } } class nt { constructor(e) { this._gpuBitmapText = {}, this._destroyRenderableBound = this.destroyRenderable.bind(this), this._renderer = e, this._renderer.renderableGC.addManagedHash(this, "_gpuBitmapText"); } validateRenderable(e) { const t = this._getGpuBitmapText(e); return e._didTextUpdate && (e._didTextUpdate = !1, this._updateContext(e, t)), this._renderer.renderPipes.graphics.validateRenderable(t); } addRenderable(e, t) { const r = this._getGpuBitmapText(e); Be(e, r), e._didTextUpdate && (e._didTextUpdate = !1, this._updateContext(e, r)), this._renderer.renderPipes.graphics.addRenderable(r, t), r.context.customShader && this._updateDistanceField(e); } destroyRenderable(e) { e.off("destroyed", this._destroyRenderableBound), this._destroyRenderableByUid(e.uid); } _destroyRenderableByUid(e) { const t = this._gpuBitmapText[e].context; t.customShader && (b.return(t.customShader), t.customShader = null), b.return(this._gpuBitmapText[e]), this._gpuBitmapText[e] = null; } updateRenderable(e) { const t = this._getGpuBitmapText(e); Be(e, t), this._renderer.renderPipes.graphics.updateRenderable(t), t.context.customShader && this._updateDistanceField(e); } _updateContext(e, t) { const { context: r } = t, s = Ut.getFont(e.text, e._style); r.clear(), s.distanceField.type !== "none" && (r.customShader || (r.customShader = b.get(lr))); const n = Array.from(e.text), a = e._style; let o = s.baseLineOffset; const l = Gt(n, a, s, !0); let u = 0; const c = a.padding, d = l.scale; let h = l.width, g = l.height + l.offsetY; a._stroke && (h += a._stroke.width / d, g += a._stroke.width / d), r.translate(-e._anchor._x * h - c, -e._anchor._y * g - c).scale(d, d); const x = s.applyFillAsTint ? a._fill.color : 16777215; for (let f = 0; f < l.lines.length; f++) { const m = l.lines[f]; for (let _ = 0; _ < m.charPositions.length; _++) { const R = n[u++], T = s.chars[R]; T != null && T.texture && r.texture( T.texture, x || "black", Math.round(m.charPositions[_] + T.xOffset), Math.round(o + T.yOffset) ); } o += s.lineHeight; } } _getGpuBitmapText(e) { return this._gpuBitmapText[e.uid] || this.initGpuText(e); } initGpuText(e) { const t = b.get(X); return this._gpuBitmapText[e.uid] = t, this._updateContext(e, t), e.on("destroyed", this._destroyRenderableBound), this._gpuBitmapText[e.uid]; } _updateDistanceField(e) { const t = this._getGpuBitmapText(e).context, r = e._style.fontFamily, s = te.get(`${r}-bitmap`), { a: n, b: a, c: o, d: l } = e.groupTransform, u = Math.sqrt(n * n + a * a), c = Math.sqrt(o * o + l * l), d = (Math.abs(u) + Math.abs(c)) / 2, h = s.baseRenderedFontSize / e._style.fontSize, g = d * s.distanceField.range * (1 / h); t.customShader.resources.localUniforms.uniforms.uDistance = g; } destroy() { for (const e in this._gpuBitmapText) this._destroyRenderableByUid(e); this._gpuBitmapText = null, this._renderer = null; } } nt.extension = { type: [ p.WebGLPipes, p.WebGPUPipes, p.CanvasPipes ], name: "bitmapText" }; function Be(i, e) { e.groupTransform = i.groupTransform, e.groupColorAlpha = i.groupColorAlpha, e.groupColor = i.groupColor, e.groupBlendMode = i.groupBlendMode, e.globalDisplayStatus = i.globalDisplayStatus, e.groupTransform = i.groupTransform, e.localDisplayStatus = i.localDisplayStatus, e.groupAlpha = i.groupAlpha, e._roundPixels = i._roundPixels; } class at { constructor(e) { this._gpuText = /* @__PURE__ */ Object.create(null), this._destroyRenderableBound = this.destroyRenderable.bind(this), this._renderer = e, this._renderer.runners.resolutionChange.add(this), this._renderer.renderableGC.addManagedHash(this, "_gpuText"); } resolutionChange() { for (const e in this._gpuText) { const t = this._gpuText[e]; if (!t) continue; const r = t.batchableSprite.renderable; r._autoResolution && (r._resolution = this._renderer.resolution, r.onViewUpdate()); } } validateRenderable(e) { const t = this._getGpuText(e), r = e._getKey(); return t.textureNeedsUploading ? (t.textureNeedsUploading = !1, !0) : t.currentKey !== r; } addRenderable(e, t) { const s = this._getGpuText(e).batchableSprite; e._didTextUpdate && this._updateText(e), this._renderer.renderPipes.batch.addToBatch(s, t); } updateRenderable(e) { const r = this._getGpuText(e).batchableSprite; e._didTextUpdate && this._updateText(e), r._batcher.updateElement(r); } destroyRenderable(e) { e.off("destroyed", this._destroyRenderableBound), this._destroyRenderableById(e.uid); } _destroyRenderableById(e) { const t = this._gpuText[e]; this._renderer.htmlText.decreaseReferenceCount(t.currentKey), b.return(t.batchableSprite), this._gpuText[e] = null; } _updateText(e) { const t = e._getKey(), r = this._getGpuText(e), s = r.batchableSprite; r.currentKey !== t && this._updateGpuText(e).catch((a) => { console.error(a); }), e._didTextUpdate = !1; const n = e._style.padding; re(s.bounds, e._anchor, s.texture, n); } async _updateGpuText(e) { e._didTextUpdate = !1; const t = this._getGpuText(e); if (t.generatingTexture) return; const r = e._getKey(); this._renderer.htmlText.decreaseReferenceCount(t.currentKey), t.generatingTexture = !0, t.currentKey = r; const s = e.resolution ?? this._renderer.resolution, n = await this._renderer.htmlText.getManagedTexture( e.text, s, e._style, e._getKey() ), a = t.batchableSprite; a.texture = t.texture = n, t.generatingTexture = !1, t.textureNeedsUploading = !0, e.onViewUpdate(); const o = e._style.padding; re(a.bounds, e._anchor, a.texture, o); } _getGpuText(e) { return this._gpuText[e.uid] || this.initGpuText(e); } initGpuText(e) { const t = { texture: A.EMPTY, currentKey: "--", batchableSprite: b.get(De), textureNeedsUploading: !1, generatingTexture: !1 }, r = t.batchableSprite; return r.renderable = e, r.transform = e.groupTransform, r.texture = A.EMPTY, r.bounds = { minX: 0, maxX: 1, minY: 0, maxY: 0 }, r.roundPixels = this._renderer._roundPixels | e._roundPixels, e._resolution = e._autoResolution ? this._renderer.resolution : e.resolution, this._gpuText[e.uid] = t, e.on("destroyed", this._destroyRenderableBound), t; } destroy() { for (const e in this._gpuText) this._destroyRenderableById(e); this._gpuText = null, this._renderer = null; } } at.extension = { type: [ p.WebGLPipes, p.WebGPUPipes, p.CanvasPipes ], name: "htmlText" }; function dr() { const { userAgent: i } = ze.get().getNavigator(); return /^((?!chrome|android).)*safari/i.test(i); } const ur = new Ge(); function ot(i, e, t, r) { const s = ur; s.minX = 0, s.minY = 0, s.maxX = i.width / r | 0, s.maxY = i.height / r | 0; const n = B.getOptimalTexture( s.width, s.height, r, !1 ); return n.source.uploadMethodId = "image", n.source.resource = i, n.source.alphaMode = "premultiply-alpha-on-upload", n.frame.width = e / r, n.frame.height = t / r, n.source.emit("update", n.source), n.updateUvs(), n; } function cr(i, e) { const t = e.fontFamily, r = [], s = {}, n = /font-family:([^;"\s]+)/g, a = i.match(n); function o(l) { s[l] || (r.push(l), s[l] = !0); } if (Array.isArray(t)) for (let l = 0; l < t.length; l++) o(t[l]); else o(t); a && a.forEach((l) => { const u = l.split(":")[1].trim(); o(u); }); for (const l in e.tagStyles) { const u = e.tagStyles[l].fontFamily; o(u); } return r; } async function hr(i) { const t = await (await ze.get().fetch(i)).blob(), r = new FileReader(); return await new Promise((n, a) => { r.onloadend = () => n(r.result), r.onerror = a, r.readAsDataURL(t); }); } async function Me(i, e) { const t = await hr(e); return `@font-face { font-family: "${i.fontFamily}"; src: url('${t}'); font-weight: ${i.fontWeight}; font-style: ${i.fontStyle}; }`; } const L = /* @__PURE__ */ new Map(); async function fr(i, e, t) { const r = i.filter((s) => te.has(`${s}-and-url`)).map((s, n) => { if (!L.has(s)) { const { url: a } = te.get(`${s}-and-url`); n === 0 ? L.set(s, Me({ fontWeight: e.fontWeight, fontStyle: e.fontStyle, fontFamily: s }, a)) : L.set(s, Me({ fontWeight: t.fontWeight, fontStyle: t.fontStyle, fontFamily: s }, a)); } return L.get(s); }); return (await Promise.all(r)).join(` `); } function pr(i, e, t, r, s) { const { domElement: n, styleElement: a, svgRoot: o } = s; n.innerHTML = `
${i}
`, n.setAttribute("style", `transform: scale(${t});transform-origin: top left; display: inline-block`), a.textContent = r; const { width: l, height: u } = s.image; return o.setAttribute("width", l.toString()), o.setAttribute("height", u.toString()), new XMLSerializer().serializeToString(o); } function gr(i, e) { const t = V.getOptimalCanvasAndContext( i.width, i.height, e ), { context: r } = t; return r.clearRect(0, 0, i.width, i.height), r.drawImage(i, 0, 0), t; } function xr(i, e, t) { return new Promise(async (r) => { t && await new Promise((s) => setTimeout(s, 100)), i.onload = () => { r(); }, i.src = `data:image/svg+xml;charset=utf8,${encodeURIComponent(e)}`, i.crossOrigin = "anonymous"; }); } class ue { constructor(e) { this._activeTextures = {}, this._renderer = e, this._createCanvas = e.type === ie.WEBGPU; } getTexture(e) { return this._buildTexturePromise( e.text, e.resolution, e.style ); } getManagedTexture(e, t, r, s) { if (this._activeTextures[s]) return this._increaseReferenceCount(s), this._activeTextures[s].promise; const n = this._buildTexturePromise(e, t, r).then((a) => (this._activeTextures[s].texture = a, a)); return this._activeTextures[s] = { texture: null, promise: n, usageCount: 1 }, n; } async _buildTexturePromise(e, t, r) { const s = b.get(je), n = cr(e, r), a = await fr( n, r, le.defaultTextStyle ), o = Vt(e, r, a, s), l = Math.ceil(Math.ceil(Math.max(1, o.width) + r.padding * 2) * t), u = Math.ceil(Math.ceil(Math.max(1, o.height) + r.padding * 2) * t), c = s.image, d = 2; c.width = (l | 0) + d, c.height = (u | 0) + d; const h = pr(e, r, t, a, s); await xr(c, h, dr() && n.length > 0); const g = c; let x; this._createCanvas && (x = gr(c, t)); const f = ot( x ? x.canvas : g, c.width - d, c.height - d, t ); return this._createCanvas && (this._renderer.texture.initSource(f.source), V.returnCanvasAndContext(x)), b.return(s), f; } _increaseReferenceCount(e) { this._activeTextures[e].usageCount++; } decreaseReferenceCount(e) { const t = this._activeTextures[e]; t && (t.usageCount--, t.usageCount === 0 && (t.texture ? this._cleanUp(t) : t.promise.then((r) => { t.texture = r, this._cleanUp(t); }).catch(() => { $("HTMLTextSystem: Failed to clean texture"); }), this._activeTextures[e] = null)); } _cleanUp(e) { B.returnTexture(e.texture), e.texture.source.resource = null, e.texture.source.uploadMethodId = "unknown"; } getReferenceCount(e) { return this._activeTextures[e].usageCount; } destroy() { this._activeTextures = null; } } ue.extension = { type: [ p.WebGLSystem, p.WebGPUSystem, p.CanvasSystem ], name: "htmlText" }; ue.defaultFontOptions = { fontFamily: "Arial", fontStyle: "normal", fontWeight: "normal" }; class lt { constructor(e) { this._gpuText = /* @__PURE__ */ Object.create(null), this._destroyRenderableBound = this.destroyRenderable.bind(this), this._renderer = e, this._renderer.runners.resolutionChange.add(this), this._renderer.renderableGC.addManagedHash(this, "_gpuText"); } resolutionChange() { for (const e in this._gpuText) { const t = this._gpuText[e]; if (!t) continue; const r = t.batchableSprite.renderable; r._autoResolution && (r._resolution = this._renderer.resolution, r.onViewUpdate()); } } validateRenderable(e) { const t = this._getGpuText(e), r = e._getKey(); return t.currentKey !== r; } addRenderable(e, t) { const s = this._getGpuText(e).batchableSprite; e._didTextUpdate && this._updateText(e), this._renderer.renderPipes.batch.addToBatch(s, t); } updateRenderable(e) { const r = this._getGpuText(e).batchableSprite; e._didTextUpdate && this._updateText(e), r._batcher.updateElement(r); } destroyRenderable(e) { e.off("destroyed", this._destroyRenderableBound), this._destroyRenderableById(e.uid); } _destroyRenderableById(e) { const t = this._gpuText[e]; this._renderer.canvasText.decreaseReferenceCount(t.currentKey), b.return(t.batchableSprite), this._gpuText[e] = null; } _updateText(e) { const t = e._getKey(), r = this._getGpuText(e), s = r.batchableSprite; r.currentKey !== t && this._updateGpuText(e), e._didTextUpdate = !1; const n = e._style.padding; re(s.bounds, e._anchor, s.texture, n); } _updateGpuText(e) { const t = this._getGpuText(e), r = t.batchableSprite; t.texture && this._renderer.canvasText.decreaseReferenceCount(t.currentKey), t.texture = r.texture = this._renderer.canvasText.getManagedTexture(e), t.currentKey = e._getKey(), r.texture = t.texture; } _getGpuText(e) { return this._gpuText[e.uid] || this.initGpuText(e); } initGpuText(e) { const t = { texture: null, currentKey: "--", batchableSprite: b.get(De) }; return t.batchableSprite.renderable = e, t.batchableSprite.transform = e.groupTransform, t.batchableSprite.bounds = { minX: 0, maxX: 1, minY: 0, maxY: 0 }, t.batchableSprite.roundPixels = this._renderer._roundPixels | e._roundPixels, this._gpuText[e.uid] = t, e._resolution = e._autoResolution ? this._renderer.resolution : e.resolution, this._updateText(e), e.on("destroyed", this._destroyRenderableBound), t; } destroy() { for (const e in this._gpuText) this._destroyRenderableById(e); this._gpuText = null, this._renderer = null; } } lt.extension = { type: [ p.WebGLPipes, p.WebGPUPipes, p.CanvasPipes ], name: "text" }; function Pe(i, e, t) { for (let r = 0, s = 4 * t * e; r < e; ++r, s += 4) if (i[s + 3] !== 0) return !1; return !0; } function Re(i, e, t, r, s) { const n = 4 * e; for (let a = r, o = r * n + 4 * t; a <= s; ++a, o += n) if (i[o + 3] !== 0) return !1; return !0; } function mr(i, e = 1) { const { width: t, height: r } = i, s = i.getContext("2d", { willReadFrequently: !0 }); if (s === null) throw new TypeError("Failed to get canvas 2D context"); const a = s.getImageData(0, 0, t, r).data; let o = 0, l = 0, u = t - 1, c = r - 1; for (; l < r && Pe(a, t, l); ) ++l; if (l === r) return ge.EMPTY; for (; Pe(a, t, c); ) --c; for (; Re(a, t, o, l, c); ) ++o; for (; Re(a, t, u, l, c); ) --u; return ++u, ++c, new ge(o / e, l / e, (u - o) / e, (c - l) / e); } class dt { constructor(e) { this._activeTextures = {}, this._renderer = e; } getTextureSize(e, t, r) { const s = k.measureText(e || " ", r); let n = Math.ceil(Math.ceil(Math.max(1, s.width) + r.padding * 2) * t), a = Math.ceil(Math.ceil(Math.max(1, s.height) + r.padding * 2) * t); return n = Math.ceil(n - 1e-6), a = Math.ceil(a - 1e-6), n = me(n), a = me(a), { width: n, height: a }; } getTexture(e, t, r, s) { typeof e == "string" && (w("8.0.0", "CanvasTextSystem.getTexture: Use object TextOptions instead of separate arguments"), e = { text: e, style: r, resolution: t }), e.style instanceof Z || (e.style = new Z(e.style)); const { texture: n, canvasAndContext: a } = this.createTextureAndCanvas( e ); return this._renderer.texture.initSource(n._source), V.returnCanvasAndContext(a), n; } createTextureAndCanvas(e) { const { text: t, style: r } = e, s = e.resolution ?? this._renderer.resolution, n = k.measureText(t || " ", r), a = Math.ceil(Math.ceil(Math.max(1, n.width) + r.padding * 2) * s), o = Math.ceil(Math.ceil(Math.max(1, n.height) + r.padding * 2) * s), l = V.getOptimalCanvasAndContext(a, o), { canvas: u } = l; this.renderTextToCanvas(t, r, s, l); const c = ot(u, a, o, s); if (r.trim) { const d = mr(u, s); c.frame.copyFrom(d), c.updateUvs(); } return { texture: c, canvasAndContext: l }; } getManagedTexture(e) { e._resolution = e._autoResolution ? this._renderer.resolution : e.resolution; const t = e._getKey(); if (this._activeTextures[t]) return this._increaseReferenceCount(t), this._activeTextures[t].texture; const { texture: r, canvasAndContext: s } = this.createTextureAndCanvas(e); return this._activeTextures[t] = { canvasAndContext: s, texture: r, usageCount: 1 }, r; } _increaseReferenceCount(e) { this._activeTextures[e].usageCount++; } decreaseReferenceCount(e) { const t = this._activeTextures[e]; if (t.usageCount--, t.usageCount === 0) { V.returnCanvasAndContext(t.canvasAndContext), B.returnTexture(t.texture); const r = t.texture.source; r.resource = null, r.uploadMethodId = "unknown", r.alphaMode = "no-premultiply-alpha", this._activeTextures[e] = null; } } getReferenceCount(e) { return this._activeTextures[e].usageCount; } /** * Renders text to its canvas, and updates its texture. * * By default this is used internally to ensure the texture is correct before rendering, * but it can be used called externally, for example from this class to 'pre-generate' the texture from a piece of text, * and then shared across multiple Sprites. * @param text * @param style * @param resolution * @param canvasAndContext */ renderTextToCanvas(e, t, r, s) { var R, T, U, z; const { canvas: n, context: a } = s, o = Ft(t), l = k.measureText(e || " ", t), u = l.lines, c = l.lineHeight, d = l.lineWidths, h = l.maxLineWidth, g = l.fontProperties, x = n.height; if (a.resetTransform(), a.scale(r, r), a.textBaseline = t.textBaseline, (R = t._stroke) != null && R.width) { const S = t._stroke; a.lineWidth = S.width, a.miterLimit = S.miterLimit, a.lineJoin = S.join, a.lineCap = S.cap; } a.font = o; let f, m; const _ = t.dropShadow ? 2 : 1; for (let S = 0; S < _; ++S) { const G = t.dropShadow && S === 0, F = G ? Math.ceil(Math.max(1, x) + t.padding * 2) : 0, ut = F * r; if (G) { a.fillStyle = "black", a.strokeStyle = "black"; const v = t.dropShadow, ct = v.color, ht = v.alpha; a.shadowColor = H.shared.setValue(ct).setAlpha(ht).toRgbaString(); const ft = v.blur * r, fe = v.distance * r; a.shadowBlur = ft, a.shadowOffsetX = Math.cos(v.angle) * fe, a.shadowOffsetY = Math.sin(v.angle) * fe + ut; } else a.fillStyle = t._fill ? xe(t._fill, a) : null, (T = t._stroke) != null && T.width && (a.strokeStyle = xe(t._stroke, a)), a.shadowColor = "black"; let ce = (c - g.fontSize) / 2; c - g.fontSize < 0 && (ce = 0); const he = ((U = t._stroke) == null ? void 0 : U.width) ?? 0; for (let v = 0; v < u.length; v++) f = he / 2, m = he / 2 + v * c + g.ascent + ce, t.align === "right" ? f += h - d[v] : t.align === "center" && (f += (h - d[v]) / 2), (z = t._stroke) != null && z.width && this._drawLetterSpacing( u[v], t, s, f + t.padding, m + t.padding - F, !0 ), t._fill !== void 0 && this._drawLetterSpacing( u[v], t, s, f + t.padding, m + t.padding - F ); } } /** * Render the text with letter-spacing. * @param text - The text to draw * @param style * @param canvasAndContext * @param x - Horizontal position to draw the text * @param y - Vertical position to draw the text * @param isStroke - Is this drawing for the outside stroke of the * text? If not, it's for the inside fill */ _drawLetterSpacing(e, t, r, s, n, a = !1) { const { context: o } = r, l = t.letterSpacing; let u = !1; if (k.experimentalLetterSpacingSupported && (k.experimentalLetterSpacing ? (o.letterSpacing = `${l}px`, o.textLetterSpacing = `${l}px`, u = !0) : (o.letterSpacing = "0px", o.textLetterSpacing = "0px")), l === 0 || u) { a ? o.strokeText(e, s, n) : o.fillText(e, s, n); return; } let c = s; const d = k.graphemeSegmenter(e); let h = o.measureText(e).width, g = 0; for (let x = 0; x < d.length; ++x) { const f = d[x]; a ? o.strokeText(f, c, n) : o.fillText(f, c, n); let m = ""; for (let _ = x + 1; _ < d.length; ++_) m += d[_]; g = o.measureText(m).width, c += h - g + l, h = g; } } destroy() { this._activeTextures = null; } } dt.extension = { type: [ p.WebGLSystem, p.WebGPUSystem, p.CanvasSystem ], name: "canvasText" }; y.add(We); y.add(Oe); y.add(Ke); y.add(kt); y.add(Qe); y.add(Ze); y.add(et); y.add(dt); y.add(lt); y.add(nt); y.add(ue); y.add(at); y.add(it); y.add(st); y.add(Ie); y.add(Ve);