@kalyptos/narcissus 0.1.3 → 0.2.0

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.
@@ -0,0 +1,3516 @@
1
+ import { B as e, b as t, f as n, h as r, m as i, p as a, s as o, y as s, z as c } from "./format-CbtEy9NS.js";
2
+ import { t as l } from "./ports-DZRKjdYD.js";
3
+ import { t as u } from "./http-DL7R39Nc.js";
4
+ //#region src/engine/gpu/layout.ts
5
+ var d = (e) => Math.max(1, Math.ceil(e / 256)) * 256, f = {
6
+ visible: 0,
7
+ projected: 4,
8
+ drawArgs: 8,
9
+ list: 16
10
+ }, p = 65535, m = (e) => [Math.min(e, p), Math.ceil(e / p)], h = .075;
11
+ //#endregion
12
+ //#region src/engine/gpu/device.ts
13
+ async function g() {
14
+ if (!navigator.gpu) return null;
15
+ let e = await navigator.gpu.requestAdapter({ powerPreference: "high-performance" });
16
+ if (!e) return null;
17
+ let t = e.features.has("timestamp-query");
18
+ return {
19
+ device: await e.requestDevice({
20
+ requiredFeatures: t ? ["timestamp-query"] : [],
21
+ requiredLimits: {
22
+ maxStorageBufferBindingSize: e.limits.maxStorageBufferBindingSize,
23
+ maxBufferSize: e.limits.maxBufferSize
24
+ }
25
+ }),
26
+ timestamps: t,
27
+ format: navigator.gpu.getPreferredCanvasFormat()
28
+ };
29
+ }
30
+ function _(e, t, n) {
31
+ let r = !1, i = e.length / 2;
32
+ for (let a = 0, o = i - 1; a < i; o = a++) {
33
+ let i = e[2 * a], s = e[2 * a + 1], c = e[2 * o], l = e[2 * o + 1];
34
+ s > n != l > n && t < (c - i) * (n - s) / (l - s) + i && (r = !r);
35
+ }
36
+ return r;
37
+ }
38
+ function v(e, t, n, r, i, a, o, s) {
39
+ let c = 0, l = 1, u = n - e, d = r - t;
40
+ for (let [n, r] of [
41
+ [-u, e - i],
42
+ [u, o - e],
43
+ [-d, t - a],
44
+ [d, s - t]
45
+ ]) {
46
+ if (n === 0) {
47
+ if (r < 0) return !1;
48
+ continue;
49
+ }
50
+ let e = r / n;
51
+ if (n < 0 ? c = Math.max(c, e) : l = Math.min(l, e), c > l) return !1;
52
+ }
53
+ return !0;
54
+ }
55
+ function y(e, t, n) {
56
+ let { polygon: r, z: i } = e;
57
+ if (n[2] < i[0] || t[2] > i[1]) return 0;
58
+ let a = r.length / 2;
59
+ for (let e = 0, i = a - 1; e < a; i = e++) {
60
+ let [a, o, s, c] = [
61
+ r[2 * e],
62
+ r[2 * e + 1],
63
+ r[2 * i],
64
+ r[2 * i + 1]
65
+ ];
66
+ if (v(a, o, s, c, t[0], t[1], n[0], n[1])) return 2;
67
+ }
68
+ return _(r, t[0], t[1]) ? t[2] >= i[0] && n[2] <= i[1] ? 1 : 2 : 0;
69
+ }
70
+ //#endregion
71
+ //#region src/engine/gpu/buffers.ts
72
+ function b(e, t, n) {
73
+ let r = (t, n, r) => e.createBuffer({
74
+ label: t,
75
+ size: n,
76
+ usage: r
77
+ }), i = GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC, a = [
78
+ r("frame uniforms", 336, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST),
79
+ r("work", (f.list + n) * 4, i | GPUBufferUsage.INDIRECT),
80
+ r("projected", t * 6 * 4, i),
81
+ r("sort", t * 16, i),
82
+ r("plugins", 256, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST),
83
+ r("visible clusters", 4, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST)
84
+ ], [o, s, c, l, u, d] = a;
85
+ return {
86
+ capacity: t,
87
+ uniforms: o,
88
+ work: s,
89
+ visible: d,
90
+ projected: c,
91
+ sort: l,
92
+ plugins: u,
93
+ bytes: a.reduce((e, t) => e + t.size, 0),
94
+ destroy: () => a.forEach((e) => e.destroy())
95
+ };
96
+ }
97
+ function x(e, t, n, r) {
98
+ return e.createBindGroupLayout({
99
+ label: t,
100
+ entries: r.map((e, t) => ({
101
+ binding: t,
102
+ visibility: n,
103
+ buffer: { type: e }
104
+ }))
105
+ });
106
+ }
107
+ function S(e, t, n, r) {
108
+ return e.createBindGroup({
109
+ label: t,
110
+ layout: n,
111
+ entries: r.map((e, t) => ({
112
+ binding: t,
113
+ resource: { buffer: e }
114
+ }))
115
+ });
116
+ }
117
+ //#endregion
118
+ //#region src/engine/gpu/masks.ts
119
+ var C = 8, w = 3e38, T = class {
120
+ layout;
121
+ #e;
122
+ #t;
123
+ #n = null;
124
+ #r = /* @__PURE__ */ new Map();
125
+ #i = 0;
126
+ #a = [
127
+ 0,
128
+ 0,
129
+ 0
130
+ ];
131
+ #o = [];
132
+ constructor(e) {
133
+ this.#e = e, this.layout = x(e, "masks", GPUShaderStage.COMPUTE, ["read-only-storage"]), this.#t = this.#s(64);
134
+ }
135
+ get group() {
136
+ return this.#n ??= S(this.#e, "masks", this.layout, [this.#t]);
137
+ }
138
+ get size() {
139
+ return this.#r.size;
140
+ }
141
+ add(e, t) {
142
+ let { polygon: n } = e, r = [
143
+ Infinity,
144
+ Infinity,
145
+ -Infinity,
146
+ -Infinity
147
+ ];
148
+ for (let e = 0; e < n.length; e += 2) r[0] = Math.min(r[0], n[e]), r[1] = Math.min(r[1], n[e + 1]), r[2] = Math.max(r[2], n[e]), r[3] = Math.max(r[3], n[e + 1]);
149
+ return this.#r.set(++this.#i, {
150
+ prism: e,
151
+ targets: t,
152
+ enabled: !0,
153
+ area: r
154
+ }), this.#i;
155
+ }
156
+ enable(e, t) {
157
+ let n = this.#r.get(e);
158
+ n && (n.enabled = t);
159
+ }
160
+ delete(e) {
161
+ this.#r.delete(e);
162
+ }
163
+ area(e) {
164
+ return this.#r.get(e)?.area;
165
+ }
166
+ relate(e, t, n, r) {
167
+ for (let [i, { prism: a, targets: o, enabled: s, area: c }] of this.#r) {
168
+ if (!s || !o.has(e) || n[0] < c[0] || n[1] < c[1] || t[0] > c[2] || t[1] > c[3]) continue;
169
+ let l = y(a, t, n);
170
+ if (l === 1) return !0;
171
+ l === 2 && r.push(i);
172
+ }
173
+ return !1;
174
+ }
175
+ setOrigin(e) {
176
+ this.#a = e;
177
+ }
178
+ get listBase() {
179
+ let e = this.#r.size * C;
180
+ for (let { prism: t } of this.#r.values()) e += t.polygon.length;
181
+ return e;
182
+ }
183
+ write(e = this.#o) {
184
+ this.#o = e;
185
+ let t = new Uint32Array(this.listBase + e.length), n = new Float32Array(t.buffer), [r, i, a] = this.#a, o = /* @__PURE__ */ new Map(), s = this.#r.size * C, c = 0;
186
+ for (let [e, { prism: l, area: u }] of this.#r) {
187
+ let { polygon: d, z: f } = l, p = c * C;
188
+ n.set([
189
+ u[0] - r,
190
+ u[1] - i,
191
+ u[2] - r,
192
+ u[3] - i
193
+ ], p), n[p + 4] = Number.isFinite(f[0]) ? f[0] - a : -3e38, n[p + 5] = Number.isFinite(f[1]) ? f[1] - a : w, t[p + 6] = s, t[p + 7] = d.length / 2;
194
+ for (let e = 0; e < d.length; e += 2) n[s++] = d[e] - r, n[s++] = d[e + 1] - i;
195
+ o.set(e, c++);
196
+ }
197
+ for (let n = 0; n < e.length; n++) t[s + n] = o.get(e[n]) ?? 0;
198
+ t.byteLength > this.#t.size && (this.#t.destroy(), this.#t = this.#s(t.byteLength), this.#n = null), t.length && this.#e.queue.writeBuffer(this.#t, 0, t);
199
+ }
200
+ destroy() {
201
+ this.#t.destroy();
202
+ }
203
+ #s(e) {
204
+ return this.#e.createBuffer({
205
+ label: "masks",
206
+ size: Math.max(256, 2 ** Math.ceil(Math.log2(e))),
207
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST
208
+ });
209
+ }
210
+ }, E = 19, D = 23, O = 7, k = 11, A = [], j = 1024, M = class {
211
+ #e = [];
212
+ mark(e, t) {
213
+ this.#e.push([e, t]);
214
+ }
215
+ clear() {
216
+ this.#e = [];
217
+ }
218
+ flush(e, t, n) {
219
+ let r = this.#e.sort((e, t) => e[0] - t[0]);
220
+ this.#e = [];
221
+ for (let i = 0; i < r.length;) {
222
+ let a = r[i][0], o = r[i++][1];
223
+ for (; i < r.length && r[i][0] <= o + j;) o = Math.max(o, r[i++][1]);
224
+ e.writeBuffer(t, a * 4, n, a, o - a);
225
+ }
226
+ }
227
+ }, ee = class {
228
+ geometry;
229
+ colour;
230
+ pages;
231
+ clusters;
232
+ list;
233
+ listed = 0;
234
+ capacity;
235
+ masks;
236
+ #e;
237
+ #t = /* @__PURE__ */ new Map();
238
+ #n = null;
239
+ #r = null;
240
+ #i = /* @__PURE__ */ new Set();
241
+ #a;
242
+ #o;
243
+ #s = 0;
244
+ #c;
245
+ #l = [
246
+ 0,
247
+ 0,
248
+ 0
249
+ ];
250
+ #u;
251
+ #d;
252
+ #f = new M();
253
+ #p;
254
+ #m;
255
+ #h = new M();
256
+ #g;
257
+ #_ = [];
258
+ #v;
259
+ #y;
260
+ #b = !1;
261
+ constructor(e, t) {
262
+ this.capacity = t, this.masks = new T(e), this.#e = e;
263
+ let n = this.slots;
264
+ this.#S(), this.#a = new Uint8Array(n), this.#o = n, this.#c = Array.from({ length: n }, (e, t) => n - 1 - t), this.#u = new Uint32Array(n * 36), this.#d = new Float32Array(this.#u.buffer), this.#p = new Uint32Array(n * 12), this.#m = new Float32Array(this.#p.buffer), this.#g = new Uint32Array(n), this.#v = new Uint8Array(n), this.#y = Array(n).fill(A);
265
+ }
266
+ get slots() {
267
+ return this.capacity / 256;
268
+ }
269
+ get bytes() {
270
+ return this.#x().reduce((e, t) => e + t.size, 0);
271
+ }
272
+ has(e) {
273
+ let t = this.#t.get(e);
274
+ return t !== void 0 && t.page === null;
275
+ }
276
+ holds(e) {
277
+ return this.#t.has(e);
278
+ }
279
+ *ids() {
280
+ for (let e = this.#n; e; e = e.next) e.page === null && (yield e.id);
281
+ }
282
+ add(t, n, r, i, a = 0) {
283
+ if (this.#t.has(t)) return !0;
284
+ let o = d(n.count) / 256;
285
+ if (!this.#T(o, i)) return !1;
286
+ let s = e.origin, c = {
287
+ id: t,
288
+ previous: null,
289
+ next: null,
290
+ page: n,
291
+ slots: this.#N(o),
292
+ active: [],
293
+ mask: 0,
294
+ table: this.#c.pop(),
295
+ base: [
296
+ n.params[s] + r[0],
297
+ n.params[s + 1] + r[1],
298
+ n.params[s + 2]
299
+ ],
300
+ factors: 0,
301
+ layer: a
302
+ };
303
+ return this.#t.set(t, c), this.#w(c), this.#i.add(t), !0;
304
+ }
305
+ remove(e) {
306
+ let t = this.#t.get(e);
307
+ if (t) {
308
+ this.#C(t), this.#t.delete(e), this.#i.delete(e);
309
+ for (let e of t.slots) this.#a[e] = 0, this.#v[e] = 0, this.#y[e].length && (this.#b = !0), this.#y[e] = A;
310
+ this.#s = Math.min(this.#s, t.slots[0]), this.#o += t.slots.length, this.#c.push(t.table), t.page === null && t.factors !== 0 && this.#O(t, 0);
311
+ }
312
+ }
313
+ clear() {
314
+ for (let e of this.#t.values()) e.layer === 0 && this.remove(e.id);
315
+ }
316
+ get queued() {
317
+ return this.#i.size;
318
+ }
319
+ upload(e) {
320
+ let t = 0;
321
+ for (let n of this.#i) {
322
+ if (t >= e) break;
323
+ t += this.#E(this.#t.get(n)), this.#i.delete(n);
324
+ }
325
+ return t;
326
+ }
327
+ draw(e) {
328
+ let t = 0, n = 0, r = !1;
329
+ for (let { id: i, factors: a } of e) {
330
+ let e = this.#t.get(i);
331
+ if (!e || e.page !== null) continue;
332
+ let o = e.active;
333
+ (e.factors !== a || e.mask < 0) && this.#O(e, a), r ||= o !== e.active, this.#w(e), r ||= this.#_[n] !== e, this.#_[n++] = e, r && this.#g.set(e.active, t), t += e.active.length;
334
+ }
335
+ r ||= this.#_.length !== n, this.#_.length = n, this.listed = t, this.#b && this.#M();
336
+ let i = this.#e.queue;
337
+ this.#f.flush(i, this.pages, this.#u), this.#h.flush(i, this.clusters, this.#p), r && t && i.writeBuffer(this.list, 0, this.#g, 0, t);
338
+ }
339
+ setOrigin(e) {
340
+ this.#l = [
341
+ e[0],
342
+ e[1],
343
+ e[2]
344
+ ];
345
+ for (let e of this.#t.values()) e.page === null && this.#D(e);
346
+ this.#e.queue.writeBuffer(this.pages, 0, this.#u), this.#f.clear(), this.masks.setOrigin(this.#l), this.masks.size && this.masks.write();
347
+ }
348
+ addMask(e, t) {
349
+ let n = this.masks.add(e, t);
350
+ return this.#k(this.masks.area(n)), n;
351
+ }
352
+ enableMask(e, t) {
353
+ this.masks.enable(e, t), this.#k(this.masks.area(e));
354
+ }
355
+ deleteMask(e) {
356
+ let t = this.masks.area(e);
357
+ this.masks.delete(e), this.#k(t);
358
+ }
359
+ grow(e) {
360
+ if (e <= this.capacity) return;
361
+ let t = this.slots, n = this.#x();
362
+ this.capacity = e, this.#S();
363
+ let r = this.#e.createCommandEncoder({ label: "pool grow" });
364
+ this.#x().forEach((e, t) => r.copyBufferToBuffer(n[t], 0, e, 0, n[t].size)), this.#e.queue.submit([r.finish()]);
365
+ for (let e of n) e.destroy();
366
+ let i = this.slots, a = new Uint8Array(i);
367
+ a.set(this.#a), this.#a = a, this.#o += i - t;
368
+ for (let e = i - 1; e >= t; e--) this.#c.push(e);
369
+ let o = new Uint32Array(i * 36);
370
+ o.set(this.#u), this.#u = o, this.#d = new Float32Array(o.buffer);
371
+ let s = new Uint32Array(i * 12);
372
+ s.set(this.#p), this.#p = s, this.#m = new Float32Array(s.buffer);
373
+ let c = new Uint32Array(i);
374
+ c.set(this.#g), this.#g = c;
375
+ let l = new Uint8Array(i);
376
+ l.set(this.#v), this.#v = l;
377
+ for (let e = t; e < i; e++) this.#y.push(A);
378
+ }
379
+ destroy() {
380
+ for (let e of this.#x()) e.destroy();
381
+ this.masks.destroy();
382
+ }
383
+ #x() {
384
+ return [
385
+ this.geometry,
386
+ this.colour,
387
+ this.pages,
388
+ this.clusters,
389
+ this.list
390
+ ];
391
+ }
392
+ #S() {
393
+ let { capacity: e, slots: t } = this, n = GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC, r = (e, t) => this.#e.createBuffer({
394
+ label: e,
395
+ size: t,
396
+ usage: n
397
+ });
398
+ this.geometry = r("pool geometry", e * 4 * 4), this.colour = r("pool colour", e * 3 * 4), this.pages = r("pool pages", t * 36 * 4), this.clusters = r("pool clusters", t * 12 * 4), this.list = r("pool list", t * 4);
399
+ }
400
+ #C(e) {
401
+ e.previous ? e.previous.next = e.next : this.#n === e && (this.#n = e.next), e.next ? e.next.previous = e.previous : this.#r === e && (this.#r = e.previous), e.previous = null, e.next = null;
402
+ }
403
+ #w(e) {
404
+ this.#r !== e && (this.#C(e), e.previous = this.#r, this.#r ? this.#r.next = e : this.#n = e, this.#r = e);
405
+ }
406
+ #T(e, t) {
407
+ let n = this.#o;
408
+ if (n >= e) return !0;
409
+ let r = [];
410
+ for (let i = this.#n; i && !(!(i.page !== null || i.layer !== 0 || t(i.id)) && (r.push(i.id), n += i.slots.length, n >= e)); i = i.next);
411
+ if (n < e) return !1;
412
+ for (let e of r) this.remove(e);
413
+ return !0;
414
+ }
415
+ #E(t) {
416
+ let n = t.page, { slots: r } = t, i = this.#e.queue, a = r.length, o = this.#p, s = this.#m;
417
+ for (let e = 0; e < a; e++) {
418
+ let i = r[e] * 12;
419
+ o.fill(0, i, i + 12), o[i] = t.table, o[i + 1] = r[e] * 256, o[i + 2] = e * 256, o[i + 3] = Math.max(0, Math.min(256, n.count - e * 256));
420
+ for (let t = 0; t < 3; t++) s[i + 4 + t] = n.clusters[e * 6 + t], s[i + 8 + t] = n.clusters[e * 6 + 3 + t];
421
+ }
422
+ for (let e = 0; e < a;) {
423
+ let t = 1;
424
+ for (; e + t < a && r[e + t] === r[e] + t;) t++;
425
+ let o = e * 256, s = Math.min((e + t) * 256, n.count) - o, c = r[e] * 256;
426
+ i.writeBuffer(this.geometry, c * 4 * 4, n.geometry, o * 4, s * 4), i.writeBuffer(this.colour, c * 3 * 4, n.colour, o * 3, s * 3), this.#h.mark(r[e] * 12, (r[e] + t) * 12), e += t;
427
+ }
428
+ let c = t.table * 36, l = this.#u, u = this.#d, d = n.params, [f, p, m] = n.quadrants;
429
+ return l.fill(0, c, c + 36), this.#D(t), l[c + 3] = n.count, u.set(d.subarray(e.step, e.step + 3), c + 4), l[c + 7] = f, u.set(d.subarray(e.scaleMin, e.scaleMin + 3), c + 8), l[c + 11] = p, u.set(d.subarray(e.scaleMax, e.scaleMax + 3), c + 12), l[c + 15] = m, u.set(d.subarray(e.dcMin, e.dcMin + 3), c + 16), u.set(d.subarray(e.dcMax, e.dcMax + 3), c + 20), l[c + D] = t.layer, u.set(d.subarray(e.shScale, e.shScale + 9), c + 24), this.#f.mark(c, c + 36), t.page = null, this.masks.size && this.#j(t), n.count * 7 * 4 + a * 12 * 4 + 144;
430
+ }
431
+ #D(e) {
432
+ let t = e.table * 36;
433
+ for (let n = 0; n < 3; n++) this.#d[t + n] = e.base[n] - this.#l[n];
434
+ }
435
+ #O(e, t) {
436
+ let n = 0;
437
+ for (let e = 0; e < 4; e++) t >>> 8 * e & 255 && (n |= 1 << e);
438
+ if (n !== e.mask) {
439
+ e.mask = n;
440
+ let t = this.#v;
441
+ if (n === 15 && this.#u[e.table * 36 + 3] > 0) e.active = e.slots.some((e) => t[e]) ? e.slots.filter((e) => !t[e]) : e.slots;
442
+ else {
443
+ let r = [], i = e.table * 36, a = 0, o = -1;
444
+ for (let s = 0; s < 4; s++) {
445
+ let c = this.#u[i + (s === 3 ? 3 : 7 + 4 * s)];
446
+ if (n & 1 << s && c > a) for (let n = Math.max(o + 1, Math.floor(a / 256)); n < Math.ceil(c / 256); n++) t[e.slots[n]] || r.push(e.slots[n]), o = n;
447
+ a = c;
448
+ }
449
+ e.active = r;
450
+ }
451
+ }
452
+ e.factors = t;
453
+ let r = e.table * 36 + E;
454
+ this.#u[r] = t, this.#f.mark(r, r + 1);
455
+ }
456
+ #k(e) {
457
+ let t = [
458
+ 0,
459
+ 0,
460
+ 0
461
+ ], n = [
462
+ 0,
463
+ 0,
464
+ 0
465
+ ];
466
+ for (let r of this.#t.values()) r.page === null && r.slots.some((i) => (this.#A(r, i, t, n), n[0] >= e[0] && n[1] >= e[1] && t[0] <= e[2] && t[1] <= e[3])) && this.#j(r);
467
+ this.#b = !0;
468
+ }
469
+ #A(e, t, n, r) {
470
+ let i = this.#m, a = t * 12;
471
+ for (let t = 0; t < 3; t++) n[t] = e.base[t] + i[a + 4 + t], r[t] = e.base[t] + i[a + 8 + t];
472
+ }
473
+ #j(e) {
474
+ let t = [
475
+ 0,
476
+ 0,
477
+ 0
478
+ ], n = [
479
+ 0,
480
+ 0,
481
+ 0
482
+ ];
483
+ for (let r of e.slots) {
484
+ this.#A(e, r, t, n);
485
+ let i = [], a = +!!this.masks.relate(e.layer, t, n, i), o = this.#y[r];
486
+ a !== this.#v[r] && (e.mask = -1), this.#v[r] = a, (o.length || i.length) && (this.#b = !0), this.#y[r] = i.length ? i : A;
487
+ }
488
+ }
489
+ #M() {
490
+ this.#b = !1;
491
+ let e = this.#p, t = [], n = this.masks.listBase;
492
+ for (let r = 0; r < this.#y.length; r++) {
493
+ let i = this.#y[r], a = r * 12, o = i.length ? n : 0;
494
+ (e[a + O] !== o || e[a + k] !== i.length) && (e[a + O] = o, e[a + k] = i.length, this.#h.mark(a, a + 12));
495
+ for (let e of i) t.push(e);
496
+ n += i.length;
497
+ }
498
+ this.masks.write(t);
499
+ }
500
+ #N(e) {
501
+ let t = this.#a, n = -1;
502
+ for (let r = this.#s; r <= t.length - e;) {
503
+ let i = r;
504
+ for (; i < r + e && !t[i];) i++;
505
+ if (i === r + e) {
506
+ n = r;
507
+ break;
508
+ }
509
+ if (r = t.indexOf(0, i + 1), r < 0) break;
510
+ }
511
+ let r = [];
512
+ if (n >= 0) for (let t = n; t < n + e; t++) r.push(t);
513
+ else for (let n = this.#s; r.length < e; n = t.indexOf(0, n + 1)) r.push(n);
514
+ for (let e of r) t[e] = 1;
515
+ let i = t.indexOf(0, this.#s);
516
+ return this.#s = i < 0 ? t.length : i, this.#o -= e, r;
517
+ }
518
+ };
519
+ //#endregion
520
+ //#region src/engine/math/mat4.ts
521
+ function te(e, t) {
522
+ let n = Math.cos(t);
523
+ return [
524
+ Math.sin(e) * n,
525
+ Math.cos(e) * n,
526
+ Math.sin(t)
527
+ ];
528
+ }
529
+ function ne(e, t, n, r) {
530
+ let [i, a, o] = te(n, r), s = Math.cos(n), c = -Math.sin(n), l = c * o, u = -s * o, d = s * a - c * i;
531
+ return e[0] = s, e[1] = l, e[2] = -i, e[3] = 0, e[4] = c, e[5] = u, e[6] = -a, e[7] = 0, e[8] = 0, e[9] = d, e[10] = -o, e[11] = 0, e[12] = -(s * t[0] + c * t[1]), e[13] = -(l * t[0] + u * t[1] + d * t[2]), e[14] = i * t[0] + a * t[1] + o * t[2], e[15] = 1, e;
532
+ }
533
+ function re(e, t, n, r, i) {
534
+ let a = 1 / Math.tan(t / 2);
535
+ return e.fill(0), e[0] = a / n, e[5] = a, e[10] = i / (r - i), e[11] = -1, e[14] = r * i / (r - i), e;
536
+ }
537
+ var ie = /* @__PURE__ */ new Float64Array(16);
538
+ function N(e, t, n) {
539
+ for (let e = 0; e < 4; e++) for (let r = 0; r < 4; r++) {
540
+ let i = 0;
541
+ for (let a = 0; a < 4; a++) i += t[a * 4 + r] * n[e * 4 + a];
542
+ ie[e * 4 + r] = i;
543
+ }
544
+ return e.set(ie), e;
545
+ }
546
+ function ae(e, t) {
547
+ let [n, r, i, a, o, s, c, l, u, d, f, p, m, h, g, _] = t, v = n * s - r * o, y = n * c - i * o, b = n * l - a * o, x = r * c - i * s, S = r * l - a * s, C = i * l - a * c, w = u * h - d * m, T = u * g - f * m, E = u * _ - p * m, D = d * g - f * h, O = d * _ - p * h, k = f * _ - p * g, A = v * k - y * O + b * D + x * E - S * T + C * w;
548
+ if (!A) return null;
549
+ let j = 1 / A;
550
+ return e[0] = (s * k - c * O + l * D) * j, e[1] = (i * O - r * k - a * D) * j, e[2] = (h * C - g * S + _ * x) * j, e[3] = (f * S - d * C - p * x) * j, e[4] = (c * E - o * k - l * T) * j, e[5] = (n * k - i * E + a * T) * j, e[6] = (g * b - m * C - _ * y) * j, e[7] = (u * C - f * b + p * y) * j, e[8] = (o * O - s * E + l * w) * j, e[9] = (r * E - n * O - a * w) * j, e[10] = (m * S - h * b + _ * v) * j, e[11] = (d * b - u * S - p * v) * j, e[12] = (s * T - o * D - c * w) * j, e[13] = (n * D - r * T + i * w) * j, e[14] = (h * y - m * x - g * v) * j, e[15] = (u * x - d * y + f * v) * j, e;
551
+ }
552
+ function oe(e, t) {
553
+ let [n, r, i] = t;
554
+ return [
555
+ e[0] * n + e[4] * r + e[8] * i + e[12],
556
+ e[1] * n + e[5] * r + e[9] * i + e[13],
557
+ e[2] * n + e[6] * r + e[10] * i + e[14],
558
+ e[3] * n + e[7] * r + e[11] * i + e[15]
559
+ ];
560
+ }
561
+ //#endregion
562
+ //#region src/engine/gpu/common.wgsl?raw
563
+ var P = "// shared by every engine pass; sizes and word offsets mirror format/spec.ts\n\nconst KEY_BITS: u32 = 24u;\n// word offsets in the work buffer, layout.ts WORK\nconst WORK_VISIBLE: u32 = 0u;\nconst WORK_PROJECTED: u32 = 4u;\nconst WORK_LIST: u32 = 16u;\n// workgroups a dispatch row holds\nconst GROUPS_X: u32 = 65535u;\nconst C0: f32 = 0.28209479177387814;\nconst C1: f32 = 0.4886025119029199;\n\n// floating-origin ENU frame; camera looks down -z of view space\nstruct FrameUniforms {\n view: mat4x4f,\n proj: mat4x4f,\n viewProj: mat4x4f,\n // inside when dot(plane.xyz, p) + plane.w >= 0\n planes: array<vec4f, 6>,\n camera: vec3f,\n time: f32,\n // render target pixels\n viewport: vec2f,\n focal: vec2f,\n near: f32,\n far: f32,\n lowPass: f32,\n // drawn cluster ids in the pool's list\n clusters: u32,\n}\n\n// one resident page; dc and sh ranges are after the colour correction\nstruct Page {\n origin: vec3f,\n count: u32,\n step: vec3f,\n q1: u32,\n scaleMin: vec3f,\n q2: u32,\n scaleMax: vec3f,\n q3: u32,\n dcMin: vec3f,\n // quadrant k opacity 0-255 at bits 8k\n factors: u32,\n dcMax: vec3f,\n // 0 for the world, else the layer that holds the page\n layer: u32,\n shScale: array<vec4f, 3>,\n}\n\n// up to CLUSTER consecutive splats of one page in one pool slot\nstruct Cluster {\n page: u32,\n // first pool record\n slot: u32,\n // index in the page of its first splat\n first: u32,\n count: u32,\n // extents relative to the page origin\n boxMin: vec3f,\n // word in masks.wgsl's buffer of the list of masks that may hide some of its splats\n maskList: u32,\n boxMax: vec3f,\n maskCount: u32,\n}\n\n// a splat on screen; pixels with y up from the bottom-left of the target\nstruct Projected {\n centre: vec2f,\n // pack2x16float: 1-sigma major axis xy, 1-sigma minor axis xy\n axes: vec2u,\n // pack2x16float: r g, b opacity\n colour: vec2u,\n}\n\n// what a shade hook may change; position in the floating-origin frame, depth in view metres\nstruct Splat {\n position: vec3f,\n depth: f32,\n colour: vec3f,\n opacity: f32,\n scale: vec3f,\n}\n\n// the byte of word at bit, 0 to 1\nfn fraction(word: u32, bit: u32) -> f32 {\n return f32(extractBits(word, bit, 8u)) / 255.0;\n}\n\n// sigmas out to where a gaussian of opacity falls under 1/255, at most 3; the quad raster draws\nfn reach(opacity: f32) -> f32 {\n return min(3.0, sqrt(max(2.0 * log(255.0 * opacity), 0.0)));\n}\n", se = "// one thread per listed cluster\n\n@group(0) @binding(0) var<uniform> uniforms: FrameUniforms;\n@group(0) @binding(1) var<storage, read> pages: array<Page>;\n@group(0) @binding(2) var<storage, read> clusters: array<Cluster>;\n@group(0) @binding(3) var<storage, read> list: array<u32>;\n@group(0) @binding(4) var<storage, read_write> work: array<atomic<u32>>;\n\n// false only when the box lies wholly outside one plane\nfn inside(lo: vec3f, hi: vec3f) -> bool {\n for (var p = 0u; p < 6u; p++) {\n let plane = uniforms.planes[p];\n let corner = select(lo, hi, plane.xyz >= vec3f(0.0));\n if (dot(plane.xyz, corner) + plane.w < 0.0) {\n return false;\n }\n }\n return true;\n}\n\n@compute @workgroup_size(64)\nfn cull(@builtin(global_invocation_id) id: vec3u) {\n if (id.x >= uniforms.clusters) {\n return;\n }\n let slot = list[id.x];\n let cluster = clusters[slot];\n let page = pages[cluster.page];\n if (!inside(page.origin + cluster.boxMin, page.origin + cluster.boxMax)) {\n return;\n }\n atomicStore(&work[WORK_LIST + atomicAdd(&work[WORK_VISIBLE], 1u)], slot);\n}\n", ce = 64, le = class {
564
+ #e;
565
+ #t;
566
+ #n;
567
+ constructor(e, t, n) {
568
+ this.#e = t;
569
+ let r = x(e, "cull", GPUShaderStage.COMPUTE, [
570
+ "uniform",
571
+ "read-only-storage",
572
+ "read-only-storage",
573
+ "read-only-storage",
574
+ "storage"
575
+ ]), i = e.createShaderModule({
576
+ label: "cull",
577
+ code: `${P}\n${se}`
578
+ });
579
+ this.#t = e.createComputePipeline({
580
+ label: "cull",
581
+ layout: e.createPipelineLayout({ bindGroupLayouts: [r] }),
582
+ compute: {
583
+ module: i,
584
+ entryPoint: "cull"
585
+ }
586
+ });
587
+ let a = [
588
+ n.uniforms,
589
+ t.pages,
590
+ t.clusters,
591
+ t.list,
592
+ n.work
593
+ ];
594
+ this.#n = S(e, "cull", r, a);
595
+ }
596
+ encode(e, t) {
597
+ let n = e.beginComputePass({
598
+ label: "cull",
599
+ timestampWrites: t
600
+ });
601
+ n.setBindGroup(0, this.#n), n.setPipeline(this.#t), this.#e.listed && n.dispatchWorkgroups(Math.ceil(this.#e.listed / ce)), n.end();
602
+ }
603
+ }, ue = "// prisms that hide splats by centre; masks.ts writes the records, their vertices, then the clusters' lists\n\n// words of a record: min x y, max x y, min z, max z (f32), first vertex word, vertices\nconst MASK_WORDS: u32 = 8u;\n\n@group(1) @binding(0) var<storage, read> masks: array<u32>;\n\nfn maskFloat(k: u32) -> f32 {\n return bitcast<f32>(masks[k]);\n}\n\n// p, floating-origin frame, inside a mask of the cluster's list: its polygon by the even-odd rule and its z range\nfn masked(cluster: Cluster, p: vec3f) -> bool {\n for (var k = 0u; k < cluster.maskCount; k++) {\n let m = masks[cluster.maskList + k] * MASK_WORDS;\n if (p.x < maskFloat(m) || p.y < maskFloat(m + 1u) || p.x > maskFloat(m + 2u) ||\n p.y > maskFloat(m + 3u) || p.z < maskFloat(m + 4u) || p.z > maskFloat(m + 5u)) {\n continue;\n }\n let first = masks[m + 6u];\n let n = masks[m + 7u];\n var odd = false;\n var b = vec2f(maskFloat(first + 2u * n - 2u), maskFloat(first + 2u * n - 1u));\n for (var i = 0u; i < n; i++) {\n let a = vec2f(maskFloat(first + 2u * i), maskFloat(first + 2u * i + 1u));\n if ((a.y > p.y) != (b.y > p.y) && p.x < (b.x - a.x) * (p.y - a.y) / (b.y - a.y) + a.x) {\n odd = !odd;\n }\n b = a;\n }\n if (odd) {\n return true;\n }\n }\n return false;\n}\n", de = "// the top of the solid drawn splats over a square of 1 m cells; one workgroup per listed cluster\n\nconst GROUP: u32 = 64u;\n\nstruct Area {\n // south-west corner, floating-origin frame\n corner: vec2f,\n cells: u32,\n clusters: u32,\n // least opacity and largest scale in metres of a splat that counts\n opacity: f32,\n scale: f32,\n}\n\n@group(0) @binding(0) var<uniform> area: Area;\n@group(0) @binding(1) var<storage, read> pages: array<Page>;\n@group(0) @binding(2) var<storage, read> clusters: array<Cluster>;\n@group(0) @binding(3) var<storage, read> list: array<u32>;\n@group(0) @binding(4) var<storage, read> geometry: array<vec4u>;\n@group(0) @binding(5) var<storage, read_write> tops: array<atomic<u32>>;\n\n// order-preserving bits of z, never 0, which marks an empty cell\nfn ordered(z: f32) -> u32 {\n let bits = bitcast<u32>(z);\n return select(bits | 0x80000000u, ~bits, z < 0.0);\n}\n\n@compute @workgroup_size(64)\nfn heights(@builtin(workgroup_id) wid: vec3u, @builtin(local_invocation_index) t: u32) {\n let index = wid.y * GROUPS_X + wid.x;\n if (index >= area.clusters) {\n return;\n }\n let cluster = clusters[list[index]];\n let page = pages[cluster.page];\n let size = f32(area.cells);\n let lo = page.origin.xy + cluster.boxMin.xy - area.corner;\n let hi = page.origin.xy + cluster.boxMax.xy - area.corner;\n if (any(hi < vec2f(0.0)) || any(lo >= vec2f(size))) {\n return;\n }\n for (var k = t; k < cluster.count; k += GROUP) {\n let g = geometry[cluster.slot + k];\n let i = cluster.first + k;\n let quadrant = u32(i >= page.q1) + u32(i >= page.q2) + u32(i >= page.q3);\n let opacity = fraction(g.y, 16u) * fraction(page.factors, 8u * quadrant);\n let level = vec3f(fraction(g.z, 24u), fraction(g.w, 0u), fraction(g.w, 8u));\n let scale = exp(mix(page.scaleMin, page.scaleMax, level));\n if (opacity < area.opacity || max(scale.x, max(scale.y, scale.z)) > area.scale) {\n continue;\n }\n let q = vec3f(f32(g.x & 0xffffu), f32(g.x >> 16u), f32(g.y & 0xffffu));\n let p = page.origin + q * page.step;\n if (masked(cluster, p)) {\n continue;\n }\n let cell = floor(p.xy - area.corner);\n if (any(cell < vec2f(0.0)) || any(cell >= vec2f(size))) {\n continue;\n }\n let c = vec2u(cell);\n atomicMax(&tops[c.y * area.cells + c.x], ordered(p.z));\n }\n}\n", fe = 32, pe = .5, me = 1;
604
+ function he(e) {
605
+ let t = new Uint32Array(e.length);
606
+ for (let n = 0; n < e.length; n++) {
607
+ let r = e[n];
608
+ t[n] = r === 0 ? 2143289344 : r & 2147483648 ? r & 2147483647 : ~r >>> 0;
609
+ }
610
+ return new Float32Array(t.buffer);
611
+ }
612
+ var ge = class {
613
+ #e;
614
+ #t;
615
+ #n;
616
+ #r;
617
+ constructor(e, t) {
618
+ this.#e = e, this.#t = t, this.#n = x(e, "heights", GPUShaderStage.COMPUTE, [
619
+ "uniform",
620
+ "read-only-storage",
621
+ "read-only-storage",
622
+ "read-only-storage",
623
+ "read-only-storage",
624
+ "storage"
625
+ ]);
626
+ let n = `${P}\n${ue}\n${de}`, r = e.createShaderModule({
627
+ label: "heights",
628
+ code: n
629
+ });
630
+ this.#r = e.createComputePipeline({
631
+ label: "heights",
632
+ layout: e.createPipelineLayout({ bindGroupLayouts: [this.#n, t.masks.layout] }),
633
+ compute: {
634
+ module: r,
635
+ entryPoint: "heights"
636
+ }
637
+ });
638
+ }
639
+ encode(e, t, n, r, i) {
640
+ let a = this.#e, o = this.#t, { listed: s } = o, c = r * r * 4, l = a.createBuffer({
641
+ label: "heights area",
642
+ size: fe,
643
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
644
+ }), u = a.createBuffer({
645
+ label: "heights",
646
+ size: c,
647
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC
648
+ }), d = a.createBuffer({
649
+ label: "heights readback",
650
+ size: c,
651
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
652
+ }), f = /* @__PURE__ */ new ArrayBuffer(fe);
653
+ new Float32Array(f).set([
654
+ t,
655
+ n,
656
+ 0,
657
+ 0,
658
+ pe,
659
+ me
660
+ ]), new Uint32Array(f).set([r, s], 2), a.queue.writeBuffer(l, 0, f);
661
+ let p = [
662
+ l,
663
+ o.pages,
664
+ o.clusters,
665
+ o.list,
666
+ o.geometry,
667
+ u
668
+ ], h = S(a, "heights", this.#n, p), g = e.beginComputePass({
669
+ label: "heights",
670
+ timestampWrites: i
671
+ });
672
+ return g.setPipeline(this.#r), g.setBindGroup(0, h), g.setBindGroup(1, o.masks.group), s > 0 && g.dispatchWorkgroups(...m(s)), g.end(), e.copyBufferToBuffer(u, 0, d, 0, c), () => d.mapAsync(GPUMapMode.READ).then(() => he(new Uint32Array(d.getMappedRange())), () => null).finally(() => {
673
+ l.destroy(), u.destroy(), d.destroy();
674
+ });
675
+ }
676
+ }, _e = "@vertex\nfn vs(@builtin(vertex_index) i: u32) -> @builtin(position) vec4f {\n // one triangle over the whole target\n let p = vec2f(f32((i << 1u) & 2u), f32(i & 2u));\n return vec4f(p * 2.0 - 1.0, 0.0, 1.0);\n}\n", ve = class {
677
+ #e;
678
+ #t;
679
+ #n;
680
+ #r = [];
681
+ #i;
682
+ constructor(e, t, n, r) {
683
+ let i = e.createShaderModule({
684
+ label: t,
685
+ code: _e + n
686
+ });
687
+ this.#e = e, this.#t = t, this.#n = e.createRenderPipeline({
688
+ label: t,
689
+ layout: "auto",
690
+ vertex: {
691
+ module: i,
692
+ entryPoint: "vs"
693
+ },
694
+ fragment: {
695
+ module: i,
696
+ entryPoint: "fs",
697
+ targets: [{ format: r }]
698
+ }
699
+ });
700
+ }
701
+ encode(e, t, n) {
702
+ (!this.#i || t.some((e, t) => e !== this.#r[t])) && (this.#r = t, this.#i = this.#e.createBindGroup({
703
+ label: this.#t,
704
+ layout: this.#n.getBindGroupLayout(0),
705
+ entries: t.map((e, t) => ({
706
+ binding: t,
707
+ resource: e
708
+ }))
709
+ }));
710
+ let r = e.beginRenderPass({
711
+ label: this.#t,
712
+ colorAttachments: [{
713
+ view: n,
714
+ loadOp: "clear",
715
+ storeOp: "store"
716
+ }]
717
+ });
718
+ r.setPipeline(this.#n), r.setBindGroup(0, this.#i), r.draw(3), r.end();
719
+ }
720
+ }, ye = "// the finished colour target onto the canvas, opaque\n\n@group(0) @binding(0) var scene: texture_2d<f32>;\n\n@fragment\nfn fs(@builtin(position) coord: vec4f) -> @location(0) vec4f {\n return vec4f(textureLoad(scene, vec2i(coord.xy), 0).rgb, 1.0);\n}\n", be = (e, t) => new ve(e, "present", ye, t), xe = "// workgroups loop over visible clusters, one thread per splat\n\n// ndc reach past the frustum, so splats centred just outside still cover the edge\nconst GUARD: f32 = 1.3;\n\n@group(0) @binding(0) var<uniform> uniforms: FrameUniforms;\n@group(0) @binding(1) var<uniform> plugins: array<vec4f, 16>;\n@group(0) @binding(2) var<storage, read> geometry: array<vec4u>;\n@group(0) @binding(3) var<storage, read> colours: array<u32>;\n@group(0) @binding(4) var<storage, read> pages: array<Page>;\n@group(0) @binding(5) var<storage, read> clusters: array<Cluster>;\n@group(0) @binding(6) var<storage, read_write> work: array<atomic<u32>>;\n@group(0) @binding(7) var<storage, read_write> projected: array<Projected>;\n// keys in [0, capacity), values in [capacity, 2 capacity)\n@group(0) @binding(8) var<storage, read_write> sort: array<u32>;\n\n@group(0) @binding(9) var<uniform> visible: u32;\nvar<workgroup> kept: atomic<u32>;\nvar<workgroup> base: u32;\n\n// false when splat t of the cluster cannot show; else its Projected and sort key\nfn shown(cluster: Cluster, t: u32, dest: ptr<function, Projected>, key: ptr<function, u32>) -> bool {\n var s: Splat;\n var g: vec4u;\n if (!decode(cluster, t, &s, &g)) {\n return false;\n }\n shade(&s);\n if (s.opacity < 1.0 / 255.0) {\n return false;\n }\n\n // project\n let viewPos = (uniforms.view * vec4f(s.position, 1.0)).xyz;\n let depth = -viewPos.z;\n if (depth < uniforms.near || depth > uniforms.far) {\n return false;\n }\n let clip = uniforms.proj * vec4f(viewPos, 1.0);\n let ndc = clip.xy / clip.w;\n if (any(abs(ndc) > vec2f(GUARD))) {\n return false;\n }\n\n let cov = covariance(g, s.scale, viewPos);\n let a = cov.x;\n let b = cov.y;\n let c = cov.z;\n let mid = 0.5 * (a + c);\n let rad = length(vec2f(0.5 * (a - c), b));\n let major = sqrt(mid + rad);\n if (3.0 * major < 0.5) {\n return false;\n }\n let minor = sqrt(max(mid - rad, 0.0));\n let angle = 0.5 * atan2(2.0 * b, a - c);\n let axis = vec2f(cos(angle), sin(angle));\n // the quad raster draws; a centre inside the guard band can still miss the screen\n let centre = (ndc * 0.5 + 0.5) * uniforms.viewport;\n let extent = reach(s.opacity) * (abs(axis) * major + abs(axis.yx) * minor);\n if (any(centre + extent < vec2f(0.0)) || any(centre - extent > uniforms.viewport)) {\n return false;\n }\n\n *dest = Projected(\n centre,\n vec2u(pack2x16float(axis * major), pack2x16float(vec2f(-axis.y, axis.x) * minor)),\n vec2u(pack2x16float(s.colour.rg), pack2x16float(vec2f(s.colour.b, s.opacity)))\n );\n let span = clamp(log(depth / uniforms.near) / log(uniforms.far / uniforms.near), 0.0, 1.0);\n *key = u32((1.0 - span) * f32((1u << KEY_BITS) - 1u));\n return true;\n}\n\n@compute @workgroup_size(256)\nfn project(\n @builtin(workgroup_id) wid: vec3u,\n @builtin(num_workgroups) groups: vec3u,\n @builtin(local_invocation_index) t: u32\n) {\n for (var index = wid.y * groups.x + wid.x; index < visible; index += groups.x * groups.y) {\n let cluster = clusters[atomicLoad(&work[WORK_LIST + index])];\n var splat: Projected;\n var key = 0u;\n var keep = false;\n if (t < cluster.count) {\n keep = shown(cluster, t, &splat, &key);\n }\n\n // one global atomic per cluster\n var rank = 0u;\n if (keep) {\n rank = atomicAdd(&kept, 1u);\n }\n workgroupBarrier();\n if (t == 0u) {\n base = atomicAdd(&work[WORK_PROJECTED], atomicExchange(&kept, 0u));\n }\n let i = workgroupUniformLoad(&base) + rank;\n let capacity = arrayLength(&projected);\n if (keep && i < capacity) {\n projected[i] = splat;\n sort[i] = key;\n sort[capacity + i] = i;\n }\n }\n}\n", Se = "// a pool splat decoded and its screen covariance, shared by project and pick; each declares the\n// uniforms, geometry, colours and pages bindings these read\n\n// i8 over 127, sign-extended by extractBits on i32\nfn code(word: u32, bit: u32) -> f32 {\n return f32(extractBits(i32(word), bit, 8u)) / 127.0;\n}\n\n// smallest three: w x y z with the largest at the stored index\nfn rotation(g: vec4u) -> vec4f {\n let v = (vec3f(fraction(g.z, 0u), fraction(g.z, 8u), fraction(g.z, 16u)) - 0.5) * sqrt(2.0);\n let big = sqrt(max(0.0, 1.0 - dot(v, v)));\n switch extractBits(g.y, 24u, 8u) {\n case 0u: {\n return normalize(vec4f(big, v));\n }\n case 1u: {\n return normalize(vec4f(v.x, big, v.yz));\n }\n case 2u: {\n return normalize(vec4f(v.xy, big, v.z));\n }\n default: {\n return normalize(vec4f(v, big));\n }\n }\n}\n\nfn rotate(q: vec4f) -> mat3x3f {\n let w = q.x;\n let x = q.y;\n let y = q.z;\n let z = q.w;\n return mat3x3f(\n 1.0 - 2.0 * (y * y + z * z), 2.0 * (x * y + w * z), 2.0 * (x * z - w * y),\n 2.0 * (x * y - w * z), 1.0 - 2.0 * (x * x + z * z), 2.0 * (y * z + w * x),\n 2.0 * (x * z + w * y), 2.0 * (y * z - w * x), 1.0 - 2.0 * (x * x + y * y)\n );\n}\n\n// splat t of a cluster in the floating-origin frame, its record in g; false when a mask hides it\nfn decode(cluster: Cluster, t: u32, s: ptr<function, Splat>, g: ptr<function, vec4u>) -> bool {\n let page = pages[cluster.page];\n let rec = cluster.slot + t;\n *g = geometry[rec];\n let w0 = colours[rec * 3u];\n let w1 = colours[rec * 3u + 1u];\n let w2 = colours[rec * 3u + 2u];\n let i = cluster.first + t;\n let quadrant = u32(i >= page.q1) + u32(i >= page.q2) + u32(i >= page.q3);\n\n var d: Splat;\n let q = vec3f(f32((*g).x & 0xffffu), f32((*g).x >> 16u), f32((*g).y & 0xffffu));\n d.position = page.origin + q * page.step;\n if (masked(cluster, d.position)) {\n return false;\n }\n d.opacity = fraction((*g).y, 16u) * fraction(page.factors, 8u * quadrant);\n let level = vec3f(fraction((*g).z, 24u), fraction((*g).w, 0u), fraction((*g).w, 8u));\n d.scale = exp(mix(page.scaleMin, page.scaleMax, level));\n let dc = mix(page.dcMin, page.dcMax, vec3f(fraction(w0, 0u), fraction(w0, 8u), fraction(w0, 16u)));\n // sh[c][m] at 3c + m, gathered per m across the colours\n let k = page.shScale;\n let m0 = vec3f(code(w0, 24u), code(w1, 16u), code(w2, 8u)) * vec3f(k[0].x, k[0].w, k[1].z);\n let m1 = vec3f(code(w1, 0u), code(w1, 24u), code(w2, 16u)) * vec3f(k[0].y, k[1].x, k[1].w);\n let m2 = vec3f(code(w1, 8u), code(w2, 0u), code(w2, 24u)) * vec3f(k[0].z, k[1].y, k[2].x);\n let toward = normalize(d.position - uniforms.camera);\n d.colour = max(0.5 + C0 * dc + C1 * (-toward.y * m0 + toward.z * m1 - toward.x * m2), vec3f(0.0));\n d.depth = -(uniforms.view * vec4f(d.position, 1.0)).z;\n *s = d;\n return true;\n}\n\n// ewa: view-space covariance wm wm^T through the jacobian of the pixel projection, as a b c in px²\nfn covariance(g: vec4u, scale: vec3f, viewPos: vec3f) -> vec3f {\n let depth = -viewPos.z;\n let r = rotate(rotation(g));\n let m = mat3x3f(r[0] * scale.x, r[1] * scale.y, r[2] * scale.z);\n let w = mat3x3f(uniforms.view[0].xyz, uniforms.view[1].xyz, uniforms.view[2].xyz);\n let wm = w * m;\n let focal = uniforms.focal;\n let j0 = vec3f(focal.x / depth, 0.0, focal.x * viewPos.x / (depth * depth));\n let j1 = vec3f(0.0, focal.y / depth, focal.y * viewPos.y / (depth * depth));\n let u = j0 * wm;\n let v = j1 * wm;\n return vec3f(dot(u, u) + uniforms.lowPass, dot(u, v), dot(v, v) + uniforms.lowPass);\n}\n", Ce = class {
721
+ #e;
722
+ #t;
723
+ #n;
724
+ #r = [];
725
+ #i;
726
+ #a;
727
+ #o;
728
+ #s;
729
+ constructor(e, t, n) {
730
+ this.#e = e, this.#a = t, this.#o = n.work, this.#s = n.visible;
731
+ let r = x(e, "project", GPUShaderStage.COMPUTE, [
732
+ "uniform",
733
+ "uniform",
734
+ "read-only-storage",
735
+ "read-only-storage",
736
+ "read-only-storage",
737
+ "read-only-storage",
738
+ "storage",
739
+ "storage",
740
+ "storage",
741
+ "uniform"
742
+ ]);
743
+ this.#t = e.createPipelineLayout({ bindGroupLayouts: [r, t.masks.layout] });
744
+ let i = [
745
+ n.uniforms,
746
+ n.plugins,
747
+ t.geometry,
748
+ t.colour,
749
+ t.pages,
750
+ t.clusters,
751
+ n.work,
752
+ n.projected,
753
+ n.sort,
754
+ n.visible
755
+ ];
756
+ this.#i = S(e, "project", r, i);
757
+ }
758
+ hooks(e) {
759
+ this.#r = e, this.#n = void 0;
760
+ }
761
+ encode(e, t, n) {
762
+ e.copyBufferToBuffer(this.#o, f.visible * 4, this.#s, 0, 4);
763
+ let r = Math.max(1, Math.min(128, this.#a.listed, t ? Math.max(32, Math.ceil(t / 16)) : 128)), i = e.beginComputePass({
764
+ label: "project",
765
+ timestampWrites: n
766
+ });
767
+ i.setPipeline(this.#n ??= this.#c()), i.setBindGroup(0, this.#i), i.setBindGroup(1, this.#a.masks.group), i.dispatchWorkgroups(r), i.end();
768
+ }
769
+ #c() {
770
+ let e = we([
771
+ P,
772
+ ue,
773
+ Se,
774
+ xe
775
+ ], this.#r), t = this.#e.createShaderModule({
776
+ label: "project",
777
+ code: e
778
+ });
779
+ return this.#e.createComputePipeline({
780
+ label: "project",
781
+ layout: this.#t,
782
+ compute: {
783
+ module: t,
784
+ entryPoint: "project"
785
+ }
786
+ });
787
+ }
788
+ };
789
+ function we(e, t) {
790
+ let n = t.map(({ shade: e, slot: t }) => {
791
+ let n = Array.from({ length: e.uniforms }, (e, n) => `plugins[${t + n}]`);
792
+ return `\t${e.name}(s, array<vec4f, ${e.uniforms}>(${n.join(", ")}));`;
793
+ });
794
+ return [
795
+ ...e,
796
+ ...t.map(({ shade: e }) => e.wgsl),
797
+ "fn shade(s: ptr<function, Splat>) {",
798
+ ...n,
799
+ "}"
800
+ ].join("\n");
801
+ }
802
+ //#endregion
803
+ //#region src/engine/gpu/overlay.wgsl?raw
804
+ var Te = "// host graphics over the frame: capsules in screen space from a to b, a marker where a is b\n\n// share of the view depth an occluding fragment may lie behind the splats, so a line on the ground clears their fringe\nconst SLACK: f32 = 0.02;\n\nstruct Capsule {\n @location(0) a: vec3f,\n @location(1) b: vec3f,\n // pixels\n @location(2) radius: f32,\n @location(3) colour: vec4f,\n @location(4) occlude: u32,\n}\n\nstruct Fragment {\n @builtin(position) position: vec4f,\n // target pixels from the top-left, of the ends\n @location(0) @interpolate(flat) a: vec2f,\n @location(1) @interpolate(flat) b: vec2f,\n // view depth of the ends\n @location(2) @interpolate(flat) depths: vec2f,\n @location(3) @interpolate(flat) radius: f32,\n @location(4) @interpolate(flat) colour: vec4f,\n @location(5) @interpolate(flat) occlude: u32,\n}\n\n@group(0) @binding(0) var<uniform> uniforms: FrameUniforms;\n@group(0) @binding(1) var depth: texture_depth_2d;\n\nfn pixel(view: vec3f) -> vec2f {\n let clip = uniforms.proj * vec4f(view, 1.0);\n let ndc = clip.xy / clip.w;\n return vec2f(ndc.x * 0.5 + 0.5, 0.5 - ndc.y * 0.5) * uniforms.viewport;\n}\n\n@vertex\nfn vs(@builtin(vertex_index) v: u32, c: Capsule) -> Fragment {\n var a = (uniforms.view * vec4f(c.a, 1.0)).xyz;\n var b = (uniforms.view * vec4f(c.b, 1.0)).xyz;\n var out: Fragment;\n // cut the part behind the near plane; nothing left draws nothing\n let near = -uniforms.near;\n if (a.z > near && b.z > near) {\n out.position = vec4f(2.0, 2.0, 0.0, 1.0);\n return out;\n }\n if (a.z > near) {\n a = mix(b, a, (near - b.z) / (a.z - b.z));\n } else if (b.z > near) {\n b = mix(a, b, (near - a.z) / (b.z - a.z));\n }\n let pa = pixel(a);\n let pb = pixel(b);\n let span = pb - pa;\n let along = select(vec2f(1.0, 0.0), normalize(span), dot(span, span) > 1e-6);\n let across = vec2f(-along.y, along.x);\n let r = c.radius + 1.0;\n let corner = select(pa - along * r, pb + along * r, (v & 1u) == 1u) + across * r * select(-1.0, 1.0, v > 1u);\n out.position = vec4f(corner.x / uniforms.viewport.x * 2.0 - 1.0, 1.0 - corner.y / uniforms.viewport.y * 2.0, 0.0, 1.0);\n out.a = pa;\n out.b = pb;\n out.depths = vec2f(-a.z, -b.z);\n out.radius = c.radius;\n out.colour = c.colour;\n out.occlude = c.occlude;\n return out;\n}\n\n@fragment\nfn fs(f: Fragment) -> @location(0) vec4f {\n let p = f.position.xy;\n let span = f.b - f.a;\n let t = select(0.0, clamp(dot(p - f.a, span) / dot(span, span), 0.0, 1.0), dot(span, span) > 1e-6);\n let coverage = clamp(f.radius - distance(p, f.a + span * t) + 0.5, 0.0, 1.0);\n if (coverage <= 0.0) {\n discard;\n }\n if (f.occlude != 0u) {\n // screen-linear in 1 / depth along a segment\n let here = 1.0 / mix(1.0 / f.depths.x, 1.0 / f.depths.y, t);\n let stored = textureLoad(depth, vec2i(p), 0);\n let scene = uniforms.near * pow(uniforms.far / uniforms.near, stored);\n if (stored < 1.0 && here > scene * (1.0 + SLACK)) {\n discard;\n }\n }\n let a = f.colour.a * coverage;\n return vec4f(f.colour.rgb * a, a);\n}\n", Ee = 36, De = {
805
+ srcFactor: "one",
806
+ dstFactor: "one-minus-src-alpha"
807
+ }, Oe = class {
808
+ #e;
809
+ #t;
810
+ #n;
811
+ #r = null;
812
+ #i = 0;
813
+ #a;
814
+ #o;
815
+ constructor(e, t, n) {
816
+ this.#e = e, this.#t = n;
817
+ let r = e.createShaderModule({
818
+ label: "overlay",
819
+ code: P + Te
820
+ }), i = [
821
+ {
822
+ shaderLocation: 0,
823
+ offset: 0,
824
+ format: "float32x3"
825
+ },
826
+ {
827
+ shaderLocation: 1,
828
+ offset: 12,
829
+ format: "float32x3"
830
+ },
831
+ {
832
+ shaderLocation: 2,
833
+ offset: 24,
834
+ format: "float32"
835
+ },
836
+ {
837
+ shaderLocation: 3,
838
+ offset: 28,
839
+ format: "unorm8x4"
840
+ },
841
+ {
842
+ shaderLocation: 4,
843
+ offset: 32,
844
+ format: "uint32"
845
+ }
846
+ ];
847
+ this.#n = e.createRenderPipeline({
848
+ label: "overlay",
849
+ layout: "auto",
850
+ vertex: {
851
+ module: r,
852
+ entryPoint: "vs",
853
+ buffers: [{
854
+ arrayStride: Ee,
855
+ stepMode: "instance",
856
+ attributes: i
857
+ }]
858
+ },
859
+ fragment: {
860
+ module: r,
861
+ entryPoint: "fs",
862
+ targets: [{
863
+ format: t,
864
+ blend: {
865
+ color: De,
866
+ alpha: De
867
+ }
868
+ }]
869
+ },
870
+ primitive: { topology: "triangle-strip" }
871
+ });
872
+ }
873
+ get count() {
874
+ return this.#i;
875
+ }
876
+ set(e, t) {
877
+ if (this.#i = e.length, !e.length) return;
878
+ let n = /* @__PURE__ */ new ArrayBuffer(e.length * Ee), r = new Float32Array(n), i = new Uint32Array(n), a = new Uint8Array(n);
879
+ e.forEach(({ a: e, b: n, radius: o, colour: s, occlude: c }, l) => {
880
+ let u = l * Ee / 4;
881
+ for (let i = 0; i < 3; i++) r[u + i] = e[i] - t[i], r[u + 3 + i] = n[i] - t[i];
882
+ r[u + 6] = o, s.forEach((e, t) => a[(u + 7) * 4 + t] = Math.round(Math.min(1, Math.max(0, e)) * 255)), i[u + 8] = +!!c;
883
+ }), (!this.#r || this.#r.size < n.byteLength) && (this.#r?.destroy(), this.#r = this.#e.createBuffer({
884
+ label: "overlay",
885
+ size: 2 ** Math.ceil(Math.log2(n.byteLength)),
886
+ usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST
887
+ })), this.#e.queue.writeBuffer(this.#r, 0, n);
888
+ }
889
+ encode(e, t, n) {
890
+ if (!this.#i) return;
891
+ n !== this.#a && (this.#a = n, this.#o = this.#e.createBindGroup({
892
+ label: "overlay",
893
+ layout: this.#n.getBindGroupLayout(0),
894
+ entries: [{
895
+ binding: 0,
896
+ resource: { buffer: this.#t }
897
+ }, {
898
+ binding: 1,
899
+ resource: n
900
+ }]
901
+ }));
902
+ let r = e.beginRenderPass({
903
+ label: "overlay",
904
+ colorAttachments: [{
905
+ view: t,
906
+ loadOp: "load",
907
+ storeOp: "store"
908
+ }]
909
+ });
910
+ r.setPipeline(this.#n), r.setBindGroup(0, this.#o), r.setVertexBuffer(0, this.#r), r.draw(4, this.#i), r.end();
911
+ }
912
+ destroy() {
913
+ this.#r?.destroy();
914
+ }
915
+ }, ke = [
916
+ [
917
+ 0,
918
+ -1,
919
+ 1
920
+ ],
921
+ [
922
+ 0,
923
+ 1,
924
+ -1
925
+ ],
926
+ [
927
+ 1,
928
+ -1,
929
+ 1
930
+ ],
931
+ [
932
+ 1,
933
+ 1,
934
+ -1
935
+ ],
936
+ [
937
+ 2,
938
+ 0,
939
+ 1
940
+ ],
941
+ [
942
+ 2,
943
+ 1,
944
+ -1
945
+ ]
946
+ ];
947
+ function Ae(e, t, n) {
948
+ return ke.forEach(([r, i, a], o) => {
949
+ let s = n?.[o] ?? i;
950
+ for (let n = 0; n < 4; n++) e[o * 4 + n] = a * (t[n * 4 + r] - s * t[n * 4 + 3]);
951
+ let c = Math.hypot(e[o * 4], e[o * 4 + 1], e[o * 4 + 2]) || 1;
952
+ for (let t = 0; t < 4; t++) e[o * 4 + t] /= c;
953
+ }), e;
954
+ }
955
+ function je(e, t, n) {
956
+ for (let r = 0; r < 24; r += 4) {
957
+ let i = e[r] >= 0 ? n[0] : t[0], a = e[r + 1] >= 0 ? n[1] : t[1], o = e[r + 2] >= 0 ? n[2] : t[2];
958
+ if (e[r] * i + e[r + 1] * a + e[r + 2] * o + e[r + 3] < 0) return !1;
959
+ }
960
+ return !0;
961
+ }
962
+ //#endregion
963
+ //#region src/engine/gpu/pick.wgsl?raw
964
+ var Me = "// the nearest solid splat under one pixel, over the last frame's visible clusters\n\n// workgroups of the dispatch, pick.ts's GROUPS; each loops over the visible clusters\nconst PICK_GROUPS: u32 = 256u;\n// least alpha at the pixel of a splat that counts as the surface\nconst SOLID: f32 = 0.5;\n\nstruct Probe {\n // target pixel, y up from the bottom-left\n pixel: vec2f,\n // the pixel's frustum sides; inside when dot(plane.xyz, p) + plane.w >= 0\n planes: array<vec4f, 4>,\n}\n\n@group(0) @binding(0) var<uniform> uniforms: FrameUniforms;\n@group(0) @binding(1) var<uniform> plugins: array<vec4f, 16>;\n@group(0) @binding(2) var<storage, read> geometry: array<vec4u>;\n@group(0) @binding(3) var<storage, read> colours: array<u32>;\n@group(0) @binding(4) var<storage, read> pages: array<Page>;\n@group(0) @binding(5) var<storage, read> clusters: array<Cluster>;\n@group(0) @binding(6) var<storage, read> work: array<u32>;\n@group(0) @binding(7) var<uniform> probe: Probe;\n// view depth bits of the nearest hit, then its layer, then its normal\n@group(0) @binding(8) var<storage, read_write> hit: array<atomic<u32>>;\n\n// false only when the box lies wholly outside one side of the pixel\nfn under(lo: vec3f, hi: vec3f) -> bool {\n for (var p = 0u; p < 4u; p++) {\n let plane = probe.planes[p];\n let corner = select(lo, hi, plane.xyz >= vec3f(0.0));\n if (dot(plane.xyz, corner) + plane.w < 0.0) {\n return false;\n }\n }\n return true;\n}\n\n// splat t of the cluster draws the pixel solid; its view depth and decoded splat then\nfn covers(cluster: Cluster, t: u32, s: ptr<function, Splat>, g: ptr<function, vec4u>) -> bool {\n if (!decode(cluster, t, s, g)) {\n return false;\n }\n shade(s);\n let viewPos = (uniforms.view * vec4f((*s).position, 1.0)).xyz;\n let depth = -viewPos.z;\n if ((*s).opacity < SOLID || depth < uniforms.near || depth > uniforms.far) {\n return false;\n }\n let clip = uniforms.proj * vec4f(viewPos, 1.0);\n let centre = (clip.xy / clip.w * 0.5 + 0.5) * uniforms.viewport;\n let cov = covariance(*g, (*s).scale, viewPos);\n let d = probe.pixel - centre;\n let power = (cov.z * d.x * d.x - 2.0 * cov.y * d.x * d.y + cov.x * d.y * d.y) / (cov.x * cov.z - cov.y * cov.y);\n (*s).depth = depth;\n return (*s).opacity * exp(-0.5 * power) >= SOLID;\n}\n\n// the cluster of visible index under the pixel, or none\nfn candidate(index: u32, cluster: ptr<function, Cluster>) -> bool {\n *cluster = clusters[work[WORK_LIST + index]];\n let page = pages[(*cluster).page];\n return under(page.origin + (*cluster).boxMin, page.origin + (*cluster).boxMax);\n}\n\n@compute @workgroup_size(256)\nfn nearest(@builtin(workgroup_id) wid: vec3u, @builtin(local_invocation_index) t: u32) {\n for (var index = wid.x; index < work[WORK_VISIBLE]; index += PICK_GROUPS) {\n var cluster: Cluster;\n var s: Splat;\n var g: vec4u;\n if (candidate(index, &cluster) && t < cluster.count && covers(cluster, t, &s, &g)) {\n atomicMin(&hit[0], bitcast<u32>(s.depth));\n }\n }\n}\n\n// the splat at the nearest depth writes its layer and its thinnest axis, toward the camera\n@compute @workgroup_size(256)\nfn surface(@builtin(workgroup_id) wid: vec3u, @builtin(local_invocation_index) t: u32) {\n let nearest = atomicLoad(&hit[0]);\n for (var index = wid.x; index < work[WORK_VISIBLE]; index += PICK_GROUPS) {\n var cluster: Cluster;\n var s: Splat;\n var g: vec4u;\n if (candidate(index, &cluster) && t < cluster.count && covers(cluster, t, &s, &g) &&\n bitcast<u32>(s.depth) == nearest) {\n let r = rotate(rotation(g));\n let k = select(select(2u, 1u, s.scale.y <= s.scale.z), 0u,\n s.scale.x <= s.scale.y && s.scale.x <= s.scale.z);\n let normal = r[k] * sign(dot(r[k], uniforms.camera - s.position) + 1e-20);\n atomicStore(&hit[1], pages[cluster.page].layer);\n atomicStore(&hit[2], bitcast<u32>(normal.x));\n atomicStore(&hit[3], bitcast<u32>(normal.y));\n atomicStore(&hit[4], bitcast<u32>(normal.z));\n }\n }\n}\n", Ne = 256, Pe = 80, Fe = 4294967295, Ie = new Uint32Array([
965
+ Fe,
966
+ 0,
967
+ 0,
968
+ 0,
969
+ 0
970
+ ]), Le = class {
971
+ #e;
972
+ #t;
973
+ #n;
974
+ #r;
975
+ #i;
976
+ #a = [];
977
+ #o = /* @__PURE__ */ new Float32Array(16);
978
+ #s = /* @__PURE__ */ new Float32Array(24);
979
+ #c = new Float32Array(Pe / 4);
980
+ #l;
981
+ #u;
982
+ #d;
983
+ constructor(e, t, n) {
984
+ this.#e = e, this.#t = t, this.#n = x(e, "pick", GPUShaderStage.COMPUTE, [
985
+ "uniform",
986
+ "uniform",
987
+ "read-only-storage",
988
+ "read-only-storage",
989
+ "read-only-storage",
990
+ "read-only-storage",
991
+ "read-only-storage",
992
+ "uniform",
993
+ "storage"
994
+ ]), this.#r = e.createPipelineLayout({ bindGroupLayouts: [this.#n, t.masks.layout] }), this.#l = e.createBuffer({
995
+ label: "pick probe",
996
+ size: Pe,
997
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
998
+ }), this.#u = e.createBuffer({
999
+ label: "pick",
1000
+ size: 20,
1001
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST
1002
+ });
1003
+ let { uniforms: r, plugins: i, work: a } = n, o = [
1004
+ r,
1005
+ i,
1006
+ t.geometry,
1007
+ t.colour,
1008
+ t.pages,
1009
+ t.clusters
1010
+ ];
1011
+ this.#d = S(e, "pick", this.#n, [
1012
+ ...o,
1013
+ a,
1014
+ this.#l,
1015
+ this.#u
1016
+ ]);
1017
+ }
1018
+ hooks(e) {
1019
+ this.#a = e, this.#i = void 0;
1020
+ }
1021
+ run(e, t, n) {
1022
+ let r = this.#e, i = this.#t, a = r.createBuffer({
1023
+ label: "pick readback",
1024
+ size: 20,
1025
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
1026
+ }), o = this.#c, s = n.height - t;
1027
+ o.set([e, s], 0), o.set(this.#f(e, s, n), 4), r.queue.writeBuffer(this.#l, 0, o), r.queue.writeBuffer(this.#u, 0, Ie);
1028
+ let c = this.#i ??= this.#p(), l = r.createCommandEncoder({ label: "pick" }), u = l.beginComputePass({ label: "pick" });
1029
+ return u.setBindGroup(0, this.#d), u.setBindGroup(1, i.masks.group), u.setPipeline(c.nearest), u.dispatchWorkgroups(Ne), u.setPipeline(c.surface), u.dispatchWorkgroups(Ne), u.end(), l.copyBufferToBuffer(this.#u, 0, a, 0, 20), r.queue.submit([l.finish()]), a.mapAsync(GPUMapMode.READ).then(() => {
1030
+ let e = new Uint32Array(a.getMappedRange());
1031
+ if (e[0] === Fe) return null;
1032
+ let t = new Float32Array(e.buffer), n = [
1033
+ t[2],
1034
+ t[3],
1035
+ t[4]
1036
+ ];
1037
+ return {
1038
+ depth: t[0],
1039
+ layer: e[1],
1040
+ normal: n
1041
+ };
1042
+ }, () => null).finally(() => a.destroy());
1043
+ }
1044
+ destroy() {
1045
+ this.#l.destroy(), this.#u.destroy();
1046
+ }
1047
+ #f(e, t, n) {
1048
+ let r = (e, t) => 2 * e / t - 1, i = N(this.#o, n.proj, n.view), a = [
1049
+ r(e - .5, n.width),
1050
+ r(e + .5, n.width),
1051
+ r(t - .5, n.height),
1052
+ r(t + .5, n.height)
1053
+ ];
1054
+ return Ae(this.#s, i, a), this.#s.subarray(0, 16);
1055
+ }
1056
+ #p() {
1057
+ let e = we([
1058
+ P,
1059
+ ue,
1060
+ Se,
1061
+ Me
1062
+ ], this.#a), t = this.#e.createShaderModule({
1063
+ label: "pick",
1064
+ code: e
1065
+ }), n = (e) => this.#e.createComputePipeline({
1066
+ label: `pick ${e}`,
1067
+ layout: this.#r,
1068
+ compute: {
1069
+ module: t,
1070
+ entryPoint: e
1071
+ }
1072
+ });
1073
+ return {
1074
+ nearest: n("nearest"),
1075
+ surface: n("surface")
1076
+ };
1077
+ }
1078
+ }, Re = "// sorted splats as screen quads, premultiplied over what lies behind them\n\n// word offsets of the sorted keys and values in the sort buffer\nstruct Sorted {\n keys: u32,\n values: u32,\n}\n\nstruct Corner {\n @builtin(position) position: vec4f,\n // offset from the centre in sigmas\n @location(0) uv: vec2f,\n @location(1) colour: vec4f,\n}\n\n@group(0) @binding(0) var<uniform> frame: FrameUniforms;\n@group(0) @binding(1) var<storage, read> projected: array<Projected>;\n@group(0) @binding(2) var<storage, read> sort: array<u32>;\n@group(0) @binding(3) var<uniform> sorted: Sorted;\n\nfn corner(v: u32, i: u32) -> Corner {\n let p = projected[sort[sorted.values + i]];\n let major = unpack2x16float(p.axes.x);\n let minor = unpack2x16float(p.axes.y);\n let colour = vec4f(unpack2x16float(p.colour.x), unpack2x16float(p.colour.y));\n let r = reach(colour.a);\n let uv = vec2f(f32(v & 1u), f32(v >> 1u)) * 2.0 - 1.0;\n let pixel = p.centre + (major * uv.x + minor * uv.y) * r;\n return Corner(vec4f(pixel / frame.viewport * 2.0 - 1.0, 0.0, 1.0), uv * r, colour);\n}\n\nfn alpha(uv: vec2f, opacity: f32) -> f32 {\n return opacity * exp(-0.5 * dot(uv, uv));\n}\n\n@vertex\nfn vsColour(@builtin(vertex_index) v: u32, @builtin(instance_index) i: u32) -> Corner {\n return corner(v, i);\n}\n\n@vertex\nfn vsDepth(@builtin(vertex_index) v: u32, @builtin(instance_index) i: u32) -> Corner {\n var c = corner(v, i);\n // inverse of the key: the span from near to far in log depth\n c.position.z = 1.0 - f32(sort[sorted.keys + i]) / f32((1u << KEY_BITS) - 1u);\n return c;\n}\n\n@fragment\nfn fs(c: Corner) -> @location(0) vec4f {\n let a = alpha(c.uv, c.colour.a);\n if (a < 1.0 / 255.0) {\n discard;\n }\n return vec4f(c.colour.rgb * a, a);\n}\n", ze = "rgb10a2unorm", Be = "depth16unorm", Ve = {
1079
+ srcFactor: "one",
1080
+ dstFactor: "one-minus-src-alpha"
1081
+ }, He = class {
1082
+ #e;
1083
+ #t;
1084
+ #n;
1085
+ #r;
1086
+ #i;
1087
+ constructor(e, t, n) {
1088
+ this.#e = t.work, this.#t = e.createBuffer({
1089
+ label: "raster sorted",
1090
+ size: 16,
1091
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
1092
+ });
1093
+ let r = new Uint32Array([
1094
+ n.keys / 4,
1095
+ n.values / 4,
1096
+ 0,
1097
+ 0
1098
+ ]);
1099
+ e.queue.writeBuffer(this.#t, 0, r);
1100
+ let i = x(e, "raster", GPUShaderStage.VERTEX, [
1101
+ "uniform",
1102
+ "read-only-storage",
1103
+ "read-only-storage",
1104
+ "uniform"
1105
+ ]);
1106
+ this.#i = S(e, "raster", i, [
1107
+ t.uniforms,
1108
+ t.projected,
1109
+ t.sort,
1110
+ this.#t
1111
+ ]);
1112
+ let a = e.createShaderModule({
1113
+ label: "raster",
1114
+ code: P + Re
1115
+ }), o = e.createPipelineLayout({ bindGroupLayouts: [i] }), s = (t, n) => e.createRenderPipeline({
1116
+ label: `raster ${t}`,
1117
+ layout: o,
1118
+ vertex: {
1119
+ module: a,
1120
+ entryPoint: `vs${t}`
1121
+ },
1122
+ fragment: {
1123
+ module: a,
1124
+ entryPoint: "fs",
1125
+ targets: [{
1126
+ format: ze,
1127
+ blend: {
1128
+ color: Ve,
1129
+ alpha: Ve
1130
+ }
1131
+ }]
1132
+ },
1133
+ primitive: { topology: "triangle-strip" },
1134
+ depthStencil: n
1135
+ });
1136
+ this.#n = s("Colour"), this.#r = s("Depth", {
1137
+ format: Be,
1138
+ depthWriteEnabled: !0,
1139
+ depthCompare: "always"
1140
+ });
1141
+ }
1142
+ encode(e, t, n, r, i) {
1143
+ let a = e.beginRenderPass({
1144
+ label: "raster",
1145
+ colorAttachments: [{
1146
+ view: t,
1147
+ loadOp: "clear",
1148
+ clearValue: [...r, 1],
1149
+ storeOp: "store"
1150
+ }],
1151
+ depthStencilAttachment: n ? {
1152
+ view: n,
1153
+ depthClearValue: 1,
1154
+ depthLoadOp: "clear",
1155
+ depthStoreOp: "store"
1156
+ } : void 0,
1157
+ timestampWrites: i
1158
+ });
1159
+ a.setPipeline(n ? this.#r : this.#n), a.setBindGroup(0, this.#i), a.drawIndirect(this.#e, f.drawArgs * 4), a.end();
1160
+ }
1161
+ destroy() {
1162
+ this.#t.destroy();
1163
+ }
1164
+ }, Ue = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan, a stable scatter; no spin-waits\n\nconst THREADS: u32 = 128u;\nconst ITEMS: u32 = 8u;\nconst BLOCK: u32 = 1024u;\n// blocks per scan chunk\nconst CHUNK: u32 = 64u;\nconst DIGITS: u32 = 256u;\n\nstruct SortParams {\n shift: u32,\n // word offsets of the keys read and written; their values follow capacity words later\n src: u32,\n dst: u32,\n capacity: u32,\n // word offsets in the work buffer\n projected: u32,\n drawArgs: u32,\n}\n\nstruct SortState {\n count: u32,\n blocks: u32,\n chunks: u32,\n}\n\n@group(0) @binding(0) var<uniform> params: SortParams;\n@group(0) @binding(1) var<storage, read_write> data: array<u32>;\n// block-major: count, then exclusive global offset, of digit d in block b at b DIGITS + d\n@group(0) @binding(2) var<storage, read_write> hist: array<u32>;\n// chunk-major sums of hist, then their exclusive global offsets\n@group(0) @binding(3) var<storage, read_write> sums: array<u32>;\n@group(0) @binding(4) var<storage, read> state: SortState;\n@group(0) @binding(5) var<storage, read_write> stateOut: SortState;\n@group(0) @binding(6) var<storage, read_write> work: array<u32>;\n\nvar<workgroup> bins: array<atomic<u32>, DIGITS>;\nvar<workgroup> totals: array<u32, DIGITS>;\nvar<workgroup> bitValues: atomic<u32>;\nvar<workgroup> activeBits: u32;\nvar<workgroup> sk: array<u32, BLOCK>;\nvar<workgroup> sv: array<u32, BLOCK>;\n// three 10-bit counts; the fourth follows from the number of items\nvar<workgroup> counts: array<u32, THREADS * 2u>;\nvar<workgroup> tail: u32;\nvar<workgroup> starts: array<u32, DIGITS>;\nvar<workgroup> offsets: array<u32, DIGITS>;\n\nfn unpack(packed: u32, count: u32) -> vec4u {\n let a = packed & 1023u;\n let b = (packed >> 10u) & 1023u;\n let c = (packed >> 20u) & 1023u;\n return vec4u(a, b, c, count - a - b - c);\n}\n\nfn digit(key: u32) -> u32 {\n return (key >> params.shift) & 0xffu;\n}\n\n@compute @workgroup_size(1)\nfn prepare() {\n let count = min(work[params.projected], params.capacity);\n let blocks = (count + BLOCK - 1u) / BLOCK;\n work[params.drawArgs] = 4u;\n work[params.drawArgs + 1u] = count;\n work[params.drawArgs + 2u] = 0u;\n work[params.drawArgs + 3u] = 0u;\n stateOut = SortState(count, blocks, (blocks + CHUNK - 1u) / CHUNK);\n}\n\n@compute @workgroup_size(THREADS)\nfn histogram(\n @builtin(workgroup_id) wid: vec3u,\n @builtin(num_workgroups) groups: vec3u,\n @builtin(local_invocation_index) t: u32\n) {\n for (var block = wid.y * groups.x + wid.x; block < state.blocks; block += groups.x * groups.y) {\n let head = block * BLOCK;\n for (var k = 0u; k < ITEMS; k++) {\n let i = head + k * THREADS + t;\n if (i < state.count) {\n atomicAdd(&bins[digit(data[params.src + i])], 1u);\n }\n }\n workgroupBarrier();\n for (var d = t; d < DIGITS; d += THREADS) {\n hist[block * DIGITS + d] = atomicExchange(&bins[d], 0u);\n }\n workgroupBarrier();\n }\n}\n\n@compute @workgroup_size(DIGITS)\nfn reduce(@builtin(workgroup_id) wid: vec3u, @builtin(local_invocation_index) t: u32) {\n let end = min((wid.x + 1u) * CHUNK, state.blocks);\n var sum = 0u;\n for (var b = wid.x * CHUNK; b < end; b++) {\n sum += hist[b * DIGITS + t];\n }\n sums[wid.x * DIGITS + t] = sum;\n}\n\n@compute @workgroup_size(DIGITS)\nfn top(@builtin(local_invocation_index) t: u32) {\n var run = 0u;\n for (var c = 0u; c < state.chunks; c++) {\n let x = sums[c * DIGITS + t];\n sums[c * DIGITS + t] = run;\n run += x;\n }\n totals[t] = run;\n // a bit varies only when both zero and one occur in nonempty digits\n if (run > 0u) {\n atomicOr(&bitValues, t | ((255u ^ t) << 8u));\n }\n workgroupBarrier();\n if (t == 0u) {\n let values = atomicLoad(&bitValues);\n sums[arrayLength(&sums) - 1u] = values & (values >> 8u);\n }\n for (var o = 1u; o < DIGITS; o *= 2u) {\n var x = 0u;\n if (t >= o) {\n x = totals[t - o];\n }\n workgroupBarrier();\n totals[t] += x;\n workgroupBarrier();\n }\n let base = totals[t] - run;\n for (var c = 0u; c < state.chunks; c++) {\n sums[c * DIGITS + t] += base;\n }\n}\n\n@compute @workgroup_size(DIGITS)\nfn down(@builtin(workgroup_id) wid: vec3u, @builtin(local_invocation_index) t: u32) {\n let end = min((wid.x + 1u) * CHUNK, state.blocks);\n var run = sums[wid.x * DIGITS + t];\n for (var b = wid.x * CHUNK; b < end; b++) {\n let x = hist[b * DIGITS + t];\n hist[b * DIGITS + t] = run;\n run += x;\n }\n}\n\n@compute @workgroup_size(THREADS)\nfn scatter(\n @builtin(workgroup_id) wid: vec3u,\n @builtin(num_workgroups) groups: vec3u,\n @builtin(local_invocation_index) t: u32\n) {\n let first = wid.y * groups.x + wid.x;\n if (first >= state.blocks) {\n return;\n }\n if (t == 0u) {\n activeBits = sums[arrayLength(&sums) - 1u];\n }\n let bits = workgroupUniformLoad(&activeBits);\n for (var block = first; block < state.blocks; block += groups.x * groups.y) {\n let head = block * BLOCK;\n let valid = min(BLOCK, state.count - head);\n // padding has digit 255 at every shift, so it sorts behind the valid keys and is never written\n for (var k = 0u; k < ITEMS; k++) {\n let i = k * THREADS + t;\n var key = 0xffffffffu;\n var value = 0u;\n if (i < valid) {\n key = data[params.src + head + i];\n value = data[params.src + params.capacity + head + i];\n }\n sk[i] = key;\n sv[i] = value;\n }\n for (var d = t; d < DIGITS; d += THREADS) {\n offsets[d] = hist[block * DIGITS + d];\n }\n workgroupBarrier();\n\n // stable local sort by the digit, two bits a split; thread t owns positions t ITEMS + k\n for (var bit = 0u; bit < 8u; bit += 2u) {\n if ((bits & (3u << bit)) == 0u) {\n continue;\n }\n var keys: array<u32, ITEMS>;\n var values: array<u32, ITEMS>;\n var before: array<u32, ITEMS>;\n var mine = vec4u(0u);\n for (var k = 0u; k < ITEMS; k++) {\n keys[k] = sk[t * ITEMS + k];\n values[k] = sv[t * ITEMS + k];\n let b = (keys[k] >> (params.shift + bit)) & 3u;\n before[k] = mine[b];\n mine[b] += 1u;\n }\n counts[t] = mine.x | (mine.y << 10u) | (mine.z << 20u);\n if (t == THREADS - 1u) {\n tail = counts[t];\n }\n workgroupBarrier();\n // separate reads and writes need only one barrier per scan step\n var source = 0u;\n for (var o = 1u; o < THREADS; o *= 2u) {\n var x = counts[source + t];\n if (t >= o) {\n x += counts[source + t - o];\n }\n let dest = source ^ THREADS;\n counts[dest + t] = x;\n workgroupBarrier();\n source = dest;\n }\n // prefixes stop at 1016 items, so no count carries into its neighbour\n let total = unpack(counts[source + THREADS - 2u], BLOCK - ITEMS) + unpack(tail, ITEMS);\n var prior = vec4u(0u);\n if (t > 0u) {\n prior = unpack(counts[source + t - 1u], t * ITEMS);\n }\n let base = vec4u(0u, total.x, total.x + total.y, total.x + total.y + total.z);\n for (var k = 0u; k < ITEMS; k++) {\n let b = (keys[k] >> (params.shift + bit)) & 3u;\n let p = base[b] + prior[b] + before[k];\n sk[p] = keys[k];\n sv[p] = values[k];\n }\n workgroupBarrier();\n }\n\n for (var k = 0u; k < ITEMS; k++) {\n let i = t * ITEMS + k;\n let d = digit(sk[i]);\n if (i == 0u || digit(sk[i - 1u]) != d) {\n starts[d] = i;\n }\n }\n workgroupBarrier();\n for (var k = 0u; k < ITEMS; k++) {\n let i = k * THREADS + t;\n if (i < valid) {\n let d = digit(sk[i]);\n let slot = offsets[d] + i - starts[d];\n data[params.dst + slot] = sk[i];\n data[params.dst + params.capacity + slot] = sv[i];\n }\n }\n workgroupBarrier();\n }\n}\n", We = 1024, Ge = 64, Ke = 256, F = 3, I = 256, qe = 32, Je = class {
1165
+ keys;
1166
+ values;
1167
+ bytes;
1168
+ #e;
1169
+ #t;
1170
+ #n;
1171
+ #r;
1172
+ #i;
1173
+ #a;
1174
+ constructor(e, t) {
1175
+ let { capacity: n } = t;
1176
+ this.keys = n * 8, this.values = n * 12;
1177
+ let r = Math.max(1, Math.ceil(n / We));
1178
+ this.#a = r;
1179
+ let i = Math.ceil(r / Ge), a = (t, n, r) => e.createBuffer({
1180
+ label: t,
1181
+ size: n,
1182
+ usage: r
1183
+ }), o = GPUBufferUsage.STORAGE, s = a("sort params", F * I, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST), c = a("sort histograms", r * Ke * 4, o), l = a("sort chunk sums", (i * Ke + 1) * 4, o), u = a("sort state", 12, o);
1184
+ this.#e = [
1185
+ s,
1186
+ c,
1187
+ l,
1188
+ u
1189
+ ], this.bytes = this.#e.reduce((e, t) => e + t.size, 0);
1190
+ let d = new Uint32Array(F * I / 4);
1191
+ for (let e = 0; e < F; e++) {
1192
+ let [t, r] = e % 2 ? [2 * n, 0] : [0, 2 * n];
1193
+ d.set([
1194
+ 8 * e,
1195
+ t,
1196
+ r,
1197
+ n,
1198
+ f.projected,
1199
+ f.drawArgs
1200
+ ], e * I / 4);
1201
+ }
1202
+ e.queue.writeBuffer(s, 0, d);
1203
+ let p = (e, t) => ({
1204
+ binding: e,
1205
+ visibility: GPUShaderStage.COMPUTE,
1206
+ buffer: { type: t }
1207
+ }), m = x(e, "sort", GPUShaderStage.COMPUTE, [
1208
+ "uniform",
1209
+ "storage",
1210
+ "storage",
1211
+ "storage",
1212
+ "read-only-storage"
1213
+ ]), h = e.createBindGroupLayout({
1214
+ label: "sort prepare",
1215
+ entries: [
1216
+ p(0, "uniform"),
1217
+ p(5, "storage"),
1218
+ p(6, "storage")
1219
+ ]
1220
+ }), g = e.createShaderModule({
1221
+ label: "sort",
1222
+ code: P + Ue
1223
+ }), _ = (t, n) => e.createComputePipeline({
1224
+ label: `sort ${t}`,
1225
+ layout: e.createPipelineLayout({ bindGroupLayouts: [n] }),
1226
+ compute: {
1227
+ module: g,
1228
+ entryPoint: t
1229
+ }
1230
+ });
1231
+ this.#t = _("prepare", h), this.#n = [
1232
+ "histogram",
1233
+ "reduce",
1234
+ "top",
1235
+ "down",
1236
+ "scatter"
1237
+ ].map((e) => _(e, m));
1238
+ let v = (e) => ({
1239
+ buffer: s,
1240
+ offset: e * I,
1241
+ size: qe
1242
+ });
1243
+ this.#r = e.createBindGroup({
1244
+ label: "sort prepare",
1245
+ layout: h,
1246
+ entries: [
1247
+ {
1248
+ binding: 0,
1249
+ resource: v(0)
1250
+ },
1251
+ {
1252
+ binding: 5,
1253
+ resource: { buffer: u }
1254
+ },
1255
+ {
1256
+ binding: 6,
1257
+ resource: { buffer: t.work }
1258
+ }
1259
+ ]
1260
+ }), this.#i = Array.from({ length: F }, (n, r) => e.createBindGroup({
1261
+ label: `sort pass ${r}`,
1262
+ layout: m,
1263
+ entries: [
1264
+ {
1265
+ binding: 0,
1266
+ resource: v(r)
1267
+ },
1268
+ {
1269
+ binding: 1,
1270
+ resource: { buffer: t.sort }
1271
+ },
1272
+ {
1273
+ binding: 2,
1274
+ resource: { buffer: c }
1275
+ },
1276
+ {
1277
+ binding: 3,
1278
+ resource: { buffer: l }
1279
+ },
1280
+ {
1281
+ binding: 4,
1282
+ resource: { buffer: u }
1283
+ }
1284
+ ]
1285
+ }));
1286
+ }
1287
+ encode(e, t, n, r) {
1288
+ let [i, a, o, s, c] = this.#n, l = Math.max(1, Math.min(this.#a, Math.ceil(t / We))), u = Math.max(l / 16, (n || t) / We), d = m(Math.min(Math.ceil(l / 4), Math.ceil(u))), f = Math.ceil(l / Ge), p = e.beginComputePass({
1289
+ label: "sort",
1290
+ timestampWrites: r
1291
+ });
1292
+ p.setPipeline(this.#t), p.setBindGroup(0, this.#r), p.dispatchWorkgroups(1);
1293
+ for (let e of this.#i) p.setBindGroup(0, e), p.setPipeline(i), p.dispatchWorkgroups(...d), p.setPipeline(a), p.dispatchWorkgroups(f), p.setPipeline(o), p.dispatchWorkgroups(1), p.setPipeline(s), p.dispatchWorkgroups(f), p.setPipeline(c), p.dispatchWorkgroups(...d);
1294
+ p.end();
1295
+ }
1296
+ destroy() {
1297
+ for (let e of this.#e) e.destroy();
1298
+ }
1299
+ }, Ye = class {
1300
+ ms = {};
1301
+ #e;
1302
+ #t;
1303
+ #n;
1304
+ #r;
1305
+ #i = !1;
1306
+ #a = !1;
1307
+ constructor(e, t, n) {
1308
+ if (this.#e = n, !t) return;
1309
+ let r = n.length * 2;
1310
+ this.#t = e.createQuerySet({
1311
+ label: "timing",
1312
+ type: "timestamp",
1313
+ count: r
1314
+ }), this.#n = e.createBuffer({
1315
+ label: "timing resolved",
1316
+ size: r * 8,
1317
+ usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC
1318
+ }), this.#r = e.createBuffer({
1319
+ label: "timing readback",
1320
+ size: r * 8,
1321
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
1322
+ });
1323
+ }
1324
+ writes(e) {
1325
+ let t = this.#t;
1326
+ if (!t || this.#i) return;
1327
+ let n = this.#e.indexOf(e);
1328
+ return {
1329
+ querySet: t,
1330
+ beginningOfPassWriteIndex: 2 * n,
1331
+ endOfPassWriteIndex: 2 * n + 1
1332
+ };
1333
+ }
1334
+ resolve(e) {
1335
+ !this.#t || !this.#n || !this.#r || this.#i || (e.resolveQuerySet(this.#t, 0, this.#e.length * 2, this.#n, 0), e.copyBufferToBuffer(this.#n, 0, this.#r, 0, this.#r.size), this.#a = !0);
1336
+ }
1337
+ read() {
1338
+ let e = this.#r;
1339
+ !e || this.#i || !this.#a || (this.#i = !0, this.#a = !1, e.mapAsync(GPUMapMode.READ).then(() => {
1340
+ let t = new BigUint64Array(e.getMappedRange());
1341
+ this.#e.forEach((e, n) => {
1342
+ let [r, i] = [t[2 * n], t[2 * n + 1]];
1343
+ this.ms[e] = i > r ? Number(i - r) / 1e6 : 0;
1344
+ }), e.unmap();
1345
+ }).catch(() => {}).finally(() => this.#i = !1));
1346
+ }
1347
+ destroy() {
1348
+ this.#t?.destroy(), this.#n?.destroy(), this.#r?.destroy();
1349
+ }
1350
+ }, Xe = [
1351
+ "cull",
1352
+ "project",
1353
+ "sort",
1354
+ "raster",
1355
+ "heights",
1356
+ "post"
1357
+ ], L = {
1358
+ view: 0,
1359
+ proj: 16,
1360
+ viewProj: 32,
1361
+ planes: 48,
1362
+ camera: 72,
1363
+ time: 75,
1364
+ viewport: 76,
1365
+ focal: 78,
1366
+ near: 80,
1367
+ far: 81,
1368
+ lowPass: 82,
1369
+ clusters: 83
1370
+ }, Ze = class {
1371
+ #e;
1372
+ #t;
1373
+ #n;
1374
+ #r;
1375
+ #i;
1376
+ #a;
1377
+ #o;
1378
+ #s;
1379
+ #c;
1380
+ #l;
1381
+ #u;
1382
+ #d;
1383
+ #f;
1384
+ #p;
1385
+ #m = /* @__PURE__ */ new Float32Array(84);
1386
+ #h = new Uint32Array(this.#m.buffer);
1387
+ #g = /* @__PURE__ */ new Float32Array(16);
1388
+ #_ = /* @__PURE__ */ new Float32Array(64);
1389
+ #v = [];
1390
+ #y = [];
1391
+ #b = {};
1392
+ #x = /* @__PURE__ */ new WeakMap();
1393
+ #S;
1394
+ #C;
1395
+ #w;
1396
+ #T = !1;
1397
+ #E = 0;
1398
+ #D = 0;
1399
+ constructor(e, t, n, r) {
1400
+ let { device: i } = e;
1401
+ this.#e = i, this.#t = t, this.#n = e.format, this.#r = n, this.#i = b(i, r, n.slots), this.#a = new le(i, n, this.#i), this.#o = new Ce(i, n, this.#i), this.#s = new Je(i, this.#i), this.#c = new He(i, this.#i, this.#s), this.#u = new ge(i, n), this.#d = new Le(i, n, this.#i), this.#f = new Oe(i, e.format, this.#i.uniforms), this.#p = new Ye(i, e.timestamps, Xe), this.#w = i.createBuffer({
1402
+ label: "counts readback",
1403
+ size: (f.projected + 1) * 4,
1404
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
1405
+ }), this.#S = Math.max(1, t.canvas.width), this.#C = Math.max(1, t.canvas.height);
1406
+ }
1407
+ shade(e) {
1408
+ if (this.#v.reduce((e, { shade: t }) => e + t.uniforms, 0) + e.uniforms > 16) throw Error("Shade hooks may use 16 uniform slots in all.");
1409
+ let t = {
1410
+ shade: e,
1411
+ slot: 0
1412
+ };
1413
+ return this.#v.push(t), this.#O(), () => {
1414
+ let e = this.#v.indexOf(t);
1415
+ e < 0 || (this.#v.splice(e, 1), this.#O());
1416
+ };
1417
+ }
1418
+ post(e) {
1419
+ let t = {
1420
+ post: e,
1421
+ pass: e.setup(this.#e, this.#n)
1422
+ }, n = e.order ?? 0, r = this.#y.findIndex(({ post: e }) => (e.order ?? 0) > n);
1423
+ return this.#y.splice(r < 0 ? this.#y.length : r, 0, t), () => {
1424
+ let e = this.#y.indexOf(t);
1425
+ e < 0 || (this.#y.splice(e, 1), t.pass.destroy());
1426
+ };
1427
+ }
1428
+ resize(e, t) {
1429
+ (e !== this.#S || t !== this.#C) && (this.#S = e, this.#C = t, this.#N());
1430
+ }
1431
+ pick(e, t, n) {
1432
+ return this.#d.run(e, t, n);
1433
+ }
1434
+ overlay(e, t) {
1435
+ this.#f.set(e, t);
1436
+ }
1437
+ render(e, t, n, r) {
1438
+ let i = this.#e, a = this.#p, o = this.#y, s = this.#j(this.#A("colour", ze)), c = this.#f.count > 0, l = c || o.some(({ post: e }) => e.depth), u = this.#M("depth", Be, l), d = u ? this.#j(u) : null, p = [this.#M("ping", this.#n, o.length > 1), this.#M("pong", this.#n, o.length > 2)];
1439
+ this.#k(e, t);
1440
+ let m = i.createCommandEncoder({ label: "frame" });
1441
+ m.clearBuffer(this.#i.work, 0, f.list * 4), this.#a.encode(m, a.writes("cull")), this.#o.encode(m, this.#D, a.writes("project")), this.#s.encode(m, this.#r.listed * 256, this.#E, a.writes("sort")), this.#c.encode(m, s, d, n, a.writes("raster"));
1442
+ let h = r.map(({ x: e, y: t, cells: n, resolve: r }, i) => ({
1443
+ resolve: r,
1444
+ read: this.#u.encode(m, e, t, n, i ? void 0 : a.writes("heights"))
1445
+ })), g = a.writes("post");
1446
+ if (g) {
1447
+ let { querySet: e, beginningOfPassWriteIndex: t } = g;
1448
+ m.beginComputePass({ timestampWrites: {
1449
+ querySet: e,
1450
+ beginningOfPassWriteIndex: t
1451
+ } }).end();
1452
+ }
1453
+ let _ = this.#t.getCurrentTexture().createView();
1454
+ if (!o.length) this.#l ??= be(i, this.#n), this.#l.encode(m, [s], _);
1455
+ else {
1456
+ let t = s;
1457
+ o.forEach(({ post: n, pass: r }, i) => {
1458
+ let a = i === o.length - 1 ? _ : this.#j(p[i % 2]);
1459
+ r.run(m, e, t, n.depth ? d : null, a), t = a;
1460
+ });
1461
+ }
1462
+ if (c && this.#f.encode(m, _, d), g) {
1463
+ let { querySet: e, endOfPassWriteIndex: t } = g;
1464
+ m.beginComputePass({ timestampWrites: {
1465
+ querySet: e,
1466
+ endOfPassWriteIndex: t
1467
+ } }).end();
1468
+ }
1469
+ a.resolve(m);
1470
+ let v = !this.#T;
1471
+ v && m.copyBufferToBuffer(this.#i.work, 0, this.#w, 0, this.#w.size), i.queue.submit([m.finish()]), a.read(), v && this.#P();
1472
+ for (let { resolve: e, read: t } of h) t().then(e);
1473
+ return i.queue.onSubmittedWorkDone();
1474
+ }
1475
+ stats() {
1476
+ let e = { ...this.#p.ms }, t = this.#i.bytes + this.#s.bytes;
1477
+ for (let e of Object.values(this.#b)) e && (t += e.width * e.height * (e.format === "depth16unorm" ? 2 : 4));
1478
+ return {
1479
+ gpuMs: Object.values(e).reduce((e, t) => e + t, 0),
1480
+ passes: e,
1481
+ drawn: this.#E,
1482
+ bytes: t
1483
+ };
1484
+ }
1485
+ destroy() {
1486
+ for (let { pass: e } of this.#y.splice(0)) e.destroy();
1487
+ this.#N(), this.#i.destroy(), this.#s.destroy(), this.#c.destroy(), this.#d.destroy(), this.#f.destroy(), this.#p.destroy(), this.#w.destroy();
1488
+ }
1489
+ #O() {
1490
+ let e = 0;
1491
+ for (let t of this.#v) t.slot = e, e += t.shade.uniforms;
1492
+ this.#o.hooks(this.#v), this.#d.hooks(this.#v);
1493
+ }
1494
+ #k(e, t) {
1495
+ let n = this.#m, [r, i] = [this.#S, this.#C];
1496
+ n.set(e.view, L.view), n.set(e.proj, L.proj), n.set(N(this.#g, e.proj, e.view), L.viewProj), n.set(t, L.planes), n.set(e.camera.subarray(0, 3), L.camera), n[L.time] = e.time, n.set([r, i], L.viewport), n.set([e.proj[0] * r / 2, e.proj[5] * i / 2], L.focal), n[L.near] = e.near, n[L.far] = e.far, n[L.lowPass] = h, this.#h[L.clusters] = this.#r.listed, this.#e.queue.writeBuffer(this.#i.uniforms, 0, n);
1497
+ for (let { shade: t, slot: n } of this.#v) t.update(e, this.#_.subarray(n * 4, (n + t.uniforms) * 4));
1498
+ this.#v.length && this.#e.queue.writeBuffer(this.#i.plugins, 0, this.#_);
1499
+ }
1500
+ #A(e, t) {
1501
+ let n = this.#b[e];
1502
+ return n || (n = this.#e.createTexture({
1503
+ label: e,
1504
+ size: [this.#S, this.#C],
1505
+ format: t,
1506
+ usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC
1507
+ }), this.#b[e] = n), n;
1508
+ }
1509
+ #j(e) {
1510
+ let t = this.#x.get(e);
1511
+ return t || this.#x.set(e, t = e.createView()), t;
1512
+ }
1513
+ #M(e, t, n) {
1514
+ if (n) return this.#A(e, t);
1515
+ this.#b[e]?.destroy(), delete this.#b[e];
1516
+ }
1517
+ #N() {
1518
+ for (let e of Object.values(this.#b)) e?.destroy();
1519
+ this.#b = {};
1520
+ }
1521
+ #P() {
1522
+ this.#T = !0;
1523
+ let e = this.#w;
1524
+ e.mapAsync(GPUMapMode.READ).then(() => {
1525
+ let t = new Uint32Array(e.getMappedRange());
1526
+ this.#D = t[f.visible], this.#E = Math.min(t[f.projected], this.#i.capacity), e.unmap();
1527
+ }).catch(() => {}).finally(() => this.#T = !1);
1528
+ }
1529
+ };
1530
+ //#endregion
1531
+ //#region src/engine/layer.ts
1532
+ async function Qe(e, n) {
1533
+ let i = await r(async (t, n) => e.subarray(t, n), e.length);
1534
+ if (i.length === 0) throw Error("the pack holds no pages");
1535
+ let a = Math.min(...i.map((e) => e.g));
1536
+ return Promise.all(i.filter((e) => e.g === a).map(async (r) => {
1537
+ let i = await t(e.subarray(r.offset, r.offset + r.length)), a = Float64Array.from(r.box, (e, t) => e + (t % 3 < 2 ? n[t % 3] : 0));
1538
+ return {
1539
+ page: o(i, null),
1540
+ box: a
1541
+ };
1542
+ }));
1543
+ }
1544
+ function $e(e) {
1545
+ let t = (t) => [Math.min(...e.map((e) => e[t])), Math.max(...e.map((e) => e[t + 3]))];
1546
+ return {
1547
+ e: t(0),
1548
+ n: t(1),
1549
+ h: t(2)
1550
+ };
1551
+ }
1552
+ var et = class {
1553
+ #e = /* @__PURE__ */ new Map();
1554
+ update(e, t, n, r) {
1555
+ let i = this.#e, a = tt(e, t), o = -1;
1556
+ for (let [e, r] of i) t(r.page.id) ? (o = Math.max(o, r.level), !r.held && (r.start !== null && n - r.start >= 250 && (r.start = null), a.has(e) || (r.frozen = R(r, n), r.start = null, r.out = null, r.covered = !1, r.held = !0))) : i.delete(e);
1557
+ let s = /* @__PURE__ */ new Set();
1558
+ for (let [e, t] of a) {
1559
+ let r = i.get(e);
1560
+ if (!r) {
1561
+ let r = nt(t, e % 4, n);
1562
+ o = Math.max(o, r.level), i.set(e, r), s.add(r);
1563
+ } else if (r.held) {
1564
+ let e = R(r, n);
1565
+ r.held = !1, r.out = null, e < 255 && (r.start = n - e / 255 * 250, s.add(r));
1566
+ }
1567
+ }
1568
+ let c = /* @__PURE__ */ new Map(), l = /* @__PURE__ */ new Map();
1569
+ for (let e of i.values()) if (e.held) {
1570
+ c.set(e.cell, e);
1571
+ for (let t = e.level, n = e.col, r = e.row; t <= o; t++, n >>= 1, r >>= 1) {
1572
+ let i = rt(t, n, r), a = l.get(i);
1573
+ a ? a.push(e) : l.set(i, [e]);
1574
+ }
1575
+ }
1576
+ let u = (e) => {
1577
+ let t = [...l.get(e.cell) ?? []];
1578
+ for (let n = e.level + 1, r = e.col >> 1, i = e.row >> 1; n <= o; n++, r >>= 1, i >>= 1) {
1579
+ let e = c.get(rt(n, r, i));
1580
+ e && t.push(e);
1581
+ }
1582
+ return t;
1583
+ }, f = /* @__PURE__ */ new Set(), p = /* @__PURE__ */ new Set(), m = 0, h = 0, g = (e) => {
1584
+ p.has(e) || (p.add(e), h += d(e.row.count));
1585
+ };
1586
+ for (let e of i.values()) if (!(e.held || e.start === null || s.has(e))) {
1587
+ m += e.splats;
1588
+ for (let t of u(e)) f.has(t) || (f.add(t), m += t.splats, g(t.page));
1589
+ }
1590
+ for (let e of i.values()) e.held && e.out !== null && !f.has(e) && (m += e.splats);
1591
+ let _ = 1 * r;
1592
+ for (let e of s) {
1593
+ let t = u(e).filter((e) => !f.has(e)), n = t.reduce((e, t) => e + t.splats, e.splats), r = new Set(t.map((e) => e.page).filter((e) => !p.has(e))), i = [...r].reduce((e, t) => e + d(t.row.count), 0);
1594
+ if (m + n > _ || h + i > _) e.start = null;
1595
+ else {
1596
+ m += n;
1597
+ for (let e of t) f.add(e);
1598
+ for (let e of r) g(e);
1599
+ }
1600
+ }
1601
+ let v = /* @__PURE__ */ new Map(), y = !1;
1602
+ for (let [e, t] of i) {
1603
+ if (t.held && f.has(t)) t.out !== null && (t.frozen = R(t, n)), t.out = null, t.covered = !0;
1604
+ else if (t.held && (t.covered && t.out === null && (t.out = n), !t.covered || R(t, n) === 0)) {
1605
+ i.delete(e);
1606
+ continue;
1607
+ }
1608
+ (t.held || t.start !== null) && (y = !0);
1609
+ let r = R(t, n);
1610
+ if (!r) continue;
1611
+ let a = v.get(t.page.id);
1612
+ a ? a.factors = (a.factors | r << 8 * t.q) >>> 0 : v.set(t.page.id, {
1613
+ id: t.page.id,
1614
+ factors: r << 8 * t.q >>> 0
1615
+ });
1616
+ }
1617
+ return {
1618
+ drawn: [...v.values()],
1619
+ fading: y
1620
+ };
1621
+ }
1622
+ };
1623
+ function tt(e, t) {
1624
+ let n = new Set(e), r = /* @__PURE__ */ new Set(), i = [];
1625
+ for (let t of e) for (let e = t; e && !r.has(e); e = e.parent) r.add(e), e.parent || i.push(e);
1626
+ let a = /* @__PURE__ */ new Map(), o = (e) => {
1627
+ for (let i = 0; i < 4; i++) {
1628
+ let s = e.children[i];
1629
+ s && r.has(s) && t(s.id) ? o(s) : (s !== null || n.has(e)) && a.set(e.id * 4 + i, e);
1630
+ }
1631
+ };
1632
+ for (let e of i) t(e.id) && o(e);
1633
+ return a;
1634
+ }
1635
+ function nt(e, t, n) {
1636
+ let r = c * 2 ** e.g, i = e.g - 1, a = 2 * (Math.round(e.unit.e / r) + e.row.i) + (t & 1), o = 2 * (Math.round(e.unit.n / r) + e.row.j) + (t >> 1);
1637
+ return {
1638
+ page: e,
1639
+ q: t,
1640
+ level: i,
1641
+ col: a,
1642
+ row: o,
1643
+ cell: rt(i, a, o),
1644
+ splats: it(e.row, t),
1645
+ start: n,
1646
+ frozen: 0,
1647
+ out: null,
1648
+ covered: !1,
1649
+ held: !1
1650
+ };
1651
+ }
1652
+ var rt = (e, t, n) => ((e + 1) * 2 ** 21 + t) * 2 ** 21 + n;
1653
+ function it({ count: e, quadrants: t }, n) {
1654
+ return (n < 3 ? t[n] : e) - (n > 0 ? t[n - 1] : 0);
1655
+ }
1656
+ function R(e, t) {
1657
+ return e.held ? e.out === null ? e.frozen : Math.max(0, Math.round(e.frozen * (1 - (t - e.out) / 250))) : e.start === null ? 255 : Math.min(255, Math.round((t - e.start) / 250 * 255));
1658
+ }
1659
+ //#endregion
1660
+ //#region src/engine/plan/footprint.ts
1661
+ var at = [
1662
+ 0,
1663
+ 0,
1664
+ 0
1665
+ ];
1666
+ function ot(e, t, n, r) {
1667
+ let i = (e * e + e * t + t * t + n * n + n * r + r * r) / 3;
1668
+ return 1 + 15 * Math.max(0, 1 - i) ** 2;
1669
+ }
1670
+ function st(e, t, n, r, i, a, o, s = 1, c = {
1671
+ shown: !1,
1672
+ pixels: 0,
1673
+ weight: 1
1674
+ }, l = at) {
1675
+ let u = (e[0] + e[3]) / 2 - l[0], d = (e[1] + e[4]) / 2 - l[1], f = (e[2] + e[5]) / 2 - l[2], p = (e[3] - e[0]) / 2, m = (e[4] - e[1]) / 2, h = (e[5] - e[2]) / 2, g = t[0] * u + t[4] * d + t[8] * f + t[12], _ = t[1] * u + t[5] * d + t[9] * f + t[13], v = -(t[2] * u + t[6] * d + t[10] * f + t[14]), y = Math.abs(t[0]) * p + Math.abs(t[4]) * m + Math.abs(t[8]) * h, b = Math.abs(t[1]) * p + Math.abs(t[5]) * m + Math.abs(t[9]) * h, x = Math.abs(t[2]) * p + Math.abs(t[6]) * m + Math.abs(t[10]) * h;
1676
+ if (c.pixels = 0, c.weight = 1, c.shown = !1, v + x < a || v - x > o) return c;
1677
+ let S = Math.max(a, v - x), C = Math.max(a, v + x), w = i * n / r;
1678
+ if (Math.abs(g) - y > s * w * C || Math.abs(_) - b > s * i * C) return c;
1679
+ let T = Math.min((g - y) / S, (g - y) / C) / w, E = Math.max((g + y) / S, (g + y) / C) / w, D = Math.min((_ - b) / S, (_ - b) / C) / i, O = Math.max((_ + b) / S, (_ + b) / C) / i;
1680
+ if (E < -s || T > s || O < -s || D > s) return c;
1681
+ let k = Math.max(-s, T), A = Math.min(s, E), j = Math.max(-s, D), M = Math.min(s, O), ee = (E - T) * (O - D), te = (A - k) * (M - j);
1682
+ return ee <= 0 || te <= 0 || (c.shown = E > -1 && T < 1 && O > -1 && D < 1, c.pixels = ee * n * r / 4, c.weight = ot(k, A, j, M)), c;
1683
+ }
1684
+ var z = /* @__PURE__ */ new Float64Array(6), ct = {
1685
+ shown: !1,
1686
+ pixels: 0,
1687
+ weight: 1
1688
+ };
1689
+ function lt(e, [t, n, r], i, a, o, s, c, l, u = at) {
1690
+ let d = r / 2, f = Math.max(0, t - e[0], n - e[1], e[3] - t - r, e[4] - n - r);
1691
+ z[2] = e[2], z[5] = e[5];
1692
+ let p = 0;
1693
+ for (let r = 0; r < 4; r++) {
1694
+ let m = t + (r & 1) * d, h = n + (r >> 1) * d;
1695
+ z[0] = Math.max(e[0], m - f), z[1] = Math.max(e[1], h - f), z[3] = Math.min(e[3], m + d + f), z[4] = Math.min(e[4], h + d + f), !(z[0] > z[3] || z[1] > z[4]) && st(z, i, a, o, s, c, l, 1, ct, u).shown && (p |= 1 << r);
1696
+ }
1697
+ return p;
1698
+ }
1699
+ //#endregion
1700
+ //#region src/engine/world/tree.ts
1701
+ var B = (e, t, n) => (e * 256 + t) * 256 + n, ut = class {
1702
+ roots = [];
1703
+ pages = /* @__PURE__ */ new Map();
1704
+ units = /* @__PURE__ */ new Map();
1705
+ #e;
1706
+ #t;
1707
+ #n = 0;
1708
+ #r = /* @__PURE__ */ new Map();
1709
+ #i = /* @__PURE__ */ new Map();
1710
+ constructor(e) {
1711
+ this.#e = new Set(e.roots.map(V)), this.#t = Math.max(...e.roots.map((e) => e.level));
1712
+ }
1713
+ add(e, t) {
1714
+ let n = V(e), r = this.units.get(n);
1715
+ if (r) return r;
1716
+ let a = /* @__PURE__ */ new Map(), o = {
1717
+ level: e.level,
1718
+ e: e.e,
1719
+ n: e.n,
1720
+ idx: e,
1721
+ path: t,
1722
+ parent: null,
1723
+ pages: [],
1724
+ grid: a
1725
+ };
1726
+ for (let t of e.rows) {
1727
+ let n = t.box, r = {
1728
+ id: this.#n++,
1729
+ unit: o,
1730
+ row: t,
1731
+ g: t.g,
1732
+ box: Float64Array.of(e.e + n[0], e.n + n[1], n[2], e.e + n[3], e.n + n[4], n[5]),
1733
+ parent: null,
1734
+ children: [
1735
+ null,
1736
+ null,
1737
+ null,
1738
+ null
1739
+ ]
1740
+ };
1741
+ this.pages.set(r.id, r), o.pages.push(r), a.set(B(t.g, t.i, t.j), r);
1742
+ }
1743
+ this.units.set(n, o), this.#r.delete(n);
1744
+ for (let t = e.level + 1; t <= this.#t; t++) {
1745
+ let n = V(H(e, t));
1746
+ this.#i.set(n, (this.#i.get(n) ?? 0) + 1);
1747
+ }
1748
+ let c = new Set(e.rows.map((e) => e.g)), l = Math.max(...c), u = e.level === 0 ? 0 : e.level + 1, d = new Set(e.children.map((e) => e.quadrant));
1749
+ for (let e of o.pages) {
1750
+ let { g: t, i: n, j: r } = e.row;
1751
+ c.has(t + 1) && (e.parent = a.get(B(t + 1, n >> 1, r >> 1)) ?? null);
1752
+ for (let i = 0; i < 4; i++) {
1753
+ let o = 2 * n + (i & 1), s = 2 * r + (i >> 1);
1754
+ c.has(t - 1) ? e.children[i] = a.get(B(t - 1, o, s)) ?? null : t === u && t > 0 && (e.children[i] = d.has((o >> 3) + 2 * (s >> 3)) ? void 0 : null);
1755
+ }
1756
+ }
1757
+ if (this.#e.has(n)) for (let e of o.pages) e.g === l && this.roots.push(e);
1758
+ else {
1759
+ let t = this.units.get(V(H(e, e.level + 1)));
1760
+ t && this.#o(t, o);
1761
+ }
1762
+ let f = i(o.idx);
1763
+ for (let { key: t } of f) {
1764
+ let n = t.level === e.level - 1 ? this.units.get(V(t)) : void 0;
1765
+ n && this.#o(o, n);
1766
+ }
1767
+ for (let { key: e, hash: t } of f) {
1768
+ let n = V(e);
1769
+ if (this.units.has(n)) continue;
1770
+ let r = this.#r.get(n);
1771
+ if (r && r.from <= o.level) continue;
1772
+ let i = this.#s(o, e), a = {
1773
+ ...e,
1774
+ path: s(e, t, "idx"),
1775
+ over: i
1776
+ };
1777
+ this.#r.set(n, {
1778
+ wanted: a,
1779
+ from: o.level
1780
+ });
1781
+ }
1782
+ return o;
1783
+ }
1784
+ wanted() {
1785
+ return Array.from(this.#r.values(), (e) => e.wanted);
1786
+ }
1787
+ ground(e, t) {
1788
+ for (let n of this.roots) {
1789
+ let [r, i, a] = ft(n);
1790
+ if (e < r || e >= r + a || t < i || t >= i + a) continue;
1791
+ let o = n;
1792
+ for (;;) {
1793
+ let n = +(e >= r + a / 2), s = +(t >= i + a / 2), c = o.children[n + 2 * s];
1794
+ if (!c) return o.box[2];
1795
+ o = c, [r, i, a] = ft(o);
1796
+ }
1797
+ }
1798
+ }
1799
+ async load(e, t, n) {
1800
+ for (;;) {
1801
+ let r = this.wanted().filter((n) => dt(n, e, t));
1802
+ if (r.length === 0) return;
1803
+ (await Promise.all(r.map((e) => n(e.path)))).forEach((e, t) => this.add(e, r[t].path));
1804
+ }
1805
+ }
1806
+ prune(e) {
1807
+ let t = [], n = [...this.units.values()].sort((e, t) => e.level - t.level);
1808
+ for (let r of n) {
1809
+ let n = V(r);
1810
+ if (this.#e.has(n) || this.#i.has(n) || r.pages.some((t) => e.has(t.id))) continue;
1811
+ for (let e of r.pages) this.pages.delete(e.id), t.push(e.id);
1812
+ let a = r.parent;
1813
+ if (a) {
1814
+ let e = 250 * 2 ** r.level, t = (r.e - a.e) / e, n = (r.n - a.n) / e, i = a.idx.children.some((e) => e.quadrant === t + 2 * n);
1815
+ for (let e of this.#s(a, r)) e.children.fill(i ? void 0 : null);
1816
+ }
1817
+ this.units.delete(n);
1818
+ for (let e = r.level + 1; e <= this.#t; e++) {
1819
+ let t = V(H(r, e)), n = this.#i.get(t) - 1;
1820
+ n ? this.#i.set(t, n) : this.#i.delete(t);
1821
+ }
1822
+ for (let { key: e } of i(r.idx)) this.#a(e);
1823
+ this.#a(r);
1824
+ }
1825
+ return t;
1826
+ }
1827
+ #a(e) {
1828
+ let t = V(e);
1829
+ this.#r.delete(t);
1830
+ for (let n = e.level + 1; n <= e.level + 3; n++) {
1831
+ let r = this.units.get(V(H(e, n)));
1832
+ if (!r) continue;
1833
+ let a = i(r.idx).find((e) => V(e.key) === t);
1834
+ if (!a) continue;
1835
+ let o = {
1836
+ level: e.level,
1837
+ e: e.e,
1838
+ n: e.n,
1839
+ path: s(a.key, a.hash, "idx"),
1840
+ over: this.#s(r, e)
1841
+ };
1842
+ this.#r.set(t, {
1843
+ wanted: o,
1844
+ from: r.level
1845
+ });
1846
+ return;
1847
+ }
1848
+ }
1849
+ #o(e, t) {
1850
+ t.parent = e;
1851
+ let n = t.level + 1, r = 250 * 2 ** t.level, i = (t.e - e.e) / r, a = (t.n - e.n) / r, o = e.grid;
1852
+ for (let n of this.#s(e, t)) n.children.fill(null);
1853
+ for (let e of t.pages) {
1854
+ if (e.g !== n) continue;
1855
+ let t = 8 * i + e.row.i, r = 8 * a + e.row.j, s = o.get(B(n + 1, t >> 1, r >> 1)) ?? null;
1856
+ e.parent = s, s && (s.children[(t & 1) + 2 * (r & 1)] = e);
1857
+ }
1858
+ }
1859
+ #s(e, t) {
1860
+ let n = e.level + 1, r = c * 2 ** n, i = (t.e - e.e) / r, a = (t.n - e.n) / r, o = 250 * 2 ** t.level / r, s = [];
1861
+ for (let t = a; t < a + o; t++) for (let r = i; r < i + o; r++) {
1862
+ let i = e.grid.get(B(n, r, t));
1863
+ i && s.push(i);
1864
+ }
1865
+ return s;
1866
+ }
1867
+ };
1868
+ function V(e) {
1869
+ return `${e.level}/${e.e}/${e.n}`;
1870
+ }
1871
+ function H(e, t) {
1872
+ let n = 250 * 2 ** t;
1873
+ return {
1874
+ level: t,
1875
+ e: Math.floor(e.e / n) * n,
1876
+ n: Math.floor(e.n / n) * n
1877
+ };
1878
+ }
1879
+ function dt(e, t, n) {
1880
+ let r = 250 * 2 ** e.level;
1881
+ return t >= e.e && t < e.e + r && n >= e.n && n < e.n + r;
1882
+ }
1883
+ function ft(e) {
1884
+ let t = c * 2 ** e.g;
1885
+ return [
1886
+ e.unit.e + e.row.i * t,
1887
+ e.unit.n + e.row.j * t,
1888
+ t
1889
+ ];
1890
+ }
1891
+ //#endregion
1892
+ //#region src/engine/plan/cut.ts
1893
+ var pt = 1 / .8 ** 2, mt = 1.1, ht = class {
1894
+ #e = /* @__PURE__ */ new Map();
1895
+ #t = /* @__PURE__ */ new Map();
1896
+ #n = {
1897
+ shown: !1,
1898
+ pixels: 0,
1899
+ weight: 1
1900
+ };
1901
+ plan(e, t, n, r) {
1902
+ let { budget: i, capacity: a, now: o, predicted: s } = r, c = [], l = [], u = [], f = /* @__PURE__ */ new Map(), p = /* @__PURE__ */ new Map(), m = e.wanted(), h = /* @__PURE__ */ new Map(), g = new vt(), _ = 0, v = 0, y = (e) => {
1903
+ let t = e.page, r = t.row.count;
1904
+ c.push(t), l.push(e.visible), u.push(e.near), v += d(r), _ += e.visible;
1905
+ let i = this.#e.get(t.id), a = i !== void 0, s = e.pixels * e.weight, f = s / Math.max(1, r);
1906
+ m.length && e.pixels > 0 && h.set(t.id, f);
1907
+ let p = a && !e.shown && o - (this.#t.get(t.id) ?? -Infinity) <= 1500 ? i : null;
1908
+ (r < s * (a ? pt : 1) || p !== null) && _t(t, n) && g.push({
1909
+ page: t,
1910
+ shown: e.shown,
1911
+ held: p,
1912
+ visible: e.visible,
1913
+ ratio: f
1914
+ });
1915
+ };
1916
+ for (let n of e.roots) y(this.#r(n, t, s));
1917
+ let b = [];
1918
+ for (; g.size;) {
1919
+ let e = g.pop(), { page: n, shown: r, held: c } = e, l = [], u = 0;
1920
+ for (let e = 0; e < n.children.length; e++) {
1921
+ let r = n.children[e];
1922
+ if (!r) continue;
1923
+ let i = this.#r(r, t, s);
1924
+ i.pixels <= 0 && !((c ?? 0) & 1 << e) || (l.push(i), u |= 1 << e);
1925
+ }
1926
+ if (!l.length) continue;
1927
+ let m = 0, h = -e.visible;
1928
+ for (let e of l) m += d(e.page.row.count), h += e.visible;
1929
+ if (v + m > a) break;
1930
+ if (h > 0 && (b.length || _ + h > i)) {
1931
+ b.push(e);
1932
+ continue;
1933
+ }
1934
+ if (h < 0) for (let e of b.splice(0)) g.push(e);
1935
+ f.set(n.id, u);
1936
+ let x = r ? o : this.#t.get(n.id);
1937
+ x !== void 0 && p.set(n.id, x), _ -= e.visible;
1938
+ for (let e of l) y(e);
1939
+ }
1940
+ this.#e = f, this.#t = p;
1941
+ let x = [], S = [], C = new Set(f.keys()), w = 0;
1942
+ for (let e = 0; e < c.length; e++) {
1943
+ let t = c[e];
1944
+ f.has(t.id) || (x.push(t), C.add(t.id), n(t.id) || (w += l[e], S.push({
1945
+ page: t,
1946
+ near: u[e]
1947
+ })));
1948
+ }
1949
+ let T = [];
1950
+ for (let e of m) {
1951
+ let t = -1;
1952
+ for (let n of e.over) t = Math.max(t, h.get(n.id) ?? -1);
1953
+ t >= 0 && T.push({
1954
+ wanted: e,
1955
+ rank: t
1956
+ });
1957
+ }
1958
+ return T.sort((e, t) => t.rank - e.rank), {
1959
+ cut: x,
1960
+ load: S.filter(({ near: e }) => e || !s && w === 0).map(({ page: e }) => e),
1961
+ idx: T.map((e) => e.wanted),
1962
+ keep: C,
1963
+ planned: _,
1964
+ missing: w
1965
+ };
1966
+ }
1967
+ #r(e, t, n) {
1968
+ let r = this.#i(e, t, mt), i = r.shown, { pixels: a, weight: o } = r, s = i;
1969
+ if (n) {
1970
+ let t = this.#i(e, n, mt);
1971
+ t.pixels > a && ({pixels: a, weight: o} = t), s ||= t.shown;
1972
+ }
1973
+ return {
1974
+ page: e,
1975
+ shown: i,
1976
+ near: s,
1977
+ visible: i ? gt(e, t) : 0,
1978
+ pixels: a,
1979
+ weight: o
1980
+ };
1981
+ }
1982
+ #i(e, t, n) {
1983
+ let { width: r, height: i, tan: a, near: o, far: s } = t;
1984
+ return st(e.box, t.view, r, i, a, o, s, n, this.#n, t.origin);
1985
+ }
1986
+ };
1987
+ function gt(e, t) {
1988
+ let { width: n, height: r, tan: i, near: a, far: o, origin: s } = t, c = lt(e.box, ft(e), t.view, n, r, i, a, o, s), l = 0;
1989
+ for (let t = 0; t < 4; t++) c & 1 << t && (l += it(e.row, t));
1990
+ return l;
1991
+ }
1992
+ function _t(e, t) {
1993
+ let { children: n } = e;
1994
+ return e.g > 0 && t(e.id) && !n.includes(void 0) && n.some((e) => e !== null);
1995
+ }
1996
+ var vt = class {
1997
+ #e = [];
1998
+ get size() {
1999
+ return this.#e.length;
2000
+ }
2001
+ push(e) {
2002
+ let t = this.#e;
2003
+ t.push(e);
2004
+ let n = t.length - 1;
2005
+ for (; n > 0;) {
2006
+ let r = n - 1 >> 1;
2007
+ if (!U(e, t[r])) break;
2008
+ t[n] = t[r], n = r;
2009
+ }
2010
+ t[n] = e;
2011
+ }
2012
+ pop() {
2013
+ let e = this.#e, t = e[0], n = e.pop();
2014
+ if (e.length) {
2015
+ let t = 0;
2016
+ for (; 2 * t + 1 < e.length;) {
2017
+ let r = 2 * t + 1;
2018
+ if (r + 1 < e.length && U(e[r + 1], e[r]) && r++, !U(e[r], n)) break;
2019
+ e[t] = e[r], t = r;
2020
+ }
2021
+ e[t] = n;
2022
+ }
2023
+ return t;
2024
+ }
2025
+ };
2026
+ function U(e, t) {
2027
+ return e.shown === t.shown ? e.ratio > t.ratio : e.shown;
2028
+ }
2029
+ //#endregion
2030
+ //#region src/engine/quality.ts
2031
+ var yt = 5e5, bt = 2073600, xt = [1, .85], St = 30, Ct = 55, wt = 2e3, Tt = 5e3, Et = 5e5, Dt = .9;
2032
+ function Ot(e, t, n, r) {
2033
+ return Math.min(n, Math.sqrt(bt / Math.max(1, e * t))) * r;
2034
+ }
2035
+ function kt(e, t) {
2036
+ if (!e.length) return 0;
2037
+ let n = [...e].sort((e, t) => e - t);
2038
+ return n[Math.ceil(n.length * t) - 1];
2039
+ }
2040
+ var At = class {
2041
+ #e = 0;
2042
+ #t;
2043
+ #n;
2044
+ #r;
2045
+ #i = [];
2046
+ #a = -Infinity;
2047
+ #o = 0;
2048
+ #s = 0;
2049
+ constructor(e, [t, n] = [e, e]) {
2050
+ this.#n = t, this.#r = Math.max(t, n), this.#t = Math.min(this.#r, Math.max(this.#n, e));
2051
+ }
2052
+ get scale() {
2053
+ return xt[this.#e];
2054
+ }
2055
+ get budget() {
2056
+ return this.#t;
2057
+ }
2058
+ full() {
2059
+ this.#e = 0, this.#c();
2060
+ }
2061
+ #c() {
2062
+ this.#i = [], this.#o = 0, this.#s = 0, this.#a = -Infinity;
2063
+ }
2064
+ sample(e, t, n, r) {
2065
+ if (!n || t - this.#a > Math.max(250, 2 * e) || !Number.isFinite(e) || e <= 0) return this.#c(), this.#a = t, !1;
2066
+ let i = Math.max(0, t - this.#a);
2067
+ if (this.#a = t, this.#i.push({
2068
+ time: t,
2069
+ ms: e
2070
+ }), this.#i = this.#i.filter((n) => t - n.time <= Math.max(1e3, 2 * e)), t - this.#i[0].time < 300) return !1;
2071
+ let a = this.#i.reduce((e, t) => e + t.ms, 0) / this.#i.length;
2072
+ if (this.#o = a > 1e3 / St ? this.#o + i : 0, this.#s = a <= 1e3 / Ct ? this.#s + i : 0, this.#o >= wt) {
2073
+ let e = Math.floor(Math.min(.9, 1e3 / St / a) * this.#t);
2074
+ if (this.#t > this.#n) this.#t = Math.max(this.#n, e);
2075
+ else if (this.#e < xt.length - 1) this.#e++;
2076
+ else return !1;
2077
+ } else if (this.#s >= Tt) {
2078
+ if (this.#e > 0) this.#e--;
2079
+ else if (this.#t < this.#r && r >= Dt * this.#t) this.#t = Math.min(this.#r, this.#t + Et);
2080
+ else return !1;
2081
+ } else return !1;
2082
+ return this.#c(), !0;
2083
+ }
2084
+ }, jt = class {
2085
+ #e;
2086
+ #t = [];
2087
+ #n = /* @__PURE__ */ new Set();
2088
+ #r = /* @__PURE__ */ new Set();
2089
+ #i = /* @__PURE__ */ new Set();
2090
+ #a = /* @__PURE__ */ new Map();
2091
+ constructor(e) {
2092
+ this.#e = e;
2093
+ }
2094
+ want(e) {
2095
+ this.#t = e, this.#n = new Set(e.map((e) => e.id));
2096
+ }
2097
+ next() {
2098
+ let e = [];
2099
+ for (let t of this.#r) this.#i.has(t) || t.pages.some((e) => this.#n.has(e.id)) || (this.#i.add(t), e.push(t));
2100
+ let t = [];
2101
+ if (this.#r.size >= this.#e.concurrency) return {
2102
+ start: t,
2103
+ abort: e
2104
+ };
2105
+ let n = /* @__PURE__ */ new Map();
2106
+ for (let e of this.#t) {
2107
+ if (this.#a.has(e.id)) continue;
2108
+ let t = n.get(e.pack);
2109
+ t ? t.push(e) : n.set(e.pack, [e]);
2110
+ }
2111
+ for (let e of n.values()) e.sort((e, t) => e.offset - t.offset);
2112
+ for (let e of this.#t) {
2113
+ if (this.#r.size >= this.#e.concurrency) break;
2114
+ if (this.#a.has(e.id)) continue;
2115
+ let r = this.#o(e, n.get(e.pack));
2116
+ for (let e of r.pages) this.#a.set(e.id, r);
2117
+ this.#r.add(r), t.push(r);
2118
+ }
2119
+ return {
2120
+ start: t,
2121
+ abort: e
2122
+ };
2123
+ }
2124
+ done(e) {
2125
+ if (this.#r.delete(e)) {
2126
+ this.#i.delete(e);
2127
+ for (let t of e.pages) this.#a.get(t.id) === e && this.#a.delete(t.id);
2128
+ }
2129
+ }
2130
+ get queued() {
2131
+ let e = 0;
2132
+ for (let t of this.#n) this.#a.has(t) || e++;
2133
+ return e;
2134
+ }
2135
+ get loading() {
2136
+ return this.#a.size;
2137
+ }
2138
+ #o(e, t) {
2139
+ let { gap: n, span: r } = this.#e, i = Math.floor(e.offset / r), a = t.indexOf(e), o = [e], s = e.offset, c = e.offset + e.length;
2140
+ for (let e = a + 1; e < t.length; e++) {
2141
+ let a = t[e];
2142
+ if (this.#a.has(a.id)) continue;
2143
+ let l = Math.max(c, a.offset + a.length);
2144
+ if (a.offset - c > n || l - s > r || Math.floor(a.offset / r) !== i) break;
2145
+ o.push(a), c = l;
2146
+ }
2147
+ for (let e = a - 1; e >= 0; e--) {
2148
+ let a = t[e];
2149
+ if (!this.#a.has(a.id)) {
2150
+ if (s - (a.offset + a.length) > n || c - a.offset > r || Math.floor(a.offset / r) !== i) break;
2151
+ o.unshift(a), s = a.offset;
2152
+ }
2153
+ }
2154
+ return {
2155
+ pack: e.pack,
2156
+ col: e.col,
2157
+ start: s,
2158
+ end: c,
2159
+ window: i,
2160
+ pages: o
2161
+ };
2162
+ }
2163
+ }, Mt = {
2164
+ idx: 8,
2165
+ concurrency: 8,
2166
+ gap: 65536,
2167
+ span: 2097152
2168
+ }, Nt = 1e3, Pt = 3e4, Ft = 1e3, It = 2e3, Lt = class {
2169
+ #e;
2170
+ #t;
2171
+ #n;
2172
+ #r;
2173
+ #i;
2174
+ #a;
2175
+ #o;
2176
+ #s = {
2177
+ cut: [],
2178
+ load: [],
2179
+ idx: [],
2180
+ keep: /* @__PURE__ */ new Set(),
2181
+ planned: 0,
2182
+ missing: 0
2183
+ };
2184
+ #c = /* @__PURE__ */ new Set();
2185
+ #l = [];
2186
+ #u = 0;
2187
+ #d = /* @__PURE__ */ new Set();
2188
+ #f = /* @__PURE__ */ new Map();
2189
+ #p = /* @__PURE__ */ new Map();
2190
+ #m = /* @__PURE__ */ new Map();
2191
+ #h = /* @__PURE__ */ new Map();
2192
+ #g = /* @__PURE__ */ new Set();
2193
+ #_ = /* @__PURE__ */ new Map();
2194
+ #v = [];
2195
+ #y = -Infinity;
2196
+ #b = !1;
2197
+ #x = !1;
2198
+ constructor(e, t, n, r, i, a = Mt) {
2199
+ this.#e = e, this.#t = t, this.#n = n, this.#r = r, this.#i = i, this.#a = a, this.#o = new jt(a);
2200
+ }
2201
+ update(e, t, n) {
2202
+ if (!this.#x) {
2203
+ this.#s = e, this.#c = t, this.#u = n;
2204
+ for (let e of this.#v) this.#_.set(e, n);
2205
+ this.#v = [], this.#S(), this.#l = this.#C(), this.#o.want(this.#l), this.#w(), this.#M();
2206
+ }
2207
+ }
2208
+ protects = (e) => this.#s.keep.has(e) || this.#c.has(e);
2209
+ get loading() {
2210
+ return this.#d.size + this.#f.size;
2211
+ }
2212
+ get queued() {
2213
+ return this.#o.queued;
2214
+ }
2215
+ get idle() {
2216
+ if (this.#d.size > 0 || this.#f.size > 0 || this.#n.queued > 0) return !1;
2217
+ let { idx: e, load: t } = this.#s;
2218
+ return e.length === 0 && t.every(({ id: e }) => this.#n.holds(e));
2219
+ }
2220
+ destroy() {
2221
+ this.#x = !0;
2222
+ for (let e of this.#f.values()) e.abort();
2223
+ this.#f.clear(), this.#d.clear();
2224
+ for (let e of this.#h.values()) clearTimeout(e);
2225
+ this.#h.clear();
2226
+ }
2227
+ #S() {
2228
+ if (!this.#b) for (let { path: e } of this.#s.idx) {
2229
+ if (this.#d.size >= this.#a.idx) break;
2230
+ this.#d.has(e) || this.#F(e) || (this.#d.add(e), this.#t.idx(e).then((t) => {
2231
+ this.#x || (this.#d.delete(e), this.#k(e), this.#v.push(this.#e.add(t, e)), this.#r());
2232
+ }, (t) => {
2233
+ this.#x || (this.#d.delete(e), this.#O(e, t));
2234
+ }));
2235
+ }
2236
+ }
2237
+ #C() {
2238
+ let e = [];
2239
+ for (let { id: t, unit: n, row: r } of this.#s.load) {
2240
+ let { idx: i } = n, a = s(n, i.pack, "pack");
2241
+ if (!this.#N(t, a)) continue;
2242
+ let o = i.col ? s(n, i.col, "col") : null;
2243
+ e.push({
2244
+ id: t,
2245
+ pack: a,
2246
+ col: o,
2247
+ offset: r.offset,
2248
+ length: r.length
2249
+ });
2250
+ }
2251
+ return e;
2252
+ }
2253
+ #w() {
2254
+ if (this.#b) return;
2255
+ let { start: e, abort: t } = this.#o.next();
2256
+ for (let e of t) this.#f.get(e)?.abort();
2257
+ for (let t of e) {
2258
+ let e = new AbortController();
2259
+ this.#f.set(t, e), this.#t.batch(t, e.signal, this.#T).then(() => this.#E(t), (e) => this.#D(t, e));
2260
+ }
2261
+ }
2262
+ #T = ({ id: e, page: t }) => {
2263
+ if (this.#x) return;
2264
+ let n = this.#e.pages.get(e);
2265
+ n && (this.#n.add(e, t, [n.unit.e, n.unit.n], this.protects) ? (this.#g.add(e), this.#m.delete(e) && this.#j(e)) : (this.#m.set(e, this.#u + Ft), this.#A(e, Ft)), this.#r());
2266
+ };
2267
+ #E(e) {
2268
+ this.#x || (this.#f.delete(e), this.#k(e.pack), this.#l = this.#l.filter((e) => this.#N(e.id, e.pack)), this.#o.want(this.#l), this.#o.done(e), this.#w(), this.#r());
2269
+ }
2270
+ #D(e, t) {
2271
+ this.#x || (this.#f.delete(e), this.#o.done(e), t instanceof DOMException && t.name === "AbortError" || this.#O(e.pack, t));
2272
+ }
2273
+ #O(e, t) {
2274
+ if (t instanceof l) {
2275
+ if (this.#b) return;
2276
+ this.#b = !0, this.#i();
2277
+ return;
2278
+ }
2279
+ let n = this.#p.get(e), r = n ? Math.min(2 * n.delay, Pt) : Nt;
2280
+ this.#p.set(e, {
2281
+ delay: r,
2282
+ until: this.#u + r
2283
+ }), this.#A(e, r);
2284
+ }
2285
+ #k(e) {
2286
+ this.#p.delete(e), this.#j(e);
2287
+ }
2288
+ #A(e, t) {
2289
+ clearTimeout(this.#h.get(e));
2290
+ let n = setTimeout(() => {
2291
+ this.#h.delete(e), this.#r();
2292
+ }, t);
2293
+ this.#h.set(e, n);
2294
+ }
2295
+ #j(e) {
2296
+ clearTimeout(this.#h.get(e)), this.#h.delete(e);
2297
+ }
2298
+ #M() {
2299
+ let e = this.#u;
2300
+ if (e - this.#y < It) return;
2301
+ this.#y = e;
2302
+ for (let e of this.#g) this.#n.holds(e) || this.#g.delete(e);
2303
+ for (let [t, n] of this.#m) n <= e && this.#m.delete(t);
2304
+ for (let [t, n] of this.#_) e - n >= It && this.#_.delete(t);
2305
+ let { keep: t } = this.#s;
2306
+ if (this.#e.pages.size <= 2 * (this.#g.size + t.size)) return;
2307
+ let n = /* @__PURE__ */ new Set([
2308
+ ...t,
2309
+ ...this.#c,
2310
+ ...this.#g
2311
+ ]);
2312
+ for (let e of this.#_.keys()) for (let { id: t } of e.pages) n.add(t);
2313
+ for (let e of this.#e.prune(n)) this.#n.holds(e) && this.#n.remove(e);
2314
+ }
2315
+ #N(e, t) {
2316
+ return !this.#e.pages.has(e) || this.#n.holds(e) ? !1 : !this.#P(e) && !this.#F(t);
2317
+ }
2318
+ #P(e) {
2319
+ let t = this.#m.get(e);
2320
+ return t !== void 0 && this.#u < t;
2321
+ }
2322
+ #F(e) {
2323
+ let t = this.#p.get(e);
2324
+ return t !== void 0 && this.#u < t.until;
2325
+ }
2326
+ };
2327
+ //#endregion
2328
+ //#region src/engine/stream/remote.ts
2329
+ function Rt(e, t) {
2330
+ let n = /* @__PURE__ */ new Map();
2331
+ return (r) => {
2332
+ if ("unfetch" in r) return void n.get(r.unfetch)?.abort();
2333
+ let i = r.fetch, a = new AbortController();
2334
+ n.set(i, a), (async () => e(r.url, r.range, a.signal))().then((e) => {
2335
+ let n = e.slice();
2336
+ t({
2337
+ fetched: i,
2338
+ bytes: n
2339
+ }, [n.buffer]);
2340
+ }, (e) => {
2341
+ let n = e instanceof Error ? e.message : String(e);
2342
+ t({
2343
+ fetched: i,
2344
+ error: n,
2345
+ missing: e instanceof l
2346
+ }, []);
2347
+ }).finally(() => n.delete(i));
2348
+ };
2349
+ }
2350
+ //#endregion
2351
+ //#region src/engine/stream/worker.ts?worker&inline
2352
+ var zt = "(function(){var e=class extends Error{name=`Missing`};let t=async(t,n,r)=>{let i=await fetch(t,n?{signal:r,headers:{Range:`bytes=${n[0]}-${n[1]-1}`}}:{signal:r});if(i.status===404)throw new e(`http 404 for ${t}`);if(i.status!==200&&i.status!==206)throw Error(`http ${i.status} for ${t}`);let a=new Uint8Array(await i.arrayBuffer());return n&&i.status===200?a.slice(n[0],n[1]):a},n=.28209479177387814,r=15.625,i=`GMIX`,a={position:0,alpha:6,rotationIndex:7,rotation:8,scale:11,dc:14,label:17},o={origin:0,step:3,scaleMin:6,scaleMax:9,dcMin:12,dcMax:15,shScale:18};async function s(e,t){let n=new ReadableStream({start(t){t.enqueue(e),t.close()}}).pipeThrough(t);return new Uint8Array(await new Response(n).arrayBuffer())}function c(e){return s(e,new DecompressionStream(`deflate-raw`))}function l(e){return s(e,new CompressionStream(`deflate-raw`))}async function u(e,t,n){let r=new DataView(e.buffer,e.byteOffset,e.byteLength);if(e.length<8||String.fromCharCode(...e.subarray(0,4))!==t)throw Error(`not a ${n} file`);let i=r.getUint16(4,!0);if(i!==1)throw Error(`${n} version ${i}; narcissus reads 1`);let a;try{a=await c(e.subarray(8))}catch{throw Error(`${n} body is not a valid deflate stream`)}return new DataView(a.buffer,a.byteOffset,a.byteLength)}function d(e,t){let n=``;for(let r=0;r<8;r++){let i=e.getUint8(t+r);n+=i.toString(16).padStart(2,`0`)}return n}function f(e,t){let n=/* @__PURE__ */ new Float32Array(6);for(let r=0;r<6;r++)n[r]=e.getFloat32(t+20+4*r,!0);return{g:e.getUint8(t),i:e.getUint8(t+1),j:e.getUint8(t+2),count:e.getUint32(t+4,!0),quadrants:[e.getUint32(t+8,!0),e.getUint32(t+12,!0),e.getUint32(t+16,!0)],box:n,offset:e.getUint32(t+44,!0),length:e.getUint32(t+48,!0)}}async function p(e){let t=await u(e,i,`.idx`);if(t.byteLength<40)throw Error(`.idx header is cut off`);let n=t.getUint16(32,!0),r=t.getUint8(34),a=t.getUint16(36,!0),o=40+n*52+r*9+a*11;if(t.byteLength!==o)throw Error(`.idx holds ${t.byteLength} bytes, its counts need ${o}`);let s=d(t,24),c={level:t.getUint8(0),e:t.getInt32(4,!0),n:t.getInt32(8,!0),pack:d(t,12),packSize:t.getUint32(20,!0),col:s===`0000000000000000`?null:s,rows:[],children:[],descendants:[]},l=40;for(let e=0;e<n;e++,l+=52)c.rows.push(f(t,l));for(let e=0;e<r;e++,l+=9)c.children.push({quadrant:t.getUint8(l),idx:d(t,l+1)});for(let e=0;e<a;e++,l+=11)c.descendants.push({depth:t.getUint8(l),column:t.getUint8(l+1),row:t.getUint8(l+2),idx:d(t,l+3)});return c}function m(e,t,n){return`u/${e.level}/${e.e}/${e.n}.${t}.${n}`}let h=/(?:^|\\/)u\\/(\\d+)\\/(-?\\d+)\\/(-?\\d+)\\.([0-9a-f]{16})\\.(?:idx|pack|col)$/;function g(e){let t=h.exec(e);return t?{level:Number(t[1]),e:Number(t[2]),n:Number(t[3]),hash:t[4]}:null}async function _(e){let t=await u(e,`GMCL`,`.col`);if(t.byteLength<60)throw Error(`.col header is cut off`);let n=t.getUint16(0,!0),r=60+12*n*n;if(t.byteLength!==r)throw Error(`.col holds ${t.byteLength} bytes, ${n} nodes need ${r}`);let i=new Float32Array(12*n*n),a=60;for(let e=0;e<12;e++){let r=t.getFloat32(12+4*e,!0)/127;for(let o=0;o<n;o++){let s=0;for(let c=0;c<n;c++,a++)s=s+t.getInt8(a)<<24>>24,i[(e*n+o)*n+c]=s*r}}return{n,pitch:t.getFloat32(4,!0),margin:t.getFloat32(8,!0),values:i}}function v(e,t,n,r){let{n:i,pitch:a,margin:o,values:s}=e,c=i-1,l=Math.min(Math.max((t+o)/a-.5,0),c),u=Math.min(Math.max((n+o)/a-.5,0),c),d=Math.min(Math.floor(l),Math.max(c-1,0)),f=Math.min(Math.floor(u),Math.max(c-1,0)),p=Math.min(d+1,c),m=Math.min(f+1,c),h=l-d,g=u-f,_=(1-h)*(1-g),v=h*(1-g),y=(1-h)*g,b=h*g,x=i*i;for(let e=0,t=0;e<12;e++,t+=x)r[e]=s[t+f*i+d]*_+s[t+f*i+p]*v+s[t+m*i+d]*y+s[t+m*i+p]*b;return r}let y=Float64Array.from({length:256},(e,t)=>(t/255-.5)*Math.SQRT2);function b(e,t,n,r,i){let a=y[t],o=y[n],s=y[r];i[e]=Math.sqrt(Math.max(0,1-a*a-o*o-s*s)),i[e>0?0:1]=a,i[e>1?1:2]=o,i[e>2?2:3]=s}function x(e,t,n,r,i){let a=e[0],o=e[1],s=e[2],c=e[3],l=t*t,u=n*n,d=r*r,f=1-2*(s*s+c*c),p=2*(o*s-a*c),m=2*(o*c+a*s),h=2*(o*s+a*c),g=1-2*(o*o+c*c),_=2*(s*c-a*o),v=2*(o*c-a*s),y=2*(s*c+a*o),b=1-2*(o*o+s*s);i[0]=3*Math.sqrt(f*f*l+p*p*u+m*m*d),i[1]=3*Math.sqrt(h*h*l+g*g*u+_*_*d),i[2]=3*Math.sqrt(v*v*l+y*y*u+b*b*d)}function S(e){if(e.length<128)throw Error(`page payload is shorter than its header`);return new DataView(e.buffer,e.byteOffset,e.byteLength)}function C(e){let t=S(e),n=t.getUint32(0,!0),r=t.getUint16(16,!0),i=128+(17+(r>0?2:0))*n,a=i+r*9;if(e.length!==a)throw Error(`page payload holds ${e.length} bytes, its header needs ${a}`);return{view:t,count:n,k:r,book:i}}function w(e){return[e.getUint32(4,!0),e.getUint32(8,!0),e.getUint32(12,!0)]}function T(e,t){let{view:n,count:r,k:i,book:s}=C(e),c=/* @__PURE__ */ new Float32Array(27);for(let e=0;e<27;e++)c[e]=n.getFloat32(20+4*e,!0);i===0&&c.fill(0,o.shScale);let l=new Uint32Array(r*4),u=new Float32Array(Math.ceil(r/256)*6),d=/* @__PURE__ */ new Float64Array(768);for(let e=0;e<3;e++){let t=c[o.scaleMin+e],n=c[o.scaleMax+e]-t;for(let r=0;r<256;r++)d[e*256+r]=Math.exp(t+r/255*n)}let f=c[o.step],p=c[o.step+1],m=c[o.step+2],h=128+a.position*r,g=128+a.alpha*r,_=128+a.rotationIndex*r,v=128+a.rotation*r,y=128+a.scale*r,S=/* @__PURE__ */ new Float64Array(4),T=/* @__PURE__ */ new Float64Array(3),O=0,k=0,A=0;for(let t=0,n=0;n<r;t++){let i=1/0,a=1/0,o=1/0,s=-1/0,c=-1/0,C=-1/0;for(let t=Math.min(n+256,r);n<t;n++){let t=e[h+n]|e[h+r+n]<<8;O=O+(t>>>1^-(t&1))&65535,t=e[h+2*r+n]|e[h+3*r+n]<<8,k=k+(t>>>1^-(t&1))&65535,t=e[h+4*r+n]|e[h+5*r+n]<<8,A=A+(t>>>1^-(t&1))&65535;let u=e[_+n],w=e[v+n],E=e[v+r+n],D=e[v+2*r+n],j=e[y+n],M=e[y+r+n],N=e[y+2*r+n],P=n*4;l[P]=O|k<<16,l[P+1]=A|e[g+n]<<16|u<<24,l[P+2]=w|E<<8|D<<16|j<<24,l[P+3]=M|N<<8,b(u,w,E,D,S),x(S,d[j],d[256+M],d[512+N],T);let F=O*f,I=k*p,L=A*m;i=Math.min(i,F-T[0]),a=Math.min(a,I-T[1]),o=Math.min(o,L-T[2]),s=Math.max(s,F+T[0]),c=Math.max(c,I+T[1]),C=Math.max(C,L+T[2])}u.set([i,a,o,s,c,C],t*6)}let j=t?D(e,r,i,s,l,c,t):E(e,r,i,s);return{count:r,quadrants:w(n),geometry:l,colour:j,params:c,clusters:u}}function E(e,t,n,r){let i=new Uint32Array(t*3),o=128+a.dc*t,s=128+a.label*t;for(let a=0;a<t;a++){let c=a*3;if(i[c]=e[o+a]|e[o+t+a]<<8|e[o+2*t+a]<<16,n===0)continue;let l=r+(e[s+a]|e[s+t+a]<<8)*9;i[c]|=e[l]<<24,i[c+1]=e[l+1]|e[l+2]<<8|e[l+3]<<16|e[l+4]<<24,i[c+2]=e[l+5]|e[l+6]<<8|e[l+7]<<16|e[l+8]<<24}return i}function D(e,t,r,i,s,c,l){let u=128+a.dc*t,d=128+a.label*t,f=new Int8Array(e.buffer,e.byteOffset+i,r*9),p=new Float32Array(t*3),m=new Float32Array(t*9),h=[1/0,1/0,1/0],g=[-1/0,-1/0,-1/0],_=/* @__PURE__ */ new Float32Array(9),y=/* @__PURE__ */ new Float32Array(12),b=c[o.origin],x=c[o.origin+1],S=c[o.step],C=c[o.step+1],w=/* @__PURE__ */ new Float64Array(768);for(let e=0;e<3;e++){let t=c[o.dcMin+e],n=c[o.dcMax+e]-t;for(let r=0;r<256;r++)w[e*256+r]=t+r/255*n}let T=new Float64Array(Math.max(r,1)*9);for(let e=0;e<r*9;e++)T[e]=f[e]/127*c[o.shScale+e%9];for(let i=0;i<t;i++){let a=s[i*4];v(l,b+(a&65535)*S,x+(a>>>16)*C,y);for(let r=0;r<3;r++){let a=i*3+r;p[a]=w[r*256+e[u+r*t+i]]+y[r]/n,h[r]=Math.min(h[r],p[a]),g[r]=Math.max(g[r],p[a])}let o=r>0?(e[d+i]|e[d+t+i]<<8)*9:0;for(let e=0;e<9;e++){let t=i*9+e;m[t]=T[o+e]+y[3+e],_[e]=Math.max(_[e],Math.abs(m[t]))}}for(let e=0;e<3;e++)c[o.dcMin+e]=t>0?h[e]:0,c[o.dcMax+e]=t>0?g[e]:0;c.set(_,o.shScale);let E=[0,1,2].map(e=>{let t=c[o.dcMax+e]-c[o.dcMin+e];return t>0?255/t:0}),D=Array.from(_,e=>e>0?127/e:0),O=[0,1,2].map(e=>c[o.dcMin+e]),k=new Uint32Array(t*3),A=new Uint8Array(k.buffer);for(let e=0;e<t;e++){let t=e*4*3;for(let n=0;n<3;n++){let r=Math.round((p[e*3+n]-O[n])*E[n]);A[t+n]=Math.min(255,Math.max(0,r))}for(let n=0;n<9;n++){let r=Math.round(m[e*9+n]*D[n]);A[t+3+n]=Math.min(127,Math.max(-127,r))}}return k}let O=(e,t,n)=>Math.min(n,Math.max(t,e));function k(e,t,n){return n>t?O(Math.round((e-t)/(n-t)*255),0,255):0}function A(e,t){return t>0?O(Math.round(e/t*127),-127,127):0}function j(e){return e&=1023,e=(e|e<<16)&50331903,e=(e|e<<8)&50393103,e=(e|e<<4)&51130563,(e|e<<2)&153391689}function M(e,t,n){return j(e>>6)|j(t>>6)<<1|j(n>>6)<<2}function N(e,t){let n=/* @__PURE__ */ new Float32Array(9);for(let r=0;r<t;r++)for(let t=0;t<9;t++)n[t]=Math.max(n[t],Math.abs(e[r*9+t]));return n}function P(e,t,n){let r=new Int8Array(t*9);for(let i=0;i<t;i++)for(let t=0;t<9;t++)r[i*9+t]=A(e[i*9+t],n[t]);let i=e=>r.subarray(e*9,(e+1)*9),a=/* @__PURE__ */ new Map,o=[],s=new Uint16Array(t);for(let e=0;e<t;e++){let t=i(e).join(),n=a.get(t);n===void 0&&(n=o.length,a.set(t,n),o.push(e)),s[e]=n}if(o.length>2048){let e=o.length/256,n=Array.from({length:256},(t,n)=>o[Math.floor(n*e)]);o.splice(0,o.length,...n);for(let e=0;e<t;e++){let t=1/0;for(let n=0;n<256;n++){let i=0;for(let t=0;t<9;t++)i+=(r[e*9+t]-r[o[n]*9+t])**2;i<t&&(t=i,s[e]=n)}}}let c=new Int8Array(o.length*9);return o.forEach((e,t)=>c.set(i(e),t*9)),{book:c,labels:s}}function F(e,t){let{count:n,position:i,rotation:o,scale:s,alpha:c,dc:l,sh:u}=e,d=[1/0,1/0,1/0],f=[-1/0,-1/0,-1/0],p=[...d],m=[...f],h=[...d],g=[...f];for(let e=0;e<n;e++)for(let t=0;t<3;t++)d[t]=Math.min(d[t],i[e*3+t]),f[t]=Math.max(f[t],i[e*3+t]),p[t]=Math.min(p[t],s[e*3+t]),m[t]=Math.max(m[t],s[e*3+t]),h[t]=Math.min(h[t],l[e*3+t]),g[t]=Math.max(g[t],l[e*3+t]);let _=5e-4*2**t.g,v=Float32Array.from(d),y=Float32Array.from(d,(e,t)=>Math.max(_,(f[t]-e)/65535)),b=new Uint16Array(n*3);for(let e=0;e<n;e++)for(let t=0;t<3;t++){let n=(i[e*3+t]-v[t])/y[t];b[e*3+t]=O(Math.round(n),0,65535)}let S=r*2**t.g,C=(t.i+.5)*S,w=(t.j+.5)*S,T=new Uint8Array(n),E=new Float64Array(n);for(let e=0;e<n;e++){let t=+(i[e*3]>=C),n=+(i[e*3+1]>=w);T[e]=t+2*n,E[e]=T[e]*2**30+M(b[e*3],b[e*3+1],b[e*3+2])}let D=Uint32Array.from({length:n},(e,t)=>t).sort((e,t)=>E[e]-E[t]),A=[0,0,0];for(let e=1;e<4;e++)A[e-1]=T.filter(t=>t<e).length;let j=u?N(u,n):/* @__PURE__ */ new Float32Array(9),{book:F,labels:I}=u?P(u,n,j):{book:null,labels:null},L=F?F.length/9:0,R=17+(L>0?2:0),z=new Uint8Array(128+R*n+L*9),B=new DataView(z.buffer);B.setUint32(0,n,!0),A.forEach((e,t)=>B.setUint32(4+4*t,e,!0)),B.setUint16(16,L,!0),[...v,...y,...p,...m,...h,...g,...j].forEach((e,t)=>B.setFloat32(20+4*t,e,!0));let V=e=>128+e*n,H=new Float32Array([...d,...f]),U=/* @__PURE__ */ new Float64Array(4),W=/* @__PURE__ */ new Float64Array(3),G=[0,0,0];for(let e=0;e<n;e++){let t=D[e];for(let n=0;n<3;n++){let r=b[t*3+n]-G[n]<<16>>16,i=r<0?-2*r-1:2*r;G[n]=b[t*3+n],z[V(a.position+2*n)+e]=i&255,z[V(a.position+2*n+1)+e]=i>>8}z[V(a.alpha)+e]=O(Math.round(c[t]*255),0,255);let n=Math.hypot(...o.subarray(t*4,t*4+4));for(let e=0;e<4;e++)U[e]=o[t*4+e]/n;let r=0;for(let e=1;e<4;e++)Math.abs(U[e])>Math.abs(U[r])&&(r=e);let u=U[r]<0?-1:1;z[V(a.rotationIndex)+e]=r;for(let t=0,n=0;t<4;t++){if(t===r)continue;let i=Math.round((u*U[t]/Math.SQRT2+.5)*255);z[V(a.rotation+n++)+e]=O(i,0,255)}for(let n=0;n<3;n++)z[V(a.scale+n)+e]=k(s[t*3+n],p[n],m[n]),z[V(a.dc+n)+e]=k(l[t*3+n],h[n],g[n]);I&&(z[V(a.label)+e]=I[t]&255,z[V(a.label+1)+e]=I[t]>>8);let[d,f,_]=[0,1,2].map(e=>Math.exp(s[t*3+e]));x(U,d,f,_,W);for(let e=0;e<3;e++)H[e]=Math.min(H[e],i[t*3+e]-W[e]),H[3+e]=Math.max(H[3+e],i[t*3+e]+W[e])}return F&&z.set(new Uint8Array(F.buffer),V(R)),{payload:z,row:{g:t.g,i:t.i,j:t.j,count:n,quadrants:A,box:H,offset:0,length:0}}}function I(e,t,n){e.setUint8(t,n.g),e.setUint8(t+1,n.i),e.setUint8(t+2,n.j),e.setUint32(t+4,n.count,!0),n.quadrants.forEach((n,r)=>e.setUint32(t+8+4*r,n,!0)),n.box.forEach((n,r)=>e.setFloat32(t+20+4*r,n,!0)),e.setUint32(t+44,n.offset,!0),e.setUint32(t+48,n.length,!0)}function L(e,t,n){for(let r=0;r<4;r++)e[t+r]=n.charCodeAt(r)}function R(e){return Uint8Array.from({length:8},(t,n)=>parseInt(e.slice(2*n,2*n+2),16))}async function z(e,t){let n=await l(e),r=new Uint8Array(8+n.length);return L(r,0,t),new DataView(r.buffer).setUint16(4,1,!0),r.set(n,8),r}async function B(e){let{rows:t,children:n,descendants:r}=e,a=new Uint8Array(40+t.length*52+n.length*9+r.length*11),o=new DataView(a.buffer);o.setUint8(0,e.level),o.setInt32(4,e.e,!0),o.setInt32(8,e.n,!0),a.set(R(e.pack),12),o.setUint32(20,e.packSize,!0),e.col&&a.set(R(e.col),24),o.setUint16(32,t.length,!0),o.setUint8(34,n.length),o.setUint16(36,r.length,!0);let s=40;for(let e of t)I(o,s,e),s+=52;for(let e of n)o.setUint8(s,e.quadrant),a.set(R(e.idx),s+1),s+=9;for(let e of r)o.setUint8(s,e.depth),o.setUint8(s+1,e.column),o.setUint8(s+2,e.row),a.set(R(e.idx),s+3),s+=11;return z(a,i)}function V(e){let t=3421674724,n=2216829733;for(let r=0;r<e.length;r++){n=(n^e[r])>>>0;let i=n*435;t=t*435+(n<<8>>>0)+Math.floor(i/4294967296)>>>0,n=i>>>0}return t.toString(16).padStart(8,`0`)+n.toString(16).padStart(8,`0`)}function H(e){return()=>{e=e+1831565813|0;let t=Math.imul(e^e>>>15,1|e);return t=t+Math.imul(t^t>>>7,61|t)^t,((t^t>>>14)>>>0)/2**32}}async function U(e,t){return p(await G(e,t))}async function*W(e,t,n,r){let i=t.col===null?null:te(e,t.col,n),a=await ee(e,t,r),o=await i;for(let[e,n]of t.pages.entries()){let t=await c(a[e]);r?.throwIfAborted(),yield{id:n.id,page:T(t,o)}}}async function G(e,t){let n=await e.cache.get(t);if(n)return n;let r=await e.fetch(e.base+t,null);return e.cache.put(t,r),r}async function ee(e,t,n){let r=t.pages.map(e=>`${t.pack}#${e.offset}+${e.length}`),i=await Promise.all(r.map(t=>e.cache.get(t)));if(n?.throwIfAborted(),i.every(e=>e!==void 0))return i;let a=await e.fetch(e.base+t.pack,[t.start,t.end],n);if(a.length!==t.end-t.start)throw Error(`${t.pack}: ${a.length} bytes for ${t.start}-${t.end}`);return t.pages.map((n,o)=>{let s=a.slice(n.offset-t.start,n.offset-t.start+n.length);return i[o]||e.cache.put(r[o],s),s})}function te(e,t,n){let r=n.get(t);if(r)n.delete(t);else{let i=G(e,t).then(_);i.catch(()=>{n.get(t)===i&&n.delete(t)}),r=i}if(n.set(t,r),n.size>64){let[e]=n.keys();n.delete(e)}return r}function ne(e){let t=/* @__PURE__ */ new Map,n=0;return{async get(e){let n=t.get(e);return n&&(t.delete(e),t.set(e,n)),n},async put(r,i){let a=t.get(r);if(a&&(t.delete(r),n-=a.length),!(i.length>e)){t.set(r,i),n+=i.length;for(let[r,i]of t){if(n<=e)break;t.delete(r),n-=i.length}}}}}async function re(e,t){let n;try{n=await(await ae()).getDirectoryHandle(String(t),{create:!0})}catch{return null}let r=/* @__PURE__ */ new Map,i=0,a=!1,o=(e,t)=>{i+=t-(r.get(e)??0),r.delete(e),r.set(e,t)},s=e=>{i-=r.get(e)??0,r.delete(e)},c=()=>{if(a)for(let[t,a]of r){if(i<=e)break;r.delete(t),i-=a,n.removeEntry(t).catch(()=>void 0)}};return ce(n).then(e=>{let t=[...r];r.clear(),i=0;for(let{name:t,size:n}of e.sort((e,t)=>e.time-t.time))o(t,n);for(let[e,n]of t)o(e,n);a=!0,c()}),{async get(e){let t=encodeURIComponent(e);if(a&&!r.has(t))return;let i=await oe(n,t);return i?o(t,i.length):s(t),i},async put(t,r){if(r.length===0||r.length>e)return;let i=encodeURIComponent(t);await se(n,i,r)&&(o(i,r.length),c())}}}async function ie(e){let t=new Set(Array.from({length:e},(e,t)=>String(t)));try{let e=await ae(),n=[];for await(let[r,i]of e.entries())(i.kind!==`directory`||!t.has(r))&&n.push(r);let r={recursive:!0};for(let t of n)await e.removeEntry(t,r).catch(()=>void 0)}catch{}}async function ae(){return(await navigator.storage.getDirectory()).getDirectoryHandle(`cache`,{create:!0})}async function oe(e,t){try{let n=await(await e.getFileHandle(t)).getFile();return n.size>0?new Uint8Array(await n.arrayBuffer()):void 0}catch{return}}async function se(e,t,n){let r;try{return r=await(await e.getFileHandle(t,{create:!0})).createWritable(),await r.write(n),await r.close(),!0}catch{return r?.abort().catch(()=>void 0),!1}}async function ce(e){let t=[];try{for await(let[n,r]of e.entries()){if(r.kind!==`file`)continue;let e=await r.getFile().catch(()=>null);e&&t.push({name:n,size:e.size,time:e.lastModified})}}catch{}return t}function le(t){let n=/* @__PURE__ */ new Map,r=0;return{fetch:(i,a,o)=>new Promise((s,c)=>{if(o?.aborted)return c(o.reason);let l=++r,u=()=>{n.delete(l),t({unfetch:l}),c(o.reason)};n.set(l,t=>{o?.removeEventListener(`abort`,u),`bytes`in t?s(t.bytes):c(t.missing?new e(t.error):Error(t.error))}),o?.addEventListener(`abort`,u,{once:!0}),t({fetch:l,url:i,range:a})}),take(e){let t=n.get(e.fetched);n.delete(e.fetched),t?.(e)}}}let K=16384,ue=1408,de=65535,q=324121,fe=.4,pe=[[12,1/7e3,0,1/9e3,.7],[9,1/2300,1.1,1/3100,.4],[6,1/800,.3,1/1100,2],[3,1/150,.9,1/210,1.7]],me=pe.reduce((e,[t,n,,r])=>e+t*(n+r),0),he=Float32Array.from({length:ue*9},(e,t)=>{let n=Math.floor(t/9),r=t%9,i=(n*(37+2*r)+11*r)%255-127;return r===0&&(i=n%255-127),r===1&&(i=20*Math.floor(n/255)-50),i/127*.04}),J=new TextEncoder,ge={version:1,crs:`synthetic`,height:`synthetic`,leaf:250,roots:[512e4,6144e3].map(e=>({level:12,e:0,n:e})).map(e=>({...e,idx:m(e,Y(e,`idx`),`idx`)})),extent:{e:[44e4,9e5],n:[605e4,641e4],h:[0,80]}},_e=J.encode(JSON.stringify(ge));function ve(){return async(t,n)=>{if(t.endsWith(`world.json`))return be(_e,n);let r=g(t),i=t.slice(t.lastIndexOf(`.`)+1);if(!r||i!==`idx`&&i!==`pack`||!xe(r)||r.hash!==Y(r,i))throw new e(`no file ${t}`);return i===`idx`?be(await De(r),n):Oe(r,n,t)}}function ye(e,t){let n=30;for(let[r,i,a,o,s]of pe)n+=r*Math.sin(i*e+a)*Math.sin(o*t+s);return n}function be(e,t){return t?e.slice(t[0],t[1]):e.slice()}function Y(e,t){return V(J.encode(`${e.level}/${e.e}/${e.n}.${t}`))}function X(e,t,n){let{e:r,n:i}=ge.extent;return e<r[1]&&e+n>r[0]&&t<i[1]&&t+n>i[0]}function xe({level:e,e:t,n}){let r=250*2**e;return e<=12&&t%r===0&&n%r===0&&X(t,n,r)}function Se(e){return e===0?[1,0]:e===12?[16,15,14,13]:[e+1]}function Ce(e){let t=0;for(let n=0;n<8;n++)t|=(e>>2*n&1)<<n;return t}function we(e){let t=[];for(let n of Se(e.level)){let i=r*2**n,a=250*2**e.level/i;for(let r=0;r<a*a;r++){let a=Ce(r),o=Ce(r>>1);X(e.e+a*i,e.n+o*i,i)&&t.push({g:n,i:a,j:o})}}return t}function Te(e,t){let n=e.level-t,r=250*2**n,i=[];for(let a=0;n>=0&&a<2**t;a++)for(let o=0;o<2**t;o++){let t={level:n,e:e.e+o*r,n:e.n+a*r};X(t.e,t.n,r)&&i.push({column:o,row:a,unit:t})}return i}function Ee(e,{g:t,i:n,j:i},a){let o=r*2**t,s=o/128,c=3*1.2*s,l=1.17*s,u=ye(e.e+(n+.5)*o,e.n+(i+.5)*o),d=me*o/2,f=Float32Array.of(n*o-c,i*o-c,Math.max(0,u-d)-l,(n+1)*o+c,(i+1)*o+c,Math.min(60,u+d)+l),p=K/4;return{g:t,i:n,j:i,count:K,quadrants:[p,2*p,3*p],box:f,offset:a,length:q}}function De(e){let t=we(e),n=[];for(let{column:t,row:r,unit:i}of Te(e,1))n.push({quadrant:t+2*r,idx:Y(i,`idx`)});let r=[];for(let t of[2,3])for(let{column:n,row:i,unit:a}of Te(e,t))r.push({depth:t,column:n,row:i,idx:Y(a,`idx`)});return B({level:e.level,e:e.e,n:e.n,pack:Y(e,`pack`),packSize:t.length*324173+16,col:null,rows:t.map((t,n)=>Ee(e,t,n*q)),children:n,descendants:r})}function Oe(e,t,n){let r=we(e);if(!t||t[0]%q!=0||t[1]%q!=0||t[0]>=t[1]||t[1]>r.length*q)throw Error(`${n}: the synthetic world serves whole pages only`);let i=new Uint8Array(t[1]-t[0]);for(let n=0;n<i.length;n+=q)ke(je(e,r[(t[0]+n)/q]),i,n);return i}function ke(e,t,n){let r=n;for(let n=0;n<e.length;n+=de){let i=Math.min(de,e.length-n);t[r]=+(n+i===e.length),t[r+1]=i&255,t[r+2]=i>>8,t[r+3]=~i&255,t[r+4]=~i>>8&255,t.set(e.subarray(n,n+i),r+5),r+=5+i}}let Ae=e=>H(parseInt(V(J.encode(e)).slice(8),16));function je(e,{g:t,i,j:a}){let o=K,s=r*2**t/128,c=Ae(`${e.level}/${e.e}/${e.n}/${t}/${i}/${a}`),l=new Float64Array(3*o),u=new Float32Array(4*o),d=new Float32Array(3*o),f=new Float32Array(o),p=new Float32Array(3*o),m=new Float32Array(9*o);for(let t=0;t<o;t++){let r=(i*128+t%128+.5+fe*(2*c()-1))*s,o=(a*128+Math.floor(t/128)+.5+fe*(2*c()-1))*s,h=ye(e.e+r,e.n+o);l[3*t]=r,l[3*t+1]=o,l[3*t+2]=h;let g=Math.PI*c(),_=.1/2*(2*c()-1);u[4*t]=Math.cos(g)*Math.cos(_),u[4*t+1]=Math.cos(g)*Math.sin(_),u[4*t+2]=Math.sin(g)*Math.sin(_),u[4*t+3]=Math.sin(g)*Math.cos(_);for(let e=0;e<2;e++)d[3*t+e]=Math.log(s*(.6+.6*c()));d[3*t+2]=Math.log(s*.15*(.5+.5*c())),f[t]=.35+.65*c();let v=h/60,y=.5+.5*Math.sin((e.e+r)/410)*Math.sin((e.n+o)/330);p[3*t]=(.32+.2*v+.1*y-.5)/n,p[3*t+1]=(.42+.15*y-.1*v-.5)/n,p[3*t+2]=(.25+.1*v+.04*c()-.5)/n;let b=t%ue;m.set(he.subarray(9*b,9*(b+1)),9*t)}return F({count:o,position:l,rotation:u,scale:d,alpha:f,dc:p,sh:m},{g:t,i,j:a}).payload}let Z=2**20,Q=self,$,Me=/* @__PURE__ */ new Map,Ne=/* @__PURE__ */ new Map,Pe=le(e=>Q.postMessage(e,[]));Q.onmessage=({data:e})=>{`fetched`in e?Pe.take(e):e.type===`init`?($=Fe(e),$.catch(()=>void 0)):e.type===`abort`?Ne.get(e.id)?.abort():Re(e)};async function Fe(e){return e.source===`synthetic`?{fetch:ve(),cache:await Ie({...e,cache:`none`}),base:e.base}:{fetch:e.source===`page`?Pe.fetch:t,cache:await Ie(e),base:e.base}}async function Ie({cache:e,shard:t,shards:n}){return e===`memory`?ne(256*Z):e===`none`?{get:async()=>void 0,put:async()=>void 0}:(t===0&&ie(n),await re(await Le()/n,t)??ne(256*Z))}async function Le(){try{let{quota:e}=await navigator.storage.estimate();return Math.min(4096*Z,e===void 0?1/0:e/2)}catch{return 4096*Z}}async function Re(t){let{id:n}=t,r=new AbortController;Ne.set(n,r);try{if(!$)throw Error(`stream worker used before init`);let e=await $;if(t.type===`idx`)Q.postMessage({id:n,value:await U(e,t.path)},[]);else{for await(let i of W(e,t.batch,Me,r.signal))Q.postMessage({id:n,page:i},ze(i));Q.postMessage({id:n,done:!0},[])}}catch(t){let r=t instanceof Error?t.message:String(t);Q.postMessage({id:n,error:r,missing:t instanceof e},[])}finally{Ne.delete(n)}}function ze({page:e}){let t=/* @__PURE__ */ new Set;for(let n of[e.geometry,e.colour,e.params,e.clusters])t.add(n.buffer);return[...t]}})();", Bt = typeof self < "u" && self.Blob && new Blob(["(self.URL || self.webkitURL).revokeObjectURL(self.location.href);", zt], { type: "text/javascript;charset=utf-8" });
2353
+ function Vt(e) {
2354
+ let t;
2355
+ try {
2356
+ if (t = Bt && (self.URL || self.webkitURL).createObjectURL(Bt), !t) throw "";
2357
+ let n = new Worker(t, { name: e?.name });
2358
+ return n.addEventListener("error", () => {
2359
+ (self.URL || self.webkitURL).revokeObjectURL(t);
2360
+ }), n;
2361
+ } catch {
2362
+ return new Worker("data:text/javascript;charset=utf-8," + encodeURIComponent(zt), { name: e?.name });
2363
+ }
2364
+ }
2365
+ //#endregion
2366
+ //#region src/engine/stream/loader.ts
2367
+ var Ht = class {
2368
+ #e;
2369
+ #t = /* @__PURE__ */ new Map();
2370
+ #n = 0;
2371
+ constructor(e) {
2372
+ let { base: t, cache: n, source: r, workers: i } = e;
2373
+ this.#e = Array.from({ length: i }, (e, a) => {
2374
+ let o = new Vt(), s = { worker: o }, c = typeof r == "function" ? Rt(r, (e, t) => o.postMessage(e, t)) : void 0;
2375
+ o.onmessage = ({ data: e }) => {
2376
+ "id" in e ? this.#i(e) : c?.(e);
2377
+ }, o.onerror = () => this.#a(s);
2378
+ let l = {
2379
+ type: "init",
2380
+ base: t,
2381
+ cache: n,
2382
+ source: typeof r == "function" ? "page" : r,
2383
+ shard: a,
2384
+ shards: i
2385
+ };
2386
+ return o.postMessage(l), s;
2387
+ });
2388
+ }
2389
+ idx(e) {
2390
+ let t = {
2391
+ type: "idx",
2392
+ id: ++this.#n,
2393
+ path: e
2394
+ };
2395
+ return this.#r(this.#e[0], t);
2396
+ }
2397
+ batch(e, t, n) {
2398
+ if (t.aborted) return Promise.reject(Wt());
2399
+ let r = this.#e[Ut(`${e.pack}#${e.window}`, this.#e.length)], i = {
2400
+ type: "batch",
2401
+ id: ++this.#n,
2402
+ batch: e
2403
+ };
2404
+ return this.#r(r, i, t, n);
2405
+ }
2406
+ destroy() {
2407
+ for (let { worker: e } of this.#e) e.terminate();
2408
+ for (let e of this.#t.values()) e.reject(Wt());
2409
+ }
2410
+ #r(e, t, n, r) {
2411
+ if (e.error) return Promise.reject(e.error);
2412
+ let { id: i } = t;
2413
+ return new Promise((a, o) => {
2414
+ let s = () => {
2415
+ this.#t.delete(i), n?.removeEventListener("abort", c);
2416
+ }, c = () => {
2417
+ s(), e.worker.postMessage({
2418
+ type: "abort",
2419
+ id: i
2420
+ }), o(Wt());
2421
+ };
2422
+ this.#t.set(i, {
2423
+ slot: e,
2424
+ page: r,
2425
+ resolve: (e) => {
2426
+ s(), a(e);
2427
+ },
2428
+ reject: (e) => {
2429
+ s(), o(e);
2430
+ }
2431
+ }), n?.addEventListener("abort", c, { once: !0 }), e.worker.postMessage(t);
2432
+ });
2433
+ }
2434
+ #i(e) {
2435
+ let t = this.#t.get(e.id);
2436
+ t && ("page" in e ? t.page?.(e.page) : "error" in e ? t.reject(e.missing ? new l(e.error) : Error(e.error)) : t.resolve("value" in e ? e.value : void 0));
2437
+ }
2438
+ #a(e) {
2439
+ e.error = /* @__PURE__ */ Error("a stream worker failed");
2440
+ for (let t of this.#t.values()) t.slot === e && t.reject(e.error);
2441
+ }
2442
+ };
2443
+ function Ut(e, t) {
2444
+ let n = 2166136261;
2445
+ for (let t = 0; t < e.length; t++) n = Math.imul(n ^ e.charCodeAt(t), 16777619);
2446
+ return (n >>> 0) % t;
2447
+ }
2448
+ function Wt() {
2449
+ return new DOMException("The request was aborted.", "AbortError");
2450
+ }
2451
+ //#endregion
2452
+ //#region src/engine/engine.ts
2453
+ var Gt = class extends Error {
2454
+ constructor() {
2455
+ super("This viewer needs WebGPU. Update to the latest Chrome, Edge, Safari or Firefox."), this.name = "NoWebGpu";
2456
+ }
2457
+ };
2458
+ async function Kt(e, t) {
2459
+ let n = await g();
2460
+ if (!n) throw new Gt();
2461
+ let r = e.getContext("webgpu");
2462
+ if (!r) throw n.device.destroy(), new Gt();
2463
+ r.configure({
2464
+ device: n.device,
2465
+ format: n.format,
2466
+ alphaMode: "opaque"
2467
+ }), (t.cache ?? "opfs") === "opfs" && navigator.storage?.persist().catch(() => !1);
2468
+ let { source: i = "http" } = t;
2469
+ return new vn(e, n, r, t, i === "synthetic" ? (await import("./synthetic-DO8oIw_x.js")).synthetic() : i === "http" ? u : i);
2470
+ }
2471
+ var W = .2, qt = 25165824, Jt = 3.25, Yt = 2, Xt = 1024, Zt = 2048, Qt = 100, $t = 2, en = 300, tn = 100, nn = 250, rn = 300, an = 1e3, on = 400, sn = 5e3, cn = 60, G = Math.PI / 180, K = "The viewer was closed.", ln = "The layers hold more splats than this device can.", un = [
2472
+ 1,
2473
+ 1,
2474
+ 1,
2475
+ 1
2476
+ ], dn = "Another world was opened.";
2477
+ function q(e, t) {
2478
+ let n = Math.min(t.maxStorageBufferBindingSize, t.maxBufferSize), r = (t, r) => {
2479
+ let i = Math.ceil(e * t / 256) * 256;
2480
+ return Math.min(i, Math.floor(n / r / 256) * 256);
2481
+ };
2482
+ return {
2483
+ pool: r(Jt, 16),
2484
+ frame: r(Yt, 24)
2485
+ };
2486
+ }
2487
+ function fn(e, t) {
2488
+ let [n, r, i] = t;
2489
+ if (Math.hypot(n - e[0], r - e[1], i - e[2]) <= Zt) return e;
2490
+ let a = (e) => Math.round(e / Xt) * Xt;
2491
+ return [
2492
+ a(n),
2493
+ a(r),
2494
+ a(i)
2495
+ ];
2496
+ }
2497
+ function pn(e, t, n, r, i, a) {
2498
+ let o = 2 * e[0] / t[0] - 1, s = 1 - 2 * e[1] / t[1], c = [
2499
+ n * o / r[0],
2500
+ n * s / r[5],
2501
+ -n
2502
+ ], [l, u, d] = oe(ae(/* @__PURE__ */ new Float64Array(16), i), c);
2503
+ return [
2504
+ l + a[0],
2505
+ u + a[1],
2506
+ d + a[2]
2507
+ ];
2508
+ }
2509
+ function mn(e) {
2510
+ if (!e.length || !e.every((e) => e.length === 3 && e.every(Number.isFinite))) throw Error("Give at least one point, each three finite numbers.");
2511
+ return e;
2512
+ }
2513
+ function hn(e, t) {
2514
+ return [
2515
+ e.e - t[0],
2516
+ e.n - t[1],
2517
+ e.h - t[2]
2518
+ ];
2519
+ }
2520
+ function gn(e, t) {
2521
+ e.push(t), e.length > cn && e.shift();
2522
+ }
2523
+ function _n({ visible: e, opacity: t }) {
2524
+ return e ? Math.round(t * 255) * 16843009 >>> 0 : 0;
2525
+ }
2526
+ var vn = class {
2527
+ #e;
2528
+ #t;
2529
+ #n;
2530
+ #r;
2531
+ #i;
2532
+ #a;
2533
+ #o;
2534
+ #s;
2535
+ #c;
2536
+ #l;
2537
+ #u = new ht();
2538
+ #d = new et();
2539
+ #f = (e) => this.#s.has(e);
2540
+ #p = null;
2541
+ #m = null;
2542
+ #h = null;
2543
+ #g = null;
2544
+ #_ = 0;
2545
+ #v = !1;
2546
+ #y = /* @__PURE__ */ new Map();
2547
+ #b = 0;
2548
+ #x = 0;
2549
+ #S = 0;
2550
+ #C = /* @__PURE__ */ new WeakMap();
2551
+ #w = !1;
2552
+ #T = /* @__PURE__ */ new Map();
2553
+ #E = 0;
2554
+ #D = !1;
2555
+ #O = {
2556
+ e: 0,
2557
+ n: 0,
2558
+ h: 0,
2559
+ yaw: 0,
2560
+ pitch: 0,
2561
+ fov: 45
2562
+ };
2563
+ #k = -Infinity;
2564
+ #A = [
2565
+ 0,
2566
+ 0,
2567
+ 0
2568
+ ];
2569
+ #j = [
2570
+ 0,
2571
+ 0,
2572
+ 0
2573
+ ];
2574
+ #M = /* @__PURE__ */ new Float64Array(16);
2575
+ #N = /* @__PURE__ */ new Float64Array(16);
2576
+ #P = /* @__PURE__ */ new Float64Array(16);
2577
+ #F = /* @__PURE__ */ new Float64Array(16);
2578
+ #I = /* @__PURE__ */ new Float32Array(24);
2579
+ #L;
2580
+ #R;
2581
+ #z = 0;
2582
+ #B = 0;
2583
+ #V = !1;
2584
+ #H = null;
2585
+ #U = -Infinity;
2586
+ #W = !0;
2587
+ #G = !0;
2588
+ #K = !1;
2589
+ #q = !1;
2590
+ #J = !1;
2591
+ #Y = [];
2592
+ #X = -Infinity;
2593
+ #Z = -Infinity;
2594
+ #Q = -Infinity;
2595
+ #$ = [];
2596
+ #ee = [];
2597
+ #te = [];
2598
+ #ne = [];
2599
+ #re = [];
2600
+ #ie = null;
2601
+ #ae = [];
2602
+ #oe = [];
2603
+ #se = /* @__PURE__ */ new Set();
2604
+ #ce = /* @__PURE__ */ new Set();
2605
+ #le = /* @__PURE__ */ new Set();
2606
+ #ue = {
2607
+ planned: 0,
2608
+ missing: 0,
2609
+ loading: !1
2610
+ };
2611
+ #de = !1;
2612
+ #fe = !1;
2613
+ #pe = !1;
2614
+ constructor(e, t, n, r, i) {
2615
+ this.#e = e, this.#t = t, this.#n = n, this.#r = r, this.#i = i, this.#a = { ...r.settings }, this.#o = this.#he(), this.#L = [
2616
+ e.width,
2617
+ e.height,
2618
+ 1
2619
+ ], this.#R = [Math.max(1, e.width), Math.max(1, e.height)];
2620
+ let { pool: a, frame: o } = q(this.#me, t.device.limits);
2621
+ this.#s = new ee(t.device, a), this.#c = new Ze(t, n, this.#s, o), this.#l = o, t.device.lost.then((e) => {
2622
+ if (!this.#fe) {
2623
+ this.#pe = !0, cancelAnimationFrame(this.#z);
2624
+ for (let t of this.#se) t(e.message || e.reason);
2625
+ }
2626
+ });
2627
+ }
2628
+ async open(e) {
2629
+ if (this.#fe) throw Error(K);
2630
+ let t = ++this.#_, r = () => {
2631
+ if (this.#fe) throw Error(K);
2632
+ if (t !== this.#_) throw Error(dn);
2633
+ }, { cache: i = "opfs", source: o = "http" } = this.#r;
2634
+ o === "http" && (e = new URL(e, document.baseURI).href);
2635
+ let s = await this.#i(e, null), c = a(JSON.parse(new TextDecoder().decode(s)));
2636
+ r();
2637
+ let l = new Ht({
2638
+ base: n(e),
2639
+ workers: Math.min(6, Math.max(2, navigator.hardwareConcurrency - 2)),
2640
+ cache: i,
2641
+ source: o
2642
+ }), u = new ut(c);
2643
+ try {
2644
+ let e = await Promise.all(c.roots.map((e) => l.idx(e.idx)));
2645
+ r(), e.forEach((e, t) => u.add(e, c.roots[t].idx));
2646
+ } catch (e) {
2647
+ throw l.destroy(), e;
2648
+ }
2649
+ return this.#g?.destroy(), this.#g = null, this.#h?.destroy(), this.#p = e, this.#m = u, this.#h = l, this.#H = null, this.#u = new ht(), this.#d = new et(), this.#s.clear(), this.#g = this.#ve(u, l), this.#G = !0, this.requestFrame(), c;
2650
+ }
2651
+ async addLayer(e, t) {
2652
+ if (this.#fe) throw Error(K);
2653
+ let n = await Qe("bytes" in e ? e.bytes : await this.#i(e.url, null), t);
2654
+ if (this.#fe) throw Error(K);
2655
+ let r = n.reduce((e, { page: t }) => e + d(t.count), 0), i = this.#t.device.limits;
2656
+ if (q(this.#me, i).pool + this.#S + r > q(Infinity, i).pool) throw Error(ln);
2657
+ this.#S += r, this.#ge();
2658
+ let a = ++this.#b, o = (e) => this.#g?.protects(e) ?? !1, s = () => this.#be(), c = !0, l = 1, u = () => {
2659
+ if (!(this.#fe || !this.#y.delete(a))) {
2660
+ for (let { id: e } of p.pages) this.#s.remove(e);
2661
+ this.#S -= r, s();
2662
+ }
2663
+ }, f = {
2664
+ splats: n.reduce((e, { page: t }) => e + t.count, 0),
2665
+ box: $e(n.map(({ box: e }) => e)),
2666
+ get visible() {
2667
+ return c;
2668
+ },
2669
+ set visible(e) {
2670
+ c = e, s();
2671
+ },
2672
+ get opacity() {
2673
+ return l;
2674
+ },
2675
+ set opacity(e) {
2676
+ l = Math.min(1, Math.max(0, e)), s();
2677
+ },
2678
+ remove: u
2679
+ }, p = {
2680
+ layer: f,
2681
+ pages: []
2682
+ };
2683
+ this.#y.set(a, p);
2684
+ for (let { page: e, box: r } of n) {
2685
+ let n = --this.#x;
2686
+ if (!this.#s.add(n, e, t, o, a)) throw u(), Error(ln);
2687
+ p.pages.push({
2688
+ id: n,
2689
+ count: e.count,
2690
+ box: r
2691
+ });
2692
+ }
2693
+ return s(), this.#C.set(f, a), f;
2694
+ }
2695
+ addMask({ polygon: e, z: t = [-Infinity, Infinity], targets: n }) {
2696
+ if (this.#fe) throw Error(K);
2697
+ if (e.length < 3 || !e.flat().every(Number.isFinite)) throw Error("A mask needs three or more corners, each two finite numbers.");
2698
+ let r = new Set(n.map((e) => e === "world" ? 0 : this.#C.get(e) ?? -1)), i = this.#s, a = {
2699
+ polygon: Float64Array.from(e.flat()),
2700
+ z: [t[0], t[1]]
2701
+ }, o = i.addMask(a, r), s = !0, c = !1, l = () => {
2702
+ this.#fe || (this.#w = !0, this.requestFrame());
2703
+ };
2704
+ return l(), {
2705
+ get enabled() {
2706
+ return s;
2707
+ },
2708
+ set enabled(e) {
2709
+ c || e === s || (s = e, i.enableMask(o, e), l());
2710
+ },
2711
+ remove() {
2712
+ c || (c = !0, i.deleteMask(o), l());
2713
+ }
2714
+ };
2715
+ }
2716
+ addLine(e, t = {}) {
2717
+ let { colour: n = un, width: r = 2, closed: i = !1, occlude: a = !0 } = t, o = (e) => {
2718
+ mn(e);
2719
+ let t = i && e.length > 2 ? [...e, e[0]] : e;
2720
+ return (t.length > 1 ? t.slice(1).map((e, n) => [t[n], e]) : [[t[0], t[0]]]).map(([e, t]) => ({
2721
+ a: e,
2722
+ b: t,
2723
+ radius: r / 2,
2724
+ colour: n,
2725
+ occlude: a
2726
+ }));
2727
+ }, s = ++this.#E, c = () => {
2728
+ this.#D = !0, this.requestFrame();
2729
+ };
2730
+ return this.#T.set(s, o(e)), c(), {
2731
+ set: (e) => {
2732
+ let t = o(e);
2733
+ this.#T.has(s) && (this.#T.set(s, t), c());
2734
+ },
2735
+ remove: () => {
2736
+ this.#T.delete(s) && c();
2737
+ }
2738
+ };
2739
+ }
2740
+ addMarker(e, t = {}) {
2741
+ let { size: n = 12, ...r } = t, i = this.addLine([e], {
2742
+ ...r,
2743
+ width: n
2744
+ });
2745
+ return {
2746
+ set: (e) => i.set([e]),
2747
+ remove: i.remove
2748
+ };
2749
+ }
2750
+ toScreen([e, t, n]) {
2751
+ let r = this.#O, [i, a] = this.#L, o = this.#j, s = ne(/* @__PURE__ */ new Float64Array(16), hn(r, o), r.yaw * G, r.pitch * G), c = re(/* @__PURE__ */ new Float64Array(16), r.fov * G, i / Math.max(1, a), W, this.#a.viewDistance), [l, u, , d] = oe(N(/* @__PURE__ */ new Float64Array(16), c, s), [
2752
+ e - o[0],
2753
+ t - o[1],
2754
+ n - o[2]
2755
+ ]);
2756
+ return d <= 0 ? null : [(l / d * .5 + .5) * i, (.5 - u / d * .5) * a];
2757
+ }
2758
+ setCamera(e) {
2759
+ if (this.#fe) return;
2760
+ let t = performance.now(), n = t - this.#k, r = this.#O, i = this.#A;
2761
+ if (n > nn) i.fill(0);
2762
+ else if (n > 0) {
2763
+ let t = 1 - Math.exp(-n / tn);
2764
+ i[0] += t * ((e.e - r.e) / n - i[0]), i[1] += t * ((e.n - r.n) / n - i[1]), i[2] += t * ((e.h - r.h) / n - i[2]);
2765
+ }
2766
+ this.#k = t, this.#O = { ...e }, this.#W = !0, this.#de || this.requestFrame();
2767
+ }
2768
+ configure(e) {
2769
+ if (this.#fe) return;
2770
+ let { budget: t, budgetRange: n } = this.#a;
2771
+ this.#a = {
2772
+ ...this.#a,
2773
+ ...e
2774
+ };
2775
+ let r = this.#a;
2776
+ (r.budget !== t || !((e, t) => e?.join() === t?.join())(r.budgetRange, n)) && (this.#o = this.#he(), this.#we()), this.#ge();
2777
+ }
2778
+ resize(e, t, n) {
2779
+ this.#fe || (this.#L = [
2780
+ e,
2781
+ t,
2782
+ n
2783
+ ], this.#we());
2784
+ }
2785
+ pick(e, t) {
2786
+ return this.#fe || this.#pe ? Promise.resolve(null) : new Promise((n) => {
2787
+ this.#re.push({
2788
+ x: e,
2789
+ y: t,
2790
+ resolve: n
2791
+ }), this.#ie ? this.#ke() : this.requestFrame();
2792
+ });
2793
+ }
2794
+ ground(e, t) {
2795
+ return this.#m?.ground(e, t);
2796
+ }
2797
+ async groundAt(e, t) {
2798
+ let n = this.#m, r = this.#h;
2799
+ if (n && r) return await n.load(e, t, (e) => r.idx(e)), this.#q = !0, this.requestFrame(), n.ground(e, t);
2800
+ }
2801
+ heights(e, t, n) {
2802
+ return this.#fe || this.#pe ? Promise.resolve(null) : new Promise((r) => {
2803
+ this.#ae.push({
2804
+ west: e,
2805
+ south: t,
2806
+ cells: n,
2807
+ resolve: r
2808
+ }), this.requestFrame();
2809
+ });
2810
+ }
2811
+ stats() {
2812
+ let e = this.#s, t = this.#g, n = this.#c.stats();
2813
+ return {
2814
+ frameMs: kt(this.#$, .5),
2815
+ cpuMs: kt(this.#ee, .5),
2816
+ gpuMs: n.gpuMs,
2817
+ passes: n.passes,
2818
+ drawn: n.drawn,
2819
+ ...this.#Ae(),
2820
+ pages: {
2821
+ resident: Array.from(e.ids()).length,
2822
+ drawn: this.#Y.length,
2823
+ loading: t?.loading ?? 0,
2824
+ queued: t?.queued ?? 0
2825
+ },
2826
+ memory: {
2827
+ pool: e.bytes,
2828
+ buffers: n.bytes
2829
+ },
2830
+ capacity: e.capacity,
2831
+ budget: this.#me,
2832
+ scale: this.#o.scale
2833
+ };
2834
+ }
2835
+ idle() {
2836
+ return this.#fe ? Promise.resolve() : new Promise((e) => {
2837
+ this.#oe.push(e), this.requestFrame();
2838
+ });
2839
+ }
2840
+ use(e) {
2841
+ if (this.#fe) return () => {};
2842
+ let t = e({
2843
+ shade: (e) => this.#Ce(this.#te, e, this.#c.shade(e)),
2844
+ post: (e) => this.#Ce(this.#ne, e, this.#c.post(e))
2845
+ });
2846
+ return () => {
2847
+ this.#fe || t();
2848
+ };
2849
+ }
2850
+ warm() {
2851
+ let e = performance.now();
2852
+ e - this.#X < an || (this.#Z = e + on, this.requestFrame());
2853
+ }
2854
+ onFrame(e) {
2855
+ return this.#ce.add(e), () => this.#ce.delete(e);
2856
+ }
2857
+ onProgress(e) {
2858
+ return this.#le.add(e), () => this.#le.delete(e);
2859
+ }
2860
+ onLost(e) {
2861
+ return this.#se.add(e), () => this.#se.delete(e);
2862
+ }
2863
+ requestFrame() {
2864
+ this.#fe || this.#pe || this.#r.manual || this.#z || (this.#z = requestAnimationFrame(this.#Te));
2865
+ }
2866
+ async step() {
2867
+ if (this.#fe || this.#pe) return {
2868
+ cpuMs: 0,
2869
+ gpuMs: 0,
2870
+ passes: {}
2871
+ };
2872
+ let { done: e, cpuMs: t } = this.#Ee(!1);
2873
+ await e;
2874
+ let { gpuMs: n, passes: r } = this.#c.stats();
2875
+ return {
2876
+ cpuMs: t,
2877
+ gpuMs: n,
2878
+ passes: r
2879
+ };
2880
+ }
2881
+ destroy() {
2882
+ if (!this.#fe) {
2883
+ this.#fe = !0, cancelAnimationFrame(this.#z), this.#g?.destroy(), this.#h?.destroy(), this.#c.destroy(), this.#s.destroy(), this.#y.clear();
2884
+ for (let { resolve: e } of this.#re.splice(0)) e(null);
2885
+ for (let { resolve: e } of this.#ae.splice(0)) e(null);
2886
+ for (let e of this.#oe.splice(0)) e();
2887
+ this.#t.device.destroy();
2888
+ }
2889
+ }
2890
+ get #me() {
2891
+ return this.#o.budget;
2892
+ }
2893
+ #he() {
2894
+ let { budget: e, budgetRange: t = [e, e] } = this.#a, n = Math.floor(q(Infinity, this.#t.device.limits).frame / Yt), r = (e) => Math.max(1, Math.min(e, n));
2895
+ return new At(r(e), [r(t[0]), r(t[1])]);
2896
+ }
2897
+ #ge() {
2898
+ let { pool: e, frame: t } = q(this.#me, this.#t.device.limits), n = e + this.#S;
2899
+ (n > this.#s.capacity || t > this.#l) && this.#_e(n, t), this.#G = !0, this.requestFrame();
2900
+ }
2901
+ #_e(e, t) {
2902
+ this.#s.grow(e), this.#c.destroy();
2903
+ let n = new Ze(this.#t, this.#n, this.#s, t);
2904
+ n.resize(...this.#R);
2905
+ for (let e of this.#te) e.off = n.shade(e.hook);
2906
+ for (let e of this.#ne) e.off = n.post(e.hook);
2907
+ this.#c = n, this.#l = t, this.#ie = null, this.#D = !0;
2908
+ }
2909
+ #ve(e, t) {
2910
+ return new Lt(e, t, this.#s, () => {
2911
+ this.#q = !0, this.requestFrame();
2912
+ }, this.#ye);
2913
+ }
2914
+ #ye = () => {
2915
+ let e = this.#p, t = this.#m;
2916
+ this.#v || this.#fe || e === null || (this.#v = !0, this.open(e).then(() => this.#v = !1, () => {
2917
+ this.#v = !1, this.#m === t && setTimeout(this.#ye, sn);
2918
+ }));
2919
+ };
2920
+ #be() {
2921
+ this.#w = !0, this.#G = !0, this.requestFrame();
2922
+ }
2923
+ #xe() {
2924
+ let e = this.#j, t = [
2925
+ 0,
2926
+ 0,
2927
+ 0
2928
+ ], n = [
2929
+ 0,
2930
+ 0,
2931
+ 0
2932
+ ], r = 0;
2933
+ for (let { layer: i, pages: a } of this.#y.values()) if (_n(i)) for (let { count: i, box: o } of a) {
2934
+ for (let r = 0; r < 3; r++) t[r] = o[r] - e[r], n[r] = o[r + 3] - e[r];
2935
+ je(this.#I, t, n) && (r += i);
2936
+ }
2937
+ return r;
2938
+ }
2939
+ #Se() {
2940
+ let e = [];
2941
+ for (let { layer: t, pages: n } of this.#y.values()) {
2942
+ let r = _n(t);
2943
+ if (r) for (let { id: t } of n) e.push({
2944
+ id: t,
2945
+ factors: r
2946
+ });
2947
+ }
2948
+ return e;
2949
+ }
2950
+ #Ce(e, t, n) {
2951
+ let r = {
2952
+ hook: t,
2953
+ off: n
2954
+ };
2955
+ return e.push(r), this.requestFrame(), () => {
2956
+ let t = e.indexOf(r);
2957
+ this.#fe || t < 0 || (e.splice(t, 1), r.off(), this.requestFrame());
2958
+ };
2959
+ }
2960
+ #we() {
2961
+ let [e, t, n] = this.#L, r = Ot(e, t, n, this.#o.scale), i = Math.max(1, Math.round(e * r)), a = Math.max(1, Math.round(t * r));
2962
+ (i !== this.#R[0] || a !== this.#R[1]) && (this.#R = [i, a], this.#e.width = i, this.#e.height = a, this.#c.resize(i, a), this.#G = !0, this.#D = !0, this.requestFrame());
2963
+ }
2964
+ #Te = (e) => {
2965
+ if (this.#z = 0, !(this.#fe || this.#pe)) {
2966
+ if (this.#B >= $t) this.#V = !0;
2967
+ else {
2968
+ this.#de = !0;
2969
+ for (let t of this.#ce) t(e);
2970
+ this.#de = !1, this.#B++, this.#Ee(!0).done.finally(() => {
2971
+ this.#B--, this.#V && (this.#V = !1, this.requestFrame());
2972
+ });
2973
+ }
2974
+ }
2975
+ };
2976
+ #Ee(e) {
2977
+ let t = performance.now(), n = this.#o, r = this.#s, i = this.#O, [a, o] = this.#R, s = this.#a.viewDistance, c = this.#W;
2978
+ this.#W = !1;
2979
+ let l = fn(this.#j, [
2980
+ i.e,
2981
+ i.n,
2982
+ i.h
2983
+ ]);
2984
+ l !== this.#j && (this.#j = l, r.setOrigin(l), this.#D = !0);
2985
+ let u = hn(i, l);
2986
+ ne(this.#M, u, i.yaw * G, i.pitch * G), re(this.#N, i.fov * G, a / o, W, s);
2987
+ let d = {
2988
+ time: t,
2989
+ width: a,
2990
+ height: o,
2991
+ view: new Float32Array(this.#M),
2992
+ proj: new Float32Array(this.#N),
2993
+ near: W,
2994
+ far: s,
2995
+ camera: Float32Array.from(u),
2996
+ origin: l
2997
+ };
2998
+ Ae(this.#I, N(this.#F, d.proj, d.view));
2999
+ let f = this.#m, p = this.#g, m = this.#q || this.#G || this.#J, h = this.#H, g = h;
3000
+ if (f && p) {
3001
+ let e = !p.idle && t - this.#U >= Qt, n = this.#G || this.#q || this.#J || this.#K;
3002
+ (!g || c || e || n) && (g = this.#De(f, t, c));
3003
+ }
3004
+ let _ = this.#Y, v = this.#J;
3005
+ if (g && p && (g !== h && (m || !h || g.cut.length !== h.cut.length || g.cut.some((e, t) => e !== h.cut[t])) && ({drawn: _, fading: v} = this.#d.update(g.cut, this.#f, t, this.#me)), p.update(g, new Set(_.map((e) => e.id)), t)), r.upload(qt) > 0 && (this.#q = !0), _ !== this.#Y || this.#q || this.#w) {
3006
+ this.#w = !1;
3007
+ let e = this.#Se();
3008
+ r.draw(e.length ? _.concat(e) : _);
3009
+ }
3010
+ if (this.#J = v, this.#Y = _, this.#D) {
3011
+ this.#D = !1;
3012
+ let e = a / Math.max(1, this.#L[0]), t = [...this.#T.values()].flat().map((t) => ({
3013
+ ...t,
3014
+ radius: t.radius * e
3015
+ }));
3016
+ this.#c.overlay(t, l);
3017
+ }
3018
+ let y = this.#ae.splice(0).map((e) => this.#Me(e, l)), b = this.#c.render(d, this.#I, this.#r.sky, y);
3019
+ this.#ie = d, this.#re.length && this.#ke();
3020
+ let x = performance.now() - t;
3021
+ if (!this.#q && !this.#K && !v && r.queued === 0 && (!p || p.idle) && (!g || g.load.length === 0 && g.idx.length === 0) && this.#oe.length) {
3022
+ let e = this.#oe.splice(0);
3023
+ b.then(() => e.forEach((e) => e()));
3024
+ }
3025
+ e && this.#Ne(t, x, c), this.#je();
3026
+ let S = t < this.#Z;
3027
+ return (r.queued > 0 || this.#q || this.#K || v || n.scale < 1 || S) && this.requestFrame(), {
3028
+ done: b,
3029
+ cpuMs: x
3030
+ };
3031
+ }
3032
+ #De(e, t, n) {
3033
+ let r = this.#O, i = this.#s, [a, o] = this.#R, s = this.#o.scale, c = this.#me, l = {
3034
+ origin: this.#j,
3035
+ width: a / s,
3036
+ height: o / s,
3037
+ tan: Math.tan(r.fov * G / 2),
3038
+ near: W,
3039
+ far: this.#a.viewDistance
3040
+ }, u = {
3041
+ ...l,
3042
+ view: this.#M
3043
+ }, d = {
3044
+ budget: Math.max(0, c - this.#xe()),
3045
+ capacity: i.capacity - Math.ceil(1 * c) - this.#S,
3046
+ now: t,
3047
+ predicted: n ? this.#Oe(l) : void 0
3048
+ }, f = this.#u.plan(e, u, this.#f, d);
3049
+ return this.#H = f, this.#U = t, this.#G = !1, this.#K = d.predicted !== void 0, this.#q = !1, f;
3050
+ }
3051
+ #Oe(e) {
3052
+ let t = this.#A;
3053
+ if (t.every((e) => e === 0)) return;
3054
+ let n = this.#O, r = [
3055
+ n.e + t[0] * en - e.origin[0],
3056
+ n.n + t[1] * en - e.origin[1],
3057
+ n.h + t[2] * en - e.origin[2]
3058
+ ];
3059
+ return {
3060
+ ...e,
3061
+ view: ne(this.#P, r, n.yaw * G, n.pitch * G)
3062
+ };
3063
+ }
3064
+ #ke() {
3065
+ let e = this.#ie, t = this.#M.slice(), [n, r] = this.#L, i = [e.width, e.height];
3066
+ for (let { x: a, y: o, resolve: s } of this.#re.splice(0)) {
3067
+ let c = [a * i[0] / Math.max(1, n), o * i[1] / Math.max(1, r)], l = (n) => n && {
3068
+ point: pn(c, i, n.depth, e.proj, t, e.origin),
3069
+ normal: n.normal,
3070
+ layer: this.#y.get(n.layer)?.layer ?? null
3071
+ };
3072
+ this.#c.pick(c[0], c[1], e).then((e) => s(l(e)));
3073
+ }
3074
+ }
3075
+ #Ae() {
3076
+ let e = this.#g;
3077
+ return {
3078
+ planned: this.#H?.planned ?? 0,
3079
+ missing: this.#H?.missing ?? 0,
3080
+ loading: e !== null && !e.idle
3081
+ };
3082
+ }
3083
+ #je() {
3084
+ let e = this.#Ae(), t = this.#ue;
3085
+ if (e.planned !== t.planned || e.missing !== t.missing || e.loading !== t.loading) {
3086
+ this.#ue = e;
3087
+ for (let t of this.#le) t(e);
3088
+ }
3089
+ }
3090
+ #Me({ west: e, south: t, cells: n, resolve: r }, i) {
3091
+ return {
3092
+ x: e - i[0],
3093
+ y: t - i[1],
3094
+ cells: n,
3095
+ resolve: (e) => {
3096
+ if (e) for (let t = 0; t < e.length; t++) e[t] += i[2];
3097
+ r(e);
3098
+ }
3099
+ };
3100
+ }
3101
+ #Ne(e, t, n) {
3102
+ let r = this.#o, { gpuMs: i } = this.#c.stats(), a = e - this.#X, o = a <= Math.max(nn, 2 * i, 2 * t);
3103
+ o && gn(this.#$, a), gn(this.#ee, t), this.#X = e;
3104
+ let s = r.budget;
3105
+ r.sample(a, e, o && n, this.#H?.planned ?? 0) && (this.#we(), r.budget !== s && this.#ge()), n ? this.#Q = e : r.scale < 1 && e - this.#Q > rn && (r.full(), this.#we());
3106
+ }
3107
+ }, yn = 45, bn = {
3108
+ yaw: 0,
3109
+ pitch: -35,
3110
+ dist: 300
3111
+ }, J = {
3112
+ pitch: [-90, -20],
3113
+ dist: [1, 2485],
3114
+ clearance: 10,
3115
+ floor: 50
3116
+ }, xn = .1, Y = Math.PI / 180, Sn = 1.1, Cn = [600, 2500], wn = 300, Tn = .5, En = (e, [t, n]) => Math.min(n, Math.max(t, e)), Dn = (e) => (e % 360 + 360) % 360, On = (e, t) => (t - e + 540) % 360 - 180;
3117
+ function kn({ leaf: e, roots: t, extent: n }) {
3118
+ let r = {
3119
+ e: (n.e[0] + n.e[1]) / 2,
3120
+ n: (n.n[0] + n.n[1]) / 2,
3121
+ h: n.h[0]
3122
+ }, i = r, a = Infinity;
3123
+ for (let o of t) {
3124
+ let t = e * 2 ** o.level, [s, c] = [Math.max(o.e, n.e[0]), Math.min(o.e + t, n.e[1])], [l, u] = [Math.max(o.n, n.n[0]), Math.min(o.n + t, n.n[1])], d = Math.hypot(Math.max(s - r.e, 0, r.e - c), Math.max(l - r.n, 0, r.n - u));
3125
+ if (d === 0) return r;
3126
+ d < a && (a = d, i = {
3127
+ e: (s + c) / 2,
3128
+ n: (l + u) / 2,
3129
+ h: n.h[0]
3130
+ });
3131
+ }
3132
+ return i;
3133
+ }
3134
+ function An(e) {
3135
+ let t = e.split(",");
3136
+ if (t.length !== 6 || t.some((e) => e.trim() === "")) return null;
3137
+ let [n, r, i, a, o, s] = t.map(Number);
3138
+ return ![
3139
+ n,
3140
+ r,
3141
+ i,
3142
+ a,
3143
+ o,
3144
+ s
3145
+ ].every(Number.isFinite) || s <= 0 ? null : {
3146
+ e: n,
3147
+ n: r,
3148
+ h: i,
3149
+ yaw: a,
3150
+ pitch: o,
3151
+ dist: s
3152
+ };
3153
+ }
3154
+ function jn(e) {
3155
+ let t = (e, t) => +e.toFixed(t);
3156
+ return [
3157
+ t(e.e, 2),
3158
+ t(e.n, 2),
3159
+ t(e.h, 2),
3160
+ t(e.yaw, 1),
3161
+ t(e.pitch, 1),
3162
+ t(e.dist, 1)
3163
+ ].join(",");
3164
+ }
3165
+ function X(e, t, n = J) {
3166
+ let r = {
3167
+ e: e.e,
3168
+ n: e.n,
3169
+ h: e.h,
3170
+ yaw: Dn(e.yaw),
3171
+ pitch: En(e.pitch, n.pitch),
3172
+ dist: En(e.dist, n.dist)
3173
+ };
3174
+ if (t) {
3175
+ let e = Z(r), i = Math.max(n.floor, t(e.e, e.n) + n.clearance);
3176
+ if (e.h < i) return {
3177
+ ...Fn({
3178
+ ...e,
3179
+ h: i
3180
+ }, r),
3181
+ yaw: r.yaw
3182
+ };
3183
+ }
3184
+ return r;
3185
+ }
3186
+ function Mn(e, t) {
3187
+ let n = Math.cos(t * Y);
3188
+ return {
3189
+ e: Math.sin(e * Y) * n,
3190
+ n: Math.cos(e * Y) * n,
3191
+ h: Math.sin(t * Y)
3192
+ };
3193
+ }
3194
+ function Z(e) {
3195
+ let t = Mn(e.yaw, e.pitch);
3196
+ return {
3197
+ e: e.e - t.e * e.dist,
3198
+ n: e.n - t.n * e.dist,
3199
+ h: e.h - t.h * e.dist
3200
+ };
3201
+ }
3202
+ function Nn(e) {
3203
+ return {
3204
+ ...Z(e),
3205
+ yaw: e.yaw,
3206
+ pitch: e.pitch,
3207
+ fov: 45
3208
+ };
3209
+ }
3210
+ function Pn(e, t, n) {
3211
+ let r = Z(e), [i, a, o] = [
3212
+ n.e - r.e,
3213
+ n.n - r.n,
3214
+ n.h - r.h
3215
+ ], [s, c] = [Math.sin(e.yaw * Y), Math.cos(e.yaw * Y)], [l, u] = [Math.sin(e.pitch * Y), Math.cos(e.pitch * Y)], d = i * s + a * c, f = 2 * Math.tan(t * Y / 2) * (d * u + o * l);
3216
+ return {
3217
+ x: (i * c - a * s) / f,
3218
+ y: (d * l - o * u) / f
3219
+ };
3220
+ }
3221
+ function Fn(e, t) {
3222
+ let [n, r, i] = [
3223
+ t.e - e.e,
3224
+ t.n - e.n,
3225
+ t.h - e.h
3226
+ ], a = Math.hypot(n, r, i);
3227
+ return {
3228
+ e: t.e,
3229
+ n: t.n,
3230
+ h: t.h,
3231
+ yaw: Dn(Math.atan2(n, r) / Y),
3232
+ pitch: Math.asin(i / a) / Y,
3233
+ dist: a
3234
+ };
3235
+ }
3236
+ function In(e, t, n, r = J) {
3237
+ let i = Z(e), a = X({
3238
+ ...e,
3239
+ yaw: t,
3240
+ pitch: n
3241
+ }, void 0, r), o = Mn(a.yaw, a.pitch);
3242
+ return {
3243
+ ...a,
3244
+ e: i.e + o.e * a.dist,
3245
+ n: i.n + o.n * a.dist,
3246
+ h: i.h + o.h * a.dist
3247
+ };
3248
+ }
3249
+ function Ln(e) {
3250
+ return e.dist * Math.max(Math.sin(-e.pitch * Y), xn);
3251
+ }
3252
+ function Rn(e, t, n, r) {
3253
+ let [i, a] = [Math.sin(e.yaw * Y), Math.cos(e.yaw * Y)];
3254
+ return {
3255
+ ...e,
3256
+ e: e.e + t * a + n * i,
3257
+ n: e.n - t * i + n * a,
3258
+ h: e.h + r
3259
+ };
3260
+ }
3261
+ function zn(e, t, n) {
3262
+ return Rn(e, t, n * e.dist / Ln(e), 0);
3263
+ }
3264
+ function Q(e, t, n) {
3265
+ return {
3266
+ e: e.e + (t.e - e.e) * n,
3267
+ n: e.n + (t.n - e.n) * n,
3268
+ h: e.h + (t.h - e.h) * n,
3269
+ yaw: Dn(e.yaw + On(e.yaw, t.yaw) * n),
3270
+ pitch: e.pitch + (t.pitch - e.pitch) * n,
3271
+ dist: e.dist * (t.dist / e.dist) ** n
3272
+ };
3273
+ }
3274
+ function Bn(e, t) {
3275
+ let n = ([e, t]) => (e + t) / 2, r = Math.hypot(e.e[1] - e.e[0], e.n[1] - e.n[0], e.h[1] - e.h[0]) / 2;
3276
+ return {
3277
+ e: n(e.e),
3278
+ n: n(e.n),
3279
+ h: n(e.h),
3280
+ yaw: t.yaw,
3281
+ pitch: t.pitch,
3282
+ dist: Sn * r / Math.sin(45 * Y / 2)
3283
+ };
3284
+ }
3285
+ function Vn(e, t) {
3286
+ let n = Math.hypot(t.e - e.e, t.n - e.n), r = Math.log1p(n / Math.min(e.dist, t.dist)) + Math.abs(Math.log(t.dist / e.dist)), i = Math.log1p(Tn * n / Math.max(e.dist, t.dist));
3287
+ return {
3288
+ ms: En(Cn[0] + wn * r, Cn),
3289
+ at(n) {
3290
+ if (n <= 0) return e;
3291
+ if (n >= 1) return t;
3292
+ let r = n * n * (3 - 2 * n), a = Q(e, t, r);
3293
+ return {
3294
+ ...a,
3295
+ dist: a.dist * Math.exp(4 * i * r * (1 - r))
3296
+ };
3297
+ }
3298
+ };
3299
+ }
3300
+ function Hn(e, t) {
3301
+ let n = e.dist * 1e-5;
3302
+ return Math.abs(e.e - t.e) < n && Math.abs(e.n - t.n) < n && Math.abs(e.h - t.h) < n && Math.abs(e.dist - t.dist) < n && Math.abs(On(e.yaw, t.yaw)) < .001 && Math.abs(e.pitch - t.pitch) < .001;
3303
+ }
3304
+ //#endregion
3305
+ //#region src/controls/controls.ts
3306
+ var Un = .2, Wn = .002, Gn = .005, Kn = .5, qn = .05;
3307
+ function Jn(e, t) {
3308
+ return 2 * e * Math.tan(45 * Math.PI / 360) / Math.max(1, t);
3309
+ }
3310
+ function Yn(e) {
3311
+ let t = (t) => +!!e.has(t);
3312
+ return [
3313
+ t("KeyD") - t("KeyA") + t("ArrowRight") - t("ArrowLeft"),
3314
+ t("KeyW") - t("KeyS") + t("ArrowUp") - t("ArrowDown"),
3315
+ t("KeyE") - t("KeyQ")
3316
+ ];
3317
+ }
3318
+ function Xn(e, t, n, r, i = J) {
3319
+ return Hn(e, t) ? t : X(Q(e, t, 1 - Math.exp(-n / qn)), r, i);
3320
+ }
3321
+ var Zn = class {
3322
+ enabled = !0;
3323
+ #e;
3324
+ #t;
3325
+ #n;
3326
+ #r;
3327
+ #i = new AbortController();
3328
+ #a = /* @__PURE__ */ new Map();
3329
+ #o = /* @__PURE__ */ new Set();
3330
+ #s = [0, 0];
3331
+ #c = [0, 0];
3332
+ #l = 0;
3333
+ #u = !1;
3334
+ #d;
3335
+ #f;
3336
+ #p = null;
3337
+ #m = /* @__PURE__ */ new Set();
3338
+ #h;
3339
+ #g = null;
3340
+ constructor(e, t, n, r, i = J) {
3341
+ this.#e = e, this.#t = t, this.#n = n, this.#r = i, this.#d = this.#j(r), this.#f = this.#d, this.#h = t.onFrame(this.#D);
3342
+ let a = this.#i.signal;
3343
+ e.addEventListener("pointerdown", this.#_, { signal: a }), e.addEventListener("pointermove", this.#v, { signal: a });
3344
+ for (let t of [
3345
+ "pointerup",
3346
+ "pointercancel",
3347
+ "lostpointercapture"
3348
+ ]) e.addEventListener(t, this.#y, { signal: a });
3349
+ e.addEventListener("wheel", this.#b, {
3350
+ passive: !1,
3351
+ signal: a
3352
+ }), e.addEventListener("dblclick", this.#C, { signal: a }), e.addEventListener("contextmenu", (e) => e.preventDefault(), { signal: a }), window.addEventListener("keydown", this.#x, { signal: a }), window.addEventListener("keyup", this.#S, { signal: a }), window.addEventListener("blur", () => this.#o.clear(), { signal: a }), this.#M();
3353
+ }
3354
+ get pose() {
3355
+ return { ...this.#f };
3356
+ }
3357
+ onChange(e) {
3358
+ return this.#m.add(e), () => this.#m.delete(e);
3359
+ }
3360
+ moveTo(e, t) {
3361
+ let n = this.#d, r = Math.min(n.dist, bn.dist);
3362
+ this.#O(this.#j({
3363
+ ...n,
3364
+ e,
3365
+ n: t,
3366
+ h: this.#n(e, t),
3367
+ dist: r
3368
+ }));
3369
+ }
3370
+ jump(e) {
3371
+ this.#k(!1), this.#d = this.#f = this.#j({
3372
+ ...this.#f,
3373
+ ...e
3374
+ }), this.#A();
3375
+ }
3376
+ flyTo(e, t = {}) {
3377
+ let { signal: n } = t;
3378
+ if (n?.aborted || this.#i.signal.aborted) return Promise.resolve(!1);
3379
+ this.#k(!1);
3380
+ let r = this.#f;
3381
+ this.#d = r;
3382
+ let i = () => this.#k(!1);
3383
+ return new Promise((t) => {
3384
+ this.#p = {
3385
+ path: Vn(r, this.#j({
3386
+ ...r,
3387
+ ...e
3388
+ })),
3389
+ start: null,
3390
+ land: (e) => {
3391
+ n?.removeEventListener("abort", i), t(e);
3392
+ }
3393
+ }, n?.addEventListener("abort", i), this.#E();
3394
+ });
3395
+ }
3396
+ destroy() {
3397
+ this.#k(!1), this.#i.abort(), this.#h(), this.#m.clear();
3398
+ }
3399
+ #_ = (e) => {
3400
+ this.#w(e) && (this.#e.setPointerCapture(e.pointerId), this.#a.set(e.pointerId, {
3401
+ x: e.clientX,
3402
+ y: e.clientY
3403
+ }));
3404
+ };
3405
+ #v = (e) => {
3406
+ if (!this.#w(e)) return;
3407
+ let t = this.#a.get(e.pointerId);
3408
+ if (!t) return this.#t.warm();
3409
+ let n = this.#T(), [r, i] = [e.clientX - t.x, e.clientY - t.y];
3410
+ if (t.x = e.clientX, t.y = e.clientY, e.pointerType === "mouse") {
3411
+ let t = !!(e.buttons & 1);
3412
+ e.buttons & 6 || t && e.shiftKey ? $(this.#c, r, i) : t && $(this.#s, r, i);
3413
+ } else if (n) {
3414
+ let e = this.#T();
3415
+ $(this.#c, e.x - n.x, e.y - n.y), this.#l += (n.d - e.d) * Gn;
3416
+ } else $(this.#s, r, i);
3417
+ this.#E();
3418
+ };
3419
+ #y = (e) => {
3420
+ this.#a.delete(e.pointerId);
3421
+ };
3422
+ #b = (e) => {
3423
+ this.#w(e) && (e.preventDefault(), this.#l += e.deltaY * Wn, this.#E());
3424
+ };
3425
+ #x = (e) => {
3426
+ this.#w(e) && (e.code === "KeyF" && !e.repeat && (this.#u = !this.#u), this.#o.add(e.code), this.#u && this.#E());
3427
+ };
3428
+ #S = (e) => {
3429
+ this.#o.delete(e.code);
3430
+ };
3431
+ #C = async (e) => {
3432
+ if (!this.#w(e)) return;
3433
+ let t = await this.#t.pick(e.offsetX, e.offsetY);
3434
+ if (!t || this.#i.signal.aborted) return;
3435
+ let [n, r, i] = t.point, a = Fn(Z(this.#f), {
3436
+ e: n,
3437
+ n: r,
3438
+ h: i
3439
+ });
3440
+ this.#O(X(a, void 0, this.#r));
3441
+ };
3442
+ #w(e) {
3443
+ return this.enabled && !e.defaultPrevented;
3444
+ }
3445
+ #T() {
3446
+ if (this.#a.size < 2) return null;
3447
+ let [e, t] = this.#a.values();
3448
+ return {
3449
+ x: (e.x + t.x) / 2,
3450
+ y: (e.y + t.y) / 2,
3451
+ d: Math.hypot(e.x - t.x, e.y - t.y)
3452
+ };
3453
+ }
3454
+ #E() {
3455
+ this.#i.signal.aborted || this.#t.requestFrame();
3456
+ }
3457
+ #D = (e) => {
3458
+ let t = this.#g === null ? 1 / 60 : Math.min(.1, (e - this.#g) / 1e3);
3459
+ this.#g = e;
3460
+ let n = this.#d, [r, i] = this.#c;
3461
+ if (r || i) {
3462
+ let e = Jn(n.dist, this.#e.clientHeight);
3463
+ n = zn(n, -r * e, i * e);
3464
+ }
3465
+ let [a, o] = this.#s;
3466
+ if (a || o) {
3467
+ let [e, t] = [n.yaw + a * Un, n.pitch - o * Un];
3468
+ n = this.#u ? In(n, e, t, this.#r) : X({
3469
+ ...n,
3470
+ yaw: e,
3471
+ pitch: t
3472
+ }, void 0, this.#r);
3473
+ }
3474
+ this.#l && (n = X({
3475
+ ...n,
3476
+ dist: n.dist * Math.exp(this.#l)
3477
+ }, void 0, this.#r)), this.#c = [0, 0], this.#s = [0, 0], this.#l = 0;
3478
+ let [s, c, l] = Yn(this.#o), u = this.enabled && this.#u && (s !== 0 || l !== 0 || c !== 0);
3479
+ if (u) {
3480
+ let e = Kn * Ln(n) * t;
3481
+ n = Rn(n, s * e, c * e, l * e);
3482
+ }
3483
+ let d = this.#f;
3484
+ n !== this.#d && this.#k(!1);
3485
+ let f = this.#p;
3486
+ if (f) {
3487
+ f.start ??= e;
3488
+ let t = Math.min(1, (e - f.start) / f.path.ms);
3489
+ this.#d = this.#f = this.#j(f.path.at(t)), t === 1 && this.#k(!0);
3490
+ } else d !== n && (this.#d = n = this.#j(n), this.#f = Xn(d, n, t, this.#n, this.#r));
3491
+ this.#f !== d && this.#A(), u || this.#p || this.#f !== this.#d ? this.#E() : this.#g = null;
3492
+ };
3493
+ #O(e) {
3494
+ this.#k(!1), this.#d = e, this.#E();
3495
+ }
3496
+ #k(e) {
3497
+ let t = this.#p;
3498
+ this.#p = null, t?.land(e);
3499
+ }
3500
+ #A() {
3501
+ this.#M();
3502
+ let e = this.pose;
3503
+ for (let t of this.#m) t(e);
3504
+ }
3505
+ #j(e) {
3506
+ return X(e, this.#n, this.#r);
3507
+ }
3508
+ #M() {
3509
+ this.#t.setCamera(Nn(this.#f));
3510
+ }
3511
+ };
3512
+ function $(e, t, n) {
3513
+ e[0] += t, e[1] += n;
3514
+ }
3515
+ //#endregion
3516
+ export { yt as C, Kt as S, An as _, Z as a, Nn as b, Bn as c, jn as d, Ln as f, zn as g, kn as h, Q as i, Vn as l, Fn as m, yn as n, X as o, In as p, J as r, bn as s, Zn as t, Rn as u, Pn as v, ve as w, Gt as x, Hn as y };