rapid-render 1.0.13 → 1.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,34 +1,17 @@
1
- var b = /* @__PURE__ */ ((n) => (n[n.Float32 = 0] = "Float32", n[n.Uint32 = 1] = "Uint32", n[n.Uint16 = 2] = "Uint16", n))(b || {});
2
- class _ {
3
- /** The number of elements currently used in the buffer. */
1
+ var S = /* @__PURE__ */ ((n) => (n[n.Float32 = 0] = "Float32", n[n.Uint32 = 1] = "Uint32", n[n.Uint16 = 2] = "Uint16", n))(S || {});
2
+ class A {
4
3
  usedElemNum;
5
- /** The main typed array view corresponding to the specified ArrayType. */
6
4
  typedArray;
7
5
  arrayType;
8
- /** The maximum number of elements the buffer can currently hold without resizing. */
9
6
  maxElemNum;
10
- /** The number of bytes per element based on the `ArrayType`. */
11
7
  bytePerElem;
12
8
  arraybuffer;
13
- /** `Uint32Array` view of the underlying memory buffer. */
14
9
  uint32;
15
- /** `Float32Array` view of the underlying memory buffer. */
16
10
  float32;
17
- /** `Uint16Array` view of the underlying memory buffer. */
18
11
  uint16;
19
- /**
20
- * Initializes a new dynamic array buffer.
21
- * @param arrayType - The type of elements this buffer will store primarily.
22
- */
23
12
  constructor(t) {
24
13
  this.usedElemNum = 0, this.maxElemNum = 512, this.bytePerElem = this.getArrayType(t).BYTES_PER_ELEMENT, this.arrayType = t, this.arraybuffer = new ArrayBuffer(this.maxElemNum * this.bytePerElem), this.updateTypedArray();
25
14
  }
26
- /**
27
- * Returns the typed array constructor for the corresponding `ArrayType`.
28
- * @param arrayType - The type of the array.
29
- * @returns The typed array constructor.
30
- * @throws Dispatches an error if the specified type is unsupported.
31
- */
32
15
  getArrayType(t) {
33
16
  switch (t) {
34
17
  case 0:
@@ -41,9 +24,6 @@ class _ {
41
24
  throw new Error("Unsupported ArrayType");
42
25
  }
43
26
  }
44
- /**
45
- * Updates the typed array views when the internal array buffer gets reallocated.
46
- */
47
27
  updateTypedArray() {
48
28
  switch (this.uint32 = new Uint32Array(this.arraybuffer), this.float32 = new Float32Array(this.arraybuffer), this.uint16 = new Uint16Array(this.arraybuffer), this.arrayType) {
49
29
  case 0:
@@ -57,38 +37,30 @@ class _ {
57
37
  break;
58
38
  }
59
39
  }
60
- /**
61
- * Resets the element usage count to zero. The underlying memory capacity is preserved.
62
- */
63
40
  clear() {
64
41
  this.usedElemNum = 0;
65
42
  }
66
43
  static removeAtIndices(t, e) {
67
- const r = Math.max(...e.map((o) => o.usedElemNum)), i = [...new Set(t)].filter(
68
- (o) => o >= 0 && o < r
69
- ).sort((o, h) => o - h);
44
+ const r = Math.max(...e.map((h) => h.usedElemNum)), i = [...new Set(t)].filter(
45
+ (h) => h >= 0 && h < r
46
+ ).sort((h, o) => h - o);
70
47
  if (i.length === 0)
71
48
  return 0;
72
49
  let s = 0, a = 0;
73
- for (let o = 0; o < r; o++) {
74
- if (a < i.length && o === i[a]) {
50
+ for (let h = 0; h < r; h++) {
51
+ if (a < i.length && h === i[a]) {
75
52
  a++;
76
53
  continue;
77
54
  }
78
- if (s !== o)
79
- for (const h of e)
80
- h.typedArray[s] = h.typedArray[o];
55
+ if (s !== h)
56
+ for (const o of e)
57
+ o.typedArray[s] = o.typedArray[h];
81
58
  s++;
82
59
  }
83
- for (const o of e)
84
- o.usedElemNum = s;
60
+ for (const h of e)
61
+ h.usedElemNum = s;
85
62
  return r - s;
86
63
  }
87
- /**
88
- * Checks if the buffer has enough space for additional elements and resizes the buffer if necessary.
89
- * @param size - The number of new elements that need to be accommodated.
90
- * @returns `true` if the buffer was resized, `false` otherwise.
91
- */
92
64
  resize(t = 0) {
93
65
  if (t += this.usedElemNum, t > this.maxElemNum) {
94
66
  for (; t > this.maxElemNum; )
@@ -97,125 +69,54 @@ class _ {
97
69
  }
98
70
  return !1;
99
71
  }
100
- /**
101
- * Reallocates the underlying array buffer to a new size and copies existing data.
102
- * @param size - The new maximum number of elements.
103
- */
104
72
  setMaxSize(t = this.maxElemNum) {
105
73
  const e = this.typedArray;
106
74
  this.maxElemNum = t, this.arraybuffer = new ArrayBuffer(t * this.bytePerElem), this.updateTypedArray(), this.typedArray.set(e);
107
75
  }
108
- /**
109
- * Appends a new 32-bit unsigned integer element to the buffer.
110
- * @param value - The item to add.
111
- */
112
76
  pushUint32(t) {
113
77
  this.resize(1), this.uint32[this.usedElemNum++] = t;
114
78
  }
115
- /**
116
- * Appends a new 32-bit floating point element to the buffer.
117
- * @param value - The item to add.
118
- */
119
79
  pushFloat32(t) {
120
80
  this.resize(1), this.float32[this.usedElemNum++] = t;
121
81
  }
122
- /**
123
- * Appends an element to the buffer, using the primary typed array view.
124
- * @param value - The item to add.
125
- */
126
82
  push(t) {
127
83
  this.resize(1), this.typedArray[this.usedElemNum++] = t;
128
84
  }
129
- /**
130
- * Removes and returns the last element in the buffer.
131
- * @returns The removed element or undefined if the buffer is empty.
132
- */
133
85
  pop() {
134
86
  return this.typedArray[--this.usedElemNum];
135
87
  }
136
- /**
137
- * Returns the last element pushed to the buffer without removing it.
138
- * @returns The last element.
139
- */
140
88
  top() {
141
89
  return this.typedArray[this.usedElemNum - 1];
142
90
  }
143
- /**
144
- * Gets the value of the element at the specified index.
145
- * @param index - The index of the element to retrieve.
146
- * @returns The requested element.
147
- */
148
91
  get(t) {
149
92
  return this.typedArray[t];
150
93
  }
151
- /**
152
- * Returns a constrained view of the primary typed array up to the specified range.
153
- * If `end` is omitted, returns the whole reallocated buffer slice.
154
- * @param begin - The starting index (inclusive). Defaults to 0.
155
- * @param end - The ending index (exclusive). Optional.
156
- * @returns A subarray corresponding to the specified range.
157
- */
158
94
  getArray(t = 0, e) {
159
95
  return e === void 0 ? this.typedArray : this.typedArray.subarray(t, e);
160
96
  }
161
- /**
162
- * The number of elements currently stored in the buffer.
163
- */
164
97
  get length() {
165
98
  return this.usedElemNum;
166
99
  }
167
- /**
168
- * Resets the buffer's used element count, effectively emptying it.
169
- * Same behavior as `clear`.
170
- */
171
- reset() {
172
- this.usedElemNum = 0;
173
- }
174
100
  }
175
- class it extends _ {
176
- /** The actual WebGLBuffer object maintained by this instance. */
101
+ class it extends A {
177
102
  buffer;
178
- /** The related WebGL rendering context. */
179
103
  gl;
180
- /** Signifies whether the buffer has been updated and requires resyncing to the GPU. */
181
104
  dirty = !0;
182
- /** The WebGL buffer type, e.g., gl.ARRAY_BUFFER. */
183
105
  type;
184
- /** Size of the allocated buffer block on the GPU side, bounded in elements count. */
185
106
  webglBufferSize = 0;
186
- /** Usage hint for WebGL, e.g., gl.DYNAMIC_DRAW. */
187
107
  usage;
188
- /**
189
- * Initializes a new WebGL dynamic buffer.
190
- * @param gl - The active WebGL rendering context state.
191
- * @param arrayType - Type of the underlying data elements to bind.
192
- * @param type - Determines the type of WebGLBuffer (defaults to gl.ARRAY_BUFFER).
193
- * @param usage - Determines the data usage pattern (defaults to gl.DYNAMIC_DRAW).
194
- */
195
108
  constructor(t, e, r = t.ARRAY_BUFFER, i = t.DYNAMIC_DRAW) {
196
109
  super(e), this.gl = t, this.buffer = t.createBuffer(), this.type = r, this.usage = i;
197
110
  }
198
- /**
199
- * Flags the buffer as dirty, marking it for future data synchronization.
200
- */
201
111
  makeDirty() {
202
112
  this.dirty = !0;
203
113
  }
204
- /**
205
- * Clears CPU side data usage and marks buffer as synced to stop needless updates.
206
- */
207
114
  clear() {
208
115
  super.clear(), this.dirty = !1;
209
116
  }
210
- /**
211
- * Binds this buffer object tracking it as the current bound buffer to the GPU.
212
- */
213
117
  bindBuffer() {
214
118
  this.gl.bindBuffer(this.type, this.buffer);
215
119
  }
216
- /**
217
- * Uploads the local buffer data to the GPU memory synchronously.
218
- */
219
120
  bufferData() {
220
121
  if (this.dirty) {
221
122
  const t = this.gl;
@@ -233,75 +134,36 @@ class x {
233
134
  static clampByte(t) {
234
135
  return t <= 0 ? 0 : t >= 255 ? 255 : Math.round(t);
235
136
  }
236
- /**
237
- * Creates an instance of Color.
238
- * @param r - The red component (0-255).
239
- * @param g - The green component (0-255).
240
- * @param b - The blue component (0-255).
241
- * @param a - The alpha component (0-255).
242
- */
243
137
  constructor(t, e, r, i = 255) {
244
138
  this._r = t, this._g = e, this._b = r, this._a = i, this.updateUint();
245
139
  }
246
140
  setClearColor(t) {
247
141
  t.clearColor(this.r / 255, this.g / 255, this.b / 255, this.a / 255);
248
142
  }
249
- /**
250
- * Gets the red component.
251
- */
252
143
  get r() {
253
144
  return this._r;
254
145
  }
255
- /**
256
- * Sets the red component and updates the uint32 representation.
257
- * @param value - The new red component (0-255).
258
- */
259
146
  set r(t) {
260
147
  this._r = t, this.updateUint();
261
148
  }
262
- /**
263
- * Gets the green component.
264
- */
265
149
  get g() {
266
150
  return this._g;
267
151
  }
268
- /**
269
- * Sets the green component and updates the uint32 representation.
270
- * @param value - The new green component (0-255).
271
- */
272
152
  set g(t) {
273
153
  this._g = t, this.updateUint();
274
154
  }
275
- /**
276
- * Gets the blue component.
277
- */
278
155
  get b() {
279
156
  return this._b;
280
157
  }
281
- /**
282
- * Sets the blue component and updates the uint32 representation.
283
- * @param value - The new blue component (0-255).
284
- */
285
158
  set b(t) {
286
159
  this._b = t, this.updateUint();
287
160
  }
288
- /**
289
- * Gets the alpha component.
290
- */
291
161
  get a() {
292
162
  return this._a;
293
163
  }
294
- /**
295
- * Sets the alpha component and updates the uint32 representation.
296
- * @param value - The new alpha component (0-255).
297
- */
298
164
  set a(t) {
299
165
  this._a = t, this.updateUint();
300
166
  }
301
- /**
302
- * Updates the uint32 representation of the color.
303
- * @private
304
- */
305
167
  updateUint() {
306
168
  this.uint32 = (this._a << 24 | this._b << 16 | this._g << 8 | this._r) >>> 0;
307
169
  const t = x.clampByte(this._a), e = x.clampByte(this._r * t / 255), r = x.clampByte(this._g * t / 255), i = x.clampByte(this._b * t / 255);
@@ -310,71 +172,28 @@ class x {
310
172
  reset() {
311
173
  this._r = 0, this._g = 0, this._b = 0, this._a = 255, this.updateUint();
312
174
  }
313
- /**
314
- * Sets the RGBA values of the color and updates the uint32 representation.
315
- * @param r - The red component (0-255).
316
- * @param g - The green component (0-255).
317
- * @param b - The blue component (0-255).
318
- * @param a - The alpha component (0-255).
319
- */
320
175
  setRGBA(t, e, r, i) {
321
- this.r = t, this.g = e, this.b = r, this.a = i, this.updateUint();
176
+ this._r = t, this._g = e, this._b = r, this._a = i, this.updateUint();
322
177
  }
323
178
  setHSL(t, e, r) {
324
179
  t = (t % 360 + 360) % 360, e = Math.max(0, Math.min(100, e)) / 100, r = Math.max(0, Math.min(100, r)) / 100;
325
180
  const i = (1 - Math.abs(2 * r - 1)) * e, s = i * (1 - Math.abs(t / 60 % 2 - 1)), a = r - i / 2;
326
- let o = 0, h = 0, c = 0;
327
- return t < 60 ? [o, h, c] = [i, s, 0] : t < 120 ? [o, h, c] = [s, i, 0] : t < 180 ? [o, h, c] = [0, i, s] : t < 240 ? [o, h, c] = [0, s, i] : t < 300 ? [o, h, c] = [s, 0, i] : [o, h, c] = [i, 0, s], this.setRGBA((o + a) * 255, (h + a) * 255, (c + a) * 255, 255), this;
181
+ let h = 0, o = 0, c = 0;
182
+ return t < 60 ? [h, o, c] = [i, s, 0] : t < 120 ? [h, o, c] = [s, i, 0] : t < 180 ? [h, o, c] = [0, i, s] : t < 240 ? [h, o, c] = [0, s, i] : t < 300 ? [h, o, c] = [s, 0, i] : [h, o, c] = [i, 0, s], this.setRGBA((h + a) * 255, (o + a) * 255, (c + a) * 255, 255), this;
328
183
  }
329
- toHex() {
330
- const t = (e) => Math.max(0, Math.min(255, Math.round(e))).toString(16).padStart(2, "0");
331
- return `#${t(this._r)}${t(this._g)}${t(this._b)}${t(this._a)}`;
332
- }
333
- /**
334
- * Copies the RGBA values from another color.
335
- * @param color - The color to copy from.
336
- */
337
184
  copy(t) {
338
185
  this.setRGBA(t.r, t.g, t.b, t.a);
339
186
  }
340
- /**
341
- * Clone the current color
342
- * @returns A new `Color` instance with the same RGBA values.
343
- */
344
187
  clone() {
345
188
  return new x(this._r, this._g, this._b, this._a);
346
189
  }
347
- /**
348
- * Converts the color to a hexadecimal string representation (e.g., '#RRGGBBAA').
349
- * @param includeAlpha - Whether to include the alpha channel in the hex string.
350
- * @returns The hexadecimal string representation of the color.
351
- */
352
190
  toHexString(t = !0) {
353
191
  const e = this.r.toString(16).padStart(2, "0"), r = this.g.toString(16).padStart(2, "0"), i = this.b.toString(16).padStart(2, "0"), s = this.a.toString(16).padStart(2, "0");
354
192
  return `#${e}${r}${i}${t ? s : ""}`;
355
193
  }
356
- /**
357
- * Checks if the current color is equal to another color.
358
- * @param color - The color to compare with.
359
- * @returns True if the colors are equal, otherwise false.
360
- */
361
- equal(t) {
194
+ equals(t) {
362
195
  return t.r === this.r && t.g === this.g && t.b === this.b && t.a === this.a;
363
196
  }
364
- equals(t) {
365
- return this.equal(t);
366
- }
367
- /**
368
- * Creates a Color instance from normalized float components (0–1 range).
369
- * Use this instead of `new Color()` when working with shader-style 0.0–1.0 values.
370
- * @param r - Red channel (0.0–1.0)
371
- * @param g - Green channel (0.0–1.0)
372
- * @param b - Blue channel (0.0–1.0)
373
- * @param a - Alpha channel (0.0–1.0), defaults to 1.0
374
- * @returns A new Color instance with components scaled to 0–255.
375
- * @example
376
- * Color.fromNorm(0.9, 0.87, 0.55, 0.1) // moon glow
377
- */
378
197
  static FromHSL(t, e, r) {
379
198
  return new x(0, 0, 0).setHSL(t, e, r);
380
199
  }
@@ -389,29 +208,16 @@ class x {
389
208
  Math.round(i * 255)
390
209
  );
391
210
  }
392
- static clampColorByte(t) {
393
- return t <= 0 ? 0 : t >= 255 ? 255 : Math.round(t);
394
- }
395
211
  static packColor(t, e, r, i, s) {
396
- const a = x.clampColorByte(i), o = s ? a / 255 : 1, h = x.clampColorByte(t * o), c = x.clampColorByte(e * o), u = x.clampColorByte(r * o);
397
- return (a << 24 | u << 16 | c << 8 | h) >>> 0;
398
- }
399
- /**
400
- * Creates a Color instance from a hexadecimal color string.
401
- * @param hexString - The hexadecimal color string, e.g., '#RRGGBB' or '#RRGGBBAA'.
402
- * @returns A new Color instance.
403
- */
212
+ const a = x.clampByte(i), h = s ? a / 255 : 1, o = x.clampByte(t * h), c = x.clampByte(e * h), u = x.clampByte(r * h);
213
+ return (a << 24 | u << 16 | c << 8 | o) >>> 0;
214
+ }
404
215
  static fromHex(t) {
405
216
  t.startsWith("#") && (t = t.slice(1));
406
217
  const e = parseInt(t.slice(0, 2), 16), r = parseInt(t.slice(2, 4), 16), i = parseInt(t.slice(4, 6), 16);
407
218
  let s = 255;
408
219
  return t.length >= 8 && (s = parseInt(t.slice(6, 8), 16)), new x(e, r, i, s);
409
220
  }
410
- /**
411
- * Adds the components of another color to this color, clamping the result to 255.
412
- * @param color - The color to add.
413
- * @returns A new Color instance with the result of the addition.
414
- */
415
221
  add(t) {
416
222
  return new x(
417
223
  Math.min(this.r + t.r, 255),
@@ -420,11 +226,6 @@ class x {
420
226
  Math.min(this.a + t.a, 255)
421
227
  );
422
228
  }
423
- /**
424
- * Subtracts the components of another color from this color, clamping the result to 0.
425
- * @param color - The color to subtract.
426
- * @returns A new Color instance with the result of the subtraction.
427
- */
428
229
  subtract(t) {
429
230
  return new x(
430
231
  this.r - t.r,
@@ -460,7 +261,7 @@ class x {
460
261
  );
461
262
  }
462
263
  clamp() {
463
- this.r = Math.max(0, Math.min(255, this.r)), this.g = Math.max(0, Math.min(255, this.g)), this.b = Math.max(0, Math.min(255, this.b)), this.a = Math.max(0, Math.min(255, this.a));
264
+ this._r = Math.max(0, Math.min(255, this._r)), this._g = Math.max(0, Math.min(255, this._g)), this._b = Math.max(0, Math.min(255, this._b)), this._a = Math.max(0, Math.min(255, this._a)), this.updateUint();
464
265
  }
465
266
  static Red = new x(255, 0, 0, 255);
466
267
  static Green = new x(0, 255, 0, 255);
@@ -477,549 +278,311 @@ class x {
477
278
  static White = new x(255, 255, 255, 255);
478
279
  static Black = new x(0, 0, 0, 255);
479
280
  static Transparent = new x(0, 0, 0, 0);
480
- static TRANSPARENT = new x(0, 0, 0, 0);
481
281
  }
482
- const E = 6;
483
- class Ut {
484
- /** Total number of matrices currently allocated in the store. */
282
+ const T = 6;
283
+ class At {
485
284
  matrixCount = 0;
486
- /** The dynamic buffer used to hold matrix data. */
487
285
  buffer;
488
- /** The raw floating-point data of all matrices. */
489
286
  data;
490
287
  temporary = -1;
491
- /**
492
- * Creates a new MatrixStore.
493
- * @param capacity - The initial capacity of the matrix store (default is 10).
494
- */
495
288
  constructor(t = 10) {
496
- this.buffer = new _(b.Float32), this.buffer.resize(t * E), this.data = this.buffer.getArray(), this.reset();
289
+ this.buffer = new A(S.Float32), this.buffer.resize(t * T), this.data = this.buffer.getArray(), this.reset();
497
290
  }
498
- /**
499
- * Allocates a new matrix and initializes it to the identity matrix.
500
- * @returns The index of the newly allocated matrix.
501
- */
502
291
  alloc() {
503
292
  const t = this.allocDirty();
504
293
  return this.identity(t), t;
505
294
  }
506
- /**
507
- * Allocates a new matrix without initializing its elements.
508
- * @returns The index of the newly allocated matrix.
509
- */
510
295
  allocDirty() {
511
- return this.buffer.resize(E) && (this.data = this.buffer.getArray()), this.buffer.usedElemNum += E, this.matrixCount++;
296
+ return this.buffer.resize(T) && (this.data = this.buffer.getArray()), this.buffer.usedElemNum += T, this.matrixCount++;
512
297
  }
513
- /**
514
- * Resets the store, clearing all allocated matrices.
515
- */
516
298
  reset() {
517
299
  this.matrixCount = 0, this.buffer.usedElemNum = 0, this.temporary = this.alloc();
518
300
  }
519
- /**
520
- * Sets the matrix at the given index to the identity matrix.
521
- * @param index - The index of the matrix to modify.
522
- */
523
301
  identity(t) {
524
- const e = t * E, r = this.data;
302
+ const e = t * T, r = this.data;
525
303
  r[e] = 1, r[e + 1] = 0, r[e + 2] = 0, r[e + 3] = 1, r[e + 4] = 0, r[e + 5] = 0;
526
304
  }
527
- /**
528
- * Translates the matrix at the given index by x and y.
529
- * @param index - The index of the matrix to modify.
530
- * @param x - The x translation.
531
- * @param y - The y translation.
532
- */
533
305
  translate(t, e, r) {
534
- const i = t * E, s = this.data;
306
+ const i = t * T, s = this.data;
535
307
  s[i + 4] = s[i] * e + s[i + 2] * r + s[i + 4], s[i + 5] = s[i + 1] * e + s[i + 3] * r + s[i + 5];
536
308
  }
537
- /**
538
- * Scales the matrix at the given index by scaleX and scaleY.
539
- * @param index - The index of the matrix to modify.
540
- * @param scaleX - The scale factor along the x-axis.
541
- * @param scaleY - The scale factor along the y-axis.
542
- */
543
309
  scale(t, e, r) {
544
- const i = t * E, s = this.data;
310
+ const i = t * T, s = this.data;
545
311
  s[i] *= e, s[i + 1] *= e, s[i + 2] *= r, s[i + 3] *= r;
546
312
  }
547
- /**
548
- * Rotates the matrix at the given index by the specified radians.
549
- * @param index - The index of the matrix to modify.
550
- * @param radians - The rotation angle in radians.
551
- */
552
313
  rotate(t, e) {
553
- const r = t * E, i = this.data, s = Math.cos(e), a = Math.sin(e), o = i[r], h = i[r + 1], c = i[r + 2], u = i[r + 3];
554
- i[r] = o * s + c * a, i[r + 1] = h * s + u * a, i[r + 2] = o * -a + c * s, i[r + 3] = h * -a + u * s;
555
- }
556
- /**
557
- * Rotates the matrix at the given index around a local offset point (pivot).
558
- *
559
- * This is equivalent to:
560
- * 1. Translating by `(offsetX, offsetY)` to move the pivot to the origin.
561
- * 2. Rotating by `radians`.
562
- * 3. Translating back by `(-offsetX, -offsetY)`.
563
- *
564
- * Useful for rotating a sprite around a point other than its own origin,
565
- * e.g. a character's limb rotating around its joint.
566
- *
567
- * @param index - The index of the matrix to modify.
568
- * @param radians - The rotation angle in radians.
569
- * @param offsetX - The x component of the pivot point in local space.
570
- * @param offsetY - The y component of the pivot point in local space.
571
- */
314
+ const r = t * T, i = this.data, s = Math.cos(e), a = Math.sin(e), h = i[r], o = i[r + 1], c = i[r + 2], u = i[r + 3];
315
+ i[r] = h * s + c * a, i[r + 1] = o * s + u * a, i[r + 2] = h * -a + c * s, i[r + 3] = o * -a + u * s;
316
+ }
572
317
  rotateWithOffset(t, e, r, i) {
573
318
  this.translate(t, r, i), this.rotate(t, e), this.translate(t, -r, -i);
574
319
  }
575
- /**
576
- * Copies the elements from the source matrix to the destination matrix.
577
- * @param dst - The index of the destination matrix.
578
- * @param src - The index of the source matrix.
579
- */
580
320
  copy(t, e) {
581
- const r = t * E, i = e * E, s = this.data;
321
+ const r = t * T, i = e * T, s = this.data;
582
322
  s[r] = s[i], s[r + 1] = s[i + 1], s[r + 2] = s[i + 2], s[r + 3] = s[i + 3], s[r + 4] = s[i + 4], s[r + 5] = s[i + 5];
583
323
  }
584
- /**
585
- * Multiplies the destination matrix by the source matrix and stores the result in the destination.
586
- * @param dst - The index of the destination matrix.
587
- * @param src - The index of the source matrix.
588
- */
589
324
  multiply(t, e) {
590
325
  this.multiplyOut(t, t, e);
591
326
  }
592
- /**
593
- * Multiplies matrix A by matrix B and stores the result in the output matrix.
594
- * @param out - The index of the output matrix.
595
- * @param aIdx - The index of matrix A.
596
- * @param bIdx - The index of matrix B.
597
- */
598
327
  multiplyOut(t, e, r) {
599
- const i = t * E, s = e * E, a = r * E, o = this.data, h = o[s], c = o[s + 1], u = o[s + 2], l = o[s + 3], d = o[s + 4], f = o[s + 5], m = o[a], v = o[a + 1], y = o[a + 2], T = o[a + 3], M = o[a + 4], A = o[a + 5];
600
- o[i] = h * m + u * v, o[i + 1] = c * m + l * v, o[i + 2] = h * y + u * T, o[i + 3] = c * y + l * T, o[i + 4] = h * M + u * A + d, o[i + 5] = c * M + l * A + f;
328
+ const i = t * T, s = e * T, a = r * T, h = this.data, o = h[s], c = h[s + 1], u = h[s + 2], l = h[s + 3], d = h[s + 4], f = h[s + 5], m = h[a], g = h[a + 1], v = h[a + 2], y = h[a + 3], w = h[a + 4], M = h[a + 5];
329
+ h[i] = o * m + u * g, h[i + 1] = c * m + l * g, h[i + 2] = o * v + u * y, h[i + 3] = c * v + l * y, h[i + 4] = o * w + u * M + d, h[i + 5] = c * w + l * M + f;
601
330
  }
602
- /**
603
- * Inverts the matrix at the given index. If the matrix is not invertible, it defaults to the identity matrix.
604
- * @param index - The index of the matrix to invert.
605
- */
606
331
  invert(t) {
607
- const e = t * E, r = this.data, i = r[e], s = r[e + 1], a = r[e + 2], o = r[e + 3], h = r[e + 4], c = r[e + 5];
608
- let u = i * o - s * a;
332
+ const e = t * T, r = this.data, i = r[e], s = r[e + 1], a = r[e + 2], h = r[e + 3], o = r[e + 4], c = r[e + 5];
333
+ let u = i * h - s * a;
609
334
  if (!u) {
610
335
  this.identity(t);
611
336
  return;
612
337
  }
613
- u = 1 / u, r[e] = o * u, r[e + 1] = -s * u, r[e + 2] = -a * u, r[e + 3] = i * u, r[e + 4] = (a * c - o * h) * u, r[e + 5] = (s * h - i * c) * u;
614
- }
615
- /**
616
- * Transforms a point by the matrix at the given index.
617
- * @param index - The index of the transformation matrix.
618
- * @param x - The x coordinate of the point.
619
- * @param y - The y coordinate of the point.
620
- * @returns The transformed point {x, y}.
621
- */
338
+ u = 1 / u, r[e] = h * u, r[e + 1] = -s * u, r[e + 2] = -a * u, r[e + 3] = i * u, r[e + 4] = (a * c - h * o) * u, r[e + 5] = (s * o - i * c) * u;
339
+ }
622
340
  transformPoint(t, e, r) {
623
- const i = t * E, s = this.data;
341
+ const i = t * T, s = this.data;
624
342
  return {
625
343
  x: e * s[i] + r * s[i + 2] + s[i + 4],
626
344
  y: e * s[i + 1] + r * s[i + 3] + s[i + 5]
627
345
  };
628
346
  }
629
- /**
630
- * Transforms a point from world coordinates to local coordinates using the matrix at the specified index.
631
- * Useful for hit testing against objects placed in world space.
632
- * @param index - The index of the world transformation matrix.
633
- * @param x - World x coordinate.
634
- * @param y - World y coordinate.
635
- * @returns The transformed point in local coordinates.
636
- */
637
347
  worldToLocal(t, e, r) {
638
348
  const i = this.allocDirty();
639
349
  this.copy(i, t), this.invert(i);
640
350
  const s = this.transformPoint(i, e, r);
641
- return this.matrixCount--, this.buffer.usedElemNum -= E, s;
642
- }
643
- /**
644
- * Transforms a point from local coordinates to world coordinates.
645
- * @param index - The index of the local transformation matrix.
646
- * @param x - Local x coordinate.
647
- * @param y - Local y coordinate.
648
- * @returns The transformed point in world coordinates.
649
- */
351
+ return this.matrixCount--, this.buffer.usedElemNum -= T, s;
352
+ }
650
353
  localToWorld(t, e, r) {
651
354
  return this.transformPoint(t, e, r);
652
355
  }
653
- /**
654
- * Extracts the global position (translation) from the matrix at the given index.
655
- * @param index - The index of the matrix.
656
- * @returns An object containing `x` and `y` global coordinates.
657
- */
658
356
  getPosition(t) {
659
- const e = t * E, r = this.data;
357
+ const e = t * T, r = this.data;
660
358
  return { x: r[e + 4], y: r[e + 5] };
661
359
  }
662
- /**
663
- * Extracts the global scale from the matrix at the given index.
664
- * @param index - The index of the matrix.
665
- * @returns An object containing `x` and `y` global scale factors.
666
- */
667
360
  getScale(t) {
668
- const e = t * E, r = this.data, i = Math.sqrt(r[e] * r[e] + r[e + 1] * r[e + 1]), s = Math.sqrt(r[e + 2] * r[e + 2] + r[e + 3] * r[e + 3]);
361
+ const e = t * T, r = this.data, i = Math.sqrt(r[e] * r[e] + r[e + 1] * r[e + 1]), s = Math.sqrt(r[e + 2] * r[e + 2] + r[e + 3] * r[e + 3]);
669
362
  return { x: i, y: s };
670
363
  }
671
- /**
672
- * Extracts the global rotation (in radians) from the matrix at the given index.
673
- * @param index - The index of the matrix.
674
- * @returns The global rotation in radians.
675
- */
676
364
  getRotation(t) {
677
- const e = t * E, r = this.data;
365
+ const e = t * T, r = this.data;
678
366
  return Math.atan2(r[e + 1], r[e]);
679
367
  }
680
- /**
681
- * Converts the matrix at the given index to a CSS matrix string.
682
- * @param index - The index of the matrix.
683
- * @param scaleX - Extra scale applied to the a/c/tx components (e.g. to convert logic pixels to CSS pixels).
684
- * @param scaleY - Extra scale applied to the b/d/ty components.
685
- * @returns A CSS matrix string.
686
- */
687
368
  toCSSMatrix(t, e = 1, r = 1) {
688
- const i = t * E, s = this.data;
369
+ const i = t * T, s = this.data;
689
370
  return `matrix(${s[i] * e}, ${s[i + 1] * r}, ${s[i + 2] * e}, ${s[i + 3] * r}, ${s[i + 4] * e}, ${s[i + 5] * r})`;
690
371
  }
691
- /**
692
- * Retrieves a copy of the 6 elements [a, b, c, d, tx, ty] for the matrix at the specified index.
693
- * Note: This uses `slice` to return a new Float32Array instance, ensuring the original data remains safely isolated.
694
- *
695
- * @param index - The index of the matrix.
696
- * @returns A new Float32Array containing the 6 elements of the matrix.
697
- */
698
372
  getMatrix(t) {
699
- const e = t * E;
700
- return this.data.slice(e, e + E);
701
- }
702
- /**
703
- * Retrieves a direct reference (view) to the 6 elements [a, b, c, d, tx, ty] for the matrix at the specified index.
704
- * Note: This uses `subarray`. Any modifications made to the returned array will directly affect the underlying MatrixStore data.
705
- *
706
- * @param index - The index of the matrix.
707
- * @returns A Float32Array view pointing directly to the matrix's data in memory.
708
- */
373
+ const e = t * T;
374
+ return this.data.slice(e, e + T);
375
+ }
709
376
  getMatrixRef(t) {
710
- const e = t * E;
711
- return this.data.subarray(e, e + E);
712
- }
713
- /**
714
- * Overwrites the matrix at the specified index with the provided 6 elements [a, b, c, d, tx, ty].
715
- *
716
- * @param index - The index of the matrix to modify.
717
- * @param f - An array (Float32Array or standard number array) containing the 6 new elements.
718
- */
377
+ const e = t * T;
378
+ return this.data.subarray(e, e + T);
379
+ }
719
380
  setMatrix(t, e) {
720
- const r = t * E, i = this.data;
381
+ const r = t * T, i = this.data;
721
382
  i[r] = e[0], i[r + 1] = e[1], i[r + 2] = e[2], i[r + 3] = e[3], i[r + 4] = e[4], i[r + 5] = e[5];
722
383
  }
723
- multiplyAffineInPlace(t, e, r, i, s, a, o) {
724
- const h = t * 6, c = this.data, u = c[h], l = c[h + 1], d = c[h + 2], f = c[h + 3], m = c[h + 4], v = c[h + 5];
725
- c[h] = u * e + d * r, c[h + 1] = l * e + f * r, c[h + 2] = u * i + d * s, c[h + 3] = l * i + f * s, c[h + 4] = u * a + d * o + m, c[h + 5] = l * a + f * o + v;
384
+ multiplyAffineInPlace(t, e, r, i, s, a, h) {
385
+ const o = t * 6, c = this.data, u = c[o], l = c[o + 1], d = c[o + 2], f = c[o + 3], m = c[o + 4], g = c[o + 5];
386
+ c[o] = u * e + d * r, c[o + 1] = l * e + f * r, c[o + 2] = u * i + d * s, c[o + 3] = l * i + f * s, c[o + 4] = u * a + d * h + m, c[o + 5] = l * a + f * h + g;
726
387
  }
727
- multiplyAffine(t, e, r, i, s, a, o, h) {
728
- const c = t * 6, u = e * 6, l = this.data, d = l[c], f = l[c + 1], m = l[c + 2], v = l[c + 3], y = l[c + 4], T = l[c + 5];
729
- l[u] = d * r + m * i, l[u + 1] = f * r + v * i, l[u + 2] = d * s + m * a, l[u + 3] = f * s + v * a, l[u + 4] = d * o + m * h + y, l[u + 5] = f * o + v * h + T;
388
+ multiplyAffine(t, e, r, i, s, a, h, o) {
389
+ const c = t * 6, u = e * 6, l = this.data, d = l[c], f = l[c + 1], m = l[c + 2], g = l[c + 3], v = l[c + 4], y = l[c + 5];
390
+ l[u] = d * r + m * i, l[u + 1] = f * r + g * i, l[u + 2] = d * s + m * a, l[u + 3] = f * s + g * a, l[u + 4] = d * h + m * o + v, l[u + 5] = f * h + g * o + y;
730
391
  }
731
392
  }
732
- class Ct {
733
- /** The underlying store for matrices. */
734
- matrix = new Ut();
735
- /** The current step or depth in the transformation hierarchy. */
393
+ class bt {
394
+ matrix = new At();
736
395
  step = 0;
737
- /** Internal stack maintaining structural information. */
738
- stack = new _(b.Uint32);
739
- /** Records the world matrices generated at each step. */
740
- stepWorldM = new _(b.Uint32);
741
- /** Records actions (push/pop) taken during the traversal. */
742
- stepAction = new _(b.Uint32);
743
- /** Records the parent world matrix for each step (used by updateMatrixSubtree). */
744
- stepParentM = new _(b.Uint32);
745
- /** Buffer used during hierarchy traversal updates. */
746
- parentStack = new _(b.Uint32);
747
- /** The index of the current local matrix in the matrix store. */
396
+ stack = new A(S.Uint32);
397
+ stepWorldM = new A(S.Uint32);
398
+ stepAction = new A(S.Uint32);
399
+ stepParentM = new A(S.Uint32);
400
+ stepClose = new A(S.Uint32);
401
+ stepStack = new A(S.Uint32);
748
402
  curLocalM = -1;
749
- /** The index of the current world matrix in the matrix store. */
750
403
  curWorldM = -1;
751
404
  rapid;
752
- /**
753
- * Creates a new MatrixStack and initializes its state.
754
- */
755
405
  constructor(t) {
756
406
  this.reset(), this.rapid = t;
757
407
  }
758
- /**
759
- * Saves the current matrix state and pushes it onto the stack.
760
- * Equivalent to context.save().
761
- * @returns The current step counter before saving.
762
- */
763
408
  save() {
764
409
  this.stack.push(this.curWorldM);
765
410
  const t = this.curWorldM;
766
- return this.curLocalM = this.matrix.alloc(), this.curWorldM = this.matrix.allocDirty(), this.stepWorldM.push(this.curWorldM), this.stepParentM.push(t), this.stepAction.push(1), this.matrix.copy(this.curWorldM, t), { world: this.curWorldM, local: this.curLocalM, step: this.step++ };
411
+ return this.curLocalM = this.matrix.alloc(), this.curWorldM = this.matrix.allocDirty(), this.stepWorldM.push(this.curWorldM), this.stepParentM.push(t), this.stepAction.push(1), this.stepClose.push(0), this.stepStack.push(this.step), this.matrix.copy(this.curWorldM, t), { world: this.curWorldM, local: this.curLocalM, step: this.step++ };
767
412
  }
768
- /**
769
- * Restores the matrix state from the top of the stack.
770
- * Equivalent to context.restore().
771
- */
772
413
  restore() {
773
- this.stack.length != 0 && (this.curWorldM = this.stack.pop(), this.curLocalM = this.curWorldM - 1, this.stepParentM.push(this.stack.get(this.stack.length - 1)), this.stepWorldM.push(this.curWorldM), this.stepAction.push(0), this.step++);
414
+ this.stack.length == 0 || this.stepStack.length == 0 || (this.curWorldM = this.stack.pop(), this.curLocalM = this.curWorldM - 1, this.stepParentM.push(this.stack.get(this.stack.length - 1)), this.stepWorldM.push(this.curWorldM), this.stepAction.push(0), this.stepClose.push(0), this.stepClose.typedArray[this.stepStack.pop()] = this.step, this.step++);
415
+ }
416
+ restoreAll() {
417
+ for (; this.stack.length > 0 && this.stepStack.length > 0; )
418
+ this.restore();
419
+ }
420
+ getStep(t) {
421
+ return typeof t == "number" ? t : t.step;
422
+ }
423
+ walkSubtree(t, e, r = 1 / 0) {
424
+ let i = 0, s = t;
425
+ for (; s < this.step; ) {
426
+ const a = this.stepAction.get(s);
427
+ if (a === 1) {
428
+ if (i++, i > r) {
429
+ const h = this.stepClose.get(s);
430
+ if (h > s) {
431
+ s = h + 1, i--;
432
+ continue;
433
+ }
434
+ }
435
+ } else
436
+ i--;
437
+ if (e(s, a, i) === !1 || a === 0 && i === 0) return;
438
+ s++;
439
+ }
440
+ }
441
+ getParent(t) {
442
+ const e = this.getStep(t);
443
+ return this.stepParentM.get(e);
444
+ }
445
+ getChildren(t) {
446
+ const e = this.getStep(t), r = this.stepClose.get(e), i = [];
447
+ let s = e + 1;
448
+ for (; s < r; )
449
+ this.stepAction.get(s) === 1 ? (i.push(s), s = this.stepClose.get(s) + 1) : s++;
450
+ return i;
774
451
  }
775
- /**
776
- * Evaluates and updates matrices from the given step. Used primarily for deferred transformation.
777
- * @param step - The initial step to update matrices from.
778
- */
779
452
  updateMatrixSubtree(t) {
780
- const e = typeof t == "number" ? t : t.step;
781
- let r = 0, i = e;
782
- for (; i < this.step; ) {
783
- if (this.stepAction.get(i) === 1) {
784
- const a = this.stepWorldM.get(i), o = a - 1, h = this.stepParentM.get(i);
785
- this.matrix.multiplyOut(a, h, o), r++;
786
- } else if (r--, r === 0)
787
- break;
788
- i++;
789
- }
453
+ const e = this.getStep(t);
454
+ this.walkSubtree(e, (r, i) => {
455
+ if (i === 1) {
456
+ const s = this.stepWorldM.get(r), a = s - 1, h = this.stepParentM.get(r);
457
+ this.matrix.multiplyOut(s, h, a);
458
+ }
459
+ });
790
460
  }
791
- /**
792
- * Translates the current local and world matrices by x and y.
793
- * @param x - Translation along the x-axis.
794
- * @param y - Translation along the y-axis.
795
- */
796
461
  translate(t, e) {
797
462
  this.matrix.translate(this.curLocalM, t, e), this.matrix.translate(this.curWorldM, t, e);
798
463
  }
799
- /**
800
- * Scales the current local and world matrices by scaleX and scaleY.
801
- * @param scaleX - Scaling factor along the x-axis.
802
- * @param scaleY - Scaling factor along the y-axis.
803
- */
804
464
  scale(t, e = t) {
805
465
  this.matrix.scale(this.curLocalM, t, e), this.matrix.scale(this.curWorldM, t, e);
806
466
  }
807
- /**
808
- * Rotates the current local and world matrices by the given radians.
809
- * @param radians - The rotation angle in radians.
810
- */
811
467
  rotate(t) {
812
468
  this.matrix.rotate(this.curLocalM, t), this.matrix.rotate(this.curWorldM, t);
813
469
  }
814
- /**
815
- * Rotates the current local and world matrices around a pivot point
816
- * that is offset from the matrix origin by `(offsetX, offsetY)`.
817
- *
818
- * This is a convenience wrapper around the common translate → rotate → translate-back
819
- * pattern, avoiding manual coordinate juggling at the call site.
820
- *
821
- * @example
822
- * ```ts
823
- * // Rotate a 64×64 sprite around its centre
824
- * stack.rotateWithOffset(angle, 32, 32);
825
- * ```
826
- *
827
- * @param radians - The rotation angle in radians.
828
- * @param offsetX - The x component of the pivot point in local space.
829
- * @param offsetY - The y component of the pivot point in local space.
830
- */
831
470
  rotateWithOffset(t, e, r) {
832
471
  this.matrix.rotateWithOffset(this.curLocalM, t, e, r), this.matrix.rotateWithOffset(this.curWorldM, t, e, r);
833
472
  }
834
- /**
835
- * Sets the current local and world matrices to the identity matrix.
836
- */
837
473
  identity() {
838
474
  this.matrix.identity(this.curLocalM), this.matrix.identity(this.curWorldM);
839
475
  }
840
- /**
841
- * Resets the entire stack state context, clearing matrices and step actions.
842
- */
843
476
  reset() {
844
- this.matrix.reset(), this.stack.reset(), this.stepAction.reset(), this.stepWorldM.reset(), this.stepParentM.reset(), this.step = 0, this.curLocalM = this.matrix.alloc(), this.curWorldM = this.matrix.alloc();
845
- }
846
- /**
847
- * Transforms a point from local coordinates to world coordinates.
848
- * Uses the current world matrix to apply the transformation.
849
- * @param x - Local x coordinate.
850
- * @param y - Local y coordinate.
851
- * @returns The transformed point in world coordinates.
852
- */
477
+ this.matrix.reset(), this.stack.clear(), this.stepAction.clear(), this.stepWorldM.clear(), this.stepParentM.clear(), this.stepClose.clear(), this.stepStack.clear(), this.step = 0, this.curLocalM = this.matrix.alloc(), this.curWorldM = this.matrix.alloc();
478
+ }
853
479
  localToWorld(t, e) {
854
480
  return this.matrix.localToWorld(this.curWorldM, t, e);
855
481
  }
856
- /**
857
- * Transforms a point from world coordinates to local coordinates.
858
- * Useful for hit testing against objects placed in world space.
859
- * @param x - World x coordinate.
860
- * @param y - World y coordinate.
861
- * @returns The transformed point in local coordinates.
862
- */
863
482
  worldToLocal(t, e) {
864
483
  return this.matrix.worldToLocal(this.curWorldM, t, e);
865
484
  }
866
- /**
867
- * Extracts the global position (translation) from the current world matrix.
868
- * @returns An object containing `x` and `y` global coordinates.
869
- */
870
485
  getGlobalPosition() {
871
486
  return this.matrix.getPosition(this.curWorldM);
872
487
  }
873
- /**
874
- * Extracts the global scale from the current world matrix.
875
- * @returns An object containing `x` and `y` global scale factors.
876
- */
877
488
  getGlobalScale() {
878
489
  return this.matrix.getScale(this.curWorldM);
879
490
  }
880
- /**
881
- * Extracts the global rotation (in radians) from the current world matrix.
882
- * @returns The global rotation in radians.
883
- */
884
491
  getGlobalRotation() {
885
492
  return this.matrix.getRotation(this.curWorldM);
886
493
  }
887
494
  toCSSMatrix() {
888
495
  return this.matrix.toCSSMatrix(this.curWorldM);
889
496
  }
890
- /**
891
- * Returns the current world matrix as Float32Array [a, b, c, d, tx, ty].
892
- */
893
497
  getTransform() {
894
- const t = this.curWorldM * E;
895
- return this.matrix.data.slice(t, t + E);
498
+ const t = this.curWorldM * T;
499
+ return this.matrix.data.slice(t, t + T);
896
500
  }
897
- /**
898
- * Directly overwrites the current world matrix with the given 6-element 2D transform.
899
- */
900
501
  setTransform(t) {
901
- const e = this.curWorldM * E, r = this.matrix.data;
502
+ const e = this.curWorldM * T, r = this.matrix.data;
902
503
  r[e] = t[0], r[e + 1] = t[1], r[e + 2] = t[2], r[e + 3] = t[3], r[e + 4] = t[4], r[e + 5] = t[5];
903
504
  }
904
505
  transformPoint(t, e) {
905
506
  return this.matrix.transformPoint(this.curLocalM, t, e);
906
507
  }
907
- /**
908
- * Applies a transform options object to the current matrix state.
909
- * Optionally saves the matrix first
910
- */
911
508
  applyTransform(t, e = 0, r = 0, i = -1) {
912
509
  let s = t.x ?? 0, a = t.y ?? 0;
913
510
  t.position && (s += t.position.x, a += t.position.y);
914
- let o = 1, h = 1;
511
+ let h = 1, o = 1;
915
512
  const c = t.scale;
916
- c && (typeof c == "number" ? (o = c, h = c) : (o = c.x, h = c.y));
513
+ c && (typeof c == "number" ? (h = c, o = c) : (h = c.x, o = c.y));
917
514
  const u = t.rotation ?? 0;
918
515
  let l = t.offsetX ?? 0, d = t.offsetY ?? 0;
919
516
  t.offset && (l += t.offset.x, d += t.offset.y);
920
517
  const f = t.origin;
921
518
  f !== void 0 && (typeof f == "number" ? (l -= f * e, d -= f * r) : (l -= f.x * e, d -= f.y * r));
922
- const m = u ? Math.cos(u) : 1, v = u ? Math.sin(u) : 0, y = m * o, T = v * o, M = -v * h, A = m * h, P = s + y * l + M * d, C = a + T * l + A * d;
519
+ const m = u ? Math.cos(u) : 1, g = u ? Math.sin(u) : 0, v = m * h, y = g * h, w = -g * o, M = m * o, _ = s + v * l + w * d, P = a + y * l + M * d;
923
520
  if (i !== -1) {
924
521
  this.matrix.multiplyAffine(
925
522
  this.curWorldM,
926
523
  i,
524
+ v,
927
525
  y,
928
- T,
526
+ w,
929
527
  M,
930
- A,
931
- P,
932
- C
528
+ _,
529
+ P
933
530
  );
934
531
  return;
935
532
  }
936
533
  this.matrix.multiplyAffineInPlace(
937
534
  this.curLocalM,
535
+ v,
938
536
  y,
939
- T,
537
+ w,
940
538
  M,
941
- A,
942
- P,
943
- C
539
+ _,
540
+ P
944
541
  ), this.matrix.multiplyAffineInPlace(
945
542
  this.curWorldM,
543
+ v,
946
544
  y,
947
- T,
545
+ w,
948
546
  M,
949
- A,
950
- P,
951
- C
547
+ _,
548
+ P
952
549
  );
953
550
  }
954
551
  }
955
- var Q = /* @__PURE__ */ ((n) => (n[n.REPEAT = 0] = "REPEAT", n[n.CLAMP = 1] = "CLAMP", n[n.MIRRORED_REPEAT = 2] = "MIRRORED_REPEAT", n))(Q || {});
956
- class _t {
552
+ var q = /* @__PURE__ */ ((n) => (n[n.REPEAT = 0] = "REPEAT", n[n.CLAMP = 1] = "CLAMP", n[n.MIRRORED_REPEAT = 2] = "MIRRORED_REPEAT", n))(q || {});
553
+ class Ut {
957
554
  render;
958
555
  cache = /* @__PURE__ */ new Map();
959
556
  constructor(t) {
960
557
  this.render = t;
961
558
  }
962
- /**
963
- * Asynchronously loads a texture from a URL.
964
- * @param url - The image URL to load.
965
- * @param options - Optional configuration for the texture.
966
- * @returns A promise that resolves to the loaded Texture.
967
- */
968
559
  async load(t, e) {
969
560
  let r = this.cache.get(t);
970
561
  if (r)
971
- return new O(r);
562
+ return new N(r);
972
563
  try {
973
564
  const i = await this._fetchImage(t);
974
- return r = z.fromSource(this.render, i, e), r.uid = t, this.cache.set(t, r), new O(r);
565
+ return r = V.fromSource(this.render, i, e), r.uid = t, this.cache.set(t, r), new N(r);
975
566
  } catch (i) {
976
567
  throw console.error(`[TextureManager] Failed to load: ${t}`, i), i;
977
568
  }
978
569
  }
979
- /**
980
- * Creates a texture synchronously from an existing HTML element (Image, Canvas, Video).
981
- * @param source - The source image element.
982
- * @param options - Optional configuration for the texture.
983
- * @returns The newly created Texture.
984
- */
985
570
  create(t, e) {
986
571
  if (e?.key && this.cache.has(e.key))
987
- return new O(this.cache.get(e.key));
988
- const r = z.fromSource(this.render, t, e);
989
- return e?.key && (r.uid = e.key, this.cache.set(e.key, r)), new O(r);
990
- }
991
- /**
992
- * Creates a generic Render Texture (FrameBuffer).
993
- * @param width - The width of the render texture.
994
- * @param height - The height of the render texture.
995
- * @param options - Optional configuration for the texture.
996
- * @returns The newly created RenderTexture.
997
- */
572
+ return new N(this.cache.get(e.key));
573
+ const r = V.fromSource(this.render, t, e);
574
+ return e?.key && (r.uid = e.key, this.cache.set(e.key, r)), new N(r);
575
+ }
998
576
  createRenderTexture(t) {
999
- return new Pt(this.render, t);
577
+ return new Ct(this.render, t);
1000
578
  }
1001
- /**
1002
- * Creates a TextTexture for rendering text.
1003
- * @param options - Optional configuration for the texture.
1004
- * @returns The newly created TextTexture.
1005
- */
1006
579
  createTextTexture(t) {
1007
- return new Lt(this.render, t);
1008
- }
1009
- /**
1010
- * Destroys a texture and potentially removes its BaseTexture from the cache.
1011
- * If a Texture instance is provided, it decrements the reference count of the BaseTexture.
1012
- * The BaseTexture will only be destroyed if its reference count drops to 0, or if `force` is true.
1013
- * @param textureOrUrl - The texture instance, base texture, or cache key (URL) to destroy.
1014
- * @param force - If true, destroys the underlying BaseTexture immediately regardless of reference count.
1015
- */
580
+ return new Pt(this.render, t);
581
+ }
1016
582
  destroy(t, e = !1) {
1017
583
  let r, i;
1018
- typeof t == "string" ? (i = t, r = this.cache.get(i)) : t instanceof O ? (r = t.base, i = r?.uid, t.destroy()) : (r = t, i = r.uid), r && (r.refCount <= 0 || e) && (r.destroy(this.render.gl), i && this.cache.delete(i));
584
+ typeof t == "string" ? (i = t, r = this.cache.get(i)) : t instanceof N ? (r = t.base, i = r?.uid, t.destroy()) : (r = t, i = r.uid), r && (r.refCount <= 0 || e) && (r.destroy(this.render.gl), i && this.cache.delete(i));
1019
585
  }
1020
- /**
1021
- * Destroys all cached textures and clears the cache, ignoring reference counts.
1022
- */
1023
586
  destroyAll() {
1024
587
  for (const t of this.cache.values())
1025
588
  t.destroy(this.render.gl);
@@ -1032,7 +595,7 @@ class _t {
1032
595
  });
1033
596
  }
1034
597
  }
1035
- class z {
598
+ class V {
1036
599
  glTexture = null;
1037
600
  width;
1038
601
  height;
@@ -1041,47 +604,24 @@ class z {
1041
604
  constructor(t, e, r) {
1042
605
  this.glTexture = t, this.width = e, this.height = r;
1043
606
  }
1044
- /**
1045
- * Creates a BaseTexture from an image source.
1046
- * @param render - The Rapid renderer instance.
1047
- * @param source - The image source.
1048
- * @param options - Optional configuration.
1049
- * @returns The created BaseTexture.
1050
- */
1051
607
  static fromSource(t, e, r = {}) {
1052
- const i = et(t, e, r);
1053
- return new z(i, e.width, e.height);
1054
- }
1055
- /**
1056
- * Updates the content of the existing texture (e.g. for Video or dynamic Canvas).
1057
- * Uses texSubImage2D if dimensions haven't changed for better performance.
1058
- * @param gl - The WebGL rendering context.
1059
- * @param source - The new image source.
1060
- */
608
+ const i = J(t, e, r);
609
+ return new V(i, e.width, e.height);
610
+ }
1061
611
  updateSource(t, e, r = {}) {
1062
612
  this.glTexture && (t.bindTexture(t.TEXTURE_2D, this.glTexture), r.textureFilter !== void 0 && nt(t, r.textureFilter), r.wrap !== void 0 && st(t, r.wrap), t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL, 1), t.pixelStorei(t.UNPACK_ALIGNMENT, 1), r.premultipliedAlpha !== void 0 && t.pixelStorei(t.UNPACK_PREMULTIPLY_ALPHA_WEBGL, r.premultipliedAlpha), this.width === e.width && this.height === e.height ? t.texSubImage2D(t.TEXTURE_2D, 0, 0, 0, t.RGBA, t.UNSIGNED_BYTE, e) : (t.texImage2D(t.TEXTURE_2D, 0, t.RGBA, t.RGBA, t.UNSIGNED_BYTE, e), this.width = e.width, this.height = e.height), r.premultipliedAlpha !== void 0 && t.pixelStorei(t.UNPACK_PREMULTIPLY_ALPHA_WEBGL, !1));
1063
613
  }
1064
- /**
1065
- * Dynamically updates the texture filtering mode.
1066
- */
1067
614
  setFilterMode(t, e) {
1068
615
  this.glTexture && (t.bindTexture(t.TEXTURE_2D, this.glTexture), nt(t, e), t.bindTexture(t.TEXTURE_2D, null));
1069
616
  }
1070
- /**
1071
- * Dynamically updates the texture wrap mode.
1072
- */
1073
617
  setWrapMode(t, e) {
1074
618
  this.glTexture && (t.bindTexture(t.TEXTURE_2D, this.glTexture), st(t, e), t.bindTexture(t.TEXTURE_2D, null));
1075
619
  }
1076
- /**
1077
- * Destroys the WebGL texture resource.
1078
- * @param gl - The WebGL rendering context.
1079
- */
1080
620
  destroy(t) {
1081
621
  this.glTexture && (t.deleteTexture(this.glTexture), this.glTexture = null);
1082
622
  }
1083
623
  }
1084
- class O {
624
+ class N {
1085
625
  base;
1086
626
  uvX = 0;
1087
627
  uvY = 0;
@@ -1097,121 +637,63 @@ class O {
1097
637
  isRotated = !1;
1098
638
  glTexture = null;
1099
639
  get width() {
1100
- return (this.isRotated ? this.rawHeight : this.rawWidth) * this.scale;
640
+ return this.isRotated ? this.rawHeight : this.rawWidth;
1101
641
  }
1102
642
  get height() {
1103
- return (this.isRotated ? this.rawWidth : this.rawHeight) * this.scale;
643
+ return this.isRotated ? this.rawWidth : this.rawHeight;
1104
644
  }
1105
645
  // Stored pixel-space region (before UV conversion), used by getSubTexture()
1106
646
  _px = 0;
1107
647
  _py = 0;
1108
- _pw = 0;
1109
- _ph = 0;
1110
648
  constructor(t) {
1111
649
  t && this.setBase(t);
1112
650
  }
1113
- /**
1114
- * Sets the base texture and increments its reference count.
1115
- * @param base - The BaseTexture instance.
1116
- * @returns The current Texture instance.
1117
- */
1118
651
  setBase(t) {
1119
652
  return this.base === t ? this : (this.base && this.base.refCount--, this.base = t, this.base.refCount++, this.setRegion(0, 0, t.width, t.height), this.glTexture = t.glTexture, this);
1120
653
  }
1121
- /**
1122
- * Sets the visible region (clipping) in pixels relative to the BaseTexture.
1123
- * @param x - The x coordinate in pixels.
1124
- * @param y - The y coordinate in pixels.
1125
- * @param w - The width in pixels.
1126
- * @param h - The height in pixels.
1127
- * @returns The current Texture instance.
1128
- */
1129
654
  setRegion(t, e, r, i) {
1130
- return this.base ? (this._px = t, this._py = e, this._pw = r, this._ph = i, this.isAtlas = t !== 0 || e !== 0 || r !== this.base.width || i !== this.base.height, this.uvX = t / this.base.width, this.uvY = e / this.base.height, this.uvW = this.uvX + r / this.base.width, this.uvH = this.uvY + i / this.base.height, this.rawWidth = r * this.scale, this.rawHeight = i * this.scale, this) : this;
1131
- }
1132
- /**
1133
- * Creates a new Texture representing a sub-region of this Texture.
1134
- * @param x - The x coordinate in pixels, relative to this texture's logical start.
1135
- * @param y - The y coordinate in pixels, relative to this texture's logical start.
1136
- * @param width - The width of the sub-texture in pixels.
1137
- * @param height - The height of the sub-texture in pixels.
1138
- * @returns A new Texture pointing to the sub-region.
1139
- */
655
+ return this.base ? (this._px = t, this._py = e, this.isAtlas = t !== 0 || e !== 0 || r !== this.base.width || i !== this.base.height, this.uvX = t / this.base.width, this.uvY = e / this.base.height, this.uvW = this.uvX + r / this.base.width, this.uvH = this.uvY + i / this.base.height, this.rawWidth = r * this.scale, this.rawHeight = i * this.scale, this) : this;
656
+ }
1140
657
  getSubTexture(t, e, r, i) {
1141
- if (!this.base) return new O();
1142
- const s = this.clone(), a = this._px, o = this._py;
1143
- return s.setRegion(a + t, o + e, r, i), s;
1144
- }
1145
- /**
1146
- * Creates a shallow copy of this Texture, sharing the same BaseTexture.
1147
- * @returns A new Texture instance.
1148
- */
658
+ if (!this.base) return new N();
659
+ const s = this.clone(), a = this._px, h = this._py;
660
+ return s.setRegion(a + t, h + e, r, i), s;
661
+ }
1149
662
  clone(t) {
1150
- const e = t ?? new O(this.base);
1151
- return t && this.base && t.setBase(this.base), e.scale = this.scale, e.uvX = this.uvX, e.uvY = this.uvY, e.uvW = this.uvW, e.uvH = this.uvH, e.rawWidth = this.rawWidth, e.rawHeight = this.rawHeight, e.offsetX = this.offsetX, e.offsetY = this.offsetY, e.flipY = this.flipY, e.isRotated = this.isRotated, e.isAtlas = this.isAtlas, e._px = this._px, e._py = this._py, e._pw = this._pw, e._ph = this._ph, e;
1152
- }
1153
- /**
1154
- * Utility to split this texture into a grid of sprite textures.
1155
- * Sub-textures will respect the current UV offsets.
1156
- * @param cellWidth - The width of each cell in pixels.
1157
- * @param cellHeight - The height of each cell in pixels.
1158
- * @param cols - Optional number of columns. Truncates based on texture width if omitted.
1159
- * @param rows - Optional number of rows. Truncates based on texture height if omitted.
1160
- * @param gap - Optional pixel gap between cells.
1161
- * @returns An array of split Textures.
1162
- */
663
+ const e = t ?? new N(this.base);
664
+ return t && this.base && t.setBase(this.base), e.scale = this.scale, e.uvX = this.uvX, e.uvY = this.uvY, e.uvW = this.uvW, e.uvH = this.uvH, e.rawWidth = this.rawWidth, e.rawHeight = this.rawHeight, e.offsetX = this.offsetX, e.offsetY = this.offsetY, e.flipY = this.flipY, e.isRotated = this.isRotated, e.isAtlas = this.isAtlas, e._px = this._px, e._py = this._py, e;
665
+ }
1163
666
  splitGrid(t, e, r, i, s = 0) {
1164
667
  if (!this.base) return [];
1165
- const a = [], o = this.rawWidth, h = this.rawHeight, c = Math.max(0, s), u = t + c, l = e + c, d = r ?? Math.floor((o + c) / u), f = i ?? Math.floor((h + c) / l);
668
+ const a = [], h = this.rawWidth, o = this.rawHeight, c = Math.max(0, s), u = t + c, l = e + c, d = r ?? Math.floor((h + c) / u), f = i ?? Math.floor((o + c) / l);
1166
669
  for (let m = 0; m < f; m++)
1167
- for (let v = 0; v < d; v++)
1168
- a.push(this.getSubTexture(v * u, m * l, t, e));
670
+ for (let g = 0; g < d; g++)
671
+ a.push(this.getSubTexture(g * u, m * l, t, e));
1169
672
  return a;
1170
673
  }
1171
- /**
1172
- * Creates a Texture directly from an image source, bypassing the TextureManager.
1173
- * @param source - The image element, canvas, video, or bitmap.
1174
- * @param options - Optional antialias and wrap mode settings.
1175
- */
1176
674
  static fromImageSource(t, e, r = {}) {
1177
- const i = et(t, e, r);
1178
- return new O(new z(i, e.width, e.height));
675
+ const i = J(t, e, r);
676
+ return new N(new V(i, e.width, e.height));
1179
677
  }
1180
- /**
1181
- * Marks this Texture as destroyed, decrementing the BaseTexture reference count.
1182
- */
1183
678
  destroy() {
1184
679
  this.base && (this.base.refCount--, this.base = void 0), this.glTexture = null;
1185
680
  }
1186
681
  }
1187
- class Pt extends O {
682
+ class Ct extends N {
1188
683
  framebuffer;
1189
684
  renderbuffer;
1190
685
  gl;
1191
686
  flipY = !0;
1192
687
  clearColor;
1193
- /** Actual GPU-allocated dimensions — grow-only, never shrink */
1194
688
  _allocW = 0;
1195
689
  _allocH = 0;
1196
690
  constructor(t, e) {
1197
691
  super(), this.gl = t.gl, this.clearColor = e.clearColor ?? x.Black;
1198
- const r = Math.max(Math.round(e.width), 1), i = Math.max(Math.round(e.height), 1), a = et(t, { width: r, height: i }, { ...e, onlySize: !0 });
1199
- if (this.setBase(new z(a, r, i)), this.framebuffer = this.gl.createFramebuffer(), this.renderbuffer = this.gl.createRenderbuffer(), !this.framebuffer || !this.renderbuffer)
692
+ const r = Math.max(Math.round(e.width), 1), i = Math.max(Math.round(e.height), 1), a = J(t, { width: r, height: i }, { ...e, onlySize: !0 });
693
+ if (this.setBase(new V(a, r, i)), this.framebuffer = this.gl.createFramebuffer(), this.renderbuffer = this.gl.createRenderbuffer(), !this.framebuffer || !this.renderbuffer)
1200
694
  throw new Error("Failed to create Framebuffer or Renderbuffer");
1201
695
  this.resize(r, i, !0);
1202
696
  }
1203
- /**
1204
- * Resizes the render texture using a grow-only GPU allocation strategy.
1205
- *
1206
- * - GPU memory is only reallocated when the new size **exceeds** the current allocation.
1207
- * - Shrinking only updates the logical dimensions and UV sub-region — no GPU work.
1208
- *
1209
- * This makes it safe to call every frame with varying sizes (e.g. inside applyFilters).
1210
- *
1211
- * @param width - New logical width.
1212
- * @param height - New logical height.
1213
- * @param force - Force full GPU reallocation regardless of current allocation size.
1214
- */
1215
697
  resize(t, e, r = !1) {
1216
698
  t = Math.max(Math.round(t), 1), e = Math.max(Math.round(e), 1);
1217
699
  const i = this.rawWidth === t && this.rawHeight === e;
@@ -1219,10 +701,6 @@ class Pt extends O {
1219
701
  const s = this.gl;
1220
702
  (r || t > this._allocW || e > this._allocH) && this.base && (this._allocW = Math.max(this._allocW, t), this._allocH = Math.max(this._allocH, e), this.base.width = this._allocW, this.base.height = this._allocH, s.bindTexture(s.TEXTURE_2D, this.base.glTexture), s.texImage2D(s.TEXTURE_2D, 0, s.RGBA, this._allocW, this._allocH, 0, s.RGBA, s.UNSIGNED_BYTE, null), s.bindRenderbuffer(s.RENDERBUFFER, this.renderbuffer), s.renderbufferStorage(s.RENDERBUFFER, s.STENCIL_INDEX8, this._allocW, this._allocH), s.bindFramebuffer(s.FRAMEBUFFER, this.framebuffer), s.framebufferTexture2D(s.FRAMEBUFFER, s.COLOR_ATTACHMENT0, s.TEXTURE_2D, this.base.glTexture, 0), s.framebufferRenderbuffer(s.FRAMEBUFFER, s.STENCIL_ATTACHMENT, s.RENDERBUFFER, this.renderbuffer), s.bindFramebuffer(s.FRAMEBUFFER, null), s.bindRenderbuffer(s.RENDERBUFFER, null), s.bindTexture(s.TEXTURE_2D, null)), this.rawWidth = t, this.rawHeight = e, this.uvX = 0, this.uvW = t / this._allocW, this.uvY = 0, this.uvH = e / this._allocH;
1221
703
  }
1222
- /**
1223
- * Activates this texture as the current render target.
1224
- * @param clear - Whether to clear the render target after activation.
1225
- */
1226
704
  activate(t = !1) {
1227
705
  if (!this.framebuffer) return;
1228
706
  const e = this.gl;
@@ -1233,48 +711,30 @@ class Pt extends O {
1233
711
  const e = this.gl, r = t ?? this.clearColor;
1234
712
  r && (r.setClearColor(e), e.clear(e.COLOR_BUFFER_BIT | e.STENCIL_BUFFER_BIT));
1235
713
  }
1236
- /**
1237
- * Deactivates this texture, returning rendering to the default frame buffer.
1238
- */
1239
714
  deactivate() {
1240
715
  const t = this.gl;
1241
716
  t.bindFramebuffer(t.FRAMEBUFFER, null);
1242
717
  }
1243
- /**
1244
- * Get raw pixels from the render texture.
1245
- * @param x - X coordinate in logical pixel space (top-left origin).
1246
- * @param y - Y coordinate in logical pixel space (top-left origin).
1247
- * @param width - Width of the region to read.
1248
- * @param height - Height of the region to read.
1249
- */
1250
718
  GetPixels(t = 0, e = 0, r = this.rawWidth, i = this.rawHeight) {
1251
719
  if (!this.framebuffer) return new Uint8Array(0);
1252
- const s = Math.floor(t), a = Math.floor(e), o = Math.floor(r), h = Math.floor(i);
1253
- if (o <= 0 || h <= 0) return new Uint8Array(0);
720
+ const s = Math.floor(t), a = Math.floor(e), h = Math.floor(r), o = Math.floor(i);
721
+ if (h <= 0 || o <= 0) return new Uint8Array(0);
1254
722
  if (s < 0 || a < 0 || s >= this.rawWidth || a >= this.rawHeight)
1255
723
  return new Uint8Array(0);
1256
- const c = Math.min(o, this.rawWidth - s), u = Math.min(h, this.rawHeight - a), l = this.rawHeight - a - u, d = this.gl, f = d.getParameter(d.FRAMEBUFFER_BINDING);
724
+ const c = Math.min(h, this.rawWidth - s), u = Math.min(o, this.rawHeight - a), l = this.rawHeight - a - u, d = this.gl, f = d.getParameter(d.FRAMEBUFFER_BINDING);
1257
725
  d.bindFramebuffer(d.FRAMEBUFFER, this.framebuffer);
1258
726
  const m = new Uint8Array(c * u * 4);
1259
727
  return d.readPixels(s, l, c, u, d.RGBA, d.UNSIGNED_BYTE, m), d.bindFramebuffer(d.FRAMEBUFFER, f), m;
1260
728
  }
1261
- /**
1262
- * Get the color at a pixel in the render texture.
1263
- * @param x - X coordinate in logical pixel space (top-left origin).
1264
- * @param y - Y coordinate in logical pixel space (top-left origin).
1265
- */
1266
729
  GetColorAt(t, e) {
1267
730
  const r = this.GetPixels(t, e, 1, 1);
1268
731
  return r.length < 4 ? new x(0, 0, 0, 0) : new x(r[0], r[1], r[2], r[3]);
1269
732
  }
1270
- /**
1271
- * Destroys the framebuffer, renderbuffer, and base texture.
1272
- */
1273
733
  destroy() {
1274
734
  super.destroy(), this.framebuffer && this.gl.deleteFramebuffer(this.framebuffer), this.renderbuffer && this.gl.deleteRenderbuffer(this.renderbuffer), this.base?.destroy(this.gl);
1275
735
  }
1276
736
  }
1277
- const Nt = {
737
+ const _t = {
1278
738
  fontFamily: "Arial",
1279
739
  fontSize: 24,
1280
740
  fontWeight: "normal",
@@ -1283,7 +743,7 @@ const Nt = {
1283
743
  align: "left",
1284
744
  lineHeight: 1
1285
745
  };
1286
- class Lt extends O {
746
+ class Pt extends N {
1287
747
  canvas;
1288
748
  ctx;
1289
749
  render;
@@ -1292,28 +752,22 @@ class Lt extends O {
1292
752
  options;
1293
753
  flipY = !0;
1294
754
  constructor(t, e) {
1295
- super(), this.render = t, this._style = { ...Nt, ...e }, this._text = e?.text ?? "", this.options = { premultipliedAlpha: t.premultipliedAlpha, ...e }, this.scale = 1 / t.dpr, this.canvas = document.createElement("canvas");
755
+ super(), this.render = t, this._style = { ..._t, ...e }, this._text = e?.text ?? "", this.options = { premultipliedAlpha: t.premultipliedAlpha, ...e }, this.scale = 1 / t.dpr, this.canvas = document.createElement("canvas");
1296
756
  const r = this.canvas.getContext("2d", { willReadFrequently: !0 });
1297
757
  if (!r) throw new Error("Failed to get 2d context for TextTexture");
1298
758
  this.ctx = r, this.canvas.width = 1, this.canvas.height = 1;
1299
- const i = et(t, this.canvas, this.options);
1300
- this.setBase(new z(i, 1, 1)), this.update();
759
+ const i = J(t, this.canvas, this.options);
760
+ this.setBase(new V(i, 1, 1)), this.update();
1301
761
  }
1302
762
  get text() {
1303
763
  return this._text;
1304
764
  }
1305
- /**
1306
- * Set new text and update the texture
1307
- */
1308
765
  set text(t) {
1309
766
  this._text !== t && (this._text = t, this.update());
1310
767
  }
1311
768
  get style() {
1312
769
  return this._style;
1313
770
  }
1314
- /**
1315
- * Set new style partially and update the texture
1316
- */
1317
771
  set style(t) {
1318
772
  this._style = { ...this._style, ...t }, this.update();
1319
773
  }
@@ -1327,37 +781,34 @@ class Lt extends O {
1327
781
  return e;
1328
782
  }
1329
783
  }
1330
- /**
1331
- * Updates the internal canvas and uploads it to WebGL
1332
- */
1333
784
  update() {
1334
- const t = this.ctx, e = this.style, r = e.fontSize, i = e.fontWeight, s = e.fontFamily, a = e.lineHeight, o = `${i} ${r}px ${s}`, h = this.render.dpr;
1335
- t.font = o, t.textBaseline = "top";
785
+ const t = this.ctx, e = this.style, r = e.fontSize, i = e.fontWeight, s = e.fontFamily, a = e.lineHeight, h = `${i} ${r}px ${s}`, o = this.render.dpr;
786
+ t.font = h, t.textBaseline = "top";
1336
787
  const c = this._text.split(`
1337
788
  `);
1338
789
  let u = 0, l = 0;
1339
- const d = t.measureText(c[0] || "M"), f = (d.fontBoundingBoxAscent || r) + (d.fontBoundingBoxDescent || r * 0.2);
1340
- for (const W of c) {
1341
- const N = t.measureText(W);
1342
- N.width > u && (u = N.width), l += f * a;
790
+ const m = t.measureText(c[0] || "M").fontBoundingBoxDescent;
791
+ for (const b of c) {
792
+ const R = t.measureText(b);
793
+ R.width > u && (u = R.width), l += m * a;
1343
794
  }
1344
- l -= f * (a - 1);
1345
- const m = this._style.strokeThickness || 0, v = Math.ceil(u + m * 2) || 1, y = Math.ceil(l + m * 2) || 1, T = Math.ceil(v * h), M = Math.ceil(y * h);
1346
- (this.canvas.width !== T || this.canvas.height !== M) && (this.canvas.width = T, this.canvas.height = M), t.setTransform(h, 0, 0, h, 0, 0), t.clearRect(0, 0, v, y), t.font = o, t.textBaseline = "top", t.textAlign = this._style.align;
1347
- const A = this.updateOffset(v, m), P = e.strokeThickness, C = P > 0;
1348
- C && (t.lineWidth = P, t.strokeStyle = e.stroke, t.lineJoin = "round"), e.fill && (t.fillStyle = e.fill);
1349
- let F = m;
1350
- for (const W of c)
1351
- C && t.strokeText(W, A, F), e.fill && t.fillText(W, A, F), F += f * a;
1352
- this.base?.updateSource(this.render.gl, this.canvas, this.options), this.setRegion(0, 0, T, M);
795
+ l -= m * (a - 1);
796
+ const g = this._style.strokeThickness || 0, v = Math.ceil(u + g * 2) || 1, y = Math.ceil(l + g * 2) || 1, w = Math.ceil(v * o), M = Math.ceil(y * o);
797
+ (this.canvas.width !== w || this.canvas.height !== M) && (this.canvas.width = w, this.canvas.height = M), t.setTransform(o, 0, 0, o, 0, 0), t.clearRect(0, 0, v, y), t.font = h, t.textBaseline = "top", t.textAlign = this._style.align;
798
+ const _ = this.updateOffset(v, g), P = e.strokeThickness, O = P > 0;
799
+ O && (t.lineWidth = P, t.strokeStyle = e.stroke, t.lineJoin = "round"), e.fill && (t.fillStyle = e.fill);
800
+ let W = g;
801
+ for (const b of c)
802
+ O && t.strokeText(b, _, W), e.fill && t.fillText(b, _, W), W += m * a;
803
+ this.base?.updateSource(this.render.gl, this.canvas, this.options), this.setRegion(0, 0, w, M);
1353
804
  }
1354
805
  }
1355
- const It = (n, t = !1, e = !0) => {
806
+ const Lt = (n, t = !1, e = !0) => {
1356
807
  const r = n.getContext("webgl2", { stencil: !0, antialias: t, premultipliedAlpha: e });
1357
808
  if (!r)
1358
809
  throw new Error("WebGL2 is not supported in this browser.");
1359
810
  return r;
1360
- }, dt = (n, t, e) => {
811
+ }, ct = (n, t, e) => {
1361
812
  const r = n.createShader(e);
1362
813
  if (!r)
1363
814
  throw new Error("Unable to create webgl shader");
@@ -1366,21 +817,21 @@ const It = (n, t = !1, e = !0) => {
1366
817
  throw console.error("Shader compilation failed:", s), new Error("Unable to compile shader: " + s + t);
1367
818
  }
1368
819
  return r;
1369
- }, Ot = (n, t, e) => {
1370
- var r = n.createProgram(), i = dt(n, t, 35633), s = dt(n, e, 35632);
820
+ }, Nt = (n, t, e) => {
821
+ var r = n.createProgram(), i = ct(n, t, 35633), s = ct(n, e, 35632);
1371
822
  if (!r)
1372
823
  throw new Error("Unable to create program shader");
1373
824
  if (n.attachShader(r, i), n.attachShader(r, s), n.linkProgram(r), !n.getProgramParameter(r, n.LINK_STATUS)) {
1374
- const o = n.getProgramInfoLog(r);
1375
- throw new Error("Unable to link shader program: " + o);
825
+ const h = n.getProgramInfoLog(r);
826
+ throw new Error("Unable to link shader program: " + h);
1376
827
  }
1377
828
  return r;
1378
829
  };
1379
830
  function st(n, t) {
1380
831
  const e = {
1381
- [Q.CLAMP]: n.CLAMP_TO_EDGE,
1382
- [Q.REPEAT]: n.REPEAT,
1383
- [Q.MIRRORED_REPEAT]: n.MIRRORED_REPEAT
832
+ [q.CLAMP]: n.CLAMP_TO_EDGE,
833
+ [q.REPEAT]: n.REPEAT,
834
+ [q.MIRRORED_REPEAT]: n.MIRRORED_REPEAT
1384
835
  }[t] || n.CLAMP_TO_EDGE;
1385
836
  n.texParameteri(n.TEXTURE_2D, n.TEXTURE_WRAP_S, e), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_WRAP_T, e);
1386
837
  }
@@ -1391,11 +842,11 @@ function nt(n, t) {
1391
842
  }[t] ?? n.NEAREST;
1392
843
  n.texParameteri(n.TEXTURE_2D, n.TEXTURE_MIN_FILTER, e), n.texParameteri(n.TEXTURE_2D, n.TEXTURE_MAG_FILTER, e);
1393
844
  }
1394
- function et(n, t, e) {
845
+ function J(n, t, e) {
1395
846
  const r = n.gl, i = r.createTexture();
1396
847
  if (!i)
1397
848
  throw new Error("Unable to create WebGL texture");
1398
- if (r.bindTexture(r.TEXTURE_2D, i), r.pixelStorei(r.UNPACK_FLIP_Y_WEBGL, 0), r.pixelStorei(r.UNPACK_ALIGNMENT, 1), st(r, e.wrap ?? Q.CLAMP), nt(r, e.textureFilter ?? n.textureFilter), e.onlySize) {
849
+ if (r.bindTexture(r.TEXTURE_2D, i), r.pixelStorei(r.UNPACK_FLIP_Y_WEBGL, 0), r.pixelStorei(r.UNPACK_ALIGNMENT, 1), st(r, e.wrap ?? q.CLAMP), nt(r, e.textureFilter ?? n.textureFilter), e.onlySize) {
1399
850
  const s = t;
1400
851
  r.texImage2D(r.TEXTURE_2D, 0, r.RGBA, s.width, s.height, 0, r.RGBA, r.UNSIGNED_BYTE, null);
1401
852
  } else {
@@ -1404,7 +855,7 @@ function et(n, t, e) {
1404
855
  }
1405
856
  return r.bindTexture(r.TEXTURE_2D, null), i;
1406
857
  }
1407
- function V(n, t) {
858
+ function B(n, t) {
1408
859
  if (n.includes("%TEXTURE_NUM%") && (n = n.replace("%TEXTURE_NUM%", t.toString())), n.includes("%GET_COLOR%")) {
1409
860
  let e = "";
1410
861
  for (let r = 0; r < t; r++)
@@ -1413,76 +864,50 @@ function V(n, t) {
1413
864
  }
1414
865
  return n;
1415
866
  }
1416
- const Ft = 5126, at = 5121;
1417
- function Wt(n, t, e) {
867
+ const It = 5126, at = 5121;
868
+ function Ot(n, t, e) {
1418
869
  n.vertexAttribDivisor(t, e);
1419
870
  }
1420
- function Mt(n, t, e, r, i) {
871
+ function yt(n, t, e, r, i) {
1421
872
  n.drawArraysInstanced(t, e, r, i);
1422
873
  }
1423
- let Bt = 0;
1424
- class wt {
874
+ let Wt = 0;
875
+ class Tt {
1425
876
  program;
1426
877
  attributeLoc = {};
1427
878
  uniformLoc = {};
1428
879
  isCustom = !1;
1429
- /** Padding in pixels this shader needs beyond the sprite bounds (for outline/glow effects) */
1430
880
  padding = 0;
1431
- /** GLSL type for each uniform, parsed from source */
1432
881
  uniformType = {};
1433
- /** Whether the uniform is an array (e.g. sampler2D uTextures[8]) */
1434
882
  uniformIsArray = {};
1435
883
  gl;
1436
- shaderId = Bt++;
884
+ shaderId = Wt++;
1437
885
  // for debug
1438
886
  vao;
1439
887
  constructor(t, e, r, i) {
1440
- this.gl = t, this.program = Ot(t, e, r), this.parseShader(e), this.parseShader(r), this.vao = t.createVertexArray(), i && this.setAttributes(i);
888
+ this.gl = t, this.program = Nt(t, e, r), this.parseShader(e), this.parseShader(r), this.vao = t.createVertexArray(), i && this.setAttributes(i);
1441
889
  }
1442
- /** Switch GPU to use this shader program */
1443
890
  use() {
1444
891
  this.gl.useProgram(this.program);
1445
892
  }
1446
- /** Bind this shader's VAO (start recording or replaying attribute state) */
1447
893
  bindVAO() {
1448
894
  this.gl.bindVertexArray(this.vao);
1449
895
  }
1450
- /** Unbind VAO (finish recording) */
1451
896
  unbindVAO() {
1452
897
  this.gl.bindVertexArray(null);
1453
898
  }
1454
899
  // ── Uniforms ─────────────────────────────────────────────────────────────
1455
- /**
1456
- * Set a single uniform by name. Type is inferred from the parsed GLSL source.
1457
- * @example
1458
- * shader.setUniform("uTime", 1.5);
1459
- * shader.setUniform("uColor", [1, 0, 0, 1]);
1460
- * shader.setUniform("uMVP", mat4array);
1461
- */
1462
900
  setUniform(t, e) {
1463
901
  const r = this.uniformLoc[t];
1464
902
  if (r === void 0) return;
1465
903
  const i = this.uniformType[t], s = this.uniformIsArray[t];
1466
- Dt(this.gl, r, i, e, s);
1467
- }
1468
- /**
1469
- * Batch-set uniforms via a plain value map.
1470
- * @example
1471
- * shader.setUniforms({
1472
- * uTime: 1.5,
1473
- * uResolution: [800, 600],
1474
- * uMVP: mat4,
1475
- * });
1476
- */
904
+ Ft(this.gl, r, i, e, s);
905
+ }
1477
906
  setUniforms(t) {
1478
907
  for (const e in t)
1479
908
  this.setUniform(e, t[e]);
1480
909
  }
1481
910
  // ── Attributes ────────────────────────────────────────────────────────────
1482
- /**
1483
- * Bind a single vertex attribute pointer.
1484
- * The VBO must already be bound before calling this.
1485
- */
1486
911
  setAttribute(t) {
1487
912
  const e = this.attributeLoc[t.name];
1488
913
  if (e === void 0) return;
@@ -1490,39 +915,37 @@ class wt {
1490
915
  r.vertexAttribPointer(
1491
916
  e,
1492
917
  t.size,
1493
- t.type ?? Ft,
918
+ t.type ?? It,
1494
919
  t.normalized ?? !1,
1495
920
  t.stride,
1496
921
  t.offset ?? 0
1497
- ), r.enableVertexAttribArray(e), Wt(r, e, t.divisor ?? 0);
922
+ ), r.enableVertexAttribArray(e), Ot(r, e, t.divisor ?? 0);
1498
923
  }
1499
- /** Bind all vertex attribute pointers at once */
1500
924
  setAttributes(t) {
1501
925
  for (const e of t)
1502
926
  this.setAttribute(e);
1503
927
  }
1504
928
  // ── Lifecycle ─────────────────────────────────────────────────────────────
1505
- /** Free GPU resources */
1506
929
  destroy() {
1507
930
  this.gl.deleteProgram(this.program);
1508
931
  }
1509
- /** Parse attribute/uniform names and GLSL types from raw shader source */
1510
932
  parseShader(t) {
1511
933
  const e = this.gl, r = t.match(/(?:in|attribute)\s+\w+\s+\w+/g);
1512
934
  if (r)
1513
935
  for (const s of r) {
1514
- const o = s.split(/\s+/)[2], h = e.getAttribLocation(this.program, o);
1515
- h !== -1 && (this.attributeLoc[o] = h);
1516
- }
1517
- const i = t.match(/uniform\s+\w+\s+\w+(?:\[\d+\])?/g);
1518
- if (i)
1519
- for (const s of i) {
1520
- const a = s.split(/\s+/), o = a[1], h = a[2].replace(/\[\d+\]$/, ""), c = e.getUniformLocation(this.program, h);
1521
- c !== null && (this.uniformLoc[h] = c, this.uniformType[h] = o, this.uniformIsArray[h] = /\[\d+\]$/.test(a[2]));
936
+ const h = s.split(/\s+/)[2], o = e.getAttribLocation(this.program, h);
937
+ o !== -1 && (this.attributeLoc[h] = o);
1522
938
  }
939
+ const i = t.matchAll(
940
+ /uniform\s+(?:(?:lowp|mediump|highp)\s+)?(\w+)\s+(\w+)(\s*\[\s*\d+\s*\])?/g
941
+ );
942
+ for (const s of i) {
943
+ const a = s[1], h = s[2], o = e.getUniformLocation(this.program, h);
944
+ o !== null && (this.uniformLoc[h] = o, this.uniformType[h] = a, this.uniformIsArray[h] = s[3] !== void 0);
945
+ }
1523
946
  }
1524
947
  }
1525
- function Dt(n, t, e, r, i = !1) {
948
+ function Ft(n, t, e, r, i = !1) {
1526
949
  switch (e) {
1527
950
  // scalars
1528
951
  case "float":
@@ -1558,10 +981,10 @@ function Dt(n, t, e, r, i = !1) {
1558
981
  return n.uniformMatrix4fv(t, !1, r);
1559
982
  // fallback: guess by value shape
1560
983
  default:
1561
- return kt(n, t, r);
984
+ return Bt(n, t, r);
1562
985
  }
1563
986
  }
1564
- function kt(n, t, e) {
987
+ function Bt(n, t, e) {
1565
988
  if (typeof e == "number")
1566
989
  return n.uniform1f(t, e);
1567
990
  const r = e;
@@ -1580,31 +1003,19 @@ function kt(n, t, e) {
1580
1003
  return n.uniform1fv(t, r);
1581
1004
  }
1582
1005
  }
1583
- class ft {
1584
- /** Custom vertex shader code */
1006
+ class ut {
1585
1007
  vs;
1586
- /** Custom fragment shader code */
1587
1008
  fs;
1588
- /** Map of compiled GLShader instances per region key */
1589
1009
  glshader = /* @__PURE__ */ new Map();
1590
- /** Currently stored uniform values */
1591
1010
  uniforms = {};
1592
- /** Set of region keys that need uniform updates */
1593
1011
  uniformDirty = /* @__PURE__ */ new Set();
1594
- /** Map of textures to be bound to this shader */
1595
1012
  uniformTextures = {};
1596
- /** Number of texture units reserved by this custom shader */
1597
1013
  usedTextureUnitNum = 0;
1598
- /** Padding in pixels this shader needs beyond the sprite bounds (for outline/glow effects) */
1599
1014
  padding = 0;
1600
1015
  rapid;
1601
1016
  constructor(t, e, r, i = 0, s) {
1602
1017
  this.vs = e, this.fs = r, this.rapid = t, this.uniforms = s ?? {}, this.usedTextureUnitNum = i;
1603
1018
  }
1604
- /**
1605
- * Updates uniform values or textures for the custom shader.
1606
- * @param uniforms Map of uniform values or WebGL textures to apply.
1607
- */
1608
1019
  setUniforms(t) {
1609
1020
  this.rapid.flush();
1610
1021
  const e = {}, r = {};
@@ -1614,34 +1025,16 @@ class ft {
1614
1025
  for (const i of this.glshader.keys())
1615
1026
  this.uniformDirty.add(i);
1616
1027
  }
1617
- /**
1618
- * Sets the padding (in pixels) for this shader and propagates to all compiled GLShaders.
1619
- * Must be called before the first draw call if set after construction.
1620
- * @param pixels - Number of pixels to expand the quad on each side.
1621
- */
1622
1028
  setPadding(t) {
1623
1029
  this.padding = t;
1624
1030
  for (const e of this.glshader.values())
1625
1031
  e.padding = t;
1626
1032
  return this;
1627
1033
  }
1628
- /**
1629
- * Applies current uniforms and texture unit mappings to the region-specific shader.
1630
- * @param key The region key.
1631
- * @param textureUniforms Map of texture uniform names to assigned texture unit indices.
1632
- */
1633
1034
  applyUniform(t, e) {
1634
1035
  const r = this.glshader.get(t);
1635
1036
  r && (Object.keys(e).length > 0 && r.setUniforms(e), this.uniformDirty.has(t) && (r.setUniforms(this.uniforms), this.uniformDirty.delete(t)));
1636
1037
  }
1637
- /**
1638
- * Retrieves or compiles a customized GLShader for a specific region.
1639
- * @param region The Region requesting the shader.
1640
- * @param key The region key.
1641
- * @param baseVS The base vertex shader template.
1642
- * @param baseFS The base fragment shader template.
1643
- * @returns The combined and compiled GLShader.
1644
- */
1645
1038
  getGLShader(t, e, r, i) {
1646
1039
  if (this.glshader.has(e))
1647
1040
  return this.glshader.get(e);
@@ -1655,7 +1048,7 @@ class ft {
1655
1048
  this.glshader.forEach((t) => t.destroy());
1656
1049
  }
1657
1050
  }
1658
- class At {
1051
+ class Et {
1659
1052
  constructor(t) {
1660
1053
  this.rapid = t, this.gl = t.gl, this.maxTextureUnits = t.maxTextureUnits, this.matrixStore = t.matrix;
1661
1054
  }
@@ -1698,7 +1091,7 @@ class At {
1698
1091
  return i == -1 ? (this.freeTextureUnitNum === 0 && this.flush(), this.usedTextures.push(t), this.usedTexturePadding.push(e), this.usedTexturePadding.push(r), this.usedTextures.length - 1) : i;
1699
1092
  }
1700
1093
  createShader(t, e) {
1701
- return new wt(this.gl, t, e);
1094
+ return new Tt(this.gl, t, e);
1702
1095
  }
1703
1096
  createCustomShader(t) {
1704
1097
  return t.getGLShader(this, this.KEY, this.vs, this.fs);
@@ -1706,22 +1099,17 @@ class At {
1706
1099
  getCustomShader(t) {
1707
1100
  if (!t)
1708
1101
  return this.defaultShader;
1709
- if (t instanceof ft) {
1102
+ if (t instanceof ut) {
1710
1103
  const e = this.createCustomShader(t);
1711
1104
  return e ?? this.defaultShader;
1712
1105
  }
1713
1106
  return t;
1714
1107
  }
1715
- /**
1716
- * Checks if the given shader is the same as the currently bound shader.
1717
- * @param customShader Optional custom shader.
1718
- * @returns True if already bound, otherwise false.
1719
- */
1720
1108
  isSameShader(t) {
1721
1109
  return this.isDefaultShader && !t ? !0 : this.getCustomShader(t) == this.currentShader;
1722
1110
  }
1723
1111
  enter(t) {
1724
- this.resetRender(), this.currentShader = this.getCustomShader(t), t instanceof ft ? (this.customShader = t, this.customShaderUsedTextureNum = t.usedTextureUnitNum) : (this.customShader = null, this.customShaderUsedTextureNum = 0), this.isDefaultShader = this.currentShader == this.defaultShader, this.currentShader.use(), this.currentShader.setUniform("u_projection", this.rapid.projection);
1112
+ this.resetRender(), this.currentShader = this.getCustomShader(t), t instanceof ut ? (this.customShader = t, this.customShaderUsedTextureNum = t.usedTextureUnitNum) : (this.customShader = null, this.customShaderUsedTextureNum = 0), this.isDefaultShader = this.currentShader == this.defaultShader, this.currentShader.use(), this.currentShader.setUniform("u_projection", this.rapid.projection);
1725
1113
  }
1726
1114
  exit() {
1727
1115
  this.hasPendingContent() && this.flush(), this.gl.bindVertexArray(null);
@@ -1758,7 +1146,7 @@ class At {
1758
1146
  return !1;
1759
1147
  }
1760
1148
  }
1761
- const tt = `#version 300 es\r
1149
+ const Z = `#version 300 es\r
1762
1150
  precision highp float;\r
1763
1151
  \r
1764
1152
  // per-vertex\r
@@ -1806,7 +1194,7 @@ void main(void) {\r
1806
1194
  \r
1807
1195
  gl_Position = u_projection * position;\r
1808
1196
  }\r
1809
- `, mt = `#version 300 es\r
1197
+ `, lt = `#version 300 es\r
1810
1198
  precision mediump float;\r
1811
1199
  \r
1812
1200
  uniform sampler2D uTextures[%TEXTURE_NUM%];\r
@@ -1855,8 +1243,8 @@ void main(void) {\r
1855
1243
  \r
1856
1244
  // CUSTOM_CODE_CALL\r
1857
1245
  }\r
1858
- `, $ = 48, Gt = new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]);
1859
- class ot extends At {
1246
+ `, $ = 48, Dt = new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]);
1247
+ class ot extends Et {
1860
1248
  instanceBuffer;
1861
1249
  quadBuffer;
1862
1250
  instanceCount = 0;
@@ -1868,12 +1256,12 @@ class ot extends At {
1868
1256
  }
1869
1257
  createBuffer() {
1870
1258
  const t = this.gl;
1871
- this.quadBuffer = new it(t, b.Float32, t.ARRAY_BUFFER, t.STATIC_DRAW), this.quadBuffer.bindBuffer();
1872
- for (const e of Gt) this.quadBuffer.pushFloat32(e);
1873
- this.quadBuffer.makeDirty(), this.quadBuffer.bufferData(), this.instanceBuffer = new it(t, b.Uint32, t.ARRAY_BUFFER, t.DYNAMIC_DRAW);
1259
+ this.quadBuffer = new it(t, S.Float32, t.ARRAY_BUFFER, t.STATIC_DRAW), this.quadBuffer.bindBuffer();
1260
+ for (const e of Dt) this.quadBuffer.pushFloat32(e);
1261
+ this.quadBuffer.makeDirty(), this.quadBuffer.bufferData(), this.instanceBuffer = new it(t, S.Uint32, t.ARRAY_BUFFER, t.DYNAMIC_DRAW);
1874
1262
  }
1875
1263
  createDefaultShader() {
1876
- const t = this.rapid, e = V(mt, t.maxTextureUnits), r = V(tt, t.maxTextureUnits);
1264
+ const t = this.rapid, e = B(lt, t.maxTextureUnits), r = B(Z, t.maxTextureUnits);
1877
1265
  return this.vs = r, this.fs = e, this.defaultShader = this.createShader(r, e), this.defaultShader;
1878
1266
  }
1879
1267
  createShader(t, e) {
@@ -1889,22 +1277,10 @@ class ot extends At {
1889
1277
  ]), r.unbindVAO(), this.currentShader && this.currentShader.use(), r;
1890
1278
  }
1891
1279
  createCustomShader(t) {
1892
- const e = V(mt, this.rapid.maxTextureUnits - t.usedTextureUnitNum), r = V(tt, this.rapid.maxTextureUnits - t.usedTextureUnitNum);
1280
+ const e = B(lt, this.rapid.maxTextureUnits - t.usedTextureUnitNum), r = B(Z, this.rapid.maxTextureUnits - t.usedTextureUnitNum);
1893
1281
  return t.getGLShader(this, this.KEY, r, e);
1894
1282
  }
1895
- /**
1896
- * Draws a textured sprite via instanced rendering to significantly improve performance.
1897
- * @param texture The WebGLTexture to map.
1898
- * @param matrixIndex The index for the transform matrix in MatrixStore.
1899
- * @param width Render width.
1900
- * @param height Render height.
1901
- * @param u0 Left UV mapped coordinate (default 0).
1902
- * @param v0 Top UV mapped coordinate (default 0).
1903
- * @param u1 Right UV mapped coordinate (default 1).
1904
- * @param v1 Bottom UV mapped coordinate (default 1).
1905
- * @param color The tint color as packed ABGR uniform uint32 (default 0xFFFFFFFF).
1906
- */
1907
- drawSprite(t, e, r = 0, i = 0, s = 1, a = 1, o = 4294967295, h = 0, c = 0, u = !1, l = !1, d = !1) {
1283
+ drawSprite(t, e, r = 0, i = 0, s = 1, a = 1, h = 4294967295, o = 0, c = 0, u = !1, l = !1, d = !1) {
1908
1284
  const f = e * 6, m = this.matrixStore.data;
1909
1285
  this.drawSpriteAffine(
1910
1286
  t,
@@ -1918,31 +1294,31 @@ class ot extends At {
1918
1294
  i,
1919
1295
  s,
1920
1296
  a,
1921
- o,
1922
1297
  h,
1298
+ o,
1923
1299
  c,
1924
1300
  u,
1925
1301
  l,
1926
1302
  d
1927
1303
  );
1928
1304
  }
1929
- drawSpriteAffine(t, e, r, i, s, a, o, h = 0, c = 0, u = 1, l = 1, d = 4294967295, f = 0, m = 0, v = !1, y = !1, T = !1) {
1930
- const M = t.base, A = t.rawWidth, P = t.rawHeight, C = t.offsetX, F = t.offsetY, W = this.useTexture(
1305
+ drawSpriteAffine(t, e, r, i, s, a, h, o = 0, c = 0, u = 1, l = 1, d = 4294967295, f = 0, m = 0, g = !1, v = !1, y = !1) {
1306
+ const w = t.base, M = t.rawWidth, _ = t.rawHeight, P = t.offsetX, O = t.offsetY, W = this.useTexture(
1931
1307
  t.glTexture,
1932
- f / M.width,
1933
- m / M.height
1934
- ), N = this.instanceBuffer, w = N.usedElemNum;
1935
- N.resize(12);
1936
- const U = N.float32, X = N.uint32, k = T ? P : A, G = T ? A : P, I = k + 2 * f, B = G + 2 * m, H = C - f, R = F - m, g = this.localSpriteMatrix;
1937
- T ? (g[0] = 0, g[1] = y ? B : -B, g[2] = v ? -I : I, g[3] = 0, g[4] = H + (v ? I : 0), g[5] = R + (y ? 0 : B)) : (g[0] = v ? -I : I, g[1] = 0, g[2] = 0, g[3] = y ? -B : B, g[4] = H + (v ? I : 0), g[5] = R + (y ? B : 0));
1938
- const S = this.worldSpriteMatrix;
1939
- S[0] = e * g[0] + i * g[1], S[1] = r * g[0] + s * g[1], S[2] = e * g[2] + i * g[3], S[3] = r * g[2] + s * g[3], S[4] = a + e * g[4] + i * g[5], S[5] = o + r * g[4] + s * g[5], U[w + 6] = h, U[w + 7] = c, U[w + 8] = u, U[w + 9] = l, X[w + 10] = d, X[w + 11] = W, this.rapid.roundPixels && (S[4] = Math.round(S[4]), S[5] = Math.round(S[5])), U[w] = S[0], U[w + 1] = S[2], U[w + 2] = S[4], U[w + 3] = S[1], U[w + 4] = S[3], U[w + 5] = S[5], N.usedElemNum += 12, N.makeDirty(), this.instanceCount++;
1308
+ f / w.width,
1309
+ m / w.height
1310
+ ), b = this.instanceBuffer, R = b.usedElemNum;
1311
+ b.resize(12);
1312
+ const C = b.float32, D = b.uint32, k = y ? _ : M, H = y ? M : _, I = k + 2 * f, F = H + 2 * m, Y = P - f, z = O - m, E = this.localSpriteMatrix;
1313
+ y ? (E[0] = 0, E[1] = v ? F : -F, E[2] = g ? -I : I, E[3] = 0, E[4] = Y + (g ? I : 0), E[5] = z + (v ? 0 : F)) : (E[0] = g ? -I : I, E[1] = 0, E[2] = 0, E[3] = v ? -F : F, E[4] = Y + (g ? I : 0), E[5] = z + (v ? F : 0));
1314
+ const U = this.worldSpriteMatrix;
1315
+ U[0] = e * E[0] + i * E[1], U[1] = r * E[0] + s * E[1], U[2] = e * E[2] + i * E[3], U[3] = r * E[2] + s * E[3], U[4] = a + e * E[4] + i * E[5], U[5] = h + r * E[4] + s * E[5], C[R + 6] = o, C[R + 7] = c, C[R + 8] = u, C[R + 9] = l, D[R + 10] = d, D[R + 11] = W, this.rapid.roundPixels && (U[4] = Math.round(U[4]), U[5] = Math.round(U[5])), C[R] = U[0], C[R + 1] = U[2], C[R + 2] = U[4], C[R + 3] = U[1], C[R + 4] = U[3], C[R + 5] = U[5], b.usedElemNum += 12, b.makeDirty(), this.instanceCount++;
1940
1316
  }
1941
1317
  render() {
1942
1318
  if (this.instanceCount === 0) return;
1943
1319
  this.prepareRender();
1944
1320
  const t = this.gl, e = this.currentShader;
1945
- this.instanceBuffer.bindBuffer(), this.instanceBuffer.bufferData(), e.bindVAO(), Mt(t, t.TRIANGLE_STRIP, 0, 4, this.instanceCount), this.rapid.drawcallCount++;
1321
+ this.instanceBuffer.bindBuffer(), this.instanceBuffer.bufferData(), e.bindVAO(), yt(t, t.TRIANGLE_STRIP, 0, 4, this.instanceCount), this.rapid.drawcallCount++;
1946
1322
  }
1947
1323
  resetRender() {
1948
1324
  super.resetRender(), this.instanceBuffer.clear(), this.instanceCount = 0;
@@ -1951,7 +1327,7 @@ class ot extends At {
1951
1327
  return this.instanceCount > 0;
1952
1328
  }
1953
1329
  }
1954
- const Ht = `#version 300 es\r
1330
+ const kt = `#version 300 es\r
1955
1331
  precision highp float;\r
1956
1332
  \r
1957
1333
  in vec2 aPosition;\r
@@ -1982,7 +1358,7 @@ void main(void) {\r
1982
1358
  // CUSTOM_CODE_CALL\r
1983
1359
  gl_Position = u_projection * position;\r
1984
1360
  }\r
1985
- `, Vt = `#version 300 es\r
1361
+ `, Ht = `#version 300 es\r
1986
1362
  precision mediump float;\r
1987
1363
  \r
1988
1364
  in vec4 vColor;\r
@@ -2028,7 +1404,7 @@ void main(void) {\r
2028
1404
  fragColor = sampleTexture(vRegion) * vColor;\r
2029
1405
  // CUSTOM_CODE_CALL\r
2030
1406
  }\r
2031
- `, Yt = `#version 300 es\r
1407
+ `, Gt = `#version 300 es\r
2032
1408
  precision highp float;\r
2033
1409
  \r
2034
1410
  in vec2 aPosition;\r
@@ -2051,7 +1427,7 @@ void main(void) {\r
2051
1427
  );\r
2052
1428
  gl_Position = u_projection * position;\r
2053
1429
  }\r
2054
- `, zt = `#version 300 es\r
1430
+ `, Vt = `#version 300 es\r
2055
1431
  precision mediump float;\r
2056
1432
  \r
2057
1433
  in vec2 vRegion;\r
@@ -2071,8 +1447,8 @@ void main(void) {\r
2071
1447
  discard;\r
2072
1448
  }\r
2073
1449
  }\r
2074
- `, K = 20;
2075
- class Xt extends At {
1450
+ `, j = 20;
1451
+ class Yt extends Et {
2076
1452
  vertexBuffer;
2077
1453
  vertexCount = 0;
2078
1454
  matrixIndex = -1;
@@ -2085,50 +1461,33 @@ class Xt extends At {
2085
1461
  }
2086
1462
  createBuffer() {
2087
1463
  const t = this.gl;
2088
- this.vertexBuffer = new it(t, b.Float32, t.ARRAY_BUFFER, t.DYNAMIC_DRAW), this.maskShader = this.createMaskShader(Yt, zt);
1464
+ this.vertexBuffer = new it(t, S.Float32, t.ARRAY_BUFFER, t.DYNAMIC_DRAW), this.maskShader = this.createMaskShader(Gt, Vt);
2089
1465
  }
2090
1466
  createDefaultShader() {
2091
- return this.vs = Ht, this.fs = Vt, this.defaultShader = this.createShader(this.vs, this.fs), this.defaultShader;
1467
+ return this.vs = kt, this.fs = Ht, this.defaultShader = this.createShader(this.vs, this.fs), this.defaultShader;
2092
1468
  }
2093
1469
  createMaskShader(t, e) {
2094
- const r = this.gl, i = new wt(r, t, e);
1470
+ const r = this.gl, i = new Tt(r, t, e);
2095
1471
  return i.use(), i.bindVAO(), this.vertexBuffer.bindBuffer(), i.setAttributes([
2096
- { name: "aPosition", size: 2, type: r.FLOAT, stride: K - 4, offset: 0, divisor: 0 },
2097
- { name: "aUV", size: 2, type: r.FLOAT, stride: K - 4, offset: 8, divisor: 0 }
1472
+ { name: "aPosition", size: 2, type: r.FLOAT, stride: j - 4, offset: 0, divisor: 0 },
1473
+ { name: "aUV", size: 2, type: r.FLOAT, stride: j - 4, offset: 8, divisor: 0 }
2098
1474
  ]), i.unbindVAO(), this.currentShader && this.currentShader.use(), i;
2099
1475
  }
2100
1476
  createShader(t, e) {
2101
1477
  const r = this.gl, i = super.createShader(t, e);
2102
1478
  return i.use(), i.bindVAO(), this.vertexBuffer.bindBuffer(), i.setAttributes([
2103
- { name: "aPosition", size: 2, type: r.FLOAT, stride: K, offset: 0, divisor: 0 },
2104
- { name: "aColor", size: 4, type: r.UNSIGNED_BYTE, normalized: !0, stride: K, offset: 8, divisor: 0 },
2105
- { name: "aUV", size: 2, type: r.FLOAT, stride: K, offset: 12, divisor: 0 }
1479
+ { name: "aPosition", size: 2, type: r.FLOAT, stride: j, offset: 0, divisor: 0 },
1480
+ { name: "aColor", size: 4, type: r.UNSIGNED_BYTE, normalized: !0, stride: j, offset: 8, divisor: 0 },
1481
+ { name: "aUV", size: 2, type: r.FLOAT, stride: j, offset: 12, divisor: 0 }
2106
1482
  ]), i.unbindVAO(), this.currentShader && this.currentShader.use(), i;
2107
1483
  }
2108
- /**
2109
- * Begins a new polygon drawing sequence. Must be followed by addVertex() calls and endGraphic().
2110
- * @param matrixIndex The index targeting a specific transform matrix in the MatrixStore.
2111
- * @param drawMode The WebGL drawing primitive mode (e.g., gl.TRIANGLES).
2112
- * @param texture Optional texture to apply over the polygon.
2113
- */
2114
1484
  startGraphic(t, e = this.gl.TRIANGLES, r) {
2115
1485
  this.vertexBuffer.clear(), this.vertexCount = 0, this.matrixIndex = t, this.drawMode = e, this.texture = r, this.texture?.glTexture && this.useTexture(this.texture.glTexture, 0, 0);
2116
1486
  }
2117
- /**
2118
- * Adds a vertex to the current polygon. Local coordinates and color settings.
2119
- * @param x Local X coordinate.
2120
- * @param y Local Y coordinate.
2121
- * @param u UV mapped X value (0-1, default 0).
2122
- * @param v UV mapped Y value (0-1, default 0).
2123
- * @param color Pre-multiplied hex color combined using ABGR byte order (default 0xFFFFFFFF).
2124
- */
2125
1487
  addVertex(t, e, r = 0, i = 0, s = 4294967295) {
2126
1488
  const a = this.vertexBuffer;
2127
1489
  a.pushFloat32(t), a.pushFloat32(e), this.currentShader != this.maskShader && a.pushUint32(s), a.pushFloat32(r), a.pushFloat32(i), this.vertexCount++, this.vertexBuffer.makeDirty();
2128
1490
  }
2129
- /**
2130
- * Finishes the graphic construction and dispatches the rendering call immediately.
2131
- */
2132
1491
  endGraphic() {
2133
1492
  this.flush();
2134
1493
  }
@@ -2167,15 +1526,9 @@ class p {
2167
1526
  subtract(t) {
2168
1527
  return new p(this.x - t.x, this.y - t.y);
2169
1528
  }
2170
- sub(t) {
2171
- return new p(this.x - t.x, this.y - t.y);
2172
- }
2173
1529
  multiply(t) {
2174
1530
  return t instanceof p ? new p(this.x * t.x, this.y * t.y) : new p(this.x * t, this.y * t);
2175
1531
  }
2176
- mul(t) {
2177
- return this.multiply(t);
2178
- }
2179
1532
  divide(t) {
2180
1533
  return t instanceof p ? new p(this.x / t.x, this.y / t.y) : new p(this.x / t, this.y / t);
2181
1534
  }
@@ -2195,9 +1548,6 @@ class p {
2195
1548
  to(t) {
2196
1549
  this.x = t.x, this.y = t.y;
2197
1550
  }
2198
- copy() {
2199
- return new p(this.x, this.y);
2200
- }
2201
1551
  equals(t) {
2202
1552
  return t.x == this.x && t.y == this.y;
2203
1553
  }
@@ -2271,8 +1621,8 @@ class p {
2271
1621
  return new p(Math.cos(t), Math.sin(t));
2272
1622
  }
2273
1623
  }
2274
- const jt = (n, t) => {
2275
- const [e, r, i, s, a, o] = t, h = new Float32Array([
1624
+ const Xt = (n, t) => {
1625
+ const [e, r, i, s, a, h] = t, o = new Float32Array([
2276
1626
  e,
2277
1627
  i,
2278
1628
  0,
@@ -2286,12 +1636,12 @@ const jt = (n, t) => {
2286
1636
  1,
2287
1637
  0,
2288
1638
  a,
2289
- o,
1639
+ h,
2290
1640
  0,
2291
1641
  1
2292
1642
  ]);
2293
- return $t(h, n);
2294
- }, $t = (n, t) => {
1643
+ return zt(o, n);
1644
+ }, zt = (n, t) => {
2295
1645
  const e = new Float32Array(16);
2296
1646
  for (let r = 0; r < 4; r++)
2297
1647
  for (let i = 0; i < 4; i++) {
@@ -2302,75 +1652,75 @@ const jt = (n, t) => {
2302
1652
  }
2303
1653
  return e;
2304
1654
  };
2305
- var Kt = /* @__PURE__ */ ((n) => (n[n.STRETCH = 0] = "STRETCH", n[n.REPEAT = 1] = "REPEAT", n))(Kt || {});
2306
- const rt = 10, xt = (n, t, e, r, i, s) => {
2307
- const a = [], o = [], h = r ? Math.atan2(t.y, t.x) : Math.atan2(-t.y, -t.x), c = Math.PI, u = new p(t.y, -t.x);
1655
+ var $t = /* @__PURE__ */ ((n) => (n[n.STRETCH = 0] = "STRETCH", n[n.REPEAT = 1] = "REPEAT", n))($t || {});
1656
+ const rt = 10, dt = (n, t, e, r, i, s) => {
1657
+ const a = [], h = [], o = r ? Math.atan2(t.y, t.x) : Math.atan2(-t.y, -t.x), c = Math.PI, u = new p(t.y, -t.x);
2308
1658
  for (let l = 0; l < rt; l++) {
2309
- const d = l / rt, f = (l + 1) / rt, m = h + d * c, v = h + f * c, y = new p(Math.cos(m) * e, Math.sin(m) * e), T = new p(Math.cos(v) * e, Math.sin(v) * e);
2310
- a.push(n), o.push(new p(i, 0.5)), a.push(n.add(y)), o.push(new p(i + y.dot(u) * s, 0.5 - 0.5 * y.dot(t) / e)), a.push(n.add(T)), o.push(new p(i + T.dot(u) * s, 0.5 - 0.5 * T.dot(t) / e));
1659
+ const d = l / rt, f = (l + 1) / rt, m = o + d * c, g = o + f * c, v = new p(Math.cos(m) * e, Math.sin(m) * e), y = new p(Math.cos(g) * e, Math.sin(g) * e);
1660
+ a.push(n), h.push(new p(i, 0.5)), a.push(n.add(v)), h.push(new p(i + v.dot(u) * s, 0.5 - 0.5 * v.dot(t) / e)), a.push(n.add(y)), h.push(new p(i + y.dot(u) * s, 0.5 - 0.5 * y.dot(t) / e));
2311
1661
  }
2312
- return { vertices: a, uv: o };
2313
- }, qt = (n, t = !1) => {
1662
+ return { vertices: a, uv: h };
1663
+ }, jt = (n, t = !1) => {
2314
1664
  const e = [];
2315
1665
  if (n.length < 2 || t && n.length < 3) return { normals: e, length: 0 };
2316
1666
  const r = 4, i = 1e-3, s = n.length;
2317
1667
  let a = 0;
2318
1668
  if (t)
2319
- for (let h = 0; h < s; h++) {
2320
- const c = n[h], u = n[(h + 1) % s];
1669
+ for (let o = 0; o < s; o++) {
1670
+ const c = n[o], u = n[(o + 1) % s];
2321
1671
  a += c.distanceTo(u);
2322
1672
  }
2323
1673
  else
2324
- for (let h = 0; h < s - 1; h++)
2325
- a += n[h].distanceTo(n[h + 1]);
2326
- const o = (h, c, u) => {
2327
- const l = c.subtract(h).normalize(), d = c.subtract(u).normalize(), f = d.dot(l);
1674
+ for (let o = 0; o < s - 1; o++)
1675
+ a += n[o].distanceTo(n[o + 1]);
1676
+ const h = (o, c, u) => {
1677
+ const l = c.subtract(o).normalize(), d = c.subtract(u).normalize(), f = d.dot(l);
2328
1678
  if (f < -1 + i)
2329
1679
  return { normal: l.perpendicular(), miters: 1 };
2330
1680
  {
2331
1681
  let m = d.add(l).normalize();
2332
1682
  l.cross(d) < 0 && (m = m.multiply(-1));
2333
- let v = 1 / Math.sqrt((1 - f) / 2);
2334
- return { normal: m, miters: Math.min(v, r) };
1683
+ let g = 1 / Math.sqrt((1 - f) / 2);
1684
+ return { normal: m, miters: Math.min(g, r) };
2335
1685
  }
2336
1686
  };
2337
1687
  if (t)
2338
- for (let h = 0; h < s; h++) {
2339
- const c = h === 0 ? n[s - 1] : n[h - 1], u = n[h], l = h === s - 1 ? n[0] : n[h + 1];
2340
- e.push(o(c, u, l));
1688
+ for (let o = 0; o < s; o++) {
1689
+ const c = o === 0 ? n[s - 1] : n[o - 1], u = n[o], l = o === s - 1 ? n[0] : n[o + 1];
1690
+ e.push(h(c, u, l));
2341
1691
  }
2342
1692
  else
2343
- for (let h = 0; h < s; h++)
2344
- if (h === 0) {
1693
+ for (let o = 0; o < s; o++)
1694
+ if (o === 0) {
2345
1695
  const c = n[1].subtract(n[0]).normalize();
2346
1696
  e.push({ normal: c.perpendicular(), miters: 1 });
2347
- } else if (h === s - 1) {
2348
- const c = n[h].subtract(n[h - 1]).normalize();
1697
+ } else if (o === s - 1) {
1698
+ const c = n[o].subtract(n[o - 1]).normalize();
2349
1699
  e.push({ normal: c.perpendicular(), miters: 1 });
2350
1700
  } else
2351
- e.push(o(n[h - 1], n[h], n[h + 1]));
1701
+ e.push(h(n[o - 1], n[o], n[o + 1]));
2352
1702
  return { normals: e, length: a };
2353
- }, Qt = (n) => {
1703
+ }, Kt = (n) => {
2354
1704
  const t = n.points;
2355
1705
  if (t.length < 2) return { vertices: [], uv: [] };
2356
- const { normals: e, length: r } = qt(t, n.closed), i = (n.width || 1) / 2, s = [], a = [], o = n.roundCap || !1, h = n.textureMode || 0;
1706
+ const { normals: e, length: r } = jt(t, n.closed), i = (n.width || 1) / 2, s = [], a = [], h = n.roundCap || !1, o = n.textureMode || 0;
2357
1707
  let c = 0;
2358
1708
  const u = n.texture?.rawWidth || 1, l = n.closed ? t.length : t.length - 1;
2359
1709
  for (let d = 0; d < l; d++) {
2360
- const f = t[d], m = e[d].normal, v = e[d].miters, y = (d + 1) % t.length, T = t[y], M = e[y].normal, A = e[y].miters, P = f.add(m.multiply(v * i)), C = f.subtract(m.multiply(v * i)), F = T.add(M.multiply(A * i)), W = T.subtract(M.multiply(A * i)), N = f.distanceTo(T);
2361
- let w = 0, U = 0;
2362
- h === 0 ? (w = c / r, U = (c + N) / r) : (w = c / u, U = w + N / u);
2363
- const X = new p(w, 0), k = new p(w, 1), G = new p(U, 0), I = new p(U, 1);
2364
- s.push(P), a.push(X), s.push(C), a.push(k), s.push(F), a.push(G), s.push(F), a.push(G), s.push(W), a.push(I), s.push(C), a.push(k), c += N;
2365
- }
2366
- if (o && !n.closed) {
2367
- const d = t[0], f = e[0].normal, m = h === 0 ? r > 0 ? 1 / r : 0 : 1 / u, v = xt(d, f, i, !0, 0, m);
2368
- s.push(...v.vertices), a.push(...v.uv);
2369
- const y = t[t.length - 1], T = e[t.length - 1].normal, M = h === 0 ? 1 : c / u, A = h === 0 ? r > 0 ? 1 / r : 0 : 1 / u, P = xt(y, T, i, !1, M, A);
2370
- s.push(...P.vertices), a.push(...P.uv);
1710
+ const f = t[d], m = e[d].normal, g = e[d].miters, v = (d + 1) % t.length, y = t[v], w = e[v].normal, M = e[v].miters, _ = f.add(m.multiply(g * i)), P = f.subtract(m.multiply(g * i)), O = y.add(w.multiply(M * i)), W = y.subtract(w.multiply(M * i)), b = f.distanceTo(y);
1711
+ let R = 0, C = 0;
1712
+ o === 0 ? (R = c / r, C = (c + b) / r) : (R = c / u, C = R + b / u);
1713
+ const D = new p(R, 0), k = new p(R, 1), H = new p(C, 0), I = new p(C, 1);
1714
+ s.push(_), a.push(D), s.push(P), a.push(k), s.push(O), a.push(H), s.push(O), a.push(H), s.push(W), a.push(I), s.push(P), a.push(k), c += b;
1715
+ }
1716
+ if (h && !n.closed) {
1717
+ const d = t[0], f = e[0].normal, m = o === 0 ? r > 0 ? 1 / r : 0 : 1 / u, g = dt(d, f, i, !0, 0, m);
1718
+ s.push(...g.vertices), a.push(...g.uv);
1719
+ const v = t[t.length - 1], y = e[t.length - 1].normal, w = o === 0 ? 1 : c / u, M = o === 0 ? r > 0 ? 1 / r : 0 : 1 / u, _ = dt(v, y, i, !1, w, M);
1720
+ s.push(..._.vertices), a.push(..._.uv);
2371
1721
  }
2372
1722
  return { vertices: s, uv: a };
2373
- }, Z = (n, t, e, r) => {
1723
+ }, Q = (n, t, e, r) => {
2374
1724
  if (t.customMatrix !== void 0)
2375
1725
  return t.customMatrix;
2376
1726
  if (t.modifyStack) {
@@ -2389,24 +1739,24 @@ const rt = 10, xt = (n, t, e, r, i, s) => {
2389
1739
  i
2390
1740
  ), i;
2391
1741
  }
2392
- }, Zt = (n, t) => t ? n ? t.premultipliedUint32 : t.uint32 : 4294967295, Jt = 2, te = (n, t) => {
2393
- const e = Z(n, t, t.texture.rawWidth, t.texture.rawHeight), r = t.texture;
1742
+ }, qt = (n, t) => t ? n ? t.premultipliedUint32 : t.uint32 : 4294967295, Qt = 2, Zt = (n, t) => {
1743
+ const e = Q(n, t, t.texture.rawWidth, t.texture.rawHeight), r = t.texture;
2394
1744
  if (!r?.base || n.inCreateMask)
2395
1745
  return;
2396
1746
  const i = r.isAtlas ? n.atlasSpriteRegion : n.spriteRegion;
2397
1747
  n.enterRegion(i, t.shader);
2398
- let s = r.uvX, a = r.uvY, o = r.uvW, h = r.uvH;
1748
+ let s = r.uvX, a = r.uvY, h = r.uvW, o = r.uvH;
2399
1749
  const c = !!t.flipX, u = !!t.flipY != !!r.flipY;
2400
1750
  let l = t.padding ?? i.currentShader.padding;
2401
- r.isAtlas && (l += Jt);
2402
- const d = s <= o ? l : -l, f = a <= h ? l : -l;
1751
+ r.isAtlas && (l += Qt);
1752
+ const d = s <= h ? l : -l, f = a <= o ? l : -l;
2403
1753
  i.drawSprite(
2404
1754
  r,
2405
1755
  e ?? t.customMatrix ?? n.matrixStack.curWorldM,
2406
1756
  s,
2407
1757
  a,
2408
- o,
2409
1758
  h,
1759
+ o,
2410
1760
  n.getColorUint32(t.color),
2411
1761
  d,
2412
1762
  f,
@@ -2414,7 +1764,7 @@ const rt = 10, xt = (n, t, e, r, i, s) => {
2414
1764
  u,
2415
1765
  r.isRotated
2416
1766
  );
2417
- }, ee = (n, t) => {
1767
+ }, Jt = (n, t) => {
2418
1768
  const e = n.particleRegion;
2419
1769
  n.enterRegion(e, t.shader);
2420
1770
  const r = t.texture, i = t.count ?? t.x.length, s = t.color;
@@ -2440,9 +1790,9 @@ const rt = 10, xt = (n, t, e, r, i, s) => {
2440
1790
  t.reverseOrder,
2441
1791
  t.customMatrix
2442
1792
  );
2443
- }, St = (n, t) => {
1793
+ }, Rt = (n, t) => {
2444
1794
  if (t.points.length === 0) return;
2445
- const e = Z(n, t, 0, 0);
1795
+ const e = Q(n, t, 0, 0);
2446
1796
  n.startGraphic(
2447
1797
  t.drawMode ?? n.gl.TRIANGLES,
2448
1798
  t.texture,
@@ -2460,18 +1810,18 @@ const rt = 10, xt = (n, t, e, r, i, s) => {
2460
1810
  );
2461
1811
  }
2462
1812
  n.endGraphic();
2463
- }, re = (n, t) => {
1813
+ }, te = (n, t) => {
2464
1814
  if (n.inCreateMask)
2465
1815
  return;
2466
- const { vertices: e, uv: r } = Qt(t);
2467
- St(n, {
1816
+ const { vertices: e, uv: r } = Kt(t);
1817
+ Rt(n, {
2468
1818
  ...t,
2469
1819
  points: e,
2470
1820
  uv: r,
2471
1821
  drawMode: n.gl.TRIANGLES
2472
1822
  });
2473
- }, ie = (n, t) => {
2474
- const e = Z(
1823
+ }, ee = (n, t) => {
1824
+ const e = Q(
2475
1825
  n,
2476
1826
  t,
2477
1827
  t.texture.rawWidth,
@@ -2482,16 +1832,16 @@ const rt = 10, xt = (n, t, e, r, i, s) => {
2482
1832
  t.texture,
2483
1833
  e ?? t.customMatrix
2484
1834
  ), n.addRectVertex(t.texture.rawWidth, t.texture.rawHeight), n.endGraphic();
2485
- }, se = (n, t) => {
2486
- const e = Z(n, t, t.width, t.height);
1835
+ }, re = (n, t) => {
1836
+ const e = Q(n, t, t.width, t.height);
2487
1837
  n.startGraphic(
2488
1838
  n.gl.TRIANGLE_FAN,
2489
1839
  t.texture,
2490
1840
  t.shader,
2491
1841
  e ?? t.customMatrix
2492
1842
  ), n.addRectVertex(t.width, t.height, t.color), n.endGraphic();
2493
- }, ne = (n, t) => {
2494
- const e = t.segments ?? 32, r = Z(n, t, 0, 0);
1843
+ }, ie = (n, t) => {
1844
+ const e = t.segments ?? 32, r = Q(n, t, 0, 0);
2495
1845
  n.startGraphic(
2496
1846
  n.gl.TRIANGLE_FAN,
2497
1847
  void 0,
@@ -2500,7 +1850,7 @@ const rt = 10, xt = (n, t, e, r, i, s) => {
2500
1850
  );
2501
1851
  const i = n.getColorUint32(t.color);
2502
1852
  n.addGraphicVertex(0, 0, 0.5, 0.5, i), n.addCircleVertex(t.radius, t.color, e), n.addGraphicVertex(t.radius, 0, 1, 0.5, i), n.endGraphic();
2503
- }, pt = `#version 300 es\r
1853
+ }, ft = `#version 300 es\r
2504
1854
  precision mediump float;\r
2505
1855
  \r
2506
1856
  uniform sampler2D uTextures[%TEXTURE_NUM%];\r
@@ -2550,21 +1900,21 @@ void main(void) {\r
2550
1900
  // CUSTOM_CODE_CALL\r
2551
1901
  }\r
2552
1902
  `;
2553
- class ae extends ot {
1903
+ class se extends ot {
2554
1904
  KEY = "AtlasSprite";
2555
1905
  constructor(t) {
2556
1906
  super(t);
2557
1907
  }
2558
1908
  createCustomShader(t) {
2559
- const e = V(pt, this.rapid.maxTextureUnits - t.usedTextureUnitNum), r = V(tt, this.rapid.maxTextureUnits - t.usedTextureUnitNum);
1909
+ const e = B(ft, this.rapid.maxTextureUnits - t.usedTextureUnitNum), r = B(Z, this.rapid.maxTextureUnits - t.usedTextureUnitNum);
2560
1910
  return t.getGLShader(this, this.KEY, r, e);
2561
1911
  }
2562
1912
  createDefaultShader() {
2563
- const t = this.rapid, e = V(pt, t.maxTextureUnits), r = V(tt, t.maxTextureUnits);
1913
+ const t = this.rapid, e = B(ft, t.maxTextureUnits), r = B(Z, t.maxTextureUnits);
2564
1914
  return this.vs = r, this.fs = e, this.defaultShader = this.createShader(r, e), this.defaultShader;
2565
1915
  }
2566
1916
  }
2567
- const gt = `#version 300 es\r
1917
+ const mt = `#version 300 es\r
2568
1918
  precision highp float;\r
2569
1919
  \r
2570
1920
  // per-vertex\r
@@ -2605,7 +1955,7 @@ void main(void) {\r
2605
1955
  \r
2606
1956
  gl_Position = u_projection * vec4(v, 0.0, 1.0);\r
2607
1957
  }\r
2608
- `, vt = `#version 300 es\r
1958
+ `, xt = `#version 300 es\r
2609
1959
  precision mediump float;\r
2610
1960
  \r
2611
1961
  uniform sampler2D uTexture;\r
@@ -2621,19 +1971,20 @@ void main(void) {\r
2621
1971
  \r
2622
1972
  // CUSTOM_CODE_CALL\r
2623
1973
  }\r
2624
- `, Y = 48, yt = Y / 4;
2625
- class he extends ot {
1974
+ `, G = 48, ne = G / 4;
1975
+ class ae extends ot {
2626
1976
  KEY = "ParticleSprite";
2627
1977
  texture;
2628
1978
  customMatrix;
1979
+ particleLoopCache = /* @__PURE__ */ new Map();
2629
1980
  constructor(t) {
2630
1981
  super(t);
2631
1982
  }
2632
1983
  createCustomShader(t) {
2633
- return t.getGLShader(this, this.KEY, gt, vt);
1984
+ return t.getGLShader(this, this.KEY, mt, xt);
2634
1985
  }
2635
1986
  createDefaultShader() {
2636
- const t = vt, e = gt;
1987
+ const t = xt, e = mt;
2637
1988
  return this.vs = e, this.fs = t, this.defaultShader = this.createShader(e, t), this.defaultShader;
2638
1989
  }
2639
1990
  enter(t) {
@@ -2642,52 +1993,113 @@ class he extends ot {
2642
1993
  createShader(t, e) {
2643
1994
  const r = super.createShader(t, e);
2644
1995
  return r.use(), r.bindVAO(), this.instanceBuffer.bindBuffer(), r.setAttributes([
2645
- { name: "aPosition", size: 2, stride: Y, offset: 0, divisor: 1 },
2646
- { name: "aScale", size: 2, stride: Y, offset: 8, divisor: 1 },
2647
- { name: "aRotation", size: 1, stride: Y, offset: 16, divisor: 1 },
2648
- { name: "aUVRect", size: 4, stride: Y, offset: 20, divisor: 1 },
2649
- { name: "aColor", size: 4, type: at, normalized: !0, stride: Y, offset: 36, divisor: 1 },
2650
- { name: "aOrigin", size: 2, stride: Y, offset: 40, divisor: 1 }
1996
+ { name: "aPosition", size: 2, stride: G, offset: 0, divisor: 1 },
1997
+ { name: "aScale", size: 2, stride: G, offset: 8, divisor: 1 },
1998
+ { name: "aRotation", size: 1, stride: G, offset: 16, divisor: 1 },
1999
+ { name: "aUVRect", size: 4, stride: G, offset: 20, divisor: 1 },
2000
+ { name: "aColor", size: 4, type: at, normalized: !0, stride: G, offset: 36, divisor: 1 },
2001
+ { name: "aOrigin", size: 2, stride: G, offset: 40, divisor: 1 }
2651
2002
  ]), this.quadBuffer.bindBuffer(), r.setAttributes([
2652
2003
  { name: "aVertex", size: 2, stride: 8, offset: 0, divisor: 0 }
2653
2004
  ]), r.unbindVAO(), this.currentShader && this.currentShader.use(), r;
2654
2005
  }
2655
- drawParticles(t, e, r, i = 0, s = 4294967295, a, o = 1, h = 1, c = 0, u = 0, l = 1, d = 1, f = !1, m = !1, v = !1, y = 0.5, T = 0.5, M, A = !1, P) {
2006
+ drawParticles(t, e, r, i = 0, s = 4294967295, a, h = 1, o = 1, c = 0, u = 0, l = 1, d = 1, f = !1, m = !1, g = !1, v = 0.5, y = 0.5, w, M = !1, _) {
2656
2007
  if (!t.glTexture || a <= 0) return;
2657
- let C = 0;
2658
- const F = typeof o == "number", W = typeof h == "number", N = typeof i == "number", w = typeof s == "number", U = typeof c == "number", X = !w && typeof s[0] == "number";
2659
- let k = t.rawWidth * (f ? -1 : 1);
2660
- F && (k *= o);
2661
- let G = t.rawHeight * (m ? -1 : 1);
2662
- W && (G *= h), U && (G *= d - u, k *= l - c);
2663
- let I = v ? Math.PI / 2 : 0;
2664
- for (N && (I += i); C < a; ) {
2665
- this.texture && t !== this.texture && this.flush(), this.texture || (this.texture = t, this.useTexture(t.glTexture, 0, 0));
2666
- const B = a - C, H = this.instanceBuffer;
2667
- let R = H.usedElemNum;
2668
- H.resize(B * yt);
2669
- const g = H.float32, S = H.uint32;
2670
- for (let J = 0; J < B; J++) {
2671
- const D = A ? a - 1 - C - J : C + J;
2672
- if (g[R] = e[D], g[R + 1] = r[D], g[R + 2] = F ? k : k * o[D], g[R + 3] = W ? G : G * h[D], g[R + 4] = N ? I : i[D] + I, U)
2673
- g[R + 5] = c, g[R + 6] = u, g[R + 7] = l, g[R + 8] = d;
2674
- else {
2675
- const j = c[D], ct = u[D], ut = l[D], lt = d[D];
2676
- g[R + 5] = j, g[R + 6] = ct, g[R + 7] = ut, g[R + 8] = lt, g[R + 2] *= lt - ct, g[R + 3] *= ut - j;
2677
- }
2678
- if (w)
2679
- S[R + 9] = 4294967295;
2680
- else if (X)
2681
- S[R + 9] = s[D];
2682
- else {
2683
- const j = s[D];
2684
- S[R + 9] = M ? j.premultipliedUint32 : j.uint32;
2685
- }
2686
- g[R + 10] = y, g[R + 11] = T, R += yt;
2687
- }
2688
- H.usedElemNum = R, H.makeDirty(), this.instanceCount += B, C += B;
2689
- }
2690
- this.customMatrix = P, this.flush();
2008
+ this.texture && t !== this.texture && this.flush();
2009
+ const P = typeof h == "number", O = typeof o == "number", W = typeof i == "number", b = typeof s == "number", R = typeof c == "number", C = !b && typeof s[0] == "number", D = t.uvW - t.uvX, k = t.uvH - t.uvY, H = D === 0 ? 0 : 1 / D, I = k === 0 ? 0 : 1 / k;
2010
+ let F = t.rawWidth * (f ? -1 : 1);
2011
+ P && (F *= h);
2012
+ let Y = t.rawHeight * (m ? -1 : 1);
2013
+ O && (Y *= o), R && (F *= (l - c) * H, Y *= (d - u) * I);
2014
+ let z = g ? Math.PI / 2 : 0;
2015
+ W && (z += i);
2016
+ const E = s ?? 4294967295, U = this.getParticleLoop(
2017
+ P,
2018
+ O,
2019
+ W,
2020
+ R,
2021
+ b,
2022
+ C,
2023
+ M,
2024
+ w
2025
+ );
2026
+ this.texture || (this.texture = t, this.useTexture(t.glTexture, 0, 0));
2027
+ const tt = a, X = this.instanceBuffer;
2028
+ let et = X.usedElemNum;
2029
+ X.resize(tt * ne);
2030
+ const Mt = X.float32, St = X.uint32;
2031
+ et = U(
2032
+ e,
2033
+ r,
2034
+ h,
2035
+ o,
2036
+ i,
2037
+ c,
2038
+ u,
2039
+ l,
2040
+ d,
2041
+ s,
2042
+ Mt,
2043
+ St,
2044
+ F,
2045
+ Y,
2046
+ H,
2047
+ I,
2048
+ z,
2049
+ E,
2050
+ v,
2051
+ y,
2052
+ a,
2053
+ tt,
2054
+ et
2055
+ ), X.usedElemNum = et, X.makeDirty(), this.instanceCount += tt, this.customMatrix = _, this.flush();
2056
+ }
2057
+ getParticleLoop(t, e, r, i, s, a, h, o) {
2058
+ const c = [...arguments].join("_");
2059
+ if (this.particleLoopCache.has(c))
2060
+ return this.particleLoopCache.get(c);
2061
+ let u = `
2062
+ return function( x, y, scaleX, scaleY, rotation, u0, v0, u1, v1, color, f32, u32, rawWidth, rawHeight, uv2texW, uv2texH, rotationOffset, staticColor, originX, originY, count, batchCount, index ) {
2063
+ ${t && i ? "const baseSx = rawWidth;" : ""}
2064
+ ${e && i ? "const baseSy = rawHeight;" : ""}
2065
+
2066
+ const endIdx = index + batchCount * 12;
2067
+ let idx = index;
2068
+ if (endIdx > f32.length) return index;
2069
+
2070
+ ${h ? "for (let src = count - 1; idx < endIdx; src--, idx += 12) {" : "for (let src = 0; idx < endIdx; src++, idx += 12) {"}
2071
+ f32[idx] = x[src];
2072
+ f32[idx + 1] = y[src];
2073
+
2074
+ ${i ? `
2075
+ f32[idx + 2] = ${t ? "baseSx" : "rawWidth * scaleX[src]"};
2076
+ f32[idx + 3] = ${e ? "baseSy" : "rawHeight * scaleY[src]"};
2077
+ f32[idx + 4] = ${r ? "rotationOffset" : "rotation[src] + rotationOffset"};
2078
+ f32[idx + 5] = u0;
2079
+ f32[idx + 6] = v0;
2080
+ f32[idx + 7] = u1;
2081
+ f32[idx + 8] = v1;
2082
+ ` : `
2083
+ const cu0 = u0[src], cv0 = v0[src], cu1 = u1[src], cv1 = v1[src];
2084
+ f32[idx + 2] = (rawWidth * (cu1 - cu0) * uv2texW) ${t ? "" : "* scaleX[src]"};
2085
+ f32[idx + 3] = (rawHeight * (cv1 - cv0) * uv2texH) ${e ? "" : "* scaleY[src]"};
2086
+ f32[idx + 4] = ${r ? "rotationOffset" : "rotation[src] + rotationOffset"};
2087
+ f32[idx + 5] = cu0;
2088
+ f32[idx + 6] = cv0;
2089
+ f32[idx + 7] = cu1;
2090
+ f32[idx + 8] = cv1;
2091
+ `}
2092
+
2093
+ u32[idx + 9] = ${s ? "staticColor" : a ? "color[src]" : `color[src].${o ? "premultipliedUint32" : "uint32"}`};
2094
+
2095
+ f32[idx + 10] = originX;
2096
+ f32[idx + 11] = originY;
2097
+ }
2098
+ return idx;
2099
+ }
2100
+ `;
2101
+ const l = new Function(u)();
2102
+ return this.particleLoopCache.set(c, l), l;
2691
2103
  }
2692
2104
  render() {
2693
2105
  if (this.instanceCount === 0) return;
@@ -2696,186 +2108,106 @@ class he extends ot {
2696
2108
  this.texture && (t.activeTexture(t.TEXTURE0), t.bindTexture(t.TEXTURE_2D, this.texture.glTexture));
2697
2109
  const e = this.currentShader;
2698
2110
  this.instanceBuffer.bindBuffer(), this.instanceBuffer.bufferData(), e.bindVAO();
2699
- const r = this.rapid.matrixStack, s = this.rapid.matrix.getMatrix(this.customMatrix ?? r.curWorldM), a = jt(this.rapid.projection, s);
2700
- this.currentShader.setUniform("u_projection", a), Mt(t, t.TRIANGLE_STRIP, 0, 4, this.instanceCount), this.rapid.drawcallCount++, this.texture = void 0, this.customMatrix = void 0;
2111
+ const r = this.rapid.matrixStack, s = this.rapid.matrix.getMatrix(this.customMatrix ?? r.curWorldM), a = Xt(this.rapid.projection, s);
2112
+ this.currentShader.setUniform("u_projection", a), yt(t, t.TRIANGLE_STRIP, 0, 4, this.instanceCount), this.rapid.drawcallCount++, this.texture = void 0, this.customMatrix = void 0;
2701
2113
  }
2702
2114
  }
2703
- var oe = /* @__PURE__ */ ((n) => (n[n.EQUAL = 0] = "EQUAL", n[n.NOT_EQUAL = 1] = "NOT_EQUAL", n))(oe || {}), ce = /* @__PURE__ */ ((n) => (n[n.NORMAL = 0] = "NORMAL", n[n.ADD = 1] = "ADD", n[n.MULTIPLY = 2] = "MULTIPLY", n[n.SCREEN = 3] = "SCREEN", n[n.ERASE = 4] = "ERASE", n))(ce || {}), ht = /* @__PURE__ */ ((n) => (n[n.LINEAR = 0] = "LINEAR", n[n.NEAREST = 1] = "NEAREST", n))(ht || {}), ue = /* @__PURE__ */ ((n) => (n[n.CanvasItem = 0] = "CanvasItem", n[n.Viewport = 1] = "Viewport", n))(ue || {});
2704
- class fe {
2705
- /** The active WebGL context. */
2115
+ var he = /* @__PURE__ */ ((n) => (n[n.EQUAL = 0] = "EQUAL", n[n.NOT_EQUAL = 1] = "NOT_EQUAL", n))(he || {}), oe = /* @__PURE__ */ ((n) => (n[n.NORMAL = 0] = "NORMAL", n[n.ADD = 1] = "ADD", n[n.MULTIPLY = 2] = "MULTIPLY", n[n.SCREEN = 3] = "SCREEN", n[n.ERASE = 4] = "ERASE", n))(oe || {}), ht = /* @__PURE__ */ ((n) => (n[n.LINEAR = 0] = "LINEAR", n[n.NEAREST = 1] = "NEAREST", n))(ht || {}), ce = /* @__PURE__ */ ((n) => (n[n.CanvasItem = 0] = "CanvasItem", n[n.Viewport = 1] = "Viewport", n))(ce || {});
2116
+ class de {
2706
2117
  gl;
2707
- /** The target HTMLCanvasElement. */
2708
2118
  canvas;
2709
- /** The current orthographic projection matrix (16 elements). */
2710
2119
  projection = new Float32Array(16);
2711
- /** Indicates if the projection matrix has changed and needs to be uploaded to shaders. */
2712
2120
  projectionDirty = !0;
2713
- /** The current device pixel ratio. */
2714
2121
  dpr;
2715
- /** Background clear color [r, g, b, a], values range from 0 to 255. */
2716
2122
  backgroundColor = x.Black;
2717
- /** Logical width in CSS pixels, used for coordinate system and projection matrix. */
2718
2123
  logicWidth = 0;
2719
- /** Logical height in CSS pixels, used for coordinate system and projection matrix. */
2720
2124
  logicHeight = 0;
2721
- /** Physical width (canvas actual pixels = logical width * dpr). */
2722
2125
  physicsWidth = 0;
2723
- /** Physical height (canvas actual pixels = logical height * dpr). */
2724
2126
  physicsHeight = 0;
2725
- /** The currently active rendering region. */
2726
2127
  currentRegion = null;
2727
- /** Maximum number of texture units supported by the device. */
2728
2128
  maxTextureUnits = 0;
2729
- /** Matrix stack for hierarchical transformations. */
2730
- matrixStack = new Ct(this);
2731
- /** Direct access to the underlying matrix store. */
2129
+ matrixStack = new bt(this);
2732
2130
  matrix;
2733
- /** Region dedicated to fast sprite rendering. */
2734
2131
  spriteRegion;
2735
- /** Region dedicated to arbitrary geometry and shapes rendering. */
2736
2132
  graphicRegion;
2737
2133
  atlasSpriteRegion;
2738
2134
  particleRegion;
2739
- /** Counts the number of WebGL draw calls made in the current frame. */
2740
2135
  drawcallCount = 0;
2741
- /** Indicates whether we are currently writing to the stencil buffer to create a mask. */
2742
2136
  inCreateMask = !1;
2743
- /** Manager for creating and organizing textures. */
2744
2137
  texture;
2745
- /** Whether textures use premultiplied alpha. Set once at construction. */
2746
2138
  premultipliedAlpha;
2747
- /** Default texture filtering preference and requested canvas MSAA setting. */
2748
2139
  antialias;
2749
2140
  roundPixels;
2750
- /** Default filtering mode used when sampling textures. */
2751
2141
  textureFilter;
2752
2142
  scaleMode;
2753
- /** Internal ping-pong RenderTextures for multi-filter chains. */
2754
2143
  _filterRT = [null, null];
2755
- _filterInput = new O();
2144
+ _filterInput = new N();
2756
2145
  get height() {
2757
2146
  return this.logicHeight;
2758
2147
  }
2759
2148
  get width() {
2760
2149
  return this.logicWidth;
2761
2150
  }
2762
- /**
2763
- * Creates a new Rapid application instance.
2764
- * @param options Initialization options including the target canvas.
2765
- */
2766
2151
  constructor(t) {
2767
2152
  this.canvas = t.canvas, this.dpr = window.devicePixelRatio || 1, this.antialias = t.antialias ?? !1, this.textureFilter = t.textureFilter ?? 1, this.premultipliedAlpha = t.premultipliedAlpha ?? !0, this.roundPixels = t.roundPixels ?? !1, this.scaleMode = t.scaleMode ?? 0;
2768
- const e = It(this.canvas, this.antialias, this.premultipliedAlpha);
2769
- this.gl = e, this.maxTextureUnits = e.getParameter(e.MAX_TEXTURE_IMAGE_UNITS), this.matrix = this.matrixStack.matrix, this.spriteRegion = new ot(this), this.graphicRegion = new Xt(this), this.atlasSpriteRegion = new ae(this), this.particleRegion = new he(this);
2153
+ const e = Lt(this.canvas, this.antialias, this.premultipliedAlpha);
2154
+ this.gl = e, this.maxTextureUnits = e.getParameter(e.MAX_TEXTURE_IMAGE_UNITS), this.matrix = this.matrixStack.matrix, this.spriteRegion = new ot(this), this.graphicRegion = new Yt(this), this.atlasSpriteRegion = new se(this), this.particleRegion = new ae(this);
2770
2155
  const r = this.canvas.clientWidth || this.canvas.width, i = this.canvas.clientHeight || this.canvas.height;
2771
- this.physicsWidth = t.physicsWidth || Math.round(r * this.dpr), this.physicsHeight = t.physicsHeight || Math.round(i * this.dpr), this.logicWidth = t.logicWidth || t.width || this.physicsWidth / this.dpr, this.logicHeight = t.logicHeight || t.height || this.physicsHeight / this.dpr, this.resize(this.logicWidth, this.logicHeight, this.physicsWidth, this.physicsHeight), this.texture = new _t(this), t.backgroundColor && (this.backgroundColor = t.backgroundColor), e.enable(e.BLEND), this.premultipliedAlpha ? e.blendFunc(e.ONE, e.ONE_MINUS_SRC_ALPHA) : e.blendFunc(e.SRC_ALPHA, e.ONE_MINUS_SRC_ALPHA), e.enable(e.STENCIL_TEST), e.stencilFunc(e.ALWAYS, 1, 255), e.stencilOp(e.KEEP, e.KEEP, e.KEEP);
2156
+ this.physicsWidth = t.physicsWidth || Math.round(r * this.dpr), this.physicsHeight = t.physicsHeight || Math.round(i * this.dpr), this.logicWidth = t.logicWidth || t.width || this.physicsWidth / this.dpr, this.logicHeight = t.logicHeight || t.height || this.physicsHeight / this.dpr, this.resize(this.logicWidth, this.logicHeight, this.physicsWidth, this.physicsHeight), this.texture = new Ut(this), t.backgroundColor && (this.backgroundColor = t.backgroundColor), e.enable(e.BLEND), this.premultipliedAlpha ? e.blendFunc(e.ONE, e.ONE_MINUS_SRC_ALPHA) : e.blendFunc(e.SRC_ALPHA, e.ONE_MINUS_SRC_ALPHA), e.enable(e.STENCIL_TEST), e.stencilFunc(e.ALWAYS, 1, 255), e.stencilOp(e.KEEP, e.KEEP, e.KEEP);
2772
2157
  }
2773
2158
  setTextureFilter(t) {
2774
2159
  this.textureFilter = t;
2775
2160
  }
2776
- setAntialias(t) {
2777
- this.antialias = t;
2778
- }
2779
2161
  getColorUint32(t) {
2780
- return Zt(this.premultipliedAlpha, t);
2162
+ return qt(this.premultipliedAlpha, t);
2781
2163
  }
2782
- /**
2783
- * Enters a specific rendering region, flushing the previous one if necessary.
2784
- * @param region The rendering region to enter.
2785
- * @param customShader An optional custom shader to use for this region.
2786
- */
2787
2164
  enterRegion(t, e) {
2788
2165
  this.currentRegion === t && this.currentRegion.isSameShader(e) || (this.flush(), this.currentRegion = t, t.enter(e));
2789
2166
  }
2790
2167
  drawParticles(t) {
2791
- ee(this, t);
2168
+ Jt(this, t);
2792
2169
  }
2793
2170
  drawSprite(t) {
2794
- te(this, t);
2171
+ Zt(this, t);
2795
2172
  }
2796
2173
  drawLine(t) {
2797
- re(this, t);
2174
+ te(this, t);
2798
2175
  }
2799
2176
  drawGraphic(t) {
2800
- St(this, t);
2177
+ Rt(this, t);
2801
2178
  }
2802
2179
  drawRect(t) {
2803
- se(this, t);
2180
+ re(this, t);
2804
2181
  }
2805
2182
  drawCircle(t) {
2806
- ne(this, t);
2807
- }
2808
- /**
2809
- * Starts rendering arbitrary graphics geometries.
2810
- * @param drawMode The WebGL drawing mode (e.g., gl.TRIANGLES, gl.TRIANGLE_FAN).
2811
- * @param texture An optional texture applied to the graphic vertices.
2812
- * @param customShader An optional custom shader overriding the region's default shader.
2813
- */
2183
+ ie(this, t);
2184
+ }
2814
2185
  startGraphic(t = this.gl.TRIANGLES, e, r, i) {
2815
2186
  this.enterRegion(this.graphicRegion, r), this.graphicRegion.startGraphic(i ?? this.matrixStack.curWorldM, t, e);
2816
2187
  }
2817
- /**
2818
- * Starts rendering graphics explicitly for use as a mask, overriding the shader.
2819
- * @param drawMode The WebGL drawing mode (e.g., gl.TRIANGLES).
2820
- * @param texture An optional texture whose alpha channel may dictate masking rules.
2821
- */
2822
2188
  startMaskGraphic(t = this.gl.TRIANGLES, e, r) {
2823
2189
  this.startGraphic(t, e, this.graphicRegion.maskShader, r);
2824
2190
  }
2825
- /**
2826
- * Utility method: Draws an image directly as a mask using a generic rectangle geometry.
2827
- * @param texture The texture to be used as a mask.
2828
- */
2829
2191
  drawMaskImage(t) {
2830
- ie(this, t);
2192
+ ee(this, t);
2831
2193
  }
2832
- /**
2833
- * Pushes vertices for a rectangle geometry. Should be enclosed by startGraphic and endGraphic.
2834
- * @param w The width of the rectangle.
2835
- * @param h The height of the rectangle.
2836
- * @param color An optional tint color.
2837
- */
2838
2194
  addRectVertex(t, e, r) {
2839
2195
  const i = this.getColorUint32(r);
2840
2196
  this.addGraphicVertex(0, 0, 0, 0, i), this.addGraphicVertex(t, 0, 1, 0, i), this.addGraphicVertex(t, e, 1, 1, i), this.addGraphicVertex(0, e, 0, 1, i);
2841
2197
  }
2842
- /**
2843
- * Pushes vertices for a circle geometry using TRIANGLES or similar primitives.
2844
- * @param r The radius of the circle.
2845
- * @param color An optional tint color.
2846
- * @param segments The number of segments (polygons) used to approximate the circle.
2847
- */
2848
2198
  addCircleVertex(t, e, r = 32) {
2849
2199
  const i = Math.PI * 2 / r, s = this.getColorUint32(e);
2850
2200
  for (let a = 0; a < r; a++) {
2851
- const o = i * a, h = Math.cos(o) * t, c = Math.sin(o) * t, u = 0.5 + Math.cos(o) * 0.5, l = 0.5 + Math.sin(o) * 0.5;
2852
- this.addGraphicVertex(h, c, u, l, s);
2201
+ const h = i * a, o = Math.cos(h) * t, c = Math.sin(h) * t, u = 0.5 + Math.cos(h) * 0.5, l = 0.5 + Math.sin(h) * 0.5;
2202
+ this.addGraphicVertex(o, c, u, l, s);
2853
2203
  }
2854
2204
  }
2855
- /**
2856
- * Adds an individual vertex to the current graphics batch.
2857
- * @param x The relative X coordinate of the vertex.
2858
- * @param y The relative Y coordinate of the vertex.
2859
- * @param u The U texture coordinate (0 to 1).
2860
- * @param v The V texture coordinate (0 to 1).
2861
- * @param color The vertex color as a 32-bit unsigned integer.
2862
- */
2863
2205
  addGraphicVertex(t, e, r = 0, i = 0, s) {
2864
2206
  this.graphicRegion.addVertex(t, e, r, i, typeof s == "number" ? s : this.getColorUint32(s));
2865
2207
  }
2866
- /**
2867
- * Ends the current graphics geometry definition, readying it for rendering.
2868
- */
2869
2208
  endGraphic() {
2870
2209
  this.graphicRegion.endGraphic();
2871
2210
  }
2872
- /**
2873
- * Resizes the canvas, updates internal viewport values, and recreates projection boundaries.
2874
- * @param logicWidth The new logical display width.
2875
- * @param logicHeight The new logical display height.
2876
- * @param cssWidth Optional CSS display width.
2877
- * @param cssHeight Optional CSS display height.
2878
- */
2879
2211
  resize(t, e, r, i) {
2880
2212
  this.flush();
2881
2213
  const s = r ?? this.canvas.clientWidth ?? this.canvas.width, a = i ?? this.canvas.clientHeight ?? this.canvas.height;
@@ -2891,100 +2223,51 @@ class fe {
2891
2223
  }
2892
2224
  this.updateProjection(0, this.logicWidth, this.logicHeight, 0);
2893
2225
  }
2894
- /**
2895
- * Updates the projection matrix using an orthographic mapping.
2896
- * Automatically sets local flag projectionDirty.
2897
- */
2898
2226
  updateProjection(t, e, r, i) {
2899
2227
  this.updateOrthMatrix(this.projection, t, e, r, i), this.projectionDirty = !0;
2900
2228
  }
2901
- /**
2902
- * Clears the active framebuffer applying the default background color.
2903
- */
2904
2229
  clear() {
2905
2230
  const t = this.gl;
2906
2231
  this.backgroundColor.setClearColor(t), t.clear(t.COLOR_BUFFER_BIT | t.STENCIL_BUFFER_BIT), this.drawcallCount = 0, this.matrixStack.reset();
2907
2232
  }
2908
- /**
2909
- * Populates an orthographic projection matrix in place.
2910
- * Avoids continuous Float32Array allocations for performance reasons.
2911
- */
2912
2233
  updateOrthMatrix(t, e, r, i, s) {
2913
2234
  t[0] = 2 / (r - e), t[1] = 0, t[2] = 0, t[3] = 0, t[4] = 0, t[5] = 2 / (s - i), t[6] = 0, t[7] = 0, t[8] = 0, t[9] = 0, t[10] = -1, t[11] = 0, t[12] = -(r + e) / (r - e), t[13] = -(s + i) / (s - i), t[14] = 0, t[15] = 1;
2914
2235
  }
2915
- /**
2916
- * Flushes currently buffered rendering operations across all active regions.
2917
- */
2918
2236
  flush() {
2919
2237
  this.currentRegion && (this.currentRegion.exit(), this.currentRegion = null);
2920
2238
  }
2921
- /**
2922
- * Applies a chain of shaders to a texture sequentially using ping-pong RenderTextures.
2923
- * Each shader receives the output of the previous one as its input.
2924
- * Two internal RenderTextures are reused across calls (resized as needed).
2925
- *
2926
- * @param source The input texture to start the filter chain from.
2927
- * @param shaders An ordered array of CustomGlShader to apply in sequence.
2928
- * @returns The RenderTexture containing the final filtered result.
2929
- * Draw it with `rapid.drawSprite({ texture: result })` to display it on screen.
2930
- *
2931
- * @example
2932
- * const result = rapid.applyFilters(tex, [blurShader, outlineShader]);
2933
- * rapid.drawSprite({ texture: result });
2934
- */
2935
2239
  applyFilters(t, e) {
2936
2240
  if (e.length === 0)
2937
2241
  throw new Error("applyFilters: shaders array must not be empty.");
2938
2242
  const r = Math.max(...e.map((c) => c.padding)), i = r, s = t.rawWidth + r * 2, a = t.rawHeight + r * 2;
2939
2243
  for (let c = 0; c < 2; c++)
2940
2244
  this._filterRT[c] ? this._filterRT[c].resize(s, a) : this._filterRT[c] = this.texture.createRenderTexture({ width: s, height: a });
2941
- let o = t.clone(this._filterInput), h = 0;
2245
+ let h = t.clone(this._filterInput), o = 0;
2942
2246
  this.matrixStack.save(), this.matrixStack.identity();
2943
2247
  for (let c = 0; c < e.length; c++) {
2944
- const u = this._filterRT[h % 2];
2248
+ const u = this._filterRT[o % 2];
2945
2249
  u.offsetX = 0, u.offsetY = 0, this.enterRenderTexture(u), this.clearRenderTexture(), this.drawSprite({
2946
- texture: o,
2250
+ texture: h,
2947
2251
  shader: e[c],
2948
2252
  offsetX: c == 0 ? i : 0,
2949
2253
  // padding back
2950
2254
  offsetY: c == 0 ? i : 0,
2951
2255
  padding: r
2952
- }), this.leaveRenderTexture(), o = u, h++;
2256
+ }), this.leaveRenderTexture(), h = u, o++;
2953
2257
  }
2954
- return this.matrixStack.restore(), o.offsetX = -i, o.offsetY = -i, o;
2258
+ return this.matrixStack.restore(), h.offsetX = -i, h.offsetY = -i, h;
2955
2259
  }
2956
2260
  enterRenderTexture(t) {
2957
2261
  this.flush(), t.activate(), this.gl.viewport(0, 0, t.rawWidth, t.rawHeight), this.updateProjection(0, t.rawWidth, t.rawHeight, 0);
2958
2262
  }
2959
- /**
2960
- * Clears a RenderTexture to a solid color.
2961
- * Must be called while the RT is the active render target (i.e. inside enterRenderTexture/leaveRenderTexture).
2962
- * Can also be called standalone — it will bind the RT, clear it, but NOT restore the main framebuffer.
2963
- * @param rt The render texture to clear.
2964
- * @param color Clear color. Defaults to transparent black (0, 0, 0, 0).
2965
- */
2966
2263
  clearRenderTexture(t = new x(0, 0, 0, 0)) {
2967
2264
  this.flush();
2968
2265
  const e = this.gl;
2969
2266
  t.setClearColor(e), e.clear(e.COLOR_BUFFER_BIT);
2970
2267
  }
2971
- /**
2972
- * Completes rendering to an offscreen render texture and reverts rendering back to the main canvas.
2973
- */
2974
2268
  leaveRenderTexture() {
2975
2269
  this.flush(), this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null), this.gl.viewport(0, 0, this.physicsWidth, this.physicsHeight), this.updateProjection(0, this.logicWidth, this.logicHeight, 0);
2976
2270
  }
2977
- /**
2978
- * Convenience wrapper: enters a RenderTexture, optionally clears it, runs a callback, then leaves.
2979
- * @param rt The RenderTexture to render into.
2980
- * @param cb The callback containing draw calls to execute inside the RT.
2981
- * @param color Clear color before rendering. Pass `null` to skip clearing. Defaults to transparent black.
2982
- *
2983
- * @example
2984
- * rapid.drawToRenderTexture(myRT, () => {
2985
- * rapid.drawSprite({ texture: mySprite });
2986
- * });
2987
- */
2988
2271
  drawToRenderTexture(t, e, r = new x(0, 0, 0, 0)) {
2989
2272
  this.enterRenderTexture(t);
2990
2273
  try {
@@ -2993,19 +2276,6 @@ class fe {
2993
2276
  this.leaveRenderTexture();
2994
2277
  }
2995
2278
  }
2996
- /**
2997
- * Convenience wrapper: writes a mask using the stencil buffer, then renders within it, then exits the mask.
2998
- * @param maskCb Callback that defines the mask geometry (drawn to stencil, not visible).
2999
- * @param drawCb Callback containing the actual draw calls masked by the stencil.
3000
- * @param type Mask type: EQUAL (draw inside) or NOT_EQUAL (draw outside). Defaults to EQUAL.
3001
- * @param ref Stencil reference value. Defaults to 1.
3002
- *
3003
- * @example
3004
- * rapid.withMask(
3005
- * () => rapid.drawRect({ width: 200, height: 200 }),
3006
- * () => rapid.drawSprite({ texture: myTexture }),
3007
- * );
3008
- */
3009
2279
  withMask(t, e, r = 0, i = 1) {
3010
2280
  this.clearMask(), this.startDrawMask(i);
3011
2281
  try {
@@ -3020,28 +2290,6 @@ class fe {
3020
2290
  this.exitMask();
3021
2291
  }
3022
2292
  }
3023
- /**
3024
- * Convenience wrapper: saves the matrix stack, applies an optional transform, runs a callback, then restores.
3025
- * When `transform` is provided, delegates to `matrixStack.applyTransform()` which handles
3026
- * position, rotation, scale, offset, and origin automatically.
3027
- * @param cb The callback to execute within the saved transform context.
3028
- * @param transform Optional transform options to apply before running the callback.
3029
- * @param width The logical width used to resolve `origin` anchoring. Defaults to 0.
3030
- * @param height The logical height used to resolve `origin` anchoring. Defaults to 0.
3031
- *
3032
- * @example
3033
- * // Simple save/restore
3034
- * rapid.withTransform(() => {
3035
- * rapid.matrixStack.translate(100, 100);
3036
- * rapid.drawSprite({ texture: myTexture });
3037
- * });
3038
- *
3039
- * @example
3040
- * // With a transform applied
3041
- * rapid.withTransform(() => {
3042
- * rapid.drawSprite({ texture: myTexture });
3043
- * }, { x: 100, y: 50, rotation: Math.PI / 4, origin: 0.5 }, myTexture.width, myTexture.height);
3044
- */
3045
2293
  withTransform(t, e, r = 0, i = 0) {
3046
2294
  this.matrixStack.save();
3047
2295
  try {
@@ -3050,19 +2298,6 @@ class fe {
3050
2298
  this.matrixStack.restore();
3051
2299
  }
3052
2300
  }
3053
- /**
3054
- * Convenience wrapper: enables scissor clipping for a region, runs a callback, then disables it.
3055
- * @param x Left edge in logical pixels.
3056
- * @param y Top edge in logical pixels.
3057
- * @param width Width in logical pixels.
3058
- * @param height Height in logical pixels.
3059
- * @param cb The callback to execute within the scissor region.
3060
- *
3061
- * @example
3062
- * rapid.withScissor(50, 50, 300, 200, () => {
3063
- * rapid.drawSprite({ texture: myTexture });
3064
- * });
3065
- */
3066
2301
  withScissor(t, e, r, i, s) {
3067
2302
  this.startScissor(t, e, r, i);
3068
2303
  try {
@@ -3071,16 +2306,6 @@ class fe {
3071
2306
  this.endScissor();
3072
2307
  }
3073
2308
  }
3074
- /**
3075
- * Convenience wrapper: sets a blend mode, runs a callback, then restores NORMAL blend mode.
3076
- * @param mode The BlendMode to apply for the duration of the callback.
3077
- * @param cb The callback to execute under the given blend mode.
3078
- *
3079
- * @example
3080
- * rapid.withBlendMode(BlendMode.ADD, () => {
3081
- * rapid.drawSprite({ texture: glowTexture });
3082
- * });
3083
- */
3084
2309
  withBlendMode(t, e) {
3085
2310
  this.setBlendMode(t);
3086
2311
  try {
@@ -3092,56 +2317,31 @@ class fe {
3092
2317
  );
3093
2318
  }
3094
2319
  }
3095
- /**
3096
- * Starts drawing into the stencil buffer to construct a rendering mask.
3097
- * @param ref The stencil reference value.
3098
- * @param mask The stencil bitmask.
3099
- */
3100
2320
  startDrawMask(t = 1, e = 255) {
3101
2321
  this.flush();
3102
2322
  const r = this.gl;
3103
2323
  r.stencilMask(e), r.colorMask(!1, !1, !1, !1), r.stencilFunc(r.ALWAYS, t, e), r.stencilOp(r.KEEP, r.KEEP, r.REPLACE), this.enterRegion(this.graphicRegion, this.graphicRegion.maskShader), this.inCreateMask = !0;
3104
2324
  }
3105
- /**
3106
- * Finishes the mask drawing phase and restores color buffer writing.
3107
- */
3108
2325
  endDrawMask() {
3109
2326
  this.flush();
3110
2327
  const t = this.gl;
3111
2328
  t.colorMask(!0, !0, !0, !0), t.stencilMask(0), this.inCreateMask = !1;
3112
2329
  }
3113
- /**
3114
- * Clears bounds created into the stencil mask.
3115
- * @param mask The bitmask specifying which stencil layer to clear.
3116
- */
3117
2330
  clearMask(t = 255) {
3118
2331
  this.flush();
3119
2332
  const e = this.gl;
3120
2333
  e.stencilMask(t), e.clear(e.STENCIL_BUFFER_BIT), this.inCreateMask = !1;
3121
2334
  }
3122
- /**
3123
- * Enters a constrained rendering phase masked by the existing stencil buffer values.
3124
- * @param type Equality check type. Use "equal" to draw inside the mask, or "notEqual" to draw outside.
3125
- * @param ref The reference value to test against.
3126
- * @param mask The bitmask specifying which stencil bits to consider.
3127
- */
3128
2335
  enterMask(t, e = 1, r = 255) {
3129
2336
  this.flush();
3130
2337
  const i = this.gl;
3131
2338
  i.colorMask(!0, !0, !0, !0), i.stencilMask(0), i.stencilFunc(t === 0 ? i.EQUAL : i.NOTEQUAL, e, r), i.stencilOp(i.KEEP, i.KEEP, i.KEEP), this.inCreateMask = !1;
3132
2339
  }
3133
- /**
3134
- * Exits the masked rendering phase, restoring default full-screen stencil values tests.
3135
- */
3136
2340
  exitMask() {
3137
2341
  this.flush();
3138
2342
  const t = this.gl;
3139
2343
  t.colorMask(!0, !0, !0, !0), t.stencilMask(255), t.stencilFunc(t.ALWAYS, 1, 255), t.stencilOp(t.KEEP, t.KEEP, t.KEEP), this.inCreateMask = !1;
3140
2344
  }
3141
- /**
3142
- * Configures the global WebGL blending behavior.
3143
- * @param mode The targeted BlendMode to switch onto.
3144
- */
3145
2345
  setBlendMode(t) {
3146
2346
  this.flush();
3147
2347
  const e = this.gl;
@@ -3163,23 +2363,11 @@ class fe {
3163
2363
  break;
3164
2364
  }
3165
2365
  }
3166
- /**
3167
- * Enables rectangular scissor clipping. Only pixels within the specified
3168
- * rectangle (in logical coordinates) will be rendered.
3169
- * Coordinates use the same system as your drawing calls (top-left origin).
3170
- * @param x Left edge in logical pixels.
3171
- * @param y Top edge in logical pixels.
3172
- * @param width Width in logical pixels.
3173
- * @param height Height in logical pixels.
3174
- */
3175
2366
  startScissor(t, e, r, i) {
3176
2367
  this.flush();
3177
- const s = this.gl, a = this.physicsWidth / this.logicWidth, o = this.physicsHeight / this.logicHeight, h = Math.round(t * a), c = Math.round(this.physicsHeight - (e + i) * o), u = Math.round(r * a), l = Math.round(i * o);
3178
- s.enable(s.SCISSOR_TEST), s.scissor(h, c, u, l);
2368
+ const s = this.gl, a = this.physicsWidth / this.logicWidth, h = this.physicsHeight / this.logicHeight, o = Math.round(t * a), c = Math.round(this.physicsHeight - (e + i) * h), u = Math.round(r * a), l = Math.round(i * h);
2369
+ s.enable(s.SCISSOR_TEST), s.scissor(o, c, u, l);
3179
2370
  }
3180
- /**
3181
- * Disables scissor clipping, restoring full-canvas rendering.
3182
- */
3183
2371
  endScissor() {
3184
2372
  this.flush(), this.gl.disable(this.gl.SCISSOR_TEST);
3185
2373
  }
@@ -3201,7 +2389,7 @@ class fe {
3201
2389
  ));
3202
2390
  }
3203
2391
  cssToDevicePixel(t) {
3204
- return t.mul(this.dpr);
2392
+ return t.multiply(this.dpr);
3205
2393
  }
3206
2394
  cssToLogic(t) {
3207
2395
  const e = this.cssToDevicePixel(t);
@@ -3210,40 +2398,27 @@ class fe {
3210
2398
  devicePixelToCss(t) {
3211
2399
  return t.divide(this.dpr);
3212
2400
  }
3213
- /**
3214
- * Exports a world matrix as a CSS `matrix(...)` string, ready to assign
3215
- * directly to a DOM element's `style.transform`.
3216
- * Unlike `matrixStack.toCSSMatrix()`, this bakes in the logic-pixel → CSS-pixel
3217
- * scale (accounting for dpr and a custom `logicWidth`/`logicHeight`), so the
3218
- * result lines up with the canvas without any extra `scale(...)` on your end.
3219
- * @param index - Matrix index to export. Defaults to the current world matrix.
3220
- */
3221
2401
  toCSSMatrix(t) {
3222
2402
  const e = this.physicsWidth / this.dpr / this.logicWidth, r = this.physicsHeight / this.dpr / this.logicHeight;
3223
2403
  return this.matrix.toCSSMatrix(t ?? this.matrixStack.curWorldM, e, r);
3224
2404
  }
3225
2405
  }
3226
- function le(n) {
2406
+ function ue(n) {
3227
2407
  return !(n === null || typeof n != "object" || Array.isArray(n) || n instanceof p || n instanceof x);
3228
2408
  }
3229
2409
  class L {
3230
- /** Random float in [min, max). */
3231
2410
  static float(t, e) {
3232
2411
  return Math.random() * (e - t) + t;
3233
2412
  }
3234
- /** Random integer in [min, max] (inclusive). */
3235
2413
  static int(t, e) {
3236
2414
  return Math.floor(Math.random() * (e - t + 1)) + t;
3237
2415
  }
3238
- /** Random angle in [0, 2π). */
3239
2416
  static angle() {
3240
2417
  return Math.random() * Math.PI * 2;
3241
2418
  }
3242
- /** Random Vec2 with components in the supplied per-axis ranges. */
3243
2419
  static vector(t, e, r, i) {
3244
2420
  return new p(L.float(t, e), L.float(r, i));
3245
2421
  }
3246
- /** Random Color with each component interpolated between minColor and maxColor. */
3247
2422
  static randomColor(t, e) {
3248
2423
  return new x(
3249
2424
  L.float(t.r, e.r),
@@ -3252,14 +2427,9 @@ class L {
3252
2427
  L.float(t.a, e.a)
3253
2428
  );
3254
2429
  }
3255
- /** Pick a random element from an array with uniform probability. */
3256
2430
  static pick(t) {
3257
2431
  return t[L.int(0, t.length - 1)];
3258
2432
  }
3259
- /**
3260
- * Pick a random element using weighted probability.
3261
- * @param array - Pairs of [item, weight]. Higher weight = more likely.
3262
- */
3263
2433
  static pickWeight(t) {
3264
2434
  if (!t || t.length === 0) return null;
3265
2435
  let e = 0;
@@ -3269,12 +2439,6 @@ class L {
3269
2439
  if (r -= s, r <= 0) return i;
3270
2440
  return t[t.length - 1][0];
3271
2441
  }
3272
- /**
3273
- * Resolves a scalar-or-range value to a concrete T.
3274
- * - `undefined` → `defaultValue`
3275
- * - `T` → `T` (or a clone for objects)
3276
- * - `[T, T]` → random value between the two bounds
3277
- */
3278
2442
  static scalarOrRange(t, e) {
3279
2443
  if (t == null) return e;
3280
2444
  if (Array.isArray(t)) {
@@ -3289,17 +2453,17 @@ class L {
3289
2453
  return typeof t == "number" ? t : t.clone();
3290
2454
  }
3291
2455
  }
3292
- var de = /* @__PURE__ */ ((n) => (n.POINT = "point", n.CIRCLE = "circle", n.RECT = "rect", n))(de || {});
3293
- const Tt = 10, Et = 0, Rt = !0;
3294
- class q {
2456
+ var le = /* @__PURE__ */ ((n) => (n.POINT = "point", n.CIRCLE = "circle", n.RECT = "rect", n))(le || {});
2457
+ const pt = 10, gt = 0, vt = !0;
2458
+ class K {
3295
2459
  components;
3296
2460
  constructor(t = 1) {
3297
2461
  if (!Number.isInteger(t) || t <= 0)
3298
2462
  throw new RangeError("ParticleAttributeStore size must be a positive integer");
3299
2463
  this.components = Array.from({ length: t }, () => ({
3300
- value: new _(b.Float32),
3301
- delta: new _(b.Float32),
3302
- damping: new _(b.Float32)
2464
+ value: new A(S.Float32),
2465
+ delta: new A(S.Float32),
2466
+ damping: new A(S.Float32)
3303
2467
  }));
3304
2468
  }
3305
2469
  getArrayBuffer() {
@@ -3338,46 +2502,41 @@ class q {
3338
2502
  ) : this.getComponent(t, e);
3339
2503
  }
3340
2504
  create(t, e, r = 1) {
3341
- const i = le(t) ? t : void 0, s = i === void 0 ? t : void 0, a = r > 0 ? r : 1;
3342
- let o = 0;
3343
- for (let h = 0; h < this.components.length; h++) {
3344
- const { value: c, delta: u, damping: l } = this.components[h], d = this.getComponent(e, h), f = s === void 0 ? this.resolveComponent(i?.start, h, d) : this.getComponent(s, h), m = i?.end === void 0 ? f : this.resolveComponent(i.end, h, d);
3345
- c.push(f), u.push(i?.delta === void 0 ? (m - f) / a : this.getComponent(i.delta, h)), l.push(i?.damping ?? 1), h === 0 && (o = f);
2505
+ const i = ue(t) ? t : void 0, s = i === void 0 ? t : void 0, a = r > 0 ? r : 1;
2506
+ let h = 0;
2507
+ for (let o = 0; o < this.components.length; o++) {
2508
+ const { value: c, delta: u, damping: l } = this.components[o], d = this.getComponent(e, o), f = s === void 0 ? this.resolveComponent(i?.start, o, d) : this.getComponent(s, o), m = i?.end === void 0 ? f : this.resolveComponent(i.end, o, d);
2509
+ c.push(f), u.push(i?.delta === void 0 ? (m - f) / a : this.getComponent(i.delta, o)), l.push(i?.damping ?? 1), o === 0 && (h = f);
3346
2510
  }
3347
- return o;
2511
+ return h;
3348
2512
  }
3349
2513
  }
3350
- class bt {
2514
+ class wt {
3351
2515
  options;
3352
2516
  emitting = !1;
3353
2517
  emitTimer = 0;
3354
- emitRate = Tt;
3355
- emitTime = Et;
2518
+ emitRate = pt;
2519
+ emitTime = gt;
3356
2520
  emitTimeCounter = 0;
3357
- /** Whether spawned particles are positioned in local emitter space (default: true). */
3358
- localSpace = Rt;
2521
+ localSpace = vt;
3359
2522
  rapid;
3360
- x = new _(b.Float32);
3361
- y = new _(b.Float32);
3362
- scaleX = new _(b.Float32);
3363
- scaleY = new _(b.Float32);
3364
- rotation = new _(b.Float32);
3365
- color = new _(b.Uint32);
2523
+ x = new A(S.Float32);
2524
+ y = new A(S.Float32);
2525
+ scaleX = new A(S.Float32);
2526
+ scaleY = new A(S.Float32);
2527
+ rotation = new A(S.Float32);
2528
+ color = new A(S.Uint32);
2529
+ remainingLife = new A(S.Float32);
3366
2530
  animations = {
3367
- speed: new q(),
3368
- rotation: new q(),
3369
- scale: new q(),
3370
- color: new q(4),
3371
- velocity: new q(2)
2531
+ speed: new K(),
2532
+ rotation: new K(),
2533
+ scale: new K(),
2534
+ color: new K(4),
2535
+ velocity: new K(2)
3372
2536
  };
3373
2537
  count = 0;
3374
- /**
3375
- * Creates a new particle emitter.
3376
- * @param rapid - The Rapid renderer instance
3377
- * @param options - Emitter configuration options
3378
- */
3379
2538
  constructor(t, e) {
3380
- this.rapid = t, this.options = e, this.emitRate = e.emitRate ?? Tt, this.emitTime = e.emitTime ?? Et, this.localSpace = e.localSpace ?? Rt;
2539
+ this.rapid = t, this.options = e, this.emitRate = e.emitRate ?? pt, this.emitTime = e.emitTime ?? gt, this.localSpace = e.localSpace ?? vt;
3381
2540
  }
3382
2541
  getAllArrayBuffer() {
3383
2542
  return [
@@ -3387,46 +2546,33 @@ class bt {
3387
2546
  this.scaleY,
3388
2547
  this.rotation,
3389
2548
  this.color,
2549
+ this.remainingLife,
3390
2550
  ...Object.values(this.animations).flatMap((t) => t.getArrayBuffer())
3391
2551
  ];
3392
2552
  }
3393
- /** Replaces the emitter's texture at runtime. */
3394
2553
  setTexture(t) {
3395
2554
  this.options.texture = t;
3396
2555
  }
3397
- /**
3398
- * Creates a new emitter sharing the same options object.
3399
- * Particle state is NOT copied.
3400
- */
3401
2556
  clone() {
3402
- return new bt(this.rapid, { ...this.options });
2557
+ return new wt(this.rapid, { ...this.options });
3403
2558
  }
3404
- /** Sets particles-per-second emission rate (continuous mode). */
3405
2559
  setEmitRate(t) {
3406
2560
  this.emitRate = t;
3407
2561
  }
3408
- /** Sets the burst interval in seconds (0 = continuous). */
3409
2562
  setEmitTime(t) {
3410
2563
  this.emitTime = t;
3411
2564
  }
3412
- /** Starts continuous particle emission. */
3413
2565
  start() {
3414
2566
  this.emitting = !0, this.emitTimeCounter = 0;
3415
2567
  }
3416
- /** Stops new particle emission; existing particles finish their lifecycle. */
3417
2568
  stop() {
3418
2569
  this.emitting = !1;
3419
2570
  }
3420
- /** Removes all particles and resets timers. */
3421
2571
  clear() {
3422
2572
  for (const t of this.getAllArrayBuffer())
3423
2573
  t.clear();
3424
2574
  this.count = 0, this.emitTimeCounter = 0;
3425
2575
  }
3426
- /**
3427
- * Spawns `count` particles immediately.
3428
- * Respects `maxParticles` if set.
3429
- */
3430
2576
  emit(t) {
3431
2577
  const e = this.options.maxParticles ?? 1 / 0, r = Math.min(t, e - this.count);
3432
2578
  for (let i = 0; i < r; i++)
@@ -3434,6 +2580,7 @@ class bt {
3434
2580
  }
3435
2581
  createParticle() {
3436
2582
  const t = L.scalarOrRange(this.options.life, 1);
2583
+ this.remainingLife.push(t);
3437
2584
  let e = 0, r = 0;
3438
2585
  switch (this.options.emitShape) {
3439
2586
  case "circle": {
@@ -3453,8 +2600,8 @@ class bt {
3453
2600
  const { x: c, y: u } = i.localToWorld(e, r);
3454
2601
  this.x.push(c), this.y.push(u);
3455
2602
  }
3456
- const s = this.options.animation, a = this.animations, o = a.scale.create(s.scale, 1, t), h = a.rotation.create(s.rotation, 0, t);
3457
- a.speed.create(s.speed, 0, t), a.velocity.create(s.velocity, p.ZERO, t), a.color.create(s.color, x.White, t), this.rotation.push(h), this.scaleX.push(o), this.scaleY.push(o), this.color.pushUint32(x.packColor(
2603
+ const s = this.options.animation, a = this.animations, h = a.scale.create(s.scale, 1, t), o = a.rotation.create(s.rotation, 0, t);
2604
+ a.speed.create(s.speed, 0, t), a.velocity.create(s.velocity, p.ZERO, t), a.color.create(s.color, x.White, t), this.rotation.push(o), this.scaleX.push(h), this.scaleY.push(h), this.color.pushUint32(x.packColor(
3458
2605
  a.color.get(this.count, 0),
3459
2606
  a.color.get(this.count, 1),
3460
2607
  a.color.get(this.count, 2),
@@ -3462,10 +2609,6 @@ class bt {
3462
2609
  this.rapid.premultipliedAlpha
3463
2610
  )), this.count += 1;
3464
2611
  }
3465
- /**
3466
- * Updates the emitter and all live particles.
3467
- * @param deltaTime - Seconds elapsed since last frame
3468
- */
3469
2612
  update(t) {
3470
2613
  if (this.emitting && this.emitRate > 0)
3471
2614
  if (this.emitTime > 0) {
@@ -3479,27 +2622,27 @@ class bt {
3479
2622
  r > 0 && (this.emit(r), this.emitTimer -= r / this.emitRate);
3480
2623
  }
3481
2624
  const e = this.updateParticle(t);
3482
- this.count -= e.length, _.removeAtIndices(e, this.getAllArrayBuffer());
2625
+ this.count -= e.length, A.removeAtIndices(e, this.getAllArrayBuffer());
3483
2626
  }
3484
2627
  updateParticle(t) {
3485
2628
  const e = [], r = this.animations;
3486
2629
  Object.values(r).forEach((i) => i.update(t));
3487
2630
  for (let i = 0; i < this.count; i++) {
3488
- const s = r.rotation.get(i), a = r.scale.get(i), o = r.speed.get(i);
2631
+ if (this.remainingLife.typedArray[i] -= t, this.remainingLife.typedArray[i] <= 0) {
2632
+ e.push(i);
2633
+ continue;
2634
+ }
2635
+ const s = r.rotation.get(i), a = r.scale.get(i), h = r.speed.get(i);
3489
2636
  this.rotation.typedArray[i] = s, this.scaleX.typedArray[i] = a, this.scaleY.typedArray[i] = a, this.color.uint32[i] = x.packColor(
3490
2637
  r.color.get(i, 0),
3491
2638
  r.color.get(i, 1),
3492
2639
  r.color.get(i, 2),
3493
2640
  r.color.get(i, 3),
3494
2641
  this.rapid.premultipliedAlpha
3495
- ), this.x.typedArray[i] += (o * Math.cos(s) + r.velocity.get(i, 0)) * t, this.y.typedArray[i] += (o * Math.sin(s) + r.velocity.get(i, 1)) * t;
2642
+ ), this.x.typedArray[i] += (h * Math.cos(s) + r.velocity.get(i, 0)) * t, this.y.typedArray[i] += (h * Math.sin(s) + r.velocity.get(i, 1)) * t;
3496
2643
  }
3497
2644
  return e;
3498
2645
  }
3499
- /**
3500
- * Renders all live particles.
3501
- * In local-space mode the emitter's own transform is applied around the batch.
3502
- */
3503
2646
  render() {
3504
2647
  const t = this.options, e = this.localSpace ? void 0 : this.rapid.matrix.alloc();
3505
2648
  this.rapid.drawParticles({
@@ -3518,53 +2661,50 @@ class bt {
3518
2661
  customMatrix: e
3519
2662
  });
3520
2663
  }
3521
- /** Returns `true` if the emitter is running or still has live particles. */
3522
2664
  isActive() {
3523
2665
  return this.emitting || this.count > 0;
3524
2666
  }
3525
- /**
3526
- * Convenience: emit `emitRate` particles in one shot (fire-and-forget burst).
3527
- */
3528
2667
  oneShot() {
3529
2668
  this.emit(this.emitRate);
3530
2669
  }
3531
2670
  }
3532
2671
  export {
3533
- b as ArrayType,
3534
- z as BaseTexture,
3535
- ce as BlendMode,
3536
- ue as CanvasScaleMode,
2672
+ S as ArrayType,
2673
+ V as BaseTexture,
2674
+ oe as BlendMode,
2675
+ ce as CanvasScaleMode,
3537
2676
  x as Color,
3538
- ft as CustomGlShader,
3539
- _ as DynamicArrayBuffer,
3540
- wt as GLShader,
3541
- Xt as GraphicRegion,
3542
- Kt as LineTextureMode,
3543
- oe as MaskType,
3544
- Ct as MatrixStack,
3545
- Ut as MatrixStore,
3546
- bt as ParticleEmitter,
3547
- de as ParticleShape,
3548
- Gt as QUAD_VERTICES,
3549
- fe as Rapid,
3550
- At as Region,
3551
- Pt as RenderTexture,
2677
+ ut as CustomGlShader,
2678
+ A as DynamicArrayBuffer,
2679
+ Tt as GLShader,
2680
+ Yt as GraphicRegion,
2681
+ $t as LineTextureMode,
2682
+ he as MaskType,
2683
+ bt as MatrixStack,
2684
+ At as MatrixStore,
2685
+ wt as ParticleEmitter,
2686
+ ae as ParticleRegion,
2687
+ le as ParticleShape,
2688
+ Dt as QUAD_VERTICES,
2689
+ de as Rapid,
2690
+ Et as Region,
2691
+ Ct as RenderTexture,
3552
2692
  ot as SpriteRegion,
3553
- Lt as TextTexture,
3554
- O as Texture,
2693
+ Pt as TextTexture,
2694
+ N as Texture,
3555
2695
  ht as TextureFilterMode,
3556
- _t as TextureManager,
3557
- Q as TextureWrapMode,
2696
+ Ut as TextureManager,
2697
+ q as TextureWrapMode,
3558
2698
  p as Vec2,
3559
2699
  it as WebglBufferArray,
3560
- jt as composeProjectionWithAffine,
3561
- ne as drawCircle,
3562
- St as drawGraphic,
3563
- re as drawLine,
3564
- ie as drawMaskImage,
3565
- ee as drawParticles,
3566
- se as drawRect,
3567
- te as drawSprite,
3568
- Zt as getColorUint32,
3569
- $t as multiplyMat4
2700
+ Xt as composeProjectionWithAffine,
2701
+ ie as drawCircle,
2702
+ Rt as drawGraphic,
2703
+ te as drawLine,
2704
+ ee as drawMaskImage,
2705
+ Jt as drawParticles,
2706
+ re as drawRect,
2707
+ Zt as drawSprite,
2708
+ qt as getColorUint32,
2709
+ zt as multiplyMat4
3570
2710
  };