@kalyptos/narcissus 0.0.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { F as e, I as t, c as n, l as r, m as i, u as a } from "./format-CxKTIugr.js";
1
+ import { F as e, I as t, c as n, l as r, m as i, u as a } from "./format-C3Vn0c2b.js";
2
2
  import { t as o } from "./ports-DZRKjdYD.js";
3
3
  import { t as s } from "./http-DL7R39Nc.js";
4
4
  //#region src/engine/gpu/layout.ts
@@ -56,22 +56,26 @@ var m = 19, h = 1024, g = class {
56
56
  capacity;
57
57
  #e;
58
58
  #t = /* @__PURE__ */ new Map();
59
- #n = /* @__PURE__ */ new Set();
60
- #r;
61
- #i;
59
+ #n = null;
60
+ #r = null;
61
+ #i = /* @__PURE__ */ new Set();
62
62
  #a;
63
- #o = [
63
+ #o;
64
+ #s = 0;
65
+ #c;
66
+ #l = [
64
67
  0,
65
68
  0,
66
69
  0
67
70
  ];
68
- #s;
69
- #c;
70
- #l = new g();
71
71
  #u;
72
72
  #d;
73
73
  #f = new g();
74
74
  #p;
75
+ #m;
76
+ #h = new g();
77
+ #g;
78
+ #_ = [];
75
79
  constructor(e, t) {
76
80
  this.capacity = t, this.#e = e;
77
81
  let n = this.slots, r = GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC, i = (t, n) => e.createBuffer({
@@ -79,7 +83,7 @@ var m = 19, h = 1024, g = class {
79
83
  size: n,
80
84
  usage: r
81
85
  });
82
- this.geometry = i("pool geometry", t * 4 * 4), this.colour = i("pool colour", t * 3 * 4), this.pages = i("pool pages", n * 36 * 4), this.clusters = i("pool clusters", n * 12 * 4), this.list = i("pool list", n * 4), this.#r = new Uint8Array(n), this.#i = n, this.#a = Array.from({ length: n }, (e, t) => n - 1 - t), this.#s = new Uint32Array(n * 36), this.#c = new Float32Array(this.#s.buffer), this.#u = new Uint32Array(n * 12), this.#d = new Float32Array(this.#u.buffer), this.#p = new Uint32Array(n);
86
+ this.geometry = i("pool geometry", t * 4 * 4), this.colour = i("pool colour", t * 3 * 4), this.pages = i("pool pages", n * 36 * 4), this.clusters = i("pool clusters", n * 12 * 4), this.list = i("pool list", n * 4), 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);
83
87
  }
84
88
  get slots() {
85
89
  return this.capacity / 256;
@@ -101,65 +105,72 @@ var m = 19, h = 1024, g = class {
101
105
  return this.#t.has(e);
102
106
  }
103
107
  *ids() {
104
- for (let [e, t] of this.#t) t.page === null && (yield e);
108
+ for (let e = this.#n; e; e = e.next) e.page === null && (yield e.id);
105
109
  }
106
110
  add(e, n, r, i) {
107
111
  if (this.#t.has(e)) return !0;
108
112
  let a = c(n.count) / 256;
109
- if (!this.#m(a, i)) return !1;
110
- let o = t.origin;
111
- return this.#t.set(e, {
113
+ if (!this.#b(a, i)) return !1;
114
+ let o = t.origin, s = {
115
+ id: e,
116
+ previous: null,
117
+ next: null,
112
118
  page: n,
113
- slots: this.#v(a),
114
- table: this.#a.pop(),
119
+ slots: this.#w(a),
120
+ active: [],
121
+ mask: 0,
122
+ table: this.#c.pop(),
115
123
  base: [
116
124
  n.params[o] + r[0],
117
125
  n.params[o + 1] + r[1],
118
126
  n.params[o + 2]
119
127
  ],
120
128
  factors: 0
121
- }), this.#n.add(e), !0;
129
+ };
130
+ return this.#t.set(e, s), this.#y(s), this.#i.add(e), !0;
122
131
  }
123
132
  remove(e) {
124
133
  let t = this.#t.get(e);
125
134
  if (t) {
126
- this.#t.delete(e), this.#n.delete(e);
127
- for (let e of t.slots) this.#r[e] = 0;
128
- this.#i += t.slots.length, this.#a.push(t.table), t.page === null && t.factors !== 0 && this.#_(t, 0);
135
+ this.#v(t), this.#t.delete(e), this.#i.delete(e);
136
+ for (let e of t.slots) this.#a[e] = 0;
137
+ 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.#C(t, 0);
129
138
  }
130
139
  }
131
140
  clear() {
132
141
  for (let e of this.#t.keys()) this.remove(e);
133
142
  }
134
143
  get queued() {
135
- return this.#n.size;
144
+ return this.#i.size;
136
145
  }
137
146
  upload(e) {
138
147
  let t = 0;
139
- for (let n of this.#n) {
148
+ for (let n of this.#i) {
140
149
  if (t >= e) break;
141
- t += this.#h(this.#t.get(n)), this.#n.delete(n);
150
+ t += this.#x(this.#t.get(n)), this.#i.delete(n);
142
151
  }
143
152
  return t;
144
153
  }
145
154
  draw(e) {
146
- let t = 0;
147
- for (let { id: n, factors: r } of e) {
148
- let e = this.#t.get(n);
149
- e && e.page === null && (e.factors !== r && this.#_(e, r), this.#t.delete(n), this.#t.set(n, e), this.#p.set(e.slots, t), t += e.slots.length);
155
+ let t = 0, n = 0, r = !1;
156
+ for (let { id: i, factors: a } of e) {
157
+ let e = this.#t.get(i);
158
+ if (!e || e.page !== null) continue;
159
+ let o = e.active;
160
+ e.factors !== a && this.#C(e, a), r ||= o !== e.active, this.#y(e), r ||= this.#_[n] !== e, this.#_[n++] = e, r && this.#g.set(e.active, t), t += e.active.length;
150
161
  }
151
- this.listed = t;
152
- let n = this.#e.queue;
153
- this.#l.flush(n, this.pages, this.#s), this.#f.flush(n, this.clusters, this.#u), n.writeBuffer(this.list, 0, this.#p, 0, t);
162
+ r ||= this.#_.length !== n, this.#_.length = n, this.listed = t;
163
+ let i = this.#e.queue;
164
+ 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);
154
165
  }
155
166
  setOrigin(e) {
156
- this.#o = [
167
+ this.#l = [
157
168
  e[0],
158
169
  e[1],
159
170
  e[2]
160
171
  ];
161
- for (let e of this.#t.values()) e.page === null && this.#g(e);
162
- this.#e.queue.writeBuffer(this.pages, 0, this.#s), this.#l.clear();
172
+ for (let e of this.#t.values()) e.page === null && this.#S(e);
173
+ this.#e.queue.writeBuffer(this.pages, 0, this.#u), this.#f.clear();
163
174
  }
164
175
  destroy() {
165
176
  let e = [
@@ -171,50 +182,77 @@ var m = 19, h = 1024, g = class {
171
182
  ];
172
183
  for (let t of e) t.destroy();
173
184
  }
174
- #m(e, t) {
175
- let n = this.#i;
185
+ #v(e) {
186
+ 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;
187
+ }
188
+ #y(e) {
189
+ this.#r !== e && (this.#v(e), e.previous = this.#r, this.#r ? this.#r.next = e : this.#n = e, this.#r = e);
190
+ }
191
+ #b(e, t) {
192
+ let n = this.#o;
176
193
  if (n >= e) return !0;
177
194
  let r = [];
178
- for (let [i, a] of this.#t) if (!(a.page !== null || t(i)) && (r.push(i), n += a.slots.length, n >= e)) break;
195
+ for (let i = this.#n; i && !(!(i.page !== null || t(i.id)) && (r.push(i.id), n += i.slots.length, n >= e)); i = i.next);
179
196
  if (n < e) return !1;
180
197
  for (let e of r) this.remove(e);
181
198
  return !0;
182
199
  }
183
- #h(e) {
184
- let n = e.page, { slots: r } = e, i = this.#e.queue, a = r.length, o = this.#u, s = this.#d;
200
+ #x(e) {
201
+ let n = e.page, { slots: r } = e, i = this.#e.queue, a = r.length, o = this.#p, s = this.#m;
185
202
  for (let t = 0; t < a; t++) {
186
203
  let i = r[t] * 12;
187
- o.fill(0, i, i + 12), o[i] = e.table, o[i + 1] = r[t] * 256, o[i + 2] = t * 256, o[i + 3] = Math.max(0, Math.min(256, n.count - t * 256)), s.set(n.clusters.subarray(t * 6, t * 6 + 3), i + 4), s.set(n.clusters.subarray(t * 6 + 3, t * 6 + 6), i + 8);
204
+ o.fill(0, i, i + 12), o[i] = e.table, o[i + 1] = r[t] * 256, o[i + 2] = t * 256, o[i + 3] = Math.max(0, Math.min(256, n.count - t * 256));
205
+ for (let e = 0; e < 3; e++) s[i + 4 + e] = n.clusters[t * 6 + e], s[i + 8 + e] = n.clusters[t * 6 + 3 + e];
188
206
  }
189
207
  for (let e = 0; e < a;) {
190
208
  let t = 1;
191
209
  for (; e + t < a && r[e + t] === r[e] + t;) t++;
192
210
  let o = e * 256, s = Math.min((e + t) * 256, n.count) - o, c = r[e] * 256;
193
- 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.#f.mark(r[e] * 12, (r[e] + t) * 12), e += t;
211
+ 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;
194
212
  }
195
- let c = e.table * 36, l = this.#s, u = this.#c, d = n.params, [f, p, m] = n.quadrants;
196
- return l.fill(0, c, c + 36), this.#g(e), l[c + 3] = n.count, u.set(d.subarray(t.step, t.step + 3), c + 4), l[c + 7] = f, u.set(d.subarray(t.scaleMin, t.scaleMin + 3), c + 8), l[c + 11] = p, u.set(d.subarray(t.scaleMax, t.scaleMax + 3), c + 12), l[c + 15] = m, u.set(d.subarray(t.dcMin, t.dcMin + 3), c + 16), u.set(d.subarray(t.dcMax, t.dcMax + 3), c + 20), u.set(d.subarray(t.shScale, t.shScale + 9), c + 24), this.#l.mark(c, c + 36), e.page = null, n.count * 7 * 4 + a * 12 * 4 + 144;
213
+ let c = e.table * 36, l = this.#u, u = this.#d, d = n.params, [f, p, m] = n.quadrants;
214
+ return l.fill(0, c, c + 36), this.#S(e), l[c + 3] = n.count, u.set(d.subarray(t.step, t.step + 3), c + 4), l[c + 7] = f, u.set(d.subarray(t.scaleMin, t.scaleMin + 3), c + 8), l[c + 11] = p, u.set(d.subarray(t.scaleMax, t.scaleMax + 3), c + 12), l[c + 15] = m, u.set(d.subarray(t.dcMin, t.dcMin + 3), c + 16), u.set(d.subarray(t.dcMax, t.dcMax + 3), c + 20), u.set(d.subarray(t.shScale, t.shScale + 9), c + 24), this.#f.mark(c, c + 36), e.page = null, n.count * 7 * 4 + a * 12 * 4 + 144;
197
215
  }
198
- #g(e) {
216
+ #S(e) {
199
217
  let t = e.table * 36;
200
- for (let n = 0; n < 3; n++) this.#c[t + n] = e.base[n] - this.#o[n];
218
+ for (let n = 0; n < 3; n++) this.#d[t + n] = e.base[n] - this.#l[n];
201
219
  }
202
- #_(e, t) {
220
+ #C(e, t) {
221
+ let n = 0;
222
+ for (let e = 0; e < 4; e++) t >>> 8 * e & 255 && (n |= 1 << e);
223
+ if (n !== e.mask) {
224
+ if (e.mask = n, n === 15 && this.#u[e.table * 36 + 3] > 0) e.active = e.slots;
225
+ else {
226
+ let t = [], r = e.table * 36, i = 0, a = -1;
227
+ for (let o = 0; o < 4; o++) {
228
+ let s = this.#u[r + (o === 3 ? 3 : 7 + 4 * o)];
229
+ if (n & 1 << o && s > i) for (let n = Math.max(a + 1, Math.floor(i / 256)); n < Math.ceil(s / 256); n++) t.push(e.slots[n]), a = n;
230
+ i = s;
231
+ }
232
+ e.active = t;
233
+ }
234
+ }
203
235
  e.factors = t;
204
- let n = e.table * 36 + m;
205
- this.#s[n] = t, this.#l.mark(n, n + 1);
206
- }
207
- #v(e) {
208
- let t = this.#r, n = -1;
209
- for (let r = 0, i = 0; r < t.length; r++) if (i = t[r] ? 0 : i + 1, i === e) {
210
- n = r - e + 1;
211
- break;
236
+ let r = e.table * 36 + m;
237
+ this.#u[r] = t, this.#f.mark(r, r + 1);
238
+ }
239
+ #w(e) {
240
+ let t = this.#a, n = -1;
241
+ for (let r = this.#s; r <= t.length - e;) {
242
+ let i = r;
243
+ for (; i < r + e && !t[i];) i++;
244
+ if (i === r + e) {
245
+ n = r;
246
+ break;
247
+ }
248
+ if (r = t.indexOf(0, i + 1), r < 0) break;
212
249
  }
213
250
  let r = [];
214
251
  if (n >= 0) for (let t = n; t < n + e; t++) r.push(t);
215
- else for (let n = 0; r.length < e; n++) t[n] || r.push(n);
252
+ else for (let n = this.#s; r.length < e; n = t.indexOf(0, n + 1)) r.push(n);
216
253
  for (let e of r) t[e] = 1;
217
- return this.#i -= e, r;
254
+ let i = t.indexOf(0, this.#s);
255
+ return this.#s = i < 0 ? t.length : i, this.#o -= e, r;
218
256
  }
219
257
  };
220
258
  //#endregion
@@ -271,12 +309,14 @@ function T(e, t, n) {
271
309
  r("work", (l.list + n) * 4, i | GPUBufferUsage.INDIRECT),
272
310
  r("projected", t * 6 * 4, i),
273
311
  r("sort", t * 16, i),
274
- r("plugins", 256, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST)
275
- ], [o, s, c, u, d] = a;
312
+ r("plugins", 256, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST),
313
+ r("visible clusters", 4, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST)
314
+ ], [o, s, c, u, d, f] = a;
276
315
  return {
277
316
  capacity: t,
278
317
  uniforms: o,
279
318
  work: s,
319
+ visible: f,
280
320
  projected: c,
281
321
  sort: u,
282
322
  plugins: d,
@@ -306,7 +346,7 @@ function D(e, t, n, r) {
306
346
  }
307
347
  //#endregion
308
348
  //#region src/engine/gpu/common.wgsl?raw
309
- var O = "// 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 pad: 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 pad0: u32,\n boxMax: vec3f,\n pad1: 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", k = "// 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// some quadrant the cluster's splats overlap has a nonzero factor\nfn lit(page: Page, cluster: Cluster) -> bool {\n var starts = array<u32, 5>(0u, page.q1, page.q2, page.q3, page.count);\n let end = cluster.first + cluster.count;\n for (var k = 0u; k < 4u; k++) {\n let overlaps = max(starts[k], cluster.first) < min(starts[k + 1u], end);\n if (overlaps && extractBits(page.factors, 8u * k, 8u) != 0u) {\n return true;\n }\n }\n return false;\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) || !lit(page, cluster)) {\n return;\n }\n atomicStore(&work[WORK_LIST + atomicAdd(&work[WORK_VISIBLE], 1u)], slot);\n}\n", A = 64, j = class {
349
+ var O = "// 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 pad: 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 pad0: u32,\n boxMax: vec3f,\n pad1: 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", k = "// 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", A = 64, j = class {
310
350
  #e;
311
351
  #t;
312
352
  #n;
@@ -344,10 +384,10 @@ var O = "// shared by every engine pass; sizes and word offsets mirror format/sp
344
384
  label: "cull",
345
385
  timestampWrites: t
346
386
  });
347
- n.setBindGroup(0, this.#n), n.setPipeline(this.#t), n.dispatchWorkgroups(Math.ceil(this.#e.listed / A)), n.end();
387
+ n.setBindGroup(0, this.#n), n.setPipeline(this.#t), this.#e.listed && n.dispatchWorkgroups(Math.ceil(this.#e.listed / A)), n.end();
348
388
  }
349
- }, M = "// 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 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", ee = 32, te = .5, ne = 1;
350
- function re(e) {
389
+ }, M = "// 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 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", N = 32, ee = .5, te = 1;
390
+ function ne(e) {
351
391
  let t = new Uint32Array(e.length);
352
392
  for (let n = 0; n < e.length; n++) {
353
393
  let r = e[n];
@@ -355,7 +395,7 @@ function re(e) {
355
395
  }
356
396
  return new Float32Array(t.buffer);
357
397
  }
358
- var ie = class {
398
+ var re = class {
359
399
  #e;
360
400
  #t;
361
401
  #n;
@@ -385,7 +425,7 @@ var ie = class {
385
425
  encode(e, t, n, r, i) {
386
426
  let a = this.#e, o = this.#t, { listed: s } = o, c = r * r * 4, l = a.createBuffer({
387
427
  label: "heights area",
388
- size: ee,
428
+ size: N,
389
429
  usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
390
430
  }), u = a.createBuffer({
391
431
  label: "heights",
@@ -395,14 +435,14 @@ var ie = class {
395
435
  label: "heights readback",
396
436
  size: c,
397
437
  usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
398
- }), p = /* @__PURE__ */ new ArrayBuffer(ee);
438
+ }), p = /* @__PURE__ */ new ArrayBuffer(N);
399
439
  new Float32Array(p).set([
400
440
  t,
401
441
  n,
402
442
  0,
403
443
  0,
404
- te,
405
- ne
444
+ ee,
445
+ te
406
446
  ]), new Uint32Array(p).set([r, s], 2), a.queue.writeBuffer(l, 0, p);
407
447
  let m = [
408
448
  l,
@@ -415,11 +455,11 @@ var ie = class {
415
455
  label: "heights",
416
456
  timestampWrites: i
417
457
  });
418
- return g.setPipeline(this.#r), g.setBindGroup(0, h), s > 0 && g.dispatchWorkgroups(...d(s)), g.end(), e.copyBufferToBuffer(u, 0, f, 0, c), () => f.mapAsync(GPUMapMode.READ).then(() => re(new Uint32Array(f.getMappedRange())), () => null).finally(() => {
458
+ return g.setPipeline(this.#r), g.setBindGroup(0, h), s > 0 && g.dispatchWorkgroups(...d(s)), g.end(), e.copyBufferToBuffer(u, 0, f, 0, c), () => f.mapAsync(GPUMapMode.READ).then(() => ne(new Uint32Array(f.getMappedRange())), () => null).finally(() => {
419
459
  l.destroy(), u.destroy(), f.destroy();
420
460
  });
421
461
  }
422
- }, ae = "@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", oe = class {
462
+ }, ie = "@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", ae = class {
423
463
  #e;
424
464
  #t;
425
465
  #n;
@@ -428,7 +468,7 @@ var ie = class {
428
468
  constructor(e, t, n, r) {
429
469
  let i = e.createShaderModule({
430
470
  label: t,
431
- code: ae + n
471
+ code: ie + n
432
472
  });
433
473
  this.#e = e, this.#t = t, this.#n = e.createRenderPipeline({
434
474
  label: t,
@@ -463,15 +503,17 @@ var ie = class {
463
503
  });
464
504
  r.setPipeline(this.#n), r.setBindGroup(0, this.#i), r.draw(3), r.end();
465
505
  }
466
- }, se = "// 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", ce = (e, t) => new oe(e, "present", se, t), le = "// one workgroup per visible cluster, one thread per splat; shade() follows, generated with the hooks\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\nvar<workgroup> visible: u32;\nvar<workgroup> kept: atomic<u32>;\nvar<workgroup> base: u32;\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// 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 let page = pages[cluster.page];\n let rec = cluster.slot + t;\n let 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 // decode\n var s: Splat;\n let q = vec3f(f32(g.x & 0xffffu), f32(g.x >> 16u), f32(g.y & 0xffffu));\n s.position = page.origin + q * page.step;\n s.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 s.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 d = normalize(s.position - uniforms.camera);\n s.colour = max(0.5 + C0 * dc + C1 * (-d.y * m0 + d.z * m1 - d.x * m2), vec3f(0.0));\n s.depth = -(uniforms.view * vec4f(s.position, 1.0)).z;\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 // ewa: view-space covariance wm wm^T through the jacobian of the pixel projection\n let r = rotate(rotation(g));\n let m = mat3x3f(r[0] * s.scale.x, r[1] * s.scale.y, r[2] * s.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 let a = dot(u, u) + uniforms.lowPass;\n let b = dot(u, v);\n let c = dot(v, v) + uniforms.lowPass;\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(@builtin(workgroup_id) wid: vec3u, @builtin(local_invocation_index) t: u32) {\n if (t == 0u) {\n visible = atomicLoad(&work[WORK_VISIBLE]);\n }\n let index = wid.y * GROUPS_X + wid.x;\n if (index >= workgroupUniformLoad(&visible)) {\n return;\n }\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 workgroup\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], atomicLoad(&kept));\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", ue = class {
506
+ }, oe = "// 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", se = (e, t) => new ae(e, "present", oe, t), ce = "// 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// 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// 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 let page = pages[cluster.page];\n let rec = cluster.slot + t;\n let 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 // decode\n var s: Splat;\n let q = vec3f(f32(g.x & 0xffffu), f32(g.x >> 16u), f32(g.y & 0xffffu));\n s.position = page.origin + q * page.step;\n s.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 s.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 d = normalize(s.position - uniforms.camera);\n s.colour = max(0.5 + C0 * dc + C1 * (-d.y * m0 + d.z * m1 - d.x * m2), vec3f(0.0));\n s.depth = -(uniforms.view * vec4f(s.position, 1.0)).z;\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 // ewa: view-space covariance wm wm^T through the jacobian of the pixel projection\n let r = rotate(rotation(g));\n let m = mat3x3f(r[0] * s.scale.x, r[1] * s.scale.y, r[2] * s.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 let a = dot(u, u) + uniforms.lowPass;\n let b = dot(u, v);\n let c = dot(v, v) + uniforms.lowPass;\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", le = class {
467
507
  #e;
468
508
  #t;
469
509
  #n;
470
510
  #r = [];
471
511
  #i;
472
512
  #a;
513
+ #o;
514
+ #s;
473
515
  constructor(e, t, n) {
474
- this.#e = e, this.#a = t;
516
+ this.#e = e, this.#a = t, this.#o = n.work, this.#s = n.visible;
475
517
  let r = E(e, "project", GPUShaderStage.COMPUTE, [
476
518
  "uniform",
477
519
  "uniform",
@@ -481,7 +523,8 @@ var ie = class {
481
523
  "read-only-storage",
482
524
  "storage",
483
525
  "storage",
484
- "storage"
526
+ "storage",
527
+ "uniform"
485
528
  ]);
486
529
  this.#t = e.createPipelineLayout({ bindGroupLayouts: [r] });
487
530
  let i = [
@@ -493,27 +536,29 @@ var ie = class {
493
536
  t.clusters,
494
537
  n.work,
495
538
  n.projected,
496
- n.sort
539
+ n.sort,
540
+ n.visible
497
541
  ];
498
542
  this.#i = D(e, "project", r, i);
499
543
  }
500
544
  hooks(e) {
501
545
  this.#r = e, this.#n = void 0;
502
546
  }
503
- encode(e, t) {
504
- let n = Math.max(1, this.#a.listed), r = e.beginComputePass({
547
+ encode(e, t, n) {
548
+ e.copyBufferToBuffer(this.#o, l.visible * 4, this.#s, 0, 4);
549
+ let r = Math.max(1, Math.min(128, this.#a.listed, t ? Math.max(32, Math.ceil(t / 16)) : 128)), i = e.beginComputePass({
505
550
  label: "project",
506
- timestampWrites: t
551
+ timestampWrites: n
507
552
  });
508
- r.setPipeline(this.#n ??= this.#o()), r.setBindGroup(0, this.#i), r.dispatchWorkgroups(...d(n)), r.end();
553
+ i.setPipeline(this.#n ??= this.#c()), i.setBindGroup(0, this.#i), i.dispatchWorkgroups(r), i.end();
509
554
  }
510
- #o() {
555
+ #c() {
511
556
  let e = this.#r, t = e.map(({ shade: e, slot: t }) => {
512
557
  let n = Array.from({ length: e.uniforms }, (e, n) => `plugins[${t + n}]`);
513
558
  return `\t${e.name}(s, array<vec4f, ${e.uniforms}>(${n.join(", ")}));`;
514
559
  }), n = [
515
560
  O,
516
- le,
561
+ ce,
517
562
  ...e.map(({ shade: e }) => e.wgsl),
518
563
  "fn shade(s: ptr<function, Splat>) {",
519
564
  ...t,
@@ -531,10 +576,10 @@ var ie = class {
531
576
  }
532
577
  });
533
578
  }
534
- }, de = "// 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", fe = "rgb10a2unorm", pe = "depth16unorm", me = {
579
+ }, ue = "// 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", de = "rgb10a2unorm", fe = "depth16unorm", pe = {
535
580
  srcFactor: "one",
536
581
  dstFactor: "one-minus-src-alpha"
537
- }, he = class {
582
+ }, me = class {
538
583
  #e;
539
584
  #t;
540
585
  #n;
@@ -567,7 +612,7 @@ var ie = class {
567
612
  ]);
568
613
  let a = e.createShaderModule({
569
614
  label: "raster",
570
- code: O + de
615
+ code: O + ue
571
616
  }), o = e.createPipelineLayout({ bindGroupLayouts: [i] }), s = (t, n) => e.createRenderPipeline({
572
617
  label: `raster ${t}`,
573
618
  layout: o,
@@ -579,10 +624,10 @@ var ie = class {
579
624
  module: a,
580
625
  entryPoint: "fs",
581
626
  targets: [{
582
- format: fe,
627
+ format: de,
583
628
  blend: {
584
- color: me,
585
- alpha: me
629
+ color: pe,
630
+ alpha: pe
586
631
  }
587
632
  }]
588
633
  },
@@ -590,7 +635,7 @@ var ie = class {
590
635
  depthStencil: n
591
636
  });
592
637
  this.#n = s("Colour"), this.#r = s("Depth", {
593
- format: pe,
638
+ format: fe,
594
639
  depthWriteEnabled: !0,
595
640
  depthCompare: "always"
596
641
  });
@@ -618,7 +663,7 @@ var ie = class {
618
663
  this.#t.destroy();
619
664
  }
620
665
  };
621
- function ge(e, t, n, r, i, a, o) {
666
+ function he(e, t, n, r, i, a, o) {
622
667
  let { width: s, height: c } = n, l = Math.ceil(s * 2 / 256) * 256, u = e.createBuffer({
623
668
  label: "pick",
624
669
  size: l * c,
@@ -636,7 +681,7 @@ function ge(e, t, n, r, i, a, o) {
636
681
  }
637
682
  //#endregion
638
683
  //#region src/engine/gpu/sort.wgsl?raw
639
- var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan, a stable scatter; no spin-waits\n\nconst THREADS: u32 = 256u;\nconst ITEMS: u32 = 4u;\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> sk: array<u32, BLOCK>;\nvar<workgroup> sv: array<u32, BLOCK>;\nvar<workgroup> counts: array<vec4u, THREADS>;\nvar<workgroup> starts: array<u32, DIGITS>;\nvar<workgroup> offsets: array<u32, DIGITS>;\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 let block = wid.y * groups.x + wid.x;\n if (block >= state.blocks) {\n return;\n }\n atomicStore(&bins[t], 0u);\n workgroupBarrier();\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 hist[block * DIGITS + t] = atomicLoad(&bins[t]);\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 workgroupBarrier();\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 block = wid.y * groups.x + wid.x;\n if (block >= state.blocks) {\n return;\n }\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 offsets[t] = hist[block * DIGITS + t];\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 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;\n workgroupBarrier();\n for (var o = 1u; o < THREADS; o *= 2u) {\n var x = vec4u(0u);\n if (t >= o) {\n x = counts[t - o];\n }\n workgroupBarrier();\n counts[t] += x;\n workgroupBarrier();\n }\n let total = counts[THREADS - 1u];\n let prior = counts[t] - mine;\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}\n", ve = 1024, ye = 64, be = 256, N = 3, P = 256, xe = 32, Se = class {
684
+ var ge = "// 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", _e = 1024, ve = 64, ye = 256, P = 3, F = 256, be = 32, xe = class {
640
685
  keys;
641
686
  values;
642
687
  bytes;
@@ -646,25 +691,24 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
646
691
  #r;
647
692
  #i;
648
693
  #a;
649
- #o;
650
694
  constructor(e, t) {
651
695
  let { capacity: n } = t;
652
696
  this.keys = n * 8, this.values = n * 12;
653
- let r = Math.max(1, Math.ceil(n / ve));
654
- this.#a = d(r), this.#o = Math.ceil(r / ye);
655
- let i = (t, n, r) => e.createBuffer({
697
+ let r = Math.max(1, Math.ceil(n / _e));
698
+ this.#a = r;
699
+ let i = Math.ceil(r / ve), a = (t, n, r) => e.createBuffer({
656
700
  label: t,
657
701
  size: n,
658
702
  usage: r
659
- }), a = GPUBufferUsage.STORAGE, o = i("sort params", N * P, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST), s = i("sort histograms", r * be * 4, a), c = i("sort chunk sums", this.#o * be * 4, a), u = i("sort state", 12, a);
703
+ }), o = GPUBufferUsage.STORAGE, s = a("sort params", P * F, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST), c = a("sort histograms", r * ye * 4, o), u = a("sort chunk sums", (i * ye + 1) * 4, o), d = a("sort state", 12, o);
660
704
  this.#e = [
661
- o,
662
705
  s,
663
706
  c,
664
- u
707
+ u,
708
+ d
665
709
  ], this.bytes = this.#e.reduce((e, t) => e + t.size, 0);
666
- let f = new Uint32Array(N * P / 4);
667
- for (let e = 0; e < N; e++) {
710
+ let f = new Uint32Array(P * F / 4);
711
+ for (let e = 0; e < P; e++) {
668
712
  let [t, r] = e % 2 ? [2 * n, 0] : [0, 2 * n];
669
713
  f.set([
670
714
  8 * e,
@@ -673,9 +717,9 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
673
717
  n,
674
718
  l.projected,
675
719
  l.drawArgs
676
- ], e * P / 4);
720
+ ], e * F / 4);
677
721
  }
678
- e.queue.writeBuffer(o, 0, f);
722
+ e.queue.writeBuffer(s, 0, f);
679
723
  let p = (e, t) => ({
680
724
  binding: e,
681
725
  visibility: GPUShaderStage.COMPUTE,
@@ -695,7 +739,7 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
695
739
  ]
696
740
  }), g = e.createShaderModule({
697
741
  label: "sort",
698
- code: O + _e
742
+ code: O + ge
699
743
  }), _ = (t, n) => e.createComputePipeline({
700
744
  label: `sort ${t}`,
701
745
  layout: e.createPipelineLayout({ bindGroupLayouts: [n] }),
@@ -712,9 +756,9 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
712
756
  "scatter"
713
757
  ].map((e) => _(e, m));
714
758
  let v = (e) => ({
715
- buffer: o,
716
- offset: e * P,
717
- size: xe
759
+ buffer: s,
760
+ offset: e * F,
761
+ size: be
718
762
  });
719
763
  this.#r = e.createBindGroup({
720
764
  label: "sort prepare",
@@ -726,14 +770,14 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
726
770
  },
727
771
  {
728
772
  binding: 5,
729
- resource: { buffer: u }
773
+ resource: { buffer: d }
730
774
  },
731
775
  {
732
776
  binding: 6,
733
777
  resource: { buffer: t.work }
734
778
  }
735
779
  ]
736
- }), this.#i = Array.from({ length: N }, (n, r) => e.createBindGroup({
780
+ }), this.#i = Array.from({ length: P }, (n, r) => e.createBindGroup({
737
781
  label: `sort pass ${r}`,
738
782
  layout: m,
739
783
  entries: [
@@ -747,32 +791,32 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
747
791
  },
748
792
  {
749
793
  binding: 2,
750
- resource: { buffer: s }
794
+ resource: { buffer: c }
751
795
  },
752
796
  {
753
797
  binding: 3,
754
- resource: { buffer: c }
798
+ resource: { buffer: u }
755
799
  },
756
800
  {
757
801
  binding: 4,
758
- resource: { buffer: u }
802
+ resource: { buffer: d }
759
803
  }
760
804
  ]
761
805
  }));
762
806
  }
763
- encode(e, t) {
764
- let [n, r, i, a, o] = this.#n, s = this.#a, c = e.beginComputePass({
807
+ encode(e, t, n, r) {
808
+ let [i, a, o, s, c] = this.#n, l = Math.max(1, Math.min(this.#a, Math.ceil(t / _e))), u = Math.max(l / 16, (n || t) / _e), f = d(Math.min(Math.ceil(l / 4), Math.ceil(u))), p = Math.ceil(l / ve), m = e.beginComputePass({
765
809
  label: "sort",
766
- timestampWrites: t
810
+ timestampWrites: r
767
811
  });
768
- c.setPipeline(this.#t), c.setBindGroup(0, this.#r), c.dispatchWorkgroups(1);
769
- for (let e of this.#i) c.setBindGroup(0, e), c.setPipeline(n), c.dispatchWorkgroups(...s), c.setPipeline(r), c.dispatchWorkgroups(this.#o), c.setPipeline(i), c.dispatchWorkgroups(1), c.setPipeline(a), c.dispatchWorkgroups(this.#o), c.setPipeline(o), c.dispatchWorkgroups(...s);
770
- c.end();
812
+ m.setPipeline(this.#t), m.setBindGroup(0, this.#r), m.dispatchWorkgroups(1);
813
+ for (let e of this.#i) m.setBindGroup(0, e), m.setPipeline(i), m.dispatchWorkgroups(...f), m.setPipeline(a), m.dispatchWorkgroups(p), m.setPipeline(o), m.dispatchWorkgroups(1), m.setPipeline(s), m.dispatchWorkgroups(p), m.setPipeline(c), m.dispatchWorkgroups(...f);
814
+ m.end();
771
815
  }
772
816
  destroy() {
773
817
  for (let e of this.#e) e.destroy();
774
818
  }
775
- }, Ce = class {
819
+ }, Se = class {
776
820
  ms = {};
777
821
  #e;
778
822
  #t;
@@ -799,7 +843,7 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
799
843
  }
800
844
  writes(e) {
801
845
  let t = this.#t;
802
- if (!t) return;
846
+ if (!t || this.#i) return;
803
847
  let n = this.#e.indexOf(e);
804
848
  return {
805
849
  querySet: t,
@@ -823,14 +867,14 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
823
867
  destroy() {
824
868
  this.#t?.destroy(), this.#n?.destroy(), this.#r?.destroy();
825
869
  }
826
- }, we = [
870
+ }, Ce = [
827
871
  "cull",
828
872
  "project",
829
873
  "sort",
830
874
  "raster",
831
875
  "heights",
832
876
  "post"
833
- ], F = {
877
+ ], I = {
834
878
  view: 0,
835
879
  proj: 16,
836
880
  viewProj: 32,
@@ -843,7 +887,7 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
843
887
  far: 81,
844
888
  lowPass: 82,
845
889
  clusters: 83
846
- }, Te = class {
890
+ }, we = class {
847
891
  #e;
848
892
  #t;
849
893
  #n;
@@ -869,11 +913,12 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
869
913
  #S;
870
914
  #C = !1;
871
915
  #w = 0;
916
+ #T = 0;
872
917
  constructor(e, t, n, r) {
873
918
  let { device: i } = e;
874
- this.#e = i, this.#t = t, this.#n = e.format, this.#r = n, this.#i = T(i, r, n.slots), this.#a = new j(i, n, this.#i), this.#o = new ue(i, n, this.#i), this.#s = new Se(i, this.#i), this.#c = new he(i, this.#i, this.#s), this.#u = new ie(i, n), this.#d = new Ce(i, e.timestamps, we), this.#S = i.createBuffer({
875
- label: "drawn readback",
876
- size: 4,
919
+ this.#e = i, this.#t = t, this.#n = e.format, this.#r = n, this.#i = T(i, r, n.slots), this.#a = new j(i, n, this.#i), this.#o = new le(i, n, this.#i), this.#s = new xe(i, this.#i), this.#c = new me(i, this.#i, this.#s), this.#u = new re(i, n), this.#d = new Se(i, e.timestamps, Ce), this.#S = i.createBuffer({
920
+ label: "counts readback",
921
+ size: (l.projected + 1) * 4,
877
922
  usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
878
923
  }), this.#b = Math.max(1, t.canvas.width), this.#x = Math.max(1, t.canvas.height);
879
924
  }
@@ -883,9 +928,9 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
883
928
  shade: e,
884
929
  slot: 0
885
930
  };
886
- return this.#g.push(t), this.#T(), () => {
931
+ return this.#g.push(t), this.#E(), () => {
887
932
  let e = this.#g.indexOf(t);
888
- e < 0 || (this.#g.splice(e, 1), this.#T());
933
+ e < 0 || (this.#g.splice(e, 1), this.#E());
889
934
  };
890
935
  }
891
936
  post(e) {
@@ -899,16 +944,16 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
899
944
  };
900
945
  }
901
946
  resize(e, t) {
902
- (e !== this.#b || t !== this.#x) && (this.#b = e, this.#x = t, this.#A());
947
+ (e !== this.#b || t !== this.#x) && (this.#b = e, this.#x = t, this.#j());
903
948
  }
904
949
  render(e, t, n, r, i) {
905
- let a = this.#e, o = this.#d, s = this.#_, c = this.#O(this.#D("colour", fe)), u = r.length > 0 || s.some(({ post: e }) => e.depth), d = this.#k("depth", pe, u), f = d ? this.#O(d) : null, p = [this.#k("ping", this.#n, s.length > 1), this.#k("pong", this.#n, s.length > 2)];
906
- this.#E(e, t);
950
+ let a = this.#e, o = this.#d, s = this.#_, c = this.#k(this.#O("colour", de)), u = r.length > 0 || s.some(({ post: e }) => e.depth), d = this.#A("depth", fe, u), f = d ? this.#k(d) : null, p = [this.#A("ping", this.#n, s.length > 1), this.#A("pong", this.#n, s.length > 2)];
951
+ this.#D(e, t);
907
952
  let m = a.createCommandEncoder({ label: "frame" });
908
- m.clearBuffer(this.#i.work, 0, l.list * 4), this.#a.encode(m, o.writes("cull")), this.#o.encode(m, o.writes("project")), this.#s.encode(m, o.writes("sort")), this.#c.encode(m, c, f, n, o.writes("raster"));
953
+ m.clearBuffer(this.#i.work, 0, l.list * 4), this.#a.encode(m, o.writes("cull")), this.#o.encode(m, this.#T, o.writes("project")), this.#s.encode(m, this.#r.listed * 256, this.#w, o.writes("sort")), this.#c.encode(m, c, f, n, o.writes("raster"));
909
954
  let h = d ? r.map(({ x: t, y: n, resolve: r }) => ({
910
955
  resolve: r,
911
- read: ge(a, m, d, t, n, e.near, e.far)
956
+ read: he(a, m, d, t, n, e.near, e.far)
912
957
  })) : [], g = i.map(({ x: e, y: t, cells: n, resolve: r }, i) => ({
913
958
  resolve: r,
914
959
  read: this.#u.encode(m, e, t, n, i ? void 0 : o.writes("heights"))
@@ -921,11 +966,11 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
921
966
  } }).end();
922
967
  }
923
968
  let v = this.#t.getCurrentTexture().createView();
924
- if (!s.length) this.#l ??= ce(a, this.#n), this.#l.encode(m, [c], v);
969
+ if (!s.length) this.#l ??= se(a, this.#n), this.#l.encode(m, [c], v);
925
970
  else {
926
971
  let t = c;
927
972
  s.forEach(({ post: n, pass: r }, i) => {
928
- let a = i === s.length - 1 ? v : this.#O(p[i % 2]);
973
+ let a = i === s.length - 1 ? v : this.#k(p[i % 2]);
929
974
  r.run(m, e, t, n.depth ? f : null, a), t = a;
930
975
  });
931
976
  }
@@ -938,7 +983,7 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
938
983
  }
939
984
  o.resolve(m);
940
985
  let y = !this.#C;
941
- y && m.copyBufferToBuffer(this.#i.work, l.projected * 4, this.#S, 0, 4), a.queue.submit([m.finish()]), o.read(), y && this.#j();
986
+ y && m.copyBufferToBuffer(this.#i.work, 0, this.#S, 0, this.#S.size), a.queue.submit([m.finish()]), o.read(), y && this.#M();
942
987
  for (let { resolve: e, read: t } of h) t().then(e);
943
988
  for (let { resolve: e, read: t } of g) t().then(e);
944
989
  return a.queue.onSubmittedWorkDone();
@@ -955,20 +1000,20 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
955
1000
  }
956
1001
  destroy() {
957
1002
  for (let { pass: e } of this.#_.splice(0)) e.destroy();
958
- this.#A(), this.#i.destroy(), this.#s.destroy(), this.#c.destroy(), this.#d.destroy(), this.#S.destroy();
1003
+ this.#j(), this.#i.destroy(), this.#s.destroy(), this.#c.destroy(), this.#d.destroy(), this.#S.destroy();
959
1004
  }
960
- #T() {
1005
+ #E() {
961
1006
  let e = 0;
962
1007
  for (let t of this.#g) t.slot = e, e += t.shade.uniforms;
963
1008
  this.#o.hooks(this.#g);
964
1009
  }
965
- #E(e, t) {
1010
+ #D(e, t) {
966
1011
  let n = this.#f, [r, i] = [this.#b, this.#x];
967
- n.set(e.view, F.view), n.set(e.proj, F.proj), n.set(S(this.#m, e.proj, e.view), F.viewProj), n.set(t, F.planes), n.set(e.camera.subarray(0, 3), F.camera), n[F.time] = e.time, n.set([r, i], F.viewport), n.set([e.proj[0] * r / 2, e.proj[5] * i / 2], F.focal), n[F.near] = e.near, n[F.far] = e.far, n[F.lowPass] = f, this.#p[F.clusters] = this.#r.listed, this.#e.queue.writeBuffer(this.#i.uniforms, 0, n);
1012
+ n.set(e.view, I.view), n.set(e.proj, I.proj), n.set(S(this.#m, e.proj, e.view), I.viewProj), n.set(t, I.planes), n.set(e.camera.subarray(0, 3), I.camera), n[I.time] = e.time, n.set([r, i], I.viewport), n.set([e.proj[0] * r / 2, e.proj[5] * i / 2], I.focal), n[I.near] = e.near, n[I.far] = e.far, n[I.lowPass] = f, this.#p[I.clusters] = this.#r.listed, this.#e.queue.writeBuffer(this.#i.uniforms, 0, n);
968
1013
  for (let { shade: t, slot: n } of this.#g) t.update(e, this.#h.subarray(n * 4, (n + t.uniforms) * 4));
969
- this.#e.queue.writeBuffer(this.#i.plugins, 0, this.#h);
1014
+ this.#g.length && this.#e.queue.writeBuffer(this.#i.plugins, 0, this.#h);
970
1015
  }
971
- #D(e, t) {
1016
+ #O(e, t) {
972
1017
  let n = this.#v[e];
973
1018
  return n || (n = this.#e.createTexture({
974
1019
  label: e,
@@ -977,27 +1022,27 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
977
1022
  usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC
978
1023
  }), this.#v[e] = n), n;
979
1024
  }
980
- #O(e) {
1025
+ #k(e) {
981
1026
  let t = this.#y.get(e);
982
1027
  return t || this.#y.set(e, t = e.createView()), t;
983
1028
  }
984
- #k(e, t, n) {
985
- if (n) return this.#D(e, t);
1029
+ #A(e, t, n) {
1030
+ if (n) return this.#O(e, t);
986
1031
  this.#v[e]?.destroy(), delete this.#v[e];
987
1032
  }
988
- #A() {
1033
+ #j() {
989
1034
  for (let e of Object.values(this.#v)) e?.destroy();
990
1035
  this.#v = {};
991
1036
  }
992
- #j() {
1037
+ #M() {
993
1038
  this.#C = !0;
994
1039
  let e = this.#S;
995
1040
  e.mapAsync(GPUMapMode.READ).then(() => {
996
- let t = new Uint32Array(e.getMappedRange())[0];
997
- this.#w = Math.min(t, this.#i.capacity), e.unmap();
1041
+ let t = new Uint32Array(e.getMappedRange());
1042
+ this.#T = t[l.visible], this.#w = Math.min(t[l.projected], this.#i.capacity), e.unmap();
998
1043
  }).catch(() => {}).finally(() => this.#C = !1);
999
1044
  }
1000
- }, Ee = [
1045
+ }, Te = [
1001
1046
  [0, 1],
1002
1047
  [0, -1],
1003
1048
  [1, 1],
@@ -1005,9 +1050,9 @@ var _e = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan
1005
1050
  [2, 0],
1006
1051
  [2, -1]
1007
1052
  ];
1008
- function De(e, t) {
1053
+ function Ee(e, t) {
1009
1054
  let n = (e, n) => t[n * 4 + e];
1010
- return Ee.forEach(([t, r], i) => {
1055
+ return Te.forEach(([t, r], i) => {
1011
1056
  for (let a = 0; a < 4; a++) e[i * 4 + a] = r ? n(3, a) + r * n(t, a) : n(t, a);
1012
1057
  let a = Math.hypot(e[i * 4], e[i * 4 + 1], e[i * 4 + 2]) || 1;
1013
1058
  for (let t = 0; t < 4; t++) e[i * 4 + t] /= a;
@@ -1015,118 +1060,127 @@ function De(e, t) {
1015
1060
  }
1016
1061
  //#endregion
1017
1062
  //#region src/engine/plan/footprint.ts
1063
+ var De = [
1064
+ 0,
1065
+ 0,
1066
+ 0
1067
+ ];
1018
1068
  function Oe(e, t, n, r) {
1019
1069
  let i = (e * e + e * t + t * t + n * n + n * r + r * r) / 3;
1020
1070
  return 1 + 15 * Math.max(0, 1 - i) ** 2;
1021
1071
  }
1022
1072
  function ke(e, t, n, r, i, a, o, s = 1, c = {
1073
+ shown: !1,
1023
1074
  pixels: 0,
1024
1075
  weight: 1
1025
- }) {
1026
- let l = (e[0] + e[3]) / 2, u = (e[1] + e[4]) / 2, d = (e[2] + e[5]) / 2, f = (e[3] - e[0]) / 2, p = (e[4] - e[1]) / 2, m = (e[5] - e[2]) / 2, h = t[0] * l + t[4] * u + t[8] * d + t[12], g = t[1] * l + t[5] * u + t[9] * d + t[13], _ = -(t[2] * l + t[6] * u + t[10] * d + t[14]), v = Math.abs(t[0]) * f + Math.abs(t[4]) * p + Math.abs(t[8]) * m, y = Math.abs(t[1]) * f + Math.abs(t[5]) * p + Math.abs(t[9]) * m, b = Math.abs(t[2]) * f + Math.abs(t[6]) * p + Math.abs(t[10]) * m;
1027
- if (c.pixels = 0, c.weight = 1, _ + b < a || _ - b > o) return c;
1028
- let x = Math.max(a, _ - b), S = Math.max(a, _ + b), C = i * n / r, w = Math.min((h - v) / x, (h - v) / S) / C, T = Math.max((h + v) / x, (h + v) / S) / C, E = Math.min((g - y) / x, (g - y) / S) / i, D = Math.max((g + y) / x, (g + y) / S) / i;
1029
- if (T < -s || w > s || D < -s || E > s) return c;
1030
- let O = Math.max(-s, w), k = Math.min(s, T), A = Math.max(-s, E), j = Math.min(s, D), M = (T - w) * (D - E), ee = (k - O) * (j - A);
1031
- return M <= 0 || ee <= 0 || (c.pixels = M * n * r / 4, c.weight = Oe(O, k, A, j)), c;
1076
+ }, l = De) {
1077
+ 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;
1078
+ if (c.pixels = 0, c.weight = 1, c.shown = !1, v + x < a || v - x > o) return c;
1079
+ let S = Math.max(a, v - x), C = Math.max(a, v + x), w = i * n / r;
1080
+ if (Math.abs(g) - y > s * w * C || Math.abs(_) - b > s * i * C) return c;
1081
+ 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;
1082
+ if (E < -s || T > s || O < -s || D > s) return c;
1083
+ let k = Math.max(-s, T), A = Math.min(s, E), j = Math.max(-s, D), M = Math.min(s, O), N = (E - T) * (O - D), ee = (A - k) * (M - j);
1084
+ return N <= 0 || ee <= 0 || (c.shown = E > -1 && T < 1 && O > -1 && D < 1, c.pixels = N * n * r / 4, c.weight = Oe(k, A, j, M)), c;
1032
1085
  }
1033
1086
  //#endregion
1034
1087
  //#region src/engine/plan/cut.ts
1035
- var Ae = 1 / .8 ** 2, je = 1500, Me = 1.1, Ne = class {
1088
+ var Ae = 1 / .8 ** 2, je = 1.1, Me = class {
1036
1089
  #e = /* @__PURE__ */ new Map();
1037
1090
  #t = /* @__PURE__ */ new Map();
1038
- #n = /* @__PURE__ */ new Float64Array(6);
1039
- #r = {
1091
+ #n = {
1092
+ shown: !1,
1040
1093
  pixels: 0,
1041
1094
  weight: 1
1042
1095
  };
1043
1096
  plan(e, t, n, r) {
1044
- let { budget: i, capacity: a, now: o, predicted: s } = r, l = [], u = /* @__PURE__ */ new Map(), d = /* @__PURE__ */ new Map(), f = /* @__PURE__ */ new Map(), p = new Fe(), m = 0, h = 0, g = /* @__PURE__ */ new Set(), _ = /* @__PURE__ */ new Set(), v = (e, t) => {
1045
- let r = e.row.count;
1046
- l.push(e), h += c(r), t.shown && (m += r, _.add(e.id)), t.near && g.add(e.id);
1047
- let i = this.#e.get(e.id), a = i !== void 0, s = t.pixels * t.weight, u = s / Math.max(1, r);
1048
- t.pixels > 0 && f.set(e.id, u);
1049
- let d = o - (this.#t.get(e.id) ?? -Infinity) <= je, v = a && !t.shown && d ? i : null;
1050
- (r < s * (a ? Ae : 1) || v !== null) && Pe(e, n) && p.push({
1051
- page: e,
1052
- shown: t.shown,
1053
- held: v,
1054
- ratio: u
1097
+ let { budget: i, capacity: a, now: o, predicted: s } = r, l = [], u = [], d = /* @__PURE__ */ new Map(), f = /* @__PURE__ */ new Map(), p = e.wanted(), m = /* @__PURE__ */ new Map(), h = new Pe(), g = 0, _ = 0, v = (e) => {
1098
+ let t = e.page, r = t.row.count;
1099
+ l.push(t), u.push(+!!e.shown | (e.near ? 2 : 0)), _ += c(r), e.shown && (g += r);
1100
+ let i = this.#e.get(t.id), a = i !== void 0, s = e.pixels * e.weight, d = s / Math.max(1, r);
1101
+ p.length && e.pixels > 0 && m.set(t.id, d);
1102
+ let f = a && !e.shown && o - (this.#t.get(t.id) ?? -Infinity) <= 1500 ? i : null;
1103
+ (r < s * (a ? Ae : 1) || f !== null) && Ne(t, n) && h.push({
1104
+ page: t,
1105
+ shown: e.shown,
1106
+ held: f,
1107
+ ratio: d
1055
1108
  });
1056
1109
  };
1057
- for (let n of e.roots) v(n, this.#i(n, t, s));
1110
+ for (let n of e.roots) v(this.#r(n, t, s));
1058
1111
  let y = !1;
1059
- for (; p.size;) {
1060
- let { page: e, shown: n, held: r } = p.pop(), l = [], f = 0;
1061
- if (e.children.forEach((e, n) => {
1062
- if (!e) return;
1063
- let i = this.#i(e, t, s);
1064
- i.pixels <= 0 && !((r ?? 0) & 1 << n) || (l.push({
1065
- child: e,
1066
- m: i
1067
- }), f |= 1 << n);
1068
- }), !l.length) continue;
1069
- let g = 0, _ = n ? -e.row.count : 0;
1070
- for (let { child: e, m: t } of l) g += c(e.row.count), t.shown && (_ += e.row.count);
1071
- if (h + g > a) break;
1072
- if (_ > 0 && (y || m + _ > i)) {
1112
+ for (; h.size;) {
1113
+ let { page: e, shown: n, held: r } = h.pop(), l = [], u = 0;
1114
+ for (let n = 0; n < e.children.length; n++) {
1115
+ let i = e.children[n];
1116
+ if (!i) continue;
1117
+ let a = this.#r(i, t, s);
1118
+ a.pixels <= 0 && !((r ?? 0) & 1 << n) || (l.push(a), u |= 1 << n);
1119
+ }
1120
+ if (!l.length) continue;
1121
+ let p = 0, m = n ? -e.row.count : 0;
1122
+ for (let e of l) p += c(e.page.row.count), e.shown && (m += e.page.row.count);
1123
+ if (_ + p > a) break;
1124
+ if (m > 0 && (y || g + m > i)) {
1073
1125
  y = !0;
1074
1126
  continue;
1075
1127
  }
1076
- u.set(e.id, f);
1128
+ d.set(e.id, u);
1077
1129
  let b = n ? o : this.#t.get(e.id);
1078
- b !== void 0 && d.set(e.id, b), n && (m -= e.row.count);
1079
- for (let { child: e, m: t } of l) v(e, t);
1130
+ b !== void 0 && f.set(e.id, b), n && (g -= e.row.count);
1131
+ for (let e of l) v(e);
1132
+ }
1133
+ this.#e = d, this.#t = f;
1134
+ let b = [], x = [], S = new Set(d.keys()), C = 0;
1135
+ for (let e = 0; e < l.length; e++) {
1136
+ let t = l[e];
1137
+ d.has(t.id) || (b.push(t), S.add(t.id), n(t.id) || (u[e] & 1 && (C += t.row.count), x.push({
1138
+ page: t,
1139
+ near: !!(u[e] & 2)
1140
+ })));
1080
1141
  }
1081
- this.#e = u, this.#t = d;
1082
- let b = l.filter((e) => !u.has(e.id)), x = new Set(u.keys());
1083
- for (let e of b) x.add(e.id);
1084
- let S = [];
1085
- for (let t of e.wanted()) {
1086
- let e = -1;
1087
- for (let n of t.over) e = Math.max(e, f.get(n.id) ?? -1);
1088
- e >= 0 && S.push({
1089
- wanted: t,
1090
- rank: e
1142
+ let w = [];
1143
+ for (let e of p) {
1144
+ let t = -1;
1145
+ for (let n of e.over) t = Math.max(t, m.get(n.id) ?? -1);
1146
+ t >= 0 && w.push({
1147
+ wanted: e,
1148
+ rank: t
1091
1149
  });
1092
1150
  }
1093
- S.sort((e, t) => t.rank - e.rank);
1094
- let C = 0;
1095
- for (let e of b) _.has(e.id) && !n(e.id) && (C += e.row.count);
1096
- return {
1151
+ return w.sort((e, t) => t.rank - e.rank), {
1097
1152
  cut: b,
1098
- load: b.filter((e) => !n(e.id) && (g.has(e.id) || !s && C === 0)),
1099
- idx: S.map((e) => e.wanted),
1100
- keep: x,
1101
- planned: m,
1153
+ load: x.filter(({ near: e }) => e || !s && C === 0).map(({ page: e }) => e),
1154
+ idx: w.map((e) => e.wanted),
1155
+ keep: S,
1156
+ planned: g,
1102
1157
  missing: C
1103
1158
  };
1104
1159
  }
1105
- #i(e, t, n) {
1106
- let r = this.#a(e, t, 1).pixels > 0, { pixels: i, weight: a } = this.#a(e, t, Me), o = r;
1160
+ #r(e, t, n) {
1161
+ let r = this.#i(e, t, je), i = r.shown, { pixels: a, weight: o } = r, s = i;
1107
1162
  if (n) {
1108
- let t = this.#a(e, n, Me);
1109
- t.pixels > i && ({pixels: i, weight: a} = t), o ||= t.pixels > 0 && this.#a(e, n, 1).pixels > 0;
1163
+ let t = this.#i(e, n, je);
1164
+ t.pixels > a && ({pixels: a, weight: o} = t), s ||= t.shown;
1110
1165
  }
1111
1166
  return {
1112
- shown: r,
1113
- near: o,
1114
- pixels: i,
1115
- weight: a
1167
+ page: e,
1168
+ shown: i,
1169
+ near: s,
1170
+ pixels: a,
1171
+ weight: o
1116
1172
  };
1117
1173
  }
1118
- #a(e, t, n) {
1119
- let r = this.#n;
1120
- for (let n = 0; n < 6; n++) r[n] = e.box[n] - t.origin[n % 3];
1121
- let { width: i, height: a, tan: o, near: s, far: c } = t;
1122
- return ke(r, t.view, i, a, o, s, c, n, this.#r);
1174
+ #i(e, t, n) {
1175
+ let { width: r, height: i, tan: a, near: o, far: s } = t;
1176
+ return ke(e.box, t.view, r, i, a, o, s, n, this.#n, t.origin);
1123
1177
  }
1124
1178
  };
1125
- function Pe(e, t) {
1179
+ function Ne(e, t) {
1126
1180
  let { children: n } = e;
1127
- return t(e.id) && !n.includes(void 0) && n.some((e) => e !== null);
1181
+ return e.g > 0 && t(e.id) && !n.includes(void 0) && n.some((e) => e !== null);
1128
1182
  }
1129
- var Fe = class {
1183
+ var Pe = class {
1130
1184
  #e = [];
1131
1185
  get size() {
1132
1186
  return this.#e.length;
@@ -1136,68 +1190,67 @@ var Fe = class {
1136
1190
  t.push(e);
1137
1191
  let n = t.length - 1;
1138
1192
  for (; n > 0;) {
1139
- let e = n - 1 >> 1;
1140
- if (!I(t[n], t[e])) break;
1141
- [t[n], t[e]] = [t[e], t[n]], n = e;
1193
+ let r = n - 1 >> 1;
1194
+ if (!L(e, t[r])) break;
1195
+ t[n] = t[r], n = r;
1142
1196
  }
1197
+ t[n] = e;
1143
1198
  }
1144
1199
  pop() {
1145
1200
  let e = this.#e, t = e[0], n = e.pop();
1146
1201
  if (e.length) {
1147
- e[0] = n;
1148
1202
  let t = 0;
1149
- for (;;) {
1150
- let n = 2 * t + 1, r = t;
1151
- if (n < e.length && I(e[n], e[r]) && (r = n), n + 1 < e.length && I(e[n + 1], e[r]) && (r = n + 1), r === t) break;
1152
- [e[t], e[r]] = [e[r], e[t]], t = r;
1203
+ for (; 2 * t + 1 < e.length;) {
1204
+ let r = 2 * t + 1;
1205
+ if (r + 1 < e.length && L(e[r + 1], e[r]) && r++, !L(e[r], n)) break;
1206
+ e[t] = e[r], t = r;
1153
1207
  }
1208
+ e[t] = n;
1154
1209
  }
1155
1210
  return t;
1156
1211
  }
1157
1212
  };
1158
- function I(e, t) {
1213
+ function L(e, t) {
1159
1214
  return e.shown === t.shown ? e.ratio > t.ratio : e.shown;
1160
1215
  }
1161
- var L = .25, Ie = class {
1216
+ var R = .25, Fe = class {
1162
1217
  #e = /* @__PURE__ */ new Map();
1163
1218
  update(e, t, n, r) {
1164
- let i = this.#e, a = Le(e, t);
1165
- for (let [e, r] of i) t(r.page.id) ? r.held || (r.start !== null && n - r.start >= 250 && (r.start = null), a.has(e) || (r.frozen = Be(r, n), r.start = null, r.held = !0)) : i.delete(e);
1166
- let o = /* @__PURE__ */ new Set();
1219
+ let i = this.#e, a = Ie(e, t), o = -1;
1220
+ 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 = ze(r, n), r.start = null, r.held = !0))) : i.delete(e);
1221
+ let s = /* @__PURE__ */ new Set();
1167
1222
  for (let [e, t] of a) {
1168
1223
  let r = i.get(e);
1169
- if (r) r.held && (r.held = !1, r.frozen < 255 && (r.start = n - r.frozen / 255 * 250, o.add(r)));
1224
+ if (r) r.held && (r.held = !1, r.frozen < 255 && (r.start = n - r.frozen / 255 * 250, s.add(r)));
1170
1225
  else {
1171
- let r = Re(t, e % 4, n);
1172
- i.set(e, r), o.add(r);
1226
+ let r = Le(t, e % 4, n);
1227
+ o = Math.max(o, r.level), i.set(e, r), s.add(r);
1173
1228
  }
1174
1229
  }
1175
- let s = -1;
1176
- for (let e of i.values()) s = Math.max(s, e.level);
1177
1230
  let l = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Map();
1178
1231
  for (let e of i.values()) if (e.held) {
1179
1232
  l.set(e.cell, e);
1180
- for (let t = e.level, n = e.col, r = e.row; t <= s; t++, n >>= 1, r >>= 1) {
1181
- let i = R(t, n, r), a = u.get(i);
1233
+ for (let t = e.level, n = e.col, r = e.row; t <= o; t++, n >>= 1, r >>= 1) {
1234
+ let i = z(t, n, r), a = u.get(i);
1182
1235
  a ? a.push(e) : u.set(i, [e]);
1183
1236
  }
1184
1237
  }
1185
1238
  let d = (e) => {
1186
1239
  let t = [...u.get(e.cell) ?? []];
1187
- for (let n = e.level + 1, r = e.col >> 1, i = e.row >> 1; n <= s; n++, r >>= 1, i >>= 1) {
1188
- let e = l.get(R(n, r, i));
1240
+ for (let n = e.level + 1, r = e.col >> 1, i = e.row >> 1; n <= o; n++, r >>= 1, i >>= 1) {
1241
+ let e = l.get(z(n, r, i));
1189
1242
  e && t.push(e);
1190
1243
  }
1191
1244
  return t;
1192
1245
  }, f = /* @__PURE__ */ new Set(), p = /* @__PURE__ */ new Set(), m = 0, h = 0, g = (e) => {
1193
1246
  p.has(e) || (p.add(e), h += c(e.row.count));
1194
1247
  };
1195
- for (let e of i.values()) if (!(e.held || e.start === null || o.has(e))) {
1248
+ for (let e of i.values()) if (!(e.held || e.start === null || s.has(e))) {
1196
1249
  m += e.splats;
1197
1250
  for (let t of d(e)) f.has(t) || (f.add(t), m += t.splats, g(t.page));
1198
1251
  }
1199
- let _ = L * r;
1200
- for (let e of o) {
1252
+ let _ = R * r;
1253
+ for (let e of s) {
1201
1254
  let t = d(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 + c(t.row.count), 0);
1202
1255
  if (m + n > _ || h + i > _) e.start = null;
1203
1256
  else {
@@ -1206,16 +1259,19 @@ var L = .25, Ie = class {
1206
1259
  for (let e of r) g(e);
1207
1260
  }
1208
1261
  }
1209
- for (let [e, t] of i) t.held && !f.has(t) && i.delete(e);
1210
1262
  let v = /* @__PURE__ */ new Map(), y = !1;
1211
- for (let e of i.values()) {
1212
- (e.held || e.start !== null) && (y = !0);
1213
- let t = Be(e, n);
1214
- if (!t) continue;
1215
- let r = v.get(e.page.id);
1216
- r ? r.factors = (r.factors | t << 8 * e.q) >>> 0 : v.set(e.page.id, {
1217
- id: e.page.id,
1218
- factors: t << 8 * e.q >>> 0
1263
+ for (let [e, t] of i) {
1264
+ if (t.held && !f.has(t)) {
1265
+ i.delete(e);
1266
+ continue;
1267
+ }
1268
+ (t.held || t.start !== null) && (y = !0);
1269
+ let r = ze(t, n);
1270
+ if (!r) continue;
1271
+ let a = v.get(t.page.id);
1272
+ a ? a.factors = (a.factors | r << 8 * t.q) >>> 0 : v.set(t.page.id, {
1273
+ id: t.page.id,
1274
+ factors: r << 8 * t.q >>> 0
1219
1275
  });
1220
1276
  }
1221
1277
  return {
@@ -1224,19 +1280,19 @@ var L = .25, Ie = class {
1224
1280
  };
1225
1281
  }
1226
1282
  };
1227
- function Le(e, t) {
1283
+ function Ie(e, t) {
1228
1284
  let n = new Set(e), r = /* @__PURE__ */ new Set(), i = [];
1229
1285
  for (let t of e) for (let e = t; e && !r.has(e); e = e.parent) r.add(e), e.parent || i.push(e);
1230
1286
  let a = /* @__PURE__ */ new Map(), o = (e) => {
1231
1287
  for (let i = 0; i < 4; i++) {
1232
1288
  let s = e.children[i];
1233
- s && t(s.id) && r.has(s) ? o(s) : (s !== null || n.has(e)) && a.set(e.id * 4 + i, e);
1289
+ s && r.has(s) && t(s.id) ? o(s) : (s !== null || n.has(e)) && a.set(e.id * 4 + i, e);
1234
1290
  }
1235
1291
  };
1236
1292
  for (let e of i) t(e.id) && o(e);
1237
1293
  return a;
1238
1294
  }
1239
- function Re(t, n, r) {
1295
+ function Le(t, n, r) {
1240
1296
  let i = e * 2 ** t.g, a = t.g - 1, o = 2 * (Math.round(t.unit.e / i) + t.row.i) + (n & 1), s = 2 * (Math.round(t.unit.n / i) + t.row.j) + (n >> 1);
1241
1297
  return {
1242
1298
  page: t,
@@ -1244,39 +1300,39 @@ function Re(t, n, r) {
1244
1300
  level: a,
1245
1301
  col: o,
1246
1302
  row: s,
1247
- cell: R(a, o, s),
1248
- splats: ze(t.row, n),
1303
+ cell: z(a, o, s),
1304
+ splats: Re(t.row, n),
1249
1305
  start: r,
1250
1306
  frozen: 0,
1251
1307
  held: !1
1252
1308
  };
1253
1309
  }
1254
- var R = (e, t, n) => ((e + 1) * 2 ** 21 + t) * 2 ** 21 + n;
1255
- function ze({ count: e, quadrants: t }, n) {
1310
+ var z = (e, t, n) => ((e + 1) * 2 ** 21 + t) * 2 ** 21 + n;
1311
+ function Re({ count: e, quadrants: t }, n) {
1256
1312
  return (n < 3 ? t[n] : e) - (n > 0 ? t[n - 1] : 0);
1257
1313
  }
1258
- function Be(e, t) {
1314
+ function ze(e, t) {
1259
1315
  return e.held ? e.frozen : e.start === null ? 255 : Math.min(255, Math.round((t - e.start) / 250 * 255));
1260
1316
  }
1261
1317
  //#endregion
1262
1318
  //#region src/engine/quality.ts
1263
- var Ve = 5e5, He = 2073600, Ue = [1, .85];
1264
- function We(e, t, n, r) {
1265
- return Math.min(n, Math.sqrt(He / Math.max(1, e * t))) * r;
1319
+ var Be = 5e5, Ve = 2073600, He = [1, .85];
1320
+ function Ue(e, t, n, r) {
1321
+ return Math.min(n, Math.sqrt(Ve / Math.max(1, e * t))) * r;
1266
1322
  }
1267
- function z(e, t) {
1323
+ function B(e, t) {
1268
1324
  if (!e.length) return 0;
1269
1325
  let n = [...e].sort((e, t) => e - t);
1270
1326
  return n[Math.ceil(n.length * t) - 1];
1271
1327
  }
1272
- var Ge = class {
1328
+ var We = class {
1273
1329
  #e = 0;
1274
1330
  #t = [];
1275
1331
  #n = -Infinity;
1276
1332
  #r = 0;
1277
1333
  #i = 0;
1278
1334
  get scale() {
1279
- return Ue[this.#e];
1335
+ return He[this.#e];
1280
1336
  }
1281
1337
  full() {
1282
1338
  this.#e = 0, this.#a();
@@ -1285,15 +1341,15 @@ var Ge = class {
1285
1341
  this.#t = [], this.#r = 0, this.#i = 0, this.#n = -Infinity;
1286
1342
  }
1287
1343
  sample(e, t, n) {
1288
- if (!n || t - this.#n > 250 || !Number.isFinite(e) || e <= 0) return this.#a(), this.#n = t, !1;
1344
+ if (!n || t - this.#n > Math.max(250, 2 * e) || !Number.isFinite(e) || e <= 0) return this.#a(), this.#n = t, !1;
1289
1345
  let r = Math.max(0, t - this.#n);
1290
1346
  if (this.#n = t, this.#t.push({
1291
1347
  time: t,
1292
1348
  ms: e
1293
- }), this.#t = this.#t.filter((e) => t - e.time <= 1e3), this.#t.length < 20) return !1;
1294
- let i = z(this.#t.map((e) => e.ms), .9);
1349
+ }), this.#t = this.#t.filter((n) => t - n.time <= Math.max(1e3, 2 * e)), t - this.#t[0].time < 300) return !1;
1350
+ let i = B(this.#t.map((e) => e.ms), .9);
1295
1351
  if (this.#r = i > 20 ? this.#r + r : 0, this.#i = i < 14 ? this.#i + r : 0, this.#r >= 2e3) {
1296
- if (this.#e < Ue.length - 1) this.#e++;
1352
+ if (this.#e < He.length - 1) this.#e++;
1297
1353
  else return !1;
1298
1354
  } else if (this.#i >= 5e3) {
1299
1355
  if (this.#e > 0) this.#e--;
@@ -1301,7 +1357,7 @@ var Ge = class {
1301
1357
  } else return !1;
1302
1358
  return this.#a(), !0;
1303
1359
  }
1304
- }, Ke = class {
1360
+ }, Ge = class {
1305
1361
  #e;
1306
1362
  #t = [];
1307
1363
  #n = /* @__PURE__ */ new Set();
@@ -1380,12 +1436,12 @@ var Ge = class {
1380
1436
  pages: o
1381
1437
  };
1382
1438
  }
1383
- }, qe = {
1439
+ }, Ke = {
1384
1440
  idx: 8,
1385
1441
  concurrency: 8,
1386
1442
  gap: 65536,
1387
1443
  span: 2097152
1388
- }, Je = 1e3, Ye = 3e4, Xe = 1e3, Ze = 2e3, Qe = class {
1444
+ }, qe = 1e3, Je = 3e4, Ye = 1e3, Xe = 2e3, Ze = class {
1389
1445
  #e;
1390
1446
  #t;
1391
1447
  #n;
@@ -1415,8 +1471,8 @@ var Ge = class {
1415
1471
  #y = -Infinity;
1416
1472
  #b = !1;
1417
1473
  #x = !1;
1418
- constructor(e, t, n, r, i, a = qe) {
1419
- this.#e = e, this.#t = t, this.#n = n, this.#r = r, this.#i = i, this.#a = a, this.#o = new Ke(a);
1474
+ constructor(e, t, n, r, i, a = Ke) {
1475
+ this.#e = e, this.#t = t, this.#n = n, this.#r = r, this.#i = i, this.#a = a, this.#o = new Ge(a);
1420
1476
  }
1421
1477
  update(e, t, n) {
1422
1478
  if (!this.#x) {
@@ -1483,7 +1539,7 @@ var Ge = class {
1483
1539
  let n = this.#e.pages.get(e);
1484
1540
  if (!n) return;
1485
1541
  let { keep: r } = this.#s, i = this.#c;
1486
- this.#n.add(e, t, [n.unit.e, n.unit.n], (e) => r.has(e) || i.has(e)) ? (this.#g.add(e), this.#m.delete(e) && this.#j(e)) : (this.#m.set(e, this.#u + Xe), this.#A(e, Xe)), this.#r();
1542
+ this.#n.add(e, t, [n.unit.e, n.unit.n], (e) => r.has(e) || i.has(e)) ? (this.#g.add(e), this.#m.delete(e) && this.#j(e)) : (this.#m.set(e, this.#u + Ye), this.#A(e, Ye)), this.#r();
1487
1543
  };
1488
1544
  #E(e) {
1489
1545
  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());
@@ -1497,7 +1553,7 @@ var Ge = class {
1497
1553
  this.#b = !0, this.#i();
1498
1554
  return;
1499
1555
  }
1500
- let n = this.#p.get(e), r = n ? Math.min(2 * n.delay, Ye) : Je;
1556
+ let n = this.#p.get(e), r = n ? Math.min(2 * n.delay, Je) : qe;
1501
1557
  this.#p.set(e, {
1502
1558
  delay: r,
1503
1559
  until: this.#u + r
@@ -1518,11 +1574,11 @@ var Ge = class {
1518
1574
  }
1519
1575
  #M() {
1520
1576
  let e = this.#u;
1521
- if (e - this.#y < Ze) return;
1577
+ if (e - this.#y < Xe) return;
1522
1578
  this.#y = e;
1523
1579
  for (let e of this.#g) this.#n.holds(e) || this.#g.delete(e);
1524
1580
  for (let [t, n] of this.#m) n <= e && this.#m.delete(t);
1525
- for (let [t, n] of this.#_) e - n >= Ze && this.#_.delete(t);
1581
+ for (let [t, n] of this.#_) e - n >= Xe && this.#_.delete(t);
1526
1582
  let { keep: t } = this.#s;
1527
1583
  if (this.#e.pages.size <= 2 * (this.#g.size + t.size)) return;
1528
1584
  let n = /* @__PURE__ */ new Set([
@@ -1547,7 +1603,7 @@ var Ge = class {
1547
1603
  };
1548
1604
  //#endregion
1549
1605
  //#region src/engine/stream/remote.ts
1550
- function $e(e, t) {
1606
+ function Qe(e, t) {
1551
1607
  let n = /* @__PURE__ */ new Map();
1552
1608
  return (r) => {
1553
1609
  if ("unfetch" in r) return void n.get(r.unfetch)?.abort();
@@ -1570,29 +1626,29 @@ function $e(e, t) {
1570
1626
  }
1571
1627
  //#endregion
1572
1628
  //#region src/engine/stream/worker.ts?worker&inline
1573
- var et = "(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}async function O(e,t){return p(await A(e,t))}async function*k(e,t,n,r){let i=t.col===null?null:M(e,t.col,n),a=await j(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 A(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 j(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 M(e,t,n){let r=n.get(t);if(r)n.delete(t);else{let i=A(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 N(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 P(e,t){let n;try{n=await(await I()).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 z(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 L(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 R(n,i,r)&&(o(i,r.length),c())}}}async function F(e){let t=new Set(Array.from({length:e},(e,t)=>String(t)));try{let e=await I(),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 I(){return(await navigator.storage.getDirectory()).getDirectoryHandle(`cache`,{create:!0})}async function L(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 R(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 z(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 B(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 V=(e,t,n)=>Math.min(n,Math.max(t,e));function ee(e,t,n){return n>t?V(Math.round((e-t)/(n-t)*255),0,255):0}function te(e,t){return t>0?V(Math.round(e/t*127),-127,127):0}function H(e){return e&=1023,e=(e|e<<16)&50331903,e=(e|e<<8)&50393103,e=(e|e<<4)&51130563,(e|e<<2)&153391689}function ne(e,t,n){return H(e>>6)|H(t>>6)<<1|H(n>>6)<<2}function re(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 ie(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]=te(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 ae(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]=V(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+ne(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]),O=[0,0,0];for(let e=1;e<4;e++)O[e-1]=T.filter(t=>t<e).length;let k=u?re(u,n):/* @__PURE__ */ new Float32Array(9),{book:A,labels:j}=u?ie(u,n,k):{book:null,labels:null},M=A?A.length/9:0,N=17+(M>0?2:0),P=new Uint8Array(128+N*n+M*9),F=new DataView(P.buffer);F.setUint32(0,n,!0),O.forEach((e,t)=>F.setUint32(4+4*t,e,!0)),F.setUint16(16,M,!0),[...v,...y,...p,...m,...h,...g,...k].forEach((e,t)=>F.setFloat32(20+4*t,e,!0));let I=e=>128+e*n,L=new Float32Array([...d,...f]),R=/* @__PURE__ */ new Float64Array(4),z=/* @__PURE__ */ new Float64Array(3),B=[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]-B[n]<<16>>16,i=r<0?-2*r-1:2*r;B[n]=b[t*3+n],P[I(a.position+2*n)+e]=i&255,P[I(a.position+2*n+1)+e]=i>>8}P[I(a.alpha)+e]=V(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++)R[e]=o[t*4+e]/n;let r=0;for(let e=1;e<4;e++)Math.abs(R[e])>Math.abs(R[r])&&(r=e);let u=R[r]<0?-1:1;P[I(a.rotationIndex)+e]=r;for(let t=0,n=0;t<4;t++){if(t===r)continue;let i=Math.round((u*R[t]/Math.SQRT2+.5)*255);P[I(a.rotation+n++)+e]=V(i,0,255)}for(let n=0;n<3;n++)P[I(a.scale+n)+e]=ee(s[t*3+n],p[n],m[n]),P[I(a.dc+n)+e]=ee(l[t*3+n],h[n],g[n]);j&&(P[I(a.label)+e]=j[t]&255,P[I(a.label+1)+e]=j[t]>>8);let[d,f,_]=[0,1,2].map(e=>Math.exp(s[t*3+e]));x(R,d,f,_,z);for(let e=0;e<3;e++)L[e]=Math.min(L[e],i[t*3+e]-z[e]),L[3+e]=Math.max(L[3+e],i[t*3+e]+z[e])}return A&&P.set(new Uint8Array(A.buffer),I(N)),{payload:P,row:{g:t.g,i:t.i,j:t.j,count:n,quadrants:O,box:L,offset:0,length:0}}}function oe(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 se(e,t,n){for(let r=0;r<4;r++)e[t+r]=n.charCodeAt(r)}function U(e){return Uint8Array.from({length:8},(t,n)=>parseInt(e.slice(2*n,2*n+2),16))}async function ce(e,t){let n=await l(e),r=new Uint8Array(8+n.length);return se(r,0,t),new DataView(r.buffer).setUint16(4,1,!0),r.set(n,8),r}async function le(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(U(e.pack),12),o.setUint32(20,e.packSize,!0),e.col&&a.set(U(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)oe(o,s,e),s+=52;for(let e of n)o.setUint8(s,e.quadrant),a.set(U(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(U(e.idx),s+3),s+=11;return ce(a,i)}function ue(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 de(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}}let W=16384,fe=1408,pe=65535,G=324121,me=.4,he=[[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]],ge=he.reduce((e,[t,n,,r])=>e+t*(n+r),0),_e=Float32Array.from({length:fe*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}),K=new TextEncoder,ve={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,q(e,`idx`),`idx`)})),extent:{e:[44e4,9e5],n:[605e4,641e4],h:[0,80]}},ye=K.encode(JSON.stringify(ve));function be(){return async(t,n)=>{if(t.endsWith(`world.json`))return Se(ye,n);let r=g(t),i=t.slice(t.lastIndexOf(`.`)+1);if(!r||i!==`idx`&&i!==`pack`||!Ce(r)||r.hash!==q(r,i))throw new e(`no file ${t}`);return i===`idx`?Se(await ke(r),n):Ae(r,n,t)}}function xe(e,t){let n=30;for(let[r,i,a,o,s]of he)n+=r*Math.sin(i*e+a)*Math.sin(o*t+s);return n}function Se(e,t){return t?e.slice(t[0],t[1]):e.slice()}function q(e,t){return ue(K.encode(`${e.level}/${e.e}/${e.n}.${t}`))}function J(e,t,n){let{e:r,n:i}=ve.extent;return e<r[1]&&e+n>r[0]&&t<i[1]&&t+n>i[0]}function Ce({level:e,e:t,n}){let r=250*2**e;return e<=12&&t%r===0&&n%r===0&&J(t,n,r)}function we(e){return e===0?[1,0]:e===12?[16,15,14,13]:[e+1]}function Te(e){let t=0;for(let n=0;n<8;n++)t|=(e>>2*n&1)<<n;return t}function Ee(e){let t=[];for(let n of we(e.level)){let i=r*2**n,a=250*2**e.level/i;for(let r=0;r<a*a;r++){let a=Te(r),o=Te(r>>1);J(e.e+a*i,e.n+o*i,i)&&t.push({g:n,i:a,j:o})}}return t}function De(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};J(t.e,t.n,r)&&i.push({column:o,row:a,unit:t})}return i}function Oe(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=xe(e.e+(n+.5)*o,e.n+(i+.5)*o),d=ge*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=W/4;return{g:t,i:n,j:i,count:W,quadrants:[p,2*p,3*p],box:f,offset:a,length:G}}function ke(e){let t=Ee(e),n=[];for(let{column:t,row:r,unit:i}of De(e,1))n.push({quadrant:t+2*r,idx:q(i,`idx`)});let r=[];for(let t of[2,3])for(let{column:n,row:i,unit:a}of De(e,t))r.push({depth:t,column:n,row:i,idx:q(a,`idx`)});return le({level:e.level,e:e.e,n:e.n,pack:q(e,`pack`),packSize:t.length*324173+16,col:null,rows:t.map((t,n)=>Oe(e,t,n*G)),children:n,descendants:r})}function Ae(e,t,n){let r=Ee(e);if(!t||t[0]%G!=0||t[1]%G!=0||t[0]>=t[1]||t[1]>r.length*G)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+=G)je(Ne(e,r[(t[0]+n)/G]),i,n);return i}function je(e,t,n){let r=n;for(let n=0;n<e.length;n+=pe){let i=Math.min(pe,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 Me=e=>de(parseInt(ue(K.encode(e)).slice(8),16));function Ne(e,{g:t,i,j:a}){let o=W,s=r*2**t/128,c=Me(`${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+me*(2*c()-1))*s,o=(a*128+Math.floor(t/128)+.5+me*(2*c()-1))*s,h=xe(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%fe;m.set(_e.subarray(9*b,9*(b+1)),9*t)}return ae({count:o,position:l,rotation:u,scale:d,alpha:f,dc:p,sh:m},{g:t,i,j:a}).payload}let Y=2**20,X=self,Z,Pe=/* @__PURE__ */ new Map,Q=/* @__PURE__ */ new Map,Fe=B(e=>X.postMessage(e,[]));X.onmessage=({data:e})=>{`fetched`in e?Fe.take(e):e.type===`init`?(Z=Ie(e),Z.catch(()=>void 0)):e.type===`abort`?Q.get(e.id)?.abort():Re(e)};async function Ie(e){return e.source===`synthetic`?{fetch:be(),cache:await $({...e,cache:`none`}),base:e.base}:{fetch:e.source===`page`?Fe.fetch:t,cache:await $(e),base:e.base}}async function $({cache:e,shard:t,shards:n}){return e===`memory`?N(256*Y):e===`none`?{get:async()=>void 0,put:async()=>void 0}:(t===0&&F(n),await P(await Le()/n,t)??N(256*Y))}async function Le(){try{let{quota:e}=await navigator.storage.estimate();return Math.min(4096*Y,e===void 0?1/0:e/2)}catch{return 4096*Y}}async function Re(t){let{id:n}=t,r=new AbortController;Q.set(n,r);try{if(!Z)throw Error(`stream worker used before init`);let e=await Z;if(t.type===`idx`)X.postMessage({id:n,value:await O(e,t.path)},[]);else{for await(let i of k(e,t.batch,Pe,r.signal))X.postMessage({id:n,page:i},ze(i));X.postMessage({id:n,done:!0},[])}}catch(t){let r=t instanceof Error?t.message:String(t);X.postMessage({id:n,error:r,missing:t instanceof e},[])}finally{Q.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]}})();", tt = typeof self < "u" && self.Blob && new Blob(["(self.URL || self.webkitURL).revokeObjectURL(self.location.href);", et], { type: "text/javascript;charset=utf-8" });
1574
- function nt(e) {
1629
+ var $e = "(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}async function O(e,t){return p(await A(e,t))}async function*k(e,t,n,r){let i=t.col===null?null:M(e,t.col,n),a=await j(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 A(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 j(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 M(e,t,n){let r=n.get(t);if(r)n.delete(t);else{let i=A(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 N(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 P(e,t){let n;try{n=await(await I()).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 z(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 L(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 R(n,i,r)&&(o(i,r.length),c())}}}async function F(e){let t=new Set(Array.from({length:e},(e,t)=>String(t)));try{let e=await I(),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 I(){return(await navigator.storage.getDirectory()).getDirectoryHandle(`cache`,{create:!0})}async function L(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 R(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 z(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 B(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 V=(e,t,n)=>Math.min(n,Math.max(t,e));function ee(e,t,n){return n>t?V(Math.round((e-t)/(n-t)*255),0,255):0}function te(e,t){return t>0?V(Math.round(e/t*127),-127,127):0}function H(e){return e&=1023,e=(e|e<<16)&50331903,e=(e|e<<8)&50393103,e=(e|e<<4)&51130563,(e|e<<2)&153391689}function ne(e,t,n){return H(e>>6)|H(t>>6)<<1|H(n>>6)<<2}function re(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 ie(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]=te(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 ae(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]=V(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+ne(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]),O=[0,0,0];for(let e=1;e<4;e++)O[e-1]=T.filter(t=>t<e).length;let k=u?re(u,n):/* @__PURE__ */ new Float32Array(9),{book:A,labels:j}=u?ie(u,n,k):{book:null,labels:null},M=A?A.length/9:0,N=17+(M>0?2:0),P=new Uint8Array(128+N*n+M*9),F=new DataView(P.buffer);F.setUint32(0,n,!0),O.forEach((e,t)=>F.setUint32(4+4*t,e,!0)),F.setUint16(16,M,!0),[...v,...y,...p,...m,...h,...g,...k].forEach((e,t)=>F.setFloat32(20+4*t,e,!0));let I=e=>128+e*n,L=new Float32Array([...d,...f]),R=/* @__PURE__ */ new Float64Array(4),z=/* @__PURE__ */ new Float64Array(3),B=[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]-B[n]<<16>>16,i=r<0?-2*r-1:2*r;B[n]=b[t*3+n],P[I(a.position+2*n)+e]=i&255,P[I(a.position+2*n+1)+e]=i>>8}P[I(a.alpha)+e]=V(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++)R[e]=o[t*4+e]/n;let r=0;for(let e=1;e<4;e++)Math.abs(R[e])>Math.abs(R[r])&&(r=e);let u=R[r]<0?-1:1;P[I(a.rotationIndex)+e]=r;for(let t=0,n=0;t<4;t++){if(t===r)continue;let i=Math.round((u*R[t]/Math.SQRT2+.5)*255);P[I(a.rotation+n++)+e]=V(i,0,255)}for(let n=0;n<3;n++)P[I(a.scale+n)+e]=ee(s[t*3+n],p[n],m[n]),P[I(a.dc+n)+e]=ee(l[t*3+n],h[n],g[n]);j&&(P[I(a.label)+e]=j[t]&255,P[I(a.label+1)+e]=j[t]>>8);let[d,f,_]=[0,1,2].map(e=>Math.exp(s[t*3+e]));x(R,d,f,_,z);for(let e=0;e<3;e++)L[e]=Math.min(L[e],i[t*3+e]-z[e]),L[3+e]=Math.max(L[3+e],i[t*3+e]+z[e])}return A&&P.set(new Uint8Array(A.buffer),I(N)),{payload:P,row:{g:t.g,i:t.i,j:t.j,count:n,quadrants:O,box:L,offset:0,length:0}}}function oe(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 se(e,t,n){for(let r=0;r<4;r++)e[t+r]=n.charCodeAt(r)}function U(e){return Uint8Array.from({length:8},(t,n)=>parseInt(e.slice(2*n,2*n+2),16))}async function ce(e,t){let n=await l(e),r=new Uint8Array(8+n.length);return se(r,0,t),new DataView(r.buffer).setUint16(4,1,!0),r.set(n,8),r}async function le(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(U(e.pack),12),o.setUint32(20,e.packSize,!0),e.col&&a.set(U(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)oe(o,s,e),s+=52;for(let e of n)o.setUint8(s,e.quadrant),a.set(U(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(U(e.idx),s+3),s+=11;return ce(a,i)}function ue(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 de(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}}let W=16384,fe=1408,pe=65535,G=324121,me=.4,he=[[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]],ge=he.reduce((e,[t,n,,r])=>e+t*(n+r),0),_e=Float32Array.from({length:fe*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}),K=new TextEncoder,ve={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,q(e,`idx`),`idx`)})),extent:{e:[44e4,9e5],n:[605e4,641e4],h:[0,80]}},ye=K.encode(JSON.stringify(ve));function be(){return async(t,n)=>{if(t.endsWith(`world.json`))return Se(ye,n);let r=g(t),i=t.slice(t.lastIndexOf(`.`)+1);if(!r||i!==`idx`&&i!==`pack`||!Ce(r)||r.hash!==q(r,i))throw new e(`no file ${t}`);return i===`idx`?Se(await ke(r),n):Ae(r,n,t)}}function xe(e,t){let n=30;for(let[r,i,a,o,s]of he)n+=r*Math.sin(i*e+a)*Math.sin(o*t+s);return n}function Se(e,t){return t?e.slice(t[0],t[1]):e.slice()}function q(e,t){return ue(K.encode(`${e.level}/${e.e}/${e.n}.${t}`))}function J(e,t,n){let{e:r,n:i}=ve.extent;return e<r[1]&&e+n>r[0]&&t<i[1]&&t+n>i[0]}function Ce({level:e,e:t,n}){let r=250*2**e;return e<=12&&t%r===0&&n%r===0&&J(t,n,r)}function we(e){return e===0?[1,0]:e===12?[16,15,14,13]:[e+1]}function Te(e){let t=0;for(let n=0;n<8;n++)t|=(e>>2*n&1)<<n;return t}function Ee(e){let t=[];for(let n of we(e.level)){let i=r*2**n,a=250*2**e.level/i;for(let r=0;r<a*a;r++){let a=Te(r),o=Te(r>>1);J(e.e+a*i,e.n+o*i,i)&&t.push({g:n,i:a,j:o})}}return t}function De(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};J(t.e,t.n,r)&&i.push({column:o,row:a,unit:t})}return i}function Oe(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=xe(e.e+(n+.5)*o,e.n+(i+.5)*o),d=ge*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=W/4;return{g:t,i:n,j:i,count:W,quadrants:[p,2*p,3*p],box:f,offset:a,length:G}}function ke(e){let t=Ee(e),n=[];for(let{column:t,row:r,unit:i}of De(e,1))n.push({quadrant:t+2*r,idx:q(i,`idx`)});let r=[];for(let t of[2,3])for(let{column:n,row:i,unit:a}of De(e,t))r.push({depth:t,column:n,row:i,idx:q(a,`idx`)});return le({level:e.level,e:e.e,n:e.n,pack:q(e,`pack`),packSize:t.length*324173+16,col:null,rows:t.map((t,n)=>Oe(e,t,n*G)),children:n,descendants:r})}function Ae(e,t,n){let r=Ee(e);if(!t||t[0]%G!=0||t[1]%G!=0||t[0]>=t[1]||t[1]>r.length*G)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+=G)je(Ne(e,r[(t[0]+n)/G]),i,n);return i}function je(e,t,n){let r=n;for(let n=0;n<e.length;n+=pe){let i=Math.min(pe,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 Me=e=>de(parseInt(ue(K.encode(e)).slice(8),16));function Ne(e,{g:t,i,j:a}){let o=W,s=r*2**t/128,c=Me(`${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+me*(2*c()-1))*s,o=(a*128+Math.floor(t/128)+.5+me*(2*c()-1))*s,h=xe(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%fe;m.set(_e.subarray(9*b,9*(b+1)),9*t)}return ae({count:o,position:l,rotation:u,scale:d,alpha:f,dc:p,sh:m},{g:t,i,j:a}).payload}let Y=2**20,X=self,Z,Pe=/* @__PURE__ */ new Map,Q=/* @__PURE__ */ new Map,Fe=B(e=>X.postMessage(e,[]));X.onmessage=({data:e})=>{`fetched`in e?Fe.take(e):e.type===`init`?(Z=Ie(e),Z.catch(()=>void 0)):e.type===`abort`?Q.get(e.id)?.abort():Re(e)};async function Ie(e){return e.source===`synthetic`?{fetch:be(),cache:await $({...e,cache:`none`}),base:e.base}:{fetch:e.source===`page`?Fe.fetch:t,cache:await $(e),base:e.base}}async function $({cache:e,shard:t,shards:n}){return e===`memory`?N(256*Y):e===`none`?{get:async()=>void 0,put:async()=>void 0}:(t===0&&F(n),await P(await Le()/n,t)??N(256*Y))}async function Le(){try{let{quota:e}=await navigator.storage.estimate();return Math.min(4096*Y,e===void 0?1/0:e/2)}catch{return 4096*Y}}async function Re(t){let{id:n}=t,r=new AbortController;Q.set(n,r);try{if(!Z)throw Error(`stream worker used before init`);let e=await Z;if(t.type===`idx`)X.postMessage({id:n,value:await O(e,t.path)},[]);else{for await(let i of k(e,t.batch,Pe,r.signal))X.postMessage({id:n,page:i},ze(i));X.postMessage({id:n,done:!0},[])}}catch(t){let r=t instanceof Error?t.message:String(t);X.postMessage({id:n,error:r,missing:t instanceof e},[])}finally{Q.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]}})();", et = typeof self < "u" && self.Blob && new Blob(["(self.URL || self.webkitURL).revokeObjectURL(self.location.href);", $e], { type: "text/javascript;charset=utf-8" });
1630
+ function tt(e) {
1575
1631
  let t;
1576
1632
  try {
1577
- if (t = tt && (self.URL || self.webkitURL).createObjectURL(tt), !t) throw "";
1633
+ if (t = et && (self.URL || self.webkitURL).createObjectURL(et), !t) throw "";
1578
1634
  let n = new Worker(t, { name: e?.name });
1579
1635
  return n.addEventListener("error", () => {
1580
1636
  (self.URL || self.webkitURL).revokeObjectURL(t);
1581
1637
  }), n;
1582
1638
  } catch {
1583
- return new Worker("data:text/javascript;charset=utf-8," + encodeURIComponent(et), { name: e?.name });
1639
+ return new Worker("data:text/javascript;charset=utf-8," + encodeURIComponent($e), { name: e?.name });
1584
1640
  }
1585
1641
  }
1586
1642
  //#endregion
1587
1643
  //#region src/engine/stream/loader.ts
1588
- var rt = class {
1644
+ var nt = class {
1589
1645
  #e;
1590
1646
  #t = /* @__PURE__ */ new Map();
1591
1647
  #n = 0;
1592
1648
  constructor(e) {
1593
1649
  let { base: t, cache: n, source: r, workers: i } = e;
1594
1650
  this.#e = Array.from({ length: i }, (e, a) => {
1595
- let o = new nt(), s = { worker: o }, c = typeof r == "function" ? $e(r, (e, t) => o.postMessage(e, t)) : void 0;
1651
+ let o = new tt(), s = { worker: o }, c = typeof r == "function" ? Qe(r, (e, t) => o.postMessage(e, t)) : void 0;
1596
1652
  o.onmessage = ({ data: e }) => {
1597
1653
  "id" in e ? this.#i(e) : c?.(e);
1598
1654
  }, o.onerror = () => this.#a(s);
@@ -1616,8 +1672,8 @@ var rt = class {
1616
1672
  return this.#r(this.#e[0], t);
1617
1673
  }
1618
1674
  batch(e, t, n) {
1619
- if (t.aborted) return Promise.reject(B());
1620
- let r = this.#e[it(`${e.pack}#${e.window}`, this.#e.length)], i = {
1675
+ if (t.aborted) return Promise.reject(V());
1676
+ let r = this.#e[rt(`${e.pack}#${e.window}`, this.#e.length)], i = {
1621
1677
  type: "batch",
1622
1678
  id: ++this.#n,
1623
1679
  batch: e
@@ -1626,7 +1682,7 @@ var rt = class {
1626
1682
  }
1627
1683
  destroy() {
1628
1684
  for (let { worker: e } of this.#e) e.terminate();
1629
- for (let e of this.#t.values()) e.reject(B());
1685
+ for (let e of this.#t.values()) e.reject(V());
1630
1686
  }
1631
1687
  #r(e, t, n, r) {
1632
1688
  if (e.error) return Promise.reject(e.error);
@@ -1638,7 +1694,7 @@ var rt = class {
1638
1694
  s(), e.worker.postMessage({
1639
1695
  type: "abort",
1640
1696
  id: i
1641
- }), o(B());
1697
+ }), o(V());
1642
1698
  };
1643
1699
  this.#t.set(i, {
1644
1700
  slot: e,
@@ -1661,17 +1717,17 @@ var rt = class {
1661
1717
  for (let t of this.#t.values()) t.slot === e && t.reject(e.error);
1662
1718
  }
1663
1719
  };
1664
- function it(e, t) {
1720
+ function rt(e, t) {
1665
1721
  let n = 2166136261;
1666
1722
  for (let t = 0; t < e.length; t++) n = Math.imul(n ^ e.charCodeAt(t), 16777619);
1667
1723
  return (n >>> 0) % t;
1668
1724
  }
1669
- function B() {
1725
+ function V() {
1670
1726
  return new DOMException("The request was aborted.", "AbortError");
1671
1727
  }
1672
1728
  //#endregion
1673
1729
  //#region src/engine/world/tree.ts
1674
- var V = (e, t, n) => (e * 256 + t) * 256 + n, at = class {
1730
+ var H = (e, t, n) => (e * 256 + t) * 256 + n, it = class {
1675
1731
  roots = [];
1676
1732
  pages = /* @__PURE__ */ new Map();
1677
1733
  units = /* @__PURE__ */ new Map();
@@ -1681,10 +1737,10 @@ var V = (e, t, n) => (e * 256 + t) * 256 + n, at = class {
1681
1737
  #r = /* @__PURE__ */ new Map();
1682
1738
  #i = /* @__PURE__ */ new Map();
1683
1739
  constructor(e) {
1684
- this.#e = new Set(e.roots.map(H)), this.#t = Math.max(...e.roots.map((e) => e.level));
1740
+ this.#e = new Set(e.roots.map(U)), this.#t = Math.max(...e.roots.map((e) => e.level));
1685
1741
  }
1686
1742
  add(e, t) {
1687
- let n = H(e), r = this.units.get(n);
1743
+ let n = U(e), r = this.units.get(n);
1688
1744
  if (r) return r;
1689
1745
  let o = /* @__PURE__ */ new Map(), s = {
1690
1746
  level: e.level,
@@ -1711,34 +1767,34 @@ var V = (e, t, n) => (e * 256 + t) * 256 + n, at = class {
1711
1767
  null
1712
1768
  ]
1713
1769
  };
1714
- this.pages.set(r.id, r), s.pages.push(r), o.set(V(t.g, t.i, t.j), r);
1770
+ this.pages.set(r.id, r), s.pages.push(r), o.set(H(t.g, t.i, t.j), r);
1715
1771
  }
1716
1772
  this.units.set(n, s), this.#r.delete(n);
1717
1773
  for (let t = e.level + 1; t <= this.#t; t++) {
1718
- let n = H(U(e, t));
1774
+ let n = U(W(e, t));
1719
1775
  this.#i.set(n, (this.#i.get(n) ?? 0) + 1);
1720
1776
  }
1721
1777
  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));
1722
1778
  for (let e of s.pages) {
1723
1779
  let { g: t, i: n, j: r } = e.row;
1724
- c.has(t + 1) && (e.parent = o.get(V(t + 1, n >> 1, r >> 1)) ?? null);
1780
+ c.has(t + 1) && (e.parent = o.get(H(t + 1, n >> 1, r >> 1)) ?? null);
1725
1781
  for (let i = 0; i < 4; i++) {
1726
1782
  let a = 2 * n + (i & 1), s = 2 * r + (i >> 1);
1727
- c.has(t - 1) ? e.children[i] = o.get(V(t - 1, a, s)) ?? null : t === u && t > 0 && (e.children[i] = d.has((a >> 3) + 2 * (s >> 3)) ? void 0 : null);
1783
+ c.has(t - 1) ? e.children[i] = o.get(H(t - 1, a, s)) ?? null : t === u && t > 0 && (e.children[i] = d.has((a >> 3) + 2 * (s >> 3)) ? void 0 : null);
1728
1784
  }
1729
1785
  }
1730
1786
  if (this.#e.has(n)) for (let e of s.pages) e.g === l && this.roots.push(e);
1731
1787
  else {
1732
- let t = this.units.get(H(U(e, e.level + 1)));
1788
+ let t = this.units.get(U(W(e, e.level + 1)));
1733
1789
  t && this.#o(t, s);
1734
1790
  }
1735
1791
  let f = a(s.idx);
1736
1792
  for (let { key: t } of f) {
1737
- let n = t.level === e.level - 1 ? this.units.get(H(t)) : void 0;
1793
+ let n = t.level === e.level - 1 ? this.units.get(U(t)) : void 0;
1738
1794
  n && this.#o(s, n);
1739
1795
  }
1740
1796
  for (let { key: e, hash: t } of f) {
1741
- let n = H(e);
1797
+ let n = U(e);
1742
1798
  if (this.units.has(n)) continue;
1743
1799
  let r = this.#r.get(n);
1744
1800
  if (r && r.from <= s.level) continue;
@@ -1759,20 +1815,20 @@ var V = (e, t, n) => (e * 256 + t) * 256 + n, at = class {
1759
1815
  }
1760
1816
  ground(e, t) {
1761
1817
  for (let n of this.roots) {
1762
- let [r, i, a] = ot(n);
1818
+ let [r, i, a] = at(n);
1763
1819
  if (e < r || e >= r + a || t < i || t >= i + a) continue;
1764
1820
  let o = n;
1765
1821
  for (;;) {
1766
1822
  let n = +(e >= r + a / 2), s = +(t >= i + a / 2), c = o.children[n + 2 * s];
1767
1823
  if (!c) return o.box[2];
1768
- o = c, [r, i, a] = ot(o);
1824
+ o = c, [r, i, a] = at(o);
1769
1825
  }
1770
1826
  }
1771
1827
  }
1772
1828
  prune(e) {
1773
1829
  let t = [], n = [...this.units.values()].sort((e, t) => e.level - t.level);
1774
1830
  for (let r of n) {
1775
- let n = H(r);
1831
+ let n = U(r);
1776
1832
  if (this.#e.has(n) || this.#i.has(n) || r.pages.some((t) => e.has(t.id))) continue;
1777
1833
  for (let e of r.pages) this.pages.delete(e.id), t.push(e.id);
1778
1834
  let i = r.parent;
@@ -1782,7 +1838,7 @@ var V = (e, t, n) => (e * 256 + t) * 256 + n, at = class {
1782
1838
  }
1783
1839
  this.units.delete(n);
1784
1840
  for (let e = r.level + 1; e <= this.#t; e++) {
1785
- let t = H(U(r, e)), n = this.#i.get(t) - 1;
1841
+ let t = U(W(r, e)), n = this.#i.get(t) - 1;
1786
1842
  n ? this.#i.set(t, n) : this.#i.delete(t);
1787
1843
  }
1788
1844
  for (let { key: e } of a(r.idx)) this.#a(e);
@@ -1791,12 +1847,12 @@ var V = (e, t, n) => (e * 256 + t) * 256 + n, at = class {
1791
1847
  return t;
1792
1848
  }
1793
1849
  #a(e) {
1794
- let t = H(e);
1850
+ let t = U(e);
1795
1851
  this.#r.delete(t);
1796
1852
  for (let n = e.level + 1; n <= e.level + 3; n++) {
1797
- let r = this.units.get(H(U(e, n)));
1853
+ let r = this.units.get(U(W(e, n)));
1798
1854
  if (!r) continue;
1799
- let o = a(r.idx).find((e) => H(e.key) === t);
1855
+ let o = a(r.idx).find((e) => U(e.key) === t);
1800
1856
  if (!o) continue;
1801
1857
  let s = {
1802
1858
  level: e.level,
@@ -1818,23 +1874,23 @@ var V = (e, t, n) => (e * 256 + t) * 256 + n, at = class {
1818
1874
  for (let n of this.#s(e, t)) n.children.fill(null);
1819
1875
  for (let e of t.pages) {
1820
1876
  if (e.g !== n) continue;
1821
- let t = 8 * i + e.row.i, r = 8 * a + e.row.j, s = o.get(V(n + 1, t >> 1, r >> 1)) ?? null;
1877
+ let t = 8 * i + e.row.i, r = 8 * a + e.row.j, s = o.get(H(n + 1, t >> 1, r >> 1)) ?? null;
1822
1878
  e.parent = s, s && (s.children[(t & 1) + 2 * (r & 1)] = e);
1823
1879
  }
1824
1880
  }
1825
1881
  #s(t, n) {
1826
1882
  let r = t.level + 1, i = e * 2 ** r, a = (n.e - t.e) / i, o = (n.n - t.n) / i, s = 250 * 2 ** n.level / i, c = [];
1827
1883
  for (let e = o; e < o + s; e++) for (let n = a; n < a + s; n++) {
1828
- let i = t.grid.get(V(r, n, e));
1884
+ let i = t.grid.get(H(r, n, e));
1829
1885
  i && c.push(i);
1830
1886
  }
1831
1887
  return c;
1832
1888
  }
1833
1889
  };
1834
- function H(e) {
1890
+ function U(e) {
1835
1891
  return `${e.level}/${e.e}/${e.n}`;
1836
1892
  }
1837
- function U(e, t) {
1893
+ function W(e, t) {
1838
1894
  let n = 250 * 2 ** t;
1839
1895
  return {
1840
1896
  level: t,
@@ -1842,7 +1898,7 @@ function U(e, t) {
1842
1898
  n: Math.floor(e.n / n) * n
1843
1899
  };
1844
1900
  }
1845
- function ot(t) {
1901
+ function at(t) {
1846
1902
  let n = e * 2 ** t.g;
1847
1903
  return [
1848
1904
  t.unit.e + t.row.i * n,
@@ -1852,39 +1908,39 @@ function ot(t) {
1852
1908
  }
1853
1909
  //#endregion
1854
1910
  //#region src/engine/engine.ts
1855
- var W = class extends Error {
1911
+ var G = class extends Error {
1856
1912
  constructor() {
1857
1913
  super("This viewer needs WebGPU. Update to the latest Chrome, Edge, Safari or Firefox."), this.name = "NoWebGpu";
1858
1914
  }
1859
1915
  };
1860
- async function st(e, t) {
1916
+ async function ot(e, t) {
1861
1917
  let n = await p();
1862
- if (!n) throw new W();
1918
+ if (!n) throw new G();
1863
1919
  let r = e.getContext("webgpu");
1864
- if (!r) throw n.device.destroy(), new W();
1920
+ if (!r) throw n.device.destroy(), new G();
1865
1921
  r.configure({
1866
1922
  device: n.device,
1867
1923
  format: n.format,
1868
1924
  alphaMode: "opaque"
1869
1925
  }), (t.cache ?? "opfs") === "opfs" && navigator.storage?.persist().catch(() => !1);
1870
1926
  let { source: i = "http" } = t;
1871
- return new Ot(e, n, r, t, i === "synthetic" ? (await import("./synthetic-BZcHRI1P.js")).synthetic() : i === "http" ? s : i);
1927
+ return new Ot(e, n, r, t, i === "synthetic" ? (await import("./synthetic-BeGCzYIv.js")).synthetic() : i === "http" ? s : i);
1872
1928
  }
1873
- var G = .2, ct = 25165824, lt = 2.5, ut = 1 + L, dt = 1024, ft = 2048, pt = 100, mt = 2, K = 300, ht = 100, gt = 250, _t = 300, vt = 1e3, yt = 400, bt = 5e3, xt = 60, q = Math.PI / 180, St = "The viewer was closed.", Ct = "Another world was opened.";
1874
- function J(e, t) {
1929
+ var K = .2, st = 25165824, ct = 2.5, lt = 1 + R, ut = 1024, dt = 2048, ft = 100, pt = 2, q = 300, mt = 100, ht = 250, gt = 300, _t = 1e3, vt = 400, yt = 5e3, bt = 60, J = Math.PI / 180, xt = "The viewer was closed.", St = "Another world was opened.";
1930
+ function Ct(e, t) {
1875
1931
  let n = Math.min(t.maxStorageBufferBindingSize, t.maxBufferSize), r = (t, r) => {
1876
1932
  let i = Math.ceil(e * t / 256) * 256;
1877
1933
  return Math.min(i, Math.floor(n / r / 256) * 256);
1878
1934
  };
1879
1935
  return {
1880
- pool: r(lt, 16),
1881
- frame: r(ut, 24)
1936
+ pool: r(ct, 16),
1937
+ frame: r(lt, 24)
1882
1938
  };
1883
1939
  }
1884
1940
  function wt(e, t) {
1885
1941
  let [n, r, i] = t;
1886
- if (Math.hypot(n - e[0], r - e[1], i - e[2]) <= ft) return e;
1887
- let a = (e) => Math.round(e / dt) * dt;
1942
+ if (Math.hypot(n - e[0], r - e[1], i - e[2]) <= dt) return e;
1943
+ let a = (e) => Math.round(e / ut) * ut;
1888
1944
  return [
1889
1945
  a(n),
1890
1946
  a(r),
@@ -1911,7 +1967,7 @@ function Et(e, t) {
1911
1967
  ];
1912
1968
  }
1913
1969
  function Dt(e, t) {
1914
- e.push(t), e.length > xt && e.shift();
1970
+ e.push(t), e.length > bt && e.shift();
1915
1971
  }
1916
1972
  var Ot = class {
1917
1973
  #e;
@@ -1920,12 +1976,12 @@ var Ot = class {
1920
1976
  #r;
1921
1977
  #i;
1922
1978
  #a;
1923
- #o = new Ge();
1979
+ #o = new We();
1924
1980
  #s;
1925
1981
  #c;
1926
1982
  #l;
1927
- #u = new Ne();
1928
- #d = new Ie();
1983
+ #u = new Me();
1984
+ #d = new Fe();
1929
1985
  #f = (e) => this.#s.has(e);
1930
1986
  #p = null;
1931
1987
  #m = null;
@@ -1969,7 +2025,7 @@ var Ot = class {
1969
2025
  #L = !1;
1970
2026
  #R = !1;
1971
2027
  #z = !1;
1972
- #B = 0;
2028
+ #B = [];
1973
2029
  #V = -Infinity;
1974
2030
  #H = -Infinity;
1975
2031
  #U = -Infinity;
@@ -1991,8 +2047,8 @@ var Ot = class {
1991
2047
  e.height,
1992
2048
  1
1993
2049
  ], this.#k = [Math.max(1, e.width), Math.max(1, e.height)];
1994
- let { pool: a, frame: o } = J(this.#ne, t.device.limits);
1995
- this.#s = new _(t.device, a), this.#c = new Te(t, n, this.#s, o), this.#l = o, t.device.lost.then((e) => {
2050
+ let { pool: a, frame: o } = Ct(this.#ne, t.device.limits);
2051
+ this.#s = new _(t.device, a), this.#c = new we(t, n, this.#s, o), this.#l = o, t.device.lost.then((e) => {
1996
2052
  if (!this.#ee) {
1997
2053
  this.#te = !0, cancelAnimationFrame(this.#A);
1998
2054
  for (let t of this.#Z) t(e.message || e.reason);
@@ -2000,34 +2056,34 @@ var Ot = class {
2000
2056
  });
2001
2057
  }
2002
2058
  async open(e) {
2003
- if (this.#ee) throw Error(St);
2059
+ if (this.#ee) throw Error(xt);
2004
2060
  let t = ++this.#_, i = () => {
2005
- if (this.#ee) throw Error(St);
2006
- if (t !== this.#_) throw Error(Ct);
2061
+ if (this.#ee) throw Error(xt);
2062
+ if (t !== this.#_) throw Error(St);
2007
2063
  }, { cache: a = "opfs", source: o = "http" } = this.#r;
2008
2064
  o === "http" && (e = new URL(e, document.baseURI).href);
2009
2065
  let s = await this.#i(e, null), c = r(JSON.parse(new TextDecoder().decode(s)));
2010
2066
  i();
2011
- let l = new rt({
2067
+ let l = new nt({
2012
2068
  base: n(e),
2013
2069
  workers: Math.min(6, Math.max(2, navigator.hardwareConcurrency - 2)),
2014
2070
  cache: a,
2015
2071
  source: o
2016
- }), u = new at(c);
2072
+ }), u = new it(c);
2017
2073
  try {
2018
2074
  let e = await Promise.all(c.roots.map((e) => l.idx(e.idx)));
2019
2075
  i(), e.forEach((e, t) => u.add(e, c.roots[t].idx));
2020
2076
  } catch (e) {
2021
2077
  throw l.destroy(), e;
2022
2078
  }
2023
- return this.#g?.destroy(), this.#g = null, this.#h?.destroy(), this.#p = e, this.#m = u, this.#h = l, this.#N = null, this.#u = new Ne(), this.#d = new Ie(), this.#s.clear(), this.#g = this.#ie(u, l), this.#I = !0, this.requestFrame(), c;
2079
+ return this.#g?.destroy(), this.#g = null, this.#h?.destroy(), this.#p = e, this.#m = u, this.#h = l, this.#N = null, this.#u = new Me(), this.#d = new Fe(), this.#s.clear(), this.#g = this.#ie(u, l), this.#I = !0, this.requestFrame(), c;
2024
2080
  }
2025
2081
  setCamera(e) {
2026
2082
  if (this.#ee) return;
2027
2083
  let t = performance.now(), n = t - this.#b, r = this.#y, i = this.#x;
2028
- if (n > gt) i.fill(0);
2084
+ if (n > ht) i.fill(0);
2029
2085
  else if (n > 0) {
2030
- let t = 1 - Math.exp(-n / ht);
2086
+ let t = 1 - Math.exp(-n / mt);
2031
2087
  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]);
2032
2088
  }
2033
2089
  this.#b = t, this.#y = { ...e }, this.#F = !0, this.#$ || this.requestFrame();
@@ -2038,7 +2094,7 @@ var Ot = class {
2038
2094
  ...this.#a,
2039
2095
  ...e
2040
2096
  };
2041
- let { pool: t, frame: n } = J(this.#ne, this.#t.device.limits);
2097
+ let { pool: t, frame: n } = Ct(this.#ne, this.#t.device.limits);
2042
2098
  (t > this.#s.capacity || n > this.#l) && this.#re(t, n), this.#I = !0, this.requestFrame();
2043
2099
  }
2044
2100
  resize(e, t, n) {
@@ -2075,8 +2131,8 @@ var Ot = class {
2075
2131
  stats() {
2076
2132
  let e = this.#s, t = this.#g, n = this.#c.stats();
2077
2133
  return {
2078
- frameMs: z(this.#W, .5),
2079
- cpuMs: z(this.#G, .5),
2134
+ frameMs: B(this.#W, .5),
2135
+ cpuMs: B(this.#G, .5),
2080
2136
  gpuMs: n.gpuMs,
2081
2137
  passes: n.passes,
2082
2138
  drawn: n.drawn,
@@ -2084,7 +2140,7 @@ var Ot = class {
2084
2140
  missing: this.#N?.missing ?? 0,
2085
2141
  pages: {
2086
2142
  resident: Array.from(e.ids()).length,
2087
- drawn: this.#B,
2143
+ drawn: this.#B.length,
2088
2144
  loading: t?.loading ?? 0,
2089
2145
  queued: t?.queued ?? 0
2090
2146
  },
@@ -2114,7 +2170,7 @@ var Ot = class {
2114
2170
  }
2115
2171
  warm() {
2116
2172
  let e = performance.now();
2117
- e - this.#V < vt || (this.#H = e + yt, this.requestFrame());
2173
+ e - this.#V < _t || (this.#H = e + vt, this.requestFrame());
2118
2174
  }
2119
2175
  onFrame(e) {
2120
2176
  return this.#Q.add(e), () => this.#Q.delete(e);
@@ -2150,26 +2206,26 @@ var Ot = class {
2150
2206
  }
2151
2207
  }
2152
2208
  get #ne() {
2153
- let e = Math.floor(J(Infinity, this.#t.device.limits).frame / ut);
2209
+ let e = Math.floor(Ct(Infinity, this.#t.device.limits).frame / lt);
2154
2210
  return Math.max(1, Math.min(this.#a.budget, e));
2155
2211
  }
2156
2212
  #re(e, t) {
2157
2213
  this.#g?.destroy(), this.#g = null, this.#c.destroy(), this.#s.destroy(), this.#s = new _(this.#t.device, e), this.#s.setOrigin(this.#S);
2158
- let n = new Te(this.#t, this.#n, this.#s, t);
2214
+ let n = new we(this.#t, this.#n, this.#s, t);
2159
2215
  n.resize(...this.#k);
2160
2216
  for (let e of this.#K) e.off = n.shade(e.hook);
2161
2217
  for (let e of this.#q) e.off = n.post(e.hook);
2162
2218
  this.#c = n, this.#l = t, this.#m && this.#h && (this.#g = this.#ie(this.#m, this.#h)), this.#N = null, this.#I = !0, this.requestFrame();
2163
2219
  }
2164
2220
  #ie(e, t) {
2165
- return new Qe(e, t, this.#s, () => {
2221
+ return new Ze(e, t, this.#s, () => {
2166
2222
  this.#R = !0, this.requestFrame();
2167
2223
  }, this.#ae);
2168
2224
  }
2169
2225
  #ae = () => {
2170
2226
  let e = this.#p, t = this.#m;
2171
2227
  this.#v || this.#ee || e === null || (this.#v = !0, this.open(e).then(() => this.#v = !1, () => {
2172
- this.#v = !1, this.#m === t && setTimeout(this.#ae, bt);
2228
+ this.#v = !1, this.#m === t && setTimeout(this.#ae, yt);
2173
2229
  }));
2174
2230
  };
2175
2231
  #oe(e, t, n) {
@@ -2183,12 +2239,12 @@ var Ot = class {
2183
2239
  };
2184
2240
  }
2185
2241
  #se() {
2186
- let [e, t, n] = this.#O, r = We(e, t, n, this.#o.scale), i = Math.max(1, Math.round(e * r)), a = Math.max(1, Math.round(t * r));
2242
+ let [e, t, n] = this.#O, r = Ue(e, t, n, this.#o.scale), i = Math.max(1, Math.round(e * r)), a = Math.max(1, Math.round(t * r));
2187
2243
  (i !== this.#k[0] || a !== this.#k[1]) && (this.#k = [i, a], this.#e.width = i, this.#e.height = a, this.#c.resize(i, a), this.#I = !0, this.requestFrame());
2188
2244
  }
2189
2245
  #ce = (e) => {
2190
2246
  if (this.#A = 0, !(this.#ee || this.#te)) {
2191
- if (this.#j >= mt) this.#M = !0;
2247
+ if (this.#j >= pt) this.#M = !0;
2192
2248
  else {
2193
2249
  this.#$ = !0;
2194
2250
  for (let t of this.#Q) t(e);
@@ -2208,36 +2264,36 @@ var Ot = class {
2208
2264
  ]);
2209
2265
  l !== this.#S && (this.#S = l, r.setOrigin(l));
2210
2266
  let u = Et(i, l);
2211
- y(this.#C, u, i.yaw * q, i.pitch * q), b(this.#w, i.fov * q, a / o, G, s);
2267
+ y(this.#C, u, i.yaw * J, i.pitch * J), b(this.#w, i.fov * J, a / o, K, s);
2212
2268
  let d = {
2213
2269
  time: t,
2214
2270
  width: a,
2215
2271
  height: o,
2216
2272
  view: new Float32Array(this.#C),
2217
2273
  proj: new Float32Array(this.#w),
2218
- near: G,
2274
+ near: K,
2219
2275
  far: s,
2220
2276
  camera: Float32Array.from(u),
2221
2277
  origin: l
2222
2278
  };
2223
- De(this.#D, S(this.#E, d.proj, d.view));
2224
- let f = this.#m, p = this.#g, m = this.#N;
2279
+ Ee(this.#D, S(this.#E, d.proj, d.view));
2280
+ let f = this.#m, p = this.#g, m = this.#R || this.#I || this.#z, h = this.#N, g = h;
2225
2281
  if (f && p) {
2226
- let e = !p.idle && t - this.#P >= pt, n = this.#I || this.#R || this.#z || this.#L;
2227
- (!m || c || e || n) && (m = this.#ue(f, t, c));
2282
+ let e = !p.idle && t - this.#P >= ft, n = this.#I || this.#R || this.#z || this.#L;
2283
+ (!g || c || e || n) && (g = this.#ue(f, t, c));
2228
2284
  }
2229
- let h = [], g = !1;
2230
- m && p && ({drawn: h, fading: g} = this.#d.update(m.cut, this.#f, t, this.#ne), p.update(m, new Set(h.map((e) => e.id)), t)), r.upload(ct) > 0 && (this.#R = !0), r.draw(h), this.#z = g, this.#B = h.length;
2231
- let _ = this.#J.splice(0).map((e) => this.#fe(e, d)), v = this.#Y.splice(0).map((e) => this.#pe(e, l)), x = this.#c.render(d, this.#D, this.#r.sky, _, v), C = performance.now() - t;
2232
- if (!this.#R && !this.#L && !g && r.queued === 0 && (!p || p.idle) && (!m || m.load.length === 0 && m.idx.length === 0) && this.#X.length) {
2285
+ let _ = this.#B, v = this.#z;
2286
+ 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.#ne)), p.update(g, new Set(_.map((e) => e.id)), t)), r.upload(st) > 0 && (this.#R = !0), (_ !== this.#B || this.#R) && r.draw(_), this.#z = v, this.#B = _;
2287
+ let x = this.#J.splice(0).map((e) => this.#fe(e, d)), C = this.#Y.splice(0).map((e) => this.#pe(e, l)), w = this.#c.render(d, this.#D, this.#r.sky, x, C), T = performance.now() - t;
2288
+ if (!this.#R && !this.#L && !v && r.queued === 0 && (!p || p.idle) && (!g || g.load.length === 0 && g.idx.length === 0) && this.#X.length) {
2233
2289
  let e = this.#X.splice(0);
2234
- x.then(() => e.forEach((e) => e()));
2290
+ w.then(() => e.forEach((e) => e()));
2235
2291
  }
2236
- e && this.#me(t, C, c);
2237
- let w = t < this.#H;
2238
- return (r.queued > 0 || this.#R || this.#L || g || n.scale < 1 || w) && this.requestFrame(), {
2239
- done: x,
2240
- cpuMs: C
2292
+ e && this.#me(t, T, c);
2293
+ let E = t < this.#H;
2294
+ return (r.queued > 0 || this.#R || this.#L || v || n.scale < 1 || E) && this.requestFrame(), {
2295
+ done: w,
2296
+ cpuMs: T
2241
2297
  };
2242
2298
  }
2243
2299
  #ue(e, t, n) {
@@ -2245,15 +2301,15 @@ var Ot = class {
2245
2301
  origin: this.#S,
2246
2302
  width: a / s,
2247
2303
  height: o / s,
2248
- tan: Math.tan(r.fov * q / 2),
2249
- near: G,
2304
+ tan: Math.tan(r.fov * J / 2),
2305
+ near: K,
2250
2306
  far: this.#a.viewDistance
2251
2307
  }, u = {
2252
2308
  ...l,
2253
2309
  view: this.#C
2254
2310
  }, d = {
2255
2311
  budget: c,
2256
- capacity: i.capacity - Math.ceil(L * c),
2312
+ capacity: i.capacity - Math.ceil(R * c),
2257
2313
  now: t,
2258
2314
  predicted: n ? this.#de(l) : void 0
2259
2315
  }, f = this.#u.plan(e, u, this.#f, d);
@@ -2263,13 +2319,13 @@ var Ot = class {
2263
2319
  let t = this.#x;
2264
2320
  if (t.every((e) => e === 0)) return;
2265
2321
  let n = this.#y, r = [
2266
- n.e + t[0] * K - e.origin[0],
2267
- n.n + t[1] * K - e.origin[1],
2268
- n.h + t[2] * K - e.origin[2]
2322
+ n.e + t[0] * q - e.origin[0],
2323
+ n.n + t[1] * q - e.origin[1],
2324
+ n.h + t[2] * q - e.origin[2]
2269
2325
  ];
2270
2326
  return {
2271
2327
  ...e,
2272
- view: y(this.#T, r, n.yaw * q, n.pitch * q)
2328
+ view: y(this.#T, r, n.yaw * J, n.pitch * J)
2273
2329
  };
2274
2330
  }
2275
2331
  #fe({ x: e, y: t, resolve: n }, r) {
@@ -2292,8 +2348,8 @@ var Ot = class {
2292
2348
  };
2293
2349
  }
2294
2350
  #me(e, t, n) {
2295
- let r = this.#o, i = e - this.#V <= gt;
2296
- i && Dt(this.#W, e - this.#V), Dt(this.#G, t), this.#V = e, r.sample(this.#c.stats().gpuMs, e, i && n) && this.#se(), n ? this.#U = e : r.scale < 1 && e - this.#U > _t && (r.full(), this.#se());
2351
+ let r = this.#o, { gpuMs: i } = this.#c.stats(), a = e - this.#V <= Math.max(ht, 2 * i, 2 * t);
2352
+ a && Dt(this.#W, e - this.#V), Dt(this.#G, t), this.#V = e, r.sample(i, e, a && n) && this.#se(), n ? this.#U = e : r.scale < 1 && e - this.#U > gt && (r.full(), this.#se());
2297
2353
  }
2298
2354
  }, kt = 45, At = {
2299
2355
  yaw: 0,
@@ -2630,4 +2686,4 @@ function $(e, t, n) {
2630
2686
  e[0] += t, e[1] += n;
2631
2687
  }
2632
2688
  //#endregion
2633
- export { oe as S, qt as _, Q as a, st as b, Wt as c, Ht as d, Vt as f, Bt as g, It as h, Kt as i, Lt as l, Gt as m, kt as n, Z as o, Ft as p, Y as r, At as s, nn as t, Ut as u, zt as v, Ve as x, W as y };
2689
+ export { ae as S, qt as _, Q as a, ot as b, Wt as c, Ht as d, Vt as f, Bt as g, It as h, Kt as i, Lt as l, Gt as m, kt as n, Z as o, Ft as p, Y as r, At as s, nn as t, Ut as u, zt as v, Be as x, G as y };