layershift 0.4.3 → 0.5.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.
Files changed (59) hide show
  1. package/README.md +79 -1
  2. package/dist/components/layershift.js +89 -47
  3. package/dist/npm/layershift.es.js +1295 -1154
  4. package/dist/types/components/layershift/index.d.ts +8 -0
  5. package/dist/types/components/layershift/index.d.ts.map +1 -1
  6. package/dist/types/components/layershift/layershift-element.d.ts +5 -1
  7. package/dist/types/components/layershift/layershift-element.d.ts.map +1 -1
  8. package/dist/types/components/layershift/portal-element.d.ts +5 -1
  9. package/dist/types/components/layershift/portal-element.d.ts.map +1 -1
  10. package/dist/types/components/layershift/types.d.ts +4 -2
  11. package/dist/types/components/layershift/types.d.ts.map +1 -1
  12. package/dist/types/depth/depth-analysis.d.ts.map +1 -0
  13. package/dist/types/{depth-estimator.d.ts → depth/depth-estimator.d.ts} +4 -15
  14. package/dist/types/depth/depth-estimator.d.ts.map +1 -0
  15. package/dist/types/depth/depth-preprocess.d.ts +26 -0
  16. package/dist/types/depth/depth-preprocess.d.ts.map +1 -0
  17. package/dist/types/depth/precomputed-depth.d.ts.map +1 -0
  18. package/dist/types/depth/workers/preprocess-worker.d.ts +36 -0
  19. package/dist/types/depth/workers/preprocess-worker.d.ts.map +1 -0
  20. package/dist/types/{quality.d.ts → gpu/quality.d.ts} +4 -4
  21. package/dist/types/gpu/quality.d.ts.map +1 -0
  22. package/dist/types/gpu/webgl-utils.d.ts.map +1 -0
  23. package/dist/types/{input-handler.d.ts → media/input-handler.d.ts} +14 -0
  24. package/dist/types/media/input-handler.d.ts.map +1 -0
  25. package/dist/types/media/input-helpers.d.ts +70 -0
  26. package/dist/types/media/input-helpers.d.ts.map +1 -0
  27. package/dist/types/media/media-source.d.ts.map +1 -0
  28. package/dist/types/{depth-effect-renderer.d.ts → renderers/depth-effect-renderer.d.ts} +21 -4
  29. package/dist/types/renderers/depth-effect-renderer.d.ts.map +1 -0
  30. package/dist/types/renderers/jfa-distance-field.d.ts.map +1 -0
  31. package/dist/types/{portal-renderer.d.ts → renderers/portal-renderer.d.ts} +4 -3
  32. package/dist/types/renderers/portal-renderer.d.ts.map +1 -0
  33. package/dist/types/renderers/render-pass.d.ts.map +1 -0
  34. package/dist/types/{renderer-base.d.ts → renderers/renderer-base.d.ts} +3 -3
  35. package/dist/types/renderers/renderer-base.d.ts.map +1 -0
  36. package/dist/types/renderers/shape-generator.d.ts.map +1 -0
  37. package/package.json +8 -2
  38. package/dist/types/depth-analysis.d.ts.map +0 -1
  39. package/dist/types/depth-effect-renderer.d.ts.map +0 -1
  40. package/dist/types/depth-estimator.d.ts.map +0 -1
  41. package/dist/types/input-handler.d.ts.map +0 -1
  42. package/dist/types/jfa-distance-field.d.ts.map +0 -1
  43. package/dist/types/media-source.d.ts.map +0 -1
  44. package/dist/types/portal-renderer.d.ts.map +0 -1
  45. package/dist/types/precomputed-depth.d.ts.map +0 -1
  46. package/dist/types/quality.d.ts.map +0 -1
  47. package/dist/types/render-pass.d.ts.map +0 -1
  48. package/dist/types/renderer-base.d.ts.map +0 -1
  49. package/dist/types/shape-generator.d.ts.map +0 -1
  50. package/dist/types/video-source.d.ts +0 -22
  51. package/dist/types/video-source.d.ts.map +0 -1
  52. package/dist/types/webgl-utils.d.ts.map +0 -1
  53. /package/dist/types/{depth-analysis.d.ts → depth/depth-analysis.d.ts} +0 -0
  54. /package/dist/types/{precomputed-depth.d.ts → depth/precomputed-depth.d.ts} +0 -0
  55. /package/dist/types/{webgl-utils.d.ts → gpu/webgl-utils.d.ts} +0 -0
  56. /package/dist/types/{media-source.d.ts → media/media-source.d.ts} +0 -0
  57. /package/dist/types/{jfa-distance-field.d.ts → renderers/jfa-distance-field.d.ts} +0 -0
  58. /package/dist/types/{render-pass.d.ts → renderers/render-pass.d.ts} +0 -0
  59. /package/dist/types/{shape-generator.d.ts → renderers/shape-generator.d.ts} +0 -0
@@ -1,4 +1,4 @@
1
- class Ot {
1
+ class Vt {
2
2
  constructor(t) {
3
3
  this.depthData = t;
4
4
  const e = t.meta.width * t.meta.height;
@@ -10,29 +10,29 @@ class Ot {
10
10
  lastNextFrameIndex = -1;
11
11
  lastLerpFactor = -1;
12
12
  sample(t) {
13
- const e = oe(t * this.depthData.meta.fps, 0, this.depthData.meta.frameCount - 1), n = Math.floor(e), i = Math.min(n + 1, this.depthData.meta.frameCount - 1), r = e - n, s = n !== this.lastFrameIndex || i !== this.lastNextFrameIndex, a = Math.abs(r - this.lastLerpFactor) > 1e-3;
14
- if (!s && !a)
13
+ const e = re(t * this.depthData.meta.fps, 0, this.depthData.meta.frameCount - 1), n = Math.floor(e), i = Math.min(n + 1, this.depthData.meta.frameCount - 1), r = e - n, o = n !== this.lastFrameIndex || i !== this.lastNextFrameIndex, l = Math.abs(r - this.lastLerpFactor) > 1e-3;
14
+ if (!o && !l)
15
15
  return this.uint8Output;
16
16
  this.lastFrameIndex = n, this.lastNextFrameIndex = i, this.lastLerpFactor = r;
17
- const l = 1 - r, u = this.depthData.frames[n], h = this.depthData.frames[i];
17
+ const a = 1 - r, h = this.depthData.frames[n], c = this.depthData.frames[i];
18
18
  for (let f = 0; f < this.uint8Output.length; f += 1)
19
- this.uint8Output[f] = u[f] * l + h[f] * r + 0.5 | 0;
19
+ this.uint8Output[f] = h[f] * a + c[f] * r + 0.5 | 0;
20
20
  return this.uint8Output;
21
21
  }
22
22
  }
23
- async function kt(o, t, e) {
23
+ async function kt(s, t, e) {
24
24
  const [n, i] = await Promise.all([
25
- ee(t),
26
- ne(o)
25
+ te(t),
26
+ ee(s)
27
27
  ]);
28
- return ie(i, n);
28
+ return ne(i, n);
29
29
  }
30
- async function ee(o) {
31
- const t = await fetch(o);
30
+ async function te(s) {
31
+ const t = await fetch(s);
32
32
  if (!t.ok)
33
33
  throw new Error(`Failed to fetch depth metadata (${t.status} ${t.statusText}).`);
34
34
  const e = await t.json();
35
- return re(e), {
35
+ return ie(e), {
36
36
  frameCount: e.frameCount,
37
37
  fps: e.fps,
38
38
  width: e.width,
@@ -40,8 +40,8 @@ async function ee(o) {
40
40
  sourceFps: e.sourceFps
41
41
  };
42
42
  }
43
- async function ne(o, t) {
44
- const e = await fetch(o);
43
+ async function ee(s, t) {
44
+ const e = await fetch(s);
45
45
  if (!e.ok)
46
46
  throw new Error(`Failed to fetch depth data (${e.status} ${e.statusText}).`);
47
47
  e.headers.get("content-length");
@@ -50,53 +50,53 @@ async function ne(o, t) {
50
50
  return new Uint8Array(await e.arrayBuffer());
51
51
  const i = [];
52
52
  let r = 0;
53
- const s = n.getReader();
53
+ const o = n.getReader();
54
54
  for (; ; ) {
55
- const { done: u, value: h } = await s.read();
56
- if (u)
55
+ const { done: h, value: c } = await o.read();
56
+ if (h)
57
57
  break;
58
- h && (i.push(h), r += h.byteLength);
58
+ c && (i.push(c), r += c.byteLength);
59
59
  }
60
- const a = new Uint8Array(r);
61
- let l = 0;
62
- for (const u of i)
63
- a.set(u, l), l += u.byteLength;
64
- return a;
60
+ const l = new Uint8Array(r);
61
+ let a = 0;
62
+ for (const h of i)
63
+ l.set(h, a), a += h.byteLength;
64
+ return l;
65
65
  }
66
- function ie(o, t) {
67
- if (o.byteLength < 4)
66
+ function ne(s, t) {
67
+ if (s.byteLength < 4)
68
68
  throw new Error("Depth data binary is missing the frame-count header.");
69
- const n = new DataView(o.buffer, o.byteOffset, o.byteLength).getUint32(0, !0), i = t.width * t.height, r = 4 + n * i;
70
- if (o.byteLength !== r)
69
+ const n = new DataView(s.buffer, s.byteOffset, s.byteLength).getUint32(0, !0), i = t.width * t.height, r = 4 + n * i;
70
+ if (s.byteLength !== r)
71
71
  throw new Error(
72
- `Depth data byte length mismatch. Expected ${r} bytes, received ${o.byteLength}.`
72
+ `Depth data byte length mismatch. Expected ${r} bytes, received ${s.byteLength}.`
73
73
  );
74
74
  if (n !== t.frameCount)
75
75
  throw new Error(
76
76
  `Depth frame count mismatch between metadata (${t.frameCount}) and binary header (${n}).`
77
77
  );
78
- const s = o.subarray(4), a = new Array(n);
79
- for (let l = 0; l < n; l += 1) {
80
- const u = l * i;
81
- a[l] = s.subarray(u, u + i);
78
+ const o = s.subarray(4), l = new Array(n);
79
+ for (let a = 0; a < n; a += 1) {
80
+ const h = a * i;
81
+ l[a] = o.subarray(h, h + i);
82
82
  }
83
- return { meta: t, frames: a };
83
+ return { meta: t, frames: l };
84
84
  }
85
- function re(o) {
86
- if (!o || typeof o.frameCount != "number" || typeof o.fps != "number" || typeof o.width != "number" || typeof o.height != "number" || typeof o.sourceFps != "number")
85
+ function ie(s) {
86
+ if (!s || typeof s.frameCount != "number" || typeof s.fps != "number" || typeof s.width != "number" || typeof s.height != "number" || typeof s.sourceFps != "number")
87
87
  throw new Error("Depth metadata is malformed.");
88
- if (!Number.isFinite(o.frameCount) || !Number.isFinite(o.fps) || !Number.isFinite(o.width) || !Number.isFinite(o.height) || !Number.isFinite(o.sourceFps) || o.frameCount <= 0 || o.fps <= 0 || o.width <= 0 || o.height <= 0 || o.sourceFps <= 0)
88
+ if (!Number.isFinite(s.frameCount) || !Number.isFinite(s.fps) || !Number.isFinite(s.width) || !Number.isFinite(s.height) || !Number.isFinite(s.sourceFps) || s.frameCount <= 0 || s.fps <= 0 || s.width <= 0 || s.height <= 0 || s.sourceFps <= 0)
89
89
  throw new Error("Depth metadata contains invalid numeric values.");
90
90
  }
91
- function H(o, t) {
92
- const e = new Uint8Array(o * t);
91
+ function N(s, t) {
92
+ const e = new Uint8Array(s * t);
93
93
  return e.fill(128), {
94
- meta: { frameCount: 1, fps: 1, width: o, height: t, sourceFps: 1 },
94
+ meta: { frameCount: 1, fps: 1, width: s, height: t, sourceFps: 1 },
95
95
  frames: [e]
96
96
  };
97
97
  }
98
- function oe(o, t, e) {
99
- return Math.min(e, Math.max(t, o));
98
+ function re(s, t, e) {
99
+ return Math.min(e, Math.max(t, s));
100
100
  }
101
101
  const se = {
102
102
  parallaxStrength: 0.05,
@@ -108,123 +108,123 @@ const se = {
108
108
  pomSteps: 16,
109
109
  overscanPadding: 0.08
110
110
  };
111
- function ae(o, t, e) {
111
+ function oe(s, t, e) {
112
112
  const n = new Float32Array(256);
113
- if (o.length === 0 || t <= 0 || e <= 0)
114
- return Ct(n);
115
- const i = he(o.length), r = t * e;
116
- let s = 0;
117
- const a = new Uint32Array(256);
118
- for (const b of i) {
119
- const T = o[b], m = Math.min(T.length, r);
120
- for (let S = 0; S < m; S += 1)
121
- a[T[S]] += 1;
122
- s += m;
123
- }
124
- if (s === 0)
125
- return Ct(n);
126
- const l = 1 / s;
127
- for (let b = 0; b < 256; b += 1)
128
- n[b] = a[b] * l;
129
- const u = new Float32Array(256);
130
- u[0] = n[0];
131
- for (let b = 1; b < 256; b += 1)
132
- u[b] = u[b - 1] + n[b];
133
- const h = et(u, 0.05), f = et(u, 0.25), c = et(u, 0.5), E = et(u, 0.75), v = et(u, 0.95);
134
- let p = 0;
135
- for (let b = 0; b < 256; b += 1)
136
- p += b / 255 * n[b];
137
- let P = 0;
138
- for (let b = 0; b < 256; b += 1) {
139
- const T = b / 255 - p;
140
- P += n[b] * T * T;
141
- }
142
- const x = Math.sqrt(P), y = v - h, d = E - f, g = ue(n);
113
+ if (s.length === 0 || t <= 0 || e <= 0)
114
+ return Pt(n);
115
+ const i = le(s.length), r = t * e;
116
+ let o = 0;
117
+ const l = new Uint32Array(256);
118
+ for (const m of i) {
119
+ const T = s[m], w = Math.min(T.length, r);
120
+ for (let A = 0; A < w; A += 1)
121
+ l[T[A]] += 1;
122
+ o += w;
123
+ }
124
+ if (o === 0)
125
+ return Pt(n);
126
+ const a = 1 / o;
127
+ for (let m = 0; m < 256; m += 1)
128
+ n[m] = l[m] * a;
129
+ const h = new Float32Array(256);
130
+ h[0] = n[0];
131
+ for (let m = 1; m < 256; m += 1)
132
+ h[m] = h[m - 1] + n[m];
133
+ const c = nt(h, 0.05), f = nt(h, 0.25), u = nt(h, 0.5), x = nt(h, 0.75), p = nt(h, 0.95);
134
+ let d = 0;
135
+ for (let m = 0; m < 256; m += 1)
136
+ d += m / 255 * n[m];
137
+ let y = 0;
138
+ for (let m = 0; m < 256; m += 1) {
139
+ const T = m / 255 - d;
140
+ y += n[m] * T * T;
141
+ }
142
+ const E = Math.sqrt(y), b = p - c, g = x - f, v = ue(n);
143
143
  return {
144
- mean: p,
145
- stdDev: x,
146
- p5: h,
144
+ mean: d,
145
+ stdDev: E,
146
+ p5: c,
147
147
  p25: f,
148
- median: c,
149
- p75: E,
150
- p95: v,
151
- effectiveRange: y,
152
- iqr: d,
153
- bimodality: g,
148
+ median: u,
149
+ p75: x,
150
+ p95: p,
151
+ effectiveRange: b,
152
+ iqr: g,
153
+ bimodality: v,
154
154
  histogram: n
155
155
  };
156
156
  }
157
- function le(o) {
158
- if (o.effectiveRange < 0.05 || o.stdDev < 0.02)
157
+ function ae(s) {
158
+ if (s.effectiveRange < 0.05 || s.stdDev < 0.02)
159
159
  return { ...se };
160
- const t = o.effectiveRange - 0.5, e = o.bimodality - 0.4, n = k(
160
+ const t = s.effectiveRange - 0.5, e = s.bimodality - 0.4, n = H(
161
161
  0.05 - t * 0.03 + e * 0.01,
162
162
  0.035,
163
163
  0.065
164
- ), i = k(o.p5 - 0.03, 0, 0.25), r = k(o.p95 + 0.03, 0.75, 1), s = k((n - 0.03) / 0.05, 0, 1), a = k(0.6 - s * 0.25, 0.35, 0.6), l = k(0.6 - t * 0.2, 0.5, 0.7), u = k(0.4 + t * 0.2, 0.25, 0.5), h = 16, f = k(n + 0.03, 0.06, 0.1);
164
+ ), i = H(s.p5 - 0.03, 0, 0.25), r = H(s.p95 + 0.03, 0.75, 1), o = H((n - 0.03) / 0.05, 0, 1), l = H(0.6 - o * 0.25, 0.35, 0.6), a = H(0.6 - t * 0.2, 0.5, 0.7), h = H(0.4 + t * 0.2, 0.25, 0.5), c = 16, f = H(n + 0.03, 0.06, 0.1);
165
165
  return {
166
166
  parallaxStrength: n,
167
167
  contrastLow: i,
168
168
  contrastHigh: r,
169
- verticalReduction: a,
170
- dofStart: l,
171
- dofStrength: u,
172
- pomSteps: h,
169
+ verticalReduction: l,
170
+ dofStart: a,
171
+ dofStrength: h,
172
+ pomSteps: c,
173
173
  overscanPadding: f
174
174
  };
175
175
  }
176
- function he(o) {
177
- if (o <= 0) return [];
178
- if (o === 1) return [0];
179
- const t = o - 1, e = [
176
+ function le(s) {
177
+ if (s <= 0) return [];
178
+ if (s === 1) return [0];
179
+ const t = s - 1, e = [
180
180
  0,
181
- Math.floor(o / 4),
182
- Math.floor(o / 2),
183
- Math.floor(3 * o / 4),
181
+ Math.floor(s / 4),
182
+ Math.floor(s / 2),
183
+ Math.floor(3 * s / 4),
184
184
  t
185
185
  ], n = /* @__PURE__ */ new Set(), i = [];
186
186
  for (const r of e)
187
187
  n.has(r) || (n.add(r), i.push(r));
188
188
  return i;
189
189
  }
190
- function et(o, t) {
190
+ function nt(s, t) {
191
191
  for (let e = 0; e < 256; e += 1)
192
- if (o[e] >= t)
192
+ if (s[e] >= t)
193
193
  return e / 255;
194
194
  return 1;
195
195
  }
196
- function ue(o) {
196
+ function ue(s) {
197
197
  const t = new Float32Array(256);
198
- for (let c = 0; c < 256; c += 1) {
199
- let E = 0, v = 0;
200
- for (let p = c - 2; p <= c + 2; p += 1)
201
- p >= 0 && p < 256 && (E += o[p], v += 1);
202
- t[c] = E / v;
198
+ for (let u = 0; u < 256; u += 1) {
199
+ let x = 0, p = 0;
200
+ for (let d = u - 2; d <= u + 2; d += 1)
201
+ d >= 0 && d < 256 && (x += s[d], p += 1);
202
+ t[u] = x / p;
203
203
  }
204
204
  let e = 0;
205
- for (let c = 0; c < 256; c += 1)
206
- e += t[c];
205
+ for (let u = 0; u < 256; u += 1)
206
+ e += t[u];
207
207
  e /= 256;
208
208
  const n = e * 2, i = 25, r = [];
209
- for (let c = 1; c < 255; c += 1)
210
- t[c] > t[c - 1] && t[c] > t[c + 1] && t[c] >= n && r.push({ bin: c, height: t[c] });
211
- if (t[0] > t[1] && t[0] >= n && r.push({ bin: 0, height: t[0] }), t[255] > t[254] && t[255] >= n && r.push({ bin: 255, height: t[255] }), r.sort((c, E) => E.height - c.height), r.length < 2) return 0;
212
- const s = r[0];
213
- let a = null;
214
- for (let c = 1; c < r.length; c += 1)
215
- if (Math.abs(r[c].bin - s.bin) >= i) {
216
- a = r[c];
209
+ for (let u = 1; u < 255; u += 1)
210
+ t[u] > t[u - 1] && t[u] > t[u + 1] && t[u] >= n && r.push({ bin: u, height: t[u] });
211
+ if (t[0] > t[1] && t[0] >= n && r.push({ bin: 0, height: t[0] }), t[255] > t[254] && t[255] >= n && r.push({ bin: 255, height: t[255] }), r.sort((u, x) => x.height - u.height), r.length < 2) return 0;
212
+ const o = r[0];
213
+ let l = null;
214
+ for (let u = 1; u < r.length; u += 1)
215
+ if (Math.abs(r[u].bin - o.bin) >= i) {
216
+ l = r[u];
217
217
  break;
218
218
  }
219
- if (!a) return 0;
220
- const l = Math.min(s.bin, a.bin), u = Math.max(s.bin, a.bin);
221
- let h = 1 / 0;
222
- for (let c = l; c <= u; c += 1)
223
- t[c] < h && (h = t[c]);
224
- const f = Math.min(s.height, a.height);
225
- return f <= 0 ? 0 : k(1 - h / f, 0, 1);
226
- }
227
- function Ct(o) {
219
+ if (!l) return 0;
220
+ const a = Math.min(o.bin, l.bin), h = Math.max(o.bin, l.bin);
221
+ let c = 1 / 0;
222
+ for (let u = a; u <= h; u += 1)
223
+ t[u] < c && (c = t[u]);
224
+ const f = Math.min(o.height, l.height);
225
+ return f <= 0 ? 0 : H(1 - c / f, 0, 1);
226
+ }
227
+ function Pt(s) {
228
228
  return {
229
229
  mean: 0,
230
230
  stdDev: 0,
@@ -236,36 +236,36 @@ function Ct(o) {
236
236
  effectiveRange: 0,
237
237
  iqr: 0,
238
238
  bimodality: 0,
239
- histogram: o
239
+ histogram: s
240
240
  };
241
241
  }
242
- function k(o, t, e) {
243
- return Math.min(e, Math.max(t, o));
242
+ function H(s, t, e) {
243
+ return Math.min(e, Math.max(t, s));
244
244
  }
245
- function Q(o, t, e) {
246
- const n = o.createShader(t);
245
+ function G(s, t, e) {
246
+ const n = s.createShader(t);
247
247
  if (!n) throw new Error("Failed to create shader.");
248
- if (o.shaderSource(n, e), o.compileShader(n), !o.getShaderParameter(n, o.COMPILE_STATUS)) {
249
- const i = o.getShaderInfoLog(n) ?? "";
250
- throw o.deleteShader(n), new Error(`Shader compilation failed:
248
+ if (s.shaderSource(n, e), s.compileShader(n), !s.getShaderParameter(n, s.COMPILE_STATUS)) {
249
+ const i = s.getShaderInfoLog(n) ?? "";
250
+ throw s.deleteShader(n), new Error(`Shader compilation failed:
251
251
  ${i}`);
252
252
  }
253
253
  return n;
254
254
  }
255
- function wt(o, t, e) {
256
- const n = o.createProgram();
255
+ function mt(s, t, e) {
256
+ const n = s.createProgram();
257
257
  if (!n) throw new Error("Failed to create program.");
258
- if (o.attachShader(n, t), o.attachShader(n, e), o.linkProgram(n), !o.getProgramParameter(n, o.LINK_STATUS)) {
259
- const i = o.getProgramInfoLog(n) ?? "";
260
- throw o.deleteProgram(n), new Error(`Program linking failed:
258
+ if (s.attachShader(n, t), s.attachShader(n, e), s.linkProgram(n), !s.getProgramParameter(n, s.LINK_STATUS)) {
259
+ const i = s.getProgramInfoLog(n) ?? "";
260
+ throw s.deleteProgram(n), new Error(`Program linking failed:
261
261
  ${i}`);
262
262
  }
263
- return o.detachShader(n, t), o.detachShader(n, e), o.deleteShader(t), o.deleteShader(e), n;
263
+ return s.detachShader(n, t), s.detachShader(n, e), s.deleteShader(t), s.deleteShader(e), n;
264
264
  }
265
- function Rt(o, t, e) {
265
+ function pt(s, t, e) {
266
266
  const n = {};
267
267
  for (const i of e)
268
- n[i] = o.getUniformLocation(t, i);
268
+ n[i] = s.getUniformLocation(t, i);
269
269
  return n;
270
270
  }
271
271
  const ce = new Float32Array([
@@ -278,14 +278,14 @@ const ce = new Float32Array([
278
278
  1,
279
279
  1
280
280
  ]);
281
- function Nt(o, t) {
282
- const e = o.createVertexArray();
281
+ function Ot(s, t) {
282
+ const e = s.createVertexArray();
283
283
  if (!e) throw new Error("Failed to create VAO.");
284
- o.bindVertexArray(e);
285
- const n = o.createBuffer();
286
- o.bindBuffer(o.ARRAY_BUFFER, n), o.bufferData(o.ARRAY_BUFFER, ce, o.STATIC_DRAW);
287
- const i = o.getAttribLocation(t, "aPosition");
288
- return o.enableVertexAttribArray(i), o.vertexAttribPointer(i, 2, o.FLOAT, !1, 0, 0), o.bindVertexArray(null), e;
284
+ s.bindVertexArray(e);
285
+ const n = s.createBuffer();
286
+ s.bindBuffer(s.ARRAY_BUFFER, n), s.bufferData(s.ARRAY_BUFFER, ce, s.STATIC_DRAW);
287
+ const i = s.getAttribLocation(t, "aPosition");
288
+ return s.enableVertexAttribArray(i), s.vertexAttribPointer(i, 2, s.FLOAT, !1, 0, 0), s.bindVertexArray(null), e;
289
289
  }
290
290
  class Ht {
291
291
  slots = /* @__PURE__ */ new Map();
@@ -323,18 +323,56 @@ class Ht {
323
323
  return this.slots.size;
324
324
  }
325
325
  }
326
- function O(o, t, e, n, i) {
327
- const r = Q(o, o.VERTEX_SHADER, e), s = Q(o, o.FRAGMENT_SHADER, n), a = wt(o, r, s), l = Rt(o, a, i);
326
+ function O(s, t, e, n, i) {
327
+ const r = G(s, s.VERTEX_SHADER, e), o = G(s, s.FRAGMENT_SHADER, n), l = mt(s, r, o), a = pt(s, l, i);
328
328
  return {
329
+ name: t,
330
+ program: l,
331
+ uniforms: a,
332
+ dispose(h) {
333
+ h.deleteProgram(l);
334
+ }
335
+ };
336
+ }
337
+ function Dt(s, t, e, n, i, r) {
338
+ const o = G(s, s.VERTEX_SHADER, e), l = G(s, s.FRAGMENT_SHADER, n), a = mt(s, o, l), h = pt(s, a, i), c = {
339
+ texture: null,
340
+ unit: r.textureUnit,
341
+ attachment: s.COLOR_ATTACHMENT0
342
+ }, f = {
329
343
  name: t,
330
344
  program: a,
331
- uniforms: l,
345
+ uniforms: h,
346
+ fbo: null,
347
+ outputs: [c],
348
+ width: 0,
349
+ height: 0,
350
+ resize(u, x, p) {
351
+ f.fbo && u.deleteFramebuffer(f.fbo), c.texture && u.deleteTexture(c.texture), f.width = x, f.height = p, c.texture = u.createTexture(), u.activeTexture(u.TEXTURE0 + c.unit), u.bindTexture(u.TEXTURE_2D, c.texture), u.texParameteri(u.TEXTURE_2D, u.TEXTURE_MIN_FILTER, u.LINEAR), u.texParameteri(u.TEXTURE_2D, u.TEXTURE_MAG_FILTER, u.LINEAR), u.texParameteri(u.TEXTURE_2D, u.TEXTURE_WRAP_S, u.CLAMP_TO_EDGE), u.texParameteri(u.TEXTURE_2D, u.TEXTURE_WRAP_T, u.CLAMP_TO_EDGE), u.texImage2D(
352
+ u.TEXTURE_2D,
353
+ 0,
354
+ r.internalFormat,
355
+ x,
356
+ p,
357
+ 0,
358
+ r.format,
359
+ r.type,
360
+ null
361
+ ), f.fbo = u.createFramebuffer(), u.bindFramebuffer(u.FRAMEBUFFER, f.fbo), u.framebufferTexture2D(
362
+ u.FRAMEBUFFER,
363
+ u.COLOR_ATTACHMENT0,
364
+ u.TEXTURE_2D,
365
+ c.texture,
366
+ 0
367
+ ), u.bindFramebuffer(u.FRAMEBUFFER, null);
368
+ },
332
369
  dispose(u) {
333
- u.deleteProgram(a);
370
+ f.fbo && (u.deleteFramebuffer(f.fbo), f.fbo = null), c.texture && (u.deleteTexture(c.texture), c.texture = null), u.deleteProgram(a);
334
371
  }
335
372
  };
373
+ return r.width > 0 && r.height > 0 && f.resize(s, r.width, r.height), f;
336
374
  }
337
- const fe = {
375
+ const he = {
338
376
  high: {
339
377
  dprCap: 2,
340
378
  depthMaxDim: 512,
@@ -344,8 +382,8 @@ const fe = {
344
382
  },
345
383
  medium: {
346
384
  dprCap: 1.5,
347
- depthMaxDim: 512,
348
- pomSteps: 16,
385
+ depthMaxDim: 384,
386
+ pomSteps: 12,
349
387
  bilateralRadius: 2,
350
388
  jfaDivisor: 2
351
389
  },
@@ -357,22 +395,22 @@ const fe = {
357
395
  jfaDivisor: 4
358
396
  }
359
397
  };
360
- function de(o) {
398
+ function fe(s) {
361
399
  let t = "unknown";
362
- const e = o.getExtension("WEBGL_debug_renderer_info");
363
- e && (t = o.getParameter(e.UNMASKED_RENDERER_WEBGL) || "unknown");
364
- const n = o.getParameter(o.MAX_TEXTURE_SIZE), i = typeof navigator < "u" && navigator.hardwareConcurrency || 0, r = typeof navigator < "u" && navigator.deviceMemory || 0, s = typeof window < "u" && window.devicePixelRatio || 1, a = typeof screen < "u" ? (screen.width || 0) * (screen.height || 0) : 0, l = typeof navigator < "u" && ("ontouchstart" in window || navigator.maxTouchPoints > 0), u = a > 0 && a < 1920 * 1080;
400
+ const e = s.getExtension("WEBGL_debug_renderer_info");
401
+ e && (t = s.getParameter(e.UNMASKED_RENDERER_WEBGL) || "unknown");
402
+ const n = s.getParameter(s.MAX_TEXTURE_SIZE), i = typeof navigator < "u" && navigator.hardwareConcurrency || 0, r = typeof navigator < "u" && navigator.deviceMemory || 0, o = typeof window < "u" && window.devicePixelRatio || 1, l = typeof screen < "u" ? (screen.width || 0) * (screen.height || 0) : 0, a = typeof navigator < "u" && ("ontouchstart" in window || navigator.maxTouchPoints > 0), h = l > 0 && l < 1920 * 1080;
365
403
  return {
366
404
  gpuRenderer: t,
367
405
  maxTextureSize: n,
368
406
  hardwareConcurrency: i,
369
407
  deviceMemory: r,
370
- devicePixelRatio: s,
371
- screenPixels: a,
372
- isMobile: l && u
408
+ devicePixelRatio: o,
409
+ screenPixels: l,
410
+ isMobile: a && h
373
411
  };
374
412
  }
375
- const me = [
413
+ const de = [
376
414
  "mali-4",
377
415
  "mali-t",
378
416
  "adreno 3",
@@ -385,7 +423,7 @@ const me = [
385
423
  "llvmpipe",
386
424
  "swiftshader",
387
425
  "software"
388
- ], pe = [
426
+ ], me = [
389
427
  "nvidia",
390
428
  "geforce",
391
429
  "radeon rx",
@@ -397,16 +435,16 @@ const me = [
397
435
  "mali-g7",
398
436
  "mali-g6"
399
437
  ];
400
- function ge(o) {
438
+ function pe(s) {
401
439
  let t = 0;
402
- const e = o.gpuRenderer.toLowerCase(), n = me.some((r) => e.includes(r)), i = pe.some((r) => e.includes(r));
403
- return n && (t -= 30), i && (t += 20), o.maxTextureSize >= 16384 ? t += 10 : o.maxTextureSize >= 8192 ? t += 5 : o.maxTextureSize <= 4096 && (t -= 15), o.hardwareConcurrency >= 8 ? t += 5 : o.hardwareConcurrency >= 4 ? t += 0 : o.hardwareConcurrency > 0 && o.hardwareConcurrency < 4 && (t -= 10), o.deviceMemory >= 8 ? t += 5 : o.deviceMemory >= 4 ? t += 0 : o.deviceMemory > 0 && o.deviceMemory < 4 && (t -= 15), o.isMobile && (t -= 10), t >= 0 ? "high" : t >= -25 ? "medium" : "low";
440
+ const e = s.gpuRenderer.toLowerCase(), n = de.some((r) => e.includes(r)), i = me.some((r) => e.includes(r));
441
+ return n && (t -= 30), i && (t += 20), s.maxTextureSize >= 16384 ? t += 10 : s.maxTextureSize >= 8192 ? t += 5 : s.maxTextureSize <= 4096 && (t -= 15), s.hardwareConcurrency >= 8 ? t += 5 : s.hardwareConcurrency >= 4 ? t += 0 : s.hardwareConcurrency > 0 && s.hardwareConcurrency < 4 && (t -= 10), s.deviceMemory >= 8 ? t += 5 : s.deviceMemory >= 4 ? t += 0 : s.deviceMemory > 0 && s.deviceMemory < 4 && (t -= 15), s.isMobile && (t -= 10), t >= 0 ? "high" : t >= -25 ? "medium" : "low";
404
442
  }
405
- function Xt(o, t) {
406
- const e = t && t !== "auto" ? t : ge(de(o));
407
- return { tier: e, ...fe[e] };
443
+ function Nt(s, t) {
444
+ const e = t && t !== "auto" ? t : pe(fe(s));
445
+ return { tier: e, ...he[e] };
408
446
  }
409
- class pt {
447
+ class gt {
410
448
  static RESIZE_DEBOUNCE_MS = 100;
411
449
  // ---- Canvas + container ----
412
450
  canvas;
@@ -449,7 +487,7 @@ class pt {
449
487
  /** Adaptive quality parameters. Set by subclass constructor after GL init. */
450
488
  qualityParams;
451
489
  constructor(t) {
452
- this.container = t, this.canvas = document.createElement("canvas"), this.container.appendChild(this.canvas), this.canvas.addEventListener("webglcontextlost", this._handleContextLost), this.canvas.addEventListener("webglcontextrestored", this._handleContextRestored);
490
+ this.container = t, this.canvas = document.createElement("canvas"), this.canvas.style.display = "block", this.canvas.style.width = "100%", this.canvas.style.height = "100%", this.container.appendChild(this.canvas), this.canvas.addEventListener("webglcontextlost", this._handleContextLost), this.canvas.addEventListener("webglcontextrestored", this._handleContextRestored);
453
491
  }
454
492
  /** The underlying canvas element. */
455
493
  get canvasElement() {
@@ -531,7 +569,7 @@ class pt {
531
569
  scheduleResizeRecalculate = () => {
532
570
  this.resizeTimer !== null && window.clearTimeout(this.resizeTimer), this.resizeTimer = window.setTimeout(() => {
533
571
  this.resizeTimer = null, this.recalculateViewportLayout();
534
- }, pt.RESIZE_DEBOUNCE_MS);
572
+ }, gt.RESIZE_DEBOUNCE_MS);
535
573
  };
536
574
  /** Read the container's pixel dimensions, with a minimum of 1x1. */
537
575
  getViewportSize() {
@@ -549,8 +587,8 @@ class pt {
549
587
  this.sourceDepthWidth = t, this.sourceDepthHeight = e;
550
588
  let i = t, r = e;
551
589
  if (i > n || r > n) {
552
- const s = n / Math.max(i, r);
553
- i = Math.max(1, Math.round(i * s)), r = Math.max(1, Math.round(r * s));
590
+ const o = n / Math.max(i, r);
591
+ i = Math.max(1, Math.round(i * o)), r = Math.max(1, Math.round(r * o));
554
592
  }
555
593
  this.depthWidth = i, this.depthHeight = r, i !== t || r !== e ? this.depthSubsampleBuffer = new Uint8Array(i * r) : this.depthSubsampleBuffer = null;
556
594
  }
@@ -563,11 +601,11 @@ class pt {
563
601
  subsampleDepth(t) {
564
602
  if (!this.depthSubsampleBuffer) return t;
565
603
  const e = this.depthSubsampleBuffer, n = this.sourceDepthWidth, i = this.depthWidth, r = this.depthHeight;
566
- for (let s = 0; s < r; s++) {
567
- const l = Math.min(Math.round(s * n / i), this.sourceDepthHeight - 1) * n, u = s * i;
568
- for (let h = 0; h < i; h++) {
569
- const f = Math.min(Math.round(h * n / i), n - 1);
570
- e[u + h] = t[l + f];
604
+ for (let o = 0; o < r; o++) {
605
+ const a = Math.min(Math.round(o * this.sourceDepthHeight / r), this.sourceDepthHeight - 1) * n, h = o * i;
606
+ for (let c = 0; c < i; c++) {
607
+ const f = Math.min(Math.round(c * n / i), n - 1);
608
+ e[h + c] = t[a + f];
571
609
  }
572
610
  }
573
611
  return e;
@@ -583,14 +621,14 @@ class pt {
583
621
  * Updates `this.uvOffset` and `this.uvScale`.
584
622
  */
585
623
  computeCoverFitUV(t, e) {
586
- const { width: n, height: i } = this.getViewportSize(), r = n / i, s = t + e;
587
- let a = 1, l = 1;
588
- r > this.videoAspect ? l = this.videoAspect / r : a = r / this.videoAspect;
589
- const u = 1 + s * 2;
590
- a /= u, l /= u, this.uvOffset = [(1 - a) / 2, (1 - l) / 2], this.uvScale = [a, l], this.isCameraSource && (this.uvOffset[0] += this.uvScale[0], this.uvScale[0] = -this.uvScale[0]);
624
+ const { width: n, height: i } = this.getViewportSize(), r = n / i, o = t + e;
625
+ let l = 1, a = 1;
626
+ r > this.videoAspect ? a = this.videoAspect / r : l = r / this.videoAspect;
627
+ const h = 1 + o * 2;
628
+ l /= h, a /= h, this.uvOffset = [(1 - l) / 2, (1 - a) / 2], this.uvScale = [l, a], this.isCameraSource && (this.uvOffset[0] += this.uvScale[0], this.uvScale[0] = -this.uvScale[0]);
591
629
  }
592
630
  }
593
- const ve = `#version 300 es
631
+ const ge = `#version 300 es
594
632
  in vec2 aPosition;
595
633
 
596
634
  // UV coordinates for cover-fit + overscan.
@@ -611,7 +649,7 @@ void main() {
611
649
  vScreenUv = baseUv;
612
650
  gl_Position = vec4(aPosition, 0.0, 1.0);
613
651
  }
614
- `, xe = `#version 300 es
652
+ `, bt = `#version 300 es
615
653
  in vec2 aPosition;
616
654
  out vec2 vUv;
617
655
 
@@ -619,7 +657,7 @@ void main() {
619
657
  vUv = aPosition * 0.5 + 0.5;
620
658
  gl_Position = vec4(aPosition, 0.0, 1.0);
621
659
  }
622
- `, Te = `#version 300 es
660
+ `, ve = `#version 300 es
623
661
  precision highp float;
624
662
 
625
663
  // BILATERAL_RADIUS is injected as a #define at compile time.
@@ -657,7 +695,7 @@ void main() {
657
695
 
658
696
  fragColor = vec4(totalDepth / totalWeight, 0.0, 0.0, 1.0);
659
697
  }
660
- `, Ee = `#version 300 es
698
+ `, xe = `#version 300 es
661
699
  precision highp float;
662
700
 
663
701
  // ---- Uniforms ----
@@ -773,6 +811,9 @@ uniform float uGlowRadius;
773
811
  /** Glow edge softness — controls blending of the glow mask. */
774
812
  uniform float uGlowSoftness;
775
813
 
814
+ /** Pre-blurred glow mask from separable blur passes (R channel). */
815
+ uniform sampler2D uGlowBlurred;
816
+
776
817
  /**
777
818
  * Color-shift curve LUT — 256×1 R8 texture.
778
819
  * Maps depth → color-shift intensity [0,1].
@@ -921,6 +962,8 @@ vec2 pomDisplace(vec2 uv) {
921
962
  return mix(uv, hitUV, fade);
922
963
  }
923
964
 
965
+ if (abs(currentLayerDepth - depthAtUV) < 0.001) break;
966
+
924
967
  currentUV += deltaUV;
925
968
  currentLayerDepth += layerDepth;
926
969
  }
@@ -994,27 +1037,12 @@ void main() {
994
1037
  }
995
1038
 
996
1039
  // ---- Glow pass ----
997
- // Samples a glow curve LUT to determine per-pixel glow intensity,
998
- // then spreads the glow to neighboring pixels via a small blur kernel.
999
- // The glow is additive: it brightens pixels without replacing color.
1040
+ // Reads the pre-blurred glow mask (computed via separable blur at RVFC rate)
1041
+ // and the direct glow curve. Blending via softness controls sharp vs spread.
1000
1042
  if (uGlowEnabled) {
1001
1043
  float glowDepth = texture(uDepth, displaced).r;
1002
1044
  float glowMask = texture(uGlowCurve, vec2(glowDepth, 0.5)).r;
1003
-
1004
- // Spread glow to neighbors for a soft halo effect
1005
- float spreadMask = 0.0;
1006
- float spreadSamples = 0.0;
1007
- for (int x = -3; x <= 3; x++) {
1008
- for (int y = -3; y <= 3; y++) {
1009
- vec2 sampleOffset = vec2(float(x), float(y)) * uImageTexelSize * uGlowRadius * 100.0;
1010
- float d = texture(uDepth, displaced + sampleOffset).r;
1011
- spreadMask += texture(uGlowCurve, vec2(d, 0.5)).r;
1012
- spreadSamples += 1.0;
1013
- }
1014
- }
1015
- spreadMask /= spreadSamples;
1016
-
1017
- // Combine direct glow mask with spread, apply softness
1045
+ float spreadMask = texture(uGlowBlurred, displaced).r;
1018
1046
  float finalGlow = mix(spreadMask * 0.5, glowMask, uGlowSoftness);
1019
1047
  color.rgb += uGlowColor * finalGlow;
1020
1048
  }
@@ -1054,6 +1082,57 @@ void main() {
1054
1082
 
1055
1083
  fragColor = color;
1056
1084
  }
1085
+ `, Ft = `#version 300 es
1086
+ precision highp float;
1087
+
1088
+ // Separable glow blur — 7-tap box filter.
1089
+ // Compile with #define PASS_HORIZONTAL for the H pass;
1090
+ // without it, runs as the vertical pass reading from the H result.
1091
+
1092
+ in vec2 vUv;
1093
+ out vec4 fragColor;
1094
+
1095
+ #ifdef PASS_HORIZONTAL
1096
+ /** Single-channel depth map (filtered, unit 1). */
1097
+ uniform sampler2D uDepth;
1098
+
1099
+ /** Glow curve LUT — maps depth → glow intensity (unit 5). */
1100
+ uniform sampler2D uGlowCurve;
1101
+ #else
1102
+ /** Horizontal pass output (unit 7). */
1103
+ uniform sampler2D uHorizResult;
1104
+ #endif
1105
+
1106
+ /** Texel size of the depth texture (1.0 / depthDimension). */
1107
+ uniform vec2 uTexelSize;
1108
+
1109
+ /** Glow spread radius multiplier. */
1110
+ uniform float uGlowRadius;
1111
+
1112
+ /** Blur direction: (1,0) for horizontal, (0,1) for vertical. */
1113
+ uniform vec2 uBlurDir;
1114
+
1115
+ void main() {
1116
+ float accum = 0.0;
1117
+ vec2 step = uBlurDir * uTexelSize * uGlowRadius * 100.0;
1118
+
1119
+ for (int i = -3; i <= 3; i++) {
1120
+ vec2 sampleUV = vUv + float(i) * step;
1121
+ sampleUV = clamp(sampleUV, vec2(0.0), vec2(1.0));
1122
+
1123
+ #ifdef PASS_HORIZONTAL
1124
+ // Sample depth → look up glow curve
1125
+ float d = texture(uDepth, sampleUV).r;
1126
+ accum += texture(uGlowCurve, vec2(d, 0.5)).r;
1127
+ #else
1128
+ // Sample the horizontal blur result
1129
+ accum += texture(uHorizResult, sampleUV).r;
1130
+ #endif
1131
+ }
1132
+
1133
+ accum /= 7.0;
1134
+ fragColor = vec4(accum, 0.0, 0.0, 1.0);
1135
+ }
1057
1136
  `, B = {
1058
1137
  contrastLow: 0.05,
1059
1138
  contrastHigh: 0.95,
@@ -1068,58 +1147,58 @@ void main() {
1068
1147
  tiltHalfTanFov: Math.tan(50 * Math.PI / 360),
1069
1148
  tiltTransitionWidth: 0.3 * 4.5,
1070
1149
  tiltPeakIntensity: 0.8
1071
- }, be = ["uRawDepth", "uTexelSize", "uSpatialSigma2"], ye = {
1150
+ }, Te = ["uRawDepth", "uTexelSize", "uSpatialSigma2"], Ee = {
1072
1151
  2: 2.25,
1073
1152
  // 1.5²
1074
1153
  1: 0.5625
1075
1154
  // 0.75²
1076
1155
  };
1077
- function Se(o, t) {
1078
- const e = Te.replace(
1156
+ function be(s, t) {
1157
+ const e = ve.replace(
1079
1158
  "#version 300 es",
1080
1159
  `#version 300 es
1081
1160
  #define BILATERAL_RADIUS ${t}`
1082
- ), n = Q(o, o.VERTEX_SHADER, xe), i = Q(o, o.FRAGMENT_SHADER, e), r = wt(o, n, i), s = Rt(o, r, be), a = ye[t] ?? 2.25;
1083
- let l = null;
1084
- const u = {
1161
+ ), n = G(s, s.VERTEX_SHADER, bt), i = G(s, s.FRAGMENT_SHADER, e), r = mt(s, n, i), o = pt(s, r, Te), l = Ee[t] ?? 2.25;
1162
+ let a = null;
1163
+ const h = {
1085
1164
  name: "bilateral-filter",
1086
1165
  program: r,
1087
- uniforms: s,
1166
+ uniforms: o,
1088
1167
  fbo: null,
1089
1168
  outputs: [],
1090
1169
  width: 0,
1091
1170
  height: 0,
1092
- resize(h, f, c) {
1171
+ resize(c, f, u) {
1093
1172
  },
1094
- initFBO(h, f, c, E) {
1095
- l && h.deleteFramebuffer(l), u.width = c, u.height = E, l = h.createFramebuffer(), u.fbo = l, h.bindFramebuffer(h.FRAMEBUFFER, l), h.framebufferTexture2D(
1096
- h.FRAMEBUFFER,
1097
- h.COLOR_ATTACHMENT0,
1098
- h.TEXTURE_2D,
1173
+ initFBO(c, f, u, x) {
1174
+ a && c.deleteFramebuffer(a), h.width = u, h.height = x, a = c.createFramebuffer(), h.fbo = a, c.bindFramebuffer(c.FRAMEBUFFER, a), c.framebufferTexture2D(
1175
+ c.FRAMEBUFFER,
1176
+ c.COLOR_ATTACHMENT0,
1177
+ c.TEXTURE_2D,
1099
1178
  f,
1100
1179
  0
1101
- ), h.bindFramebuffer(h.FRAMEBUFFER, null), h.useProgram(r), h.uniform1i(s.uRawDepth, 2), h.uniform2f(s.uTexelSize, 1 / c, 1 / E), h.uniform1f(s.uSpatialSigma2, a);
1180
+ ), c.bindFramebuffer(c.FRAMEBUFFER, null), c.useProgram(r), c.uniform1i(o.uRawDepth, 2), c.uniform2f(o.uTexelSize, 1 / u, 1 / x), c.uniform1f(o.uSpatialSigma2, l);
1102
1181
  },
1103
- execute(h, f, c, E, v, p, P, x) {
1104
- l && (h.activeTexture(h.TEXTURE2), h.bindTexture(h.TEXTURE_2D, c), h.texSubImage2D(
1105
- h.TEXTURE_2D,
1182
+ execute(c, f, u, x, p, d, y, E) {
1183
+ a && (c.activeTexture(c.TEXTURE2), c.bindTexture(c.TEXTURE_2D, u), c.texSubImage2D(
1184
+ c.TEXTURE_2D,
1106
1185
  0,
1107
1186
  0,
1108
1187
  0,
1109
- v,
1110
1188
  p,
1111
- h.RED,
1112
- h.UNSIGNED_BYTE,
1113
- E
1114
- ), h.bindFramebuffer(h.FRAMEBUFFER, l), h.viewport(0, 0, v, p), h.useProgram(r), h.bindVertexArray(f), h.drawArrays(h.TRIANGLE_STRIP, 0, 4), h.bindFramebuffer(h.FRAMEBUFFER, null), h.viewport(0, 0, P, x));
1189
+ d,
1190
+ c.RED,
1191
+ c.UNSIGNED_BYTE,
1192
+ x
1193
+ ), c.bindFramebuffer(c.FRAMEBUFFER, a), c.viewport(0, 0, p, d), c.useProgram(r), c.bindVertexArray(f), c.drawArrays(c.TRIANGLE_STRIP, 0, 4), c.bindFramebuffer(c.FRAMEBUFFER, null), c.viewport(0, 0, y, E));
1115
1194
  },
1116
- dispose(h) {
1117
- l && (h.deleteFramebuffer(l), l = null, u.fbo = null), h.deleteProgram(r);
1195
+ dispose(c) {
1196
+ a && (c.deleteFramebuffer(a), a = null, h.fbo = null), c.deleteProgram(r);
1118
1197
  }
1119
1198
  };
1120
- return u;
1199
+ return h;
1121
1200
  }
1122
- const Ae = [
1201
+ const Se = [
1123
1202
  "uImage",
1124
1203
  "uDepth",
1125
1204
  "uOffset",
@@ -1144,6 +1223,7 @@ const Ae = [
1144
1223
  "uGlowColor",
1145
1224
  "uGlowRadius",
1146
1225
  "uGlowSoftness",
1226
+ "uGlowBlurred",
1147
1227
  "uColorShiftCurve",
1148
1228
  "uColorShiftEnabled",
1149
1229
  "uColorShiftHue",
@@ -1157,29 +1237,29 @@ const Ae = [
1157
1237
  "uTiltPeakIntensity",
1158
1238
  "uTiltPlaneNormal",
1159
1239
  "uTiltPlaneD"
1160
- ], we = 64;
1161
- function Re(o) {
1162
- const t = Ee.replace(
1240
+ ], ye = 64;
1241
+ function we(s) {
1242
+ const t = xe.replace(
1163
1243
  "#version 300 es",
1164
1244
  `#version 300 es
1165
- #define MAX_POM_STEPS ${we}`
1166
- ), e = Q(o, o.VERTEX_SHADER, ve), n = Q(o, o.FRAGMENT_SHADER, t), i = wt(o, e, n), r = Rt(o, i, Ae);
1245
+ #define MAX_POM_STEPS ${ye}`
1246
+ ), e = G(s, s.VERTEX_SHADER, ge), n = G(s, s.FRAGMENT_SHADER, t), i = mt(s, e, n), r = pt(s, i, Se);
1167
1247
  return {
1168
1248
  name: "depth-effect",
1169
1249
  program: i,
1170
1250
  uniforms: r,
1171
- setStaticUniforms(s, a, l, u) {
1172
- s.useProgram(i), s.uniform1i(r.uImage, 0), s.uniform1i(r.uDepth, 1), s.uniform1f(r.uStrength, a.parallaxStrength), s.uniform1i(r.uPomEnabled, a.pomEnabled ? 1 : 0), s.uniform1i(r.uPomSteps, a.pomSteps), s.uniform1f(r.uContrastLow, a.contrastLow), s.uniform1f(r.uContrastHigh, a.contrastHigh), s.uniform1f(r.uVerticalReduction, a.verticalReduction), s.uniform1f(r.uDofStart, a.dofStart), s.uniform1f(r.uDofStrength, a.dofStrength), s.uniform2f(r.uImageTexelSize, 1 / l, 1 / u), s.uniform1i(r.uDisplacementCurve, 3), s.uniform1i(r.uBlurCurve, 4), s.uniform1i(r.uCurvesEnabled, 0), s.uniform1f(r.uBlurRadius, a.blurRadius), s.uniform1f(r.uFocalBandOffset, 0), s.uniform1i(r.uGlowCurve, 5), s.uniform1i(r.uGlowEnabled, 0), s.uniform3f(r.uGlowColor, a.glowColor[0], a.glowColor[1], a.glowColor[2]), s.uniform1f(r.uGlowRadius, a.glowRadius), s.uniform1f(r.uGlowSoftness, a.glowSoftness), s.uniform1i(r.uColorShiftCurve, 6), s.uniform1i(r.uColorShiftEnabled, 0), s.uniform1f(r.uColorShiftHue, 0), s.uniform1f(r.uColorShiftSaturation, 1), s.uniform1f(r.uColorShiftBrightness, 1), s.uniform1f(r.uColorShiftTintStrength, 0), s.uniform3f(r.uColorShiftTintColor, 0.7, 0.8, 0.9), s.uniform1i(r.uTiltEnabled, a.tiltEnabled ? 1 : 0), s.uniform1f(r.uTiltHalfTanFov, a.tiltHalfTanFov), s.uniform1f(r.uTiltTransitionWidth, a.tiltTransitionWidth), s.uniform1f(r.uTiltPeakIntensity, a.tiltPeakIntensity), s.uniform3f(r.uTiltPlaneNormal, 0, 0, 1), s.uniform1f(r.uTiltPlaneD, 2.75);
1251
+ setStaticUniforms(o, l, a, h) {
1252
+ o.useProgram(i), o.uniform1i(r.uImage, 0), o.uniform1i(r.uDepth, 1), o.uniform1f(r.uStrength, l.parallaxStrength), o.uniform1i(r.uPomEnabled, l.pomEnabled ? 1 : 0), o.uniform1i(r.uPomSteps, l.pomSteps), o.uniform1f(r.uContrastLow, l.contrastLow), o.uniform1f(r.uContrastHigh, l.contrastHigh), o.uniform1f(r.uVerticalReduction, l.verticalReduction), o.uniform1f(r.uDofStart, l.dofStart), o.uniform1f(r.uDofStrength, l.dofStrength), o.uniform2f(r.uImageTexelSize, 1 / a, 1 / h), o.uniform1i(r.uDisplacementCurve, 3), o.uniform1i(r.uBlurCurve, 4), o.uniform1i(r.uCurvesEnabled, 0), o.uniform1f(r.uBlurRadius, l.blurRadius), o.uniform1f(r.uFocalBandOffset, 0), o.uniform1i(r.uGlowCurve, 5), o.uniform1i(r.uGlowEnabled, 0), o.uniform3f(r.uGlowColor, l.glowColor[0], l.glowColor[1], l.glowColor[2]), o.uniform1f(r.uGlowRadius, l.glowRadius), o.uniform1f(r.uGlowSoftness, l.glowSoftness), o.uniform1i(r.uGlowBlurred, 8), o.uniform1i(r.uColorShiftCurve, 6), o.uniform1i(r.uColorShiftEnabled, 0), o.uniform1f(r.uColorShiftHue, 0), o.uniform1f(r.uColorShiftSaturation, 1), o.uniform1f(r.uColorShiftBrightness, 1), o.uniform1f(r.uColorShiftTintStrength, 0), o.uniform3f(r.uColorShiftTintColor, 0.7, 0.8, 0.9), o.uniform1i(r.uTiltEnabled, l.tiltEnabled ? 1 : 0), o.uniform1f(r.uTiltHalfTanFov, l.tiltHalfTanFov), o.uniform1f(r.uTiltTransitionWidth, l.tiltTransitionWidth), o.uniform1f(r.uTiltPeakIntensity, l.tiltPeakIntensity), o.uniform3f(r.uTiltPlaneNormal, 0, 0, 1), o.uniform1f(r.uTiltPlaneD, 2.75);
1173
1253
  },
1174
- updateUvTransform(s, a, l) {
1175
- s.useProgram(i), s.uniform2f(r.uUvOffset, a[0], a[1]), s.uniform2f(r.uUvScale, l[0], l[1]);
1254
+ updateUvTransform(o, l, a) {
1255
+ o.useProgram(i), o.uniform2f(r.uUvOffset, l[0], l[1]), o.uniform2f(r.uUvScale, a[0], a[1]);
1176
1256
  },
1177
- dispose(s) {
1178
- s.deleteProgram(i);
1257
+ dispose(o) {
1258
+ o.deleteProgram(i);
1179
1259
  }
1180
1260
  };
1181
1261
  }
1182
- class De extends pt {
1262
+ class Re extends gt {
1183
1263
  // ---- Shared GPU resources ----
1184
1264
  gl = null;
1185
1265
  quadVao = null;
@@ -1195,6 +1275,12 @@ class De extends pt {
1195
1275
  blurLutSlot;
1196
1276
  glowLutSlot;
1197
1277
  colorShiftLutSlot;
1278
+ glowBlurHorizSlot;
1279
+ glowBlurResultSlot;
1280
+ // ---- Glow blur passes ----
1281
+ glowBlurHPass = null;
1282
+ glowBlurVPass = null;
1283
+ glowEnabled = !1;
1198
1284
  /** Resolved config with all optional shader params filled from defaults. */
1199
1285
  config;
1200
1286
  /**
@@ -1206,7 +1292,7 @@ class De extends pt {
1206
1292
  * Optional shader parameters are merged with calibrated defaults.
1207
1293
  */
1208
1294
  constructor(t, e) {
1209
- super(t), this.videoSlot = this.textures.register("video"), this.filteredDepthSlot = this.textures.register("filteredDepth"), this.rawDepthSlot = this.textures.register("rawDepth"), this.displacementLutSlot = this.textures.register("displacementLut"), this.blurLutSlot = this.textures.register("blurLut"), this.glowLutSlot = this.textures.register("glowLut"), this.colorShiftLutSlot = this.textures.register("colorShiftLut"), this.config = {
1295
+ super(t), this.videoSlot = this.textures.register("video"), this.filteredDepthSlot = this.textures.register("filteredDepth"), this.rawDepthSlot = this.textures.register("rawDepth"), this.displacementLutSlot = this.textures.register("displacementLut"), this.blurLutSlot = this.textures.register("blurLut"), this.glowLutSlot = this.textures.register("glowLut"), this.colorShiftLutSlot = this.textures.register("colorShiftLut"), this.glowBlurHorizSlot = this.textures.register("glowBlurHoriz"), this.glowBlurResultSlot = this.textures.register("glowBlurResult"), this.config = {
1210
1296
  parallaxStrength: e.parallaxStrength,
1211
1297
  pomEnabled: e.pomEnabled,
1212
1298
  pomSteps: e.pomSteps,
@@ -1232,7 +1318,7 @@ class De extends pt {
1232
1318
  powerPreference: "high-performance"
1233
1319
  });
1234
1320
  if (!n) throw new Error("WebGL 2 is not supported.");
1235
- this.gl = n, this.qualityParams = Xt(n, e.quality), "drawingBufferColorSpace" in n && (n.drawingBufferColorSpace = "srgb"), n.clearColor(0, 0, 0, 1), n.pixelStorei(n.UNPACK_FLIP_Y_WEBGL, !0), this.initGPUResources(), this.setupResizeHandling();
1321
+ this.gl = n, this.qualityParams = Nt(n, e.quality), "drawingBufferColorSpace" in n && (n.drawingBufferColorSpace = "srgb"), n.clearColor(0, 0, 0, 1), n.pixelStorei(n.UNPACK_FLIP_Y_WEBGL, !0), this.initGPUResources(), this.setupResizeHandling();
1236
1322
  }
1237
1323
  /**
1238
1324
  * Set up the scene: create video texture, depth textures + FBO, and
@@ -1247,7 +1333,13 @@ class De extends pt {
1247
1333
  */
1248
1334
  initialize(t, e, n) {
1249
1335
  const i = this.gl;
1250
- i && (this.disposeTextures(), this.isCameraSource = t.type === "camera", this.videoAspect = t.width / t.height, this.clampDepthDimensions(e, n, this.qualityParams.depthMaxDim), this.videoSlot.texture = i.createTexture(), i.activeTexture(i.TEXTURE0 + this.videoSlot.unit), i.bindTexture(i.TEXTURE_2D, this.videoSlot.texture), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MIN_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MAG_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_S, i.CLAMP_TO_EDGE), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_T, i.CLAMP_TO_EDGE), this.rawDepthSlot.texture = i.createTexture(), i.activeTexture(i.TEXTURE0 + this.rawDepthSlot.unit), i.bindTexture(i.TEXTURE_2D, this.rawDepthSlot.texture), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MIN_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MAG_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_S, i.CLAMP_TO_EDGE), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_T, i.CLAMP_TO_EDGE), i.texStorage2D(i.TEXTURE_2D, 1, i.R8, e, n), this.filteredDepthSlot.texture = i.createTexture(), i.activeTexture(i.TEXTURE0 + this.filteredDepthSlot.unit), i.bindTexture(i.TEXTURE_2D, this.filteredDepthSlot.texture), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MIN_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MAG_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_S, i.CLAMP_TO_EDGE), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_T, i.CLAMP_TO_EDGE), i.texStorage2D(i.TEXTURE_2D, 1, i.R8, e, n), this.bilateralPass && this.filteredDepthSlot.texture && this.bilateralPass.initFBO(i, this.filteredDepthSlot.texture, e, n), this.effectPass && this.effectPass.setStaticUniforms(i, this.config, t.width, t.height), this.recalculateViewportLayout());
1336
+ if (i) {
1337
+ if (this.disposeTextures(), this.isCameraSource = t.type === "camera", this.videoAspect = t.width / t.height, this.clampDepthDimensions(e, n, this.qualityParams.depthMaxDim), this.videoSlot.texture = i.createTexture(), i.activeTexture(i.TEXTURE0 + this.videoSlot.unit), i.bindTexture(i.TEXTURE_2D, this.videoSlot.texture), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MIN_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MAG_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_S, i.CLAMP_TO_EDGE), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_T, i.CLAMP_TO_EDGE), this.rawDepthSlot.texture = i.createTexture(), i.activeTexture(i.TEXTURE0 + this.rawDepthSlot.unit), i.bindTexture(i.TEXTURE_2D, this.rawDepthSlot.texture), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MIN_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MAG_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_S, i.CLAMP_TO_EDGE), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_T, i.CLAMP_TO_EDGE), i.texStorage2D(i.TEXTURE_2D, 1, i.R8, e, n), this.filteredDepthSlot.texture = i.createTexture(), i.activeTexture(i.TEXTURE0 + this.filteredDepthSlot.unit), i.bindTexture(i.TEXTURE_2D, this.filteredDepthSlot.texture), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MIN_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MAG_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_S, i.CLAMP_TO_EDGE), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_T, i.CLAMP_TO_EDGE), i.texStorage2D(i.TEXTURE_2D, 1, i.R8, e, n), this.bilateralPass && this.filteredDepthSlot.texture && this.bilateralPass.initFBO(i, this.filteredDepthSlot.texture, e, n), this.glowBlurHPass && this.glowBlurVPass) {
1338
+ const r = this.depthWidth, o = this.depthHeight;
1339
+ this.glowBlurHPass.resize(i, r, o), this.glowBlurVPass.resize(i, r, o), this.glowBlurHorizSlot.texture = this.glowBlurHPass.outputs[0].texture, this.glowBlurResultSlot.texture = this.glowBlurVPass.outputs[0].texture, i.useProgram(this.glowBlurHPass.program), i.uniform1i(this.glowBlurHPass.uniforms.uDepth, this.filteredDepthSlot.unit), i.uniform1i(this.glowBlurHPass.uniforms.uGlowCurve, this.glowLutSlot.unit), i.uniform2f(this.glowBlurHPass.uniforms.uBlurDir, 1, 0), i.uniform2f(this.glowBlurHPass.uniforms.uTexelSize, 1 / r, 1 / o), i.uniform1f(this.glowBlurHPass.uniforms.uGlowRadius, this.config.glowRadius), i.useProgram(this.glowBlurVPass.program), i.uniform1i(this.glowBlurVPass.uniforms.uHorizResult, this.glowBlurHorizSlot.unit), i.uniform2f(this.glowBlurVPass.uniforms.uBlurDir, 0, 1), i.uniform2f(this.glowBlurVPass.uniforms.uTexelSize, 1 / r, 1 / o), i.uniform1f(this.glowBlurVPass.uniforms.uGlowRadius, this.config.glowRadius);
1340
+ }
1341
+ this.effectPass && this.effectPass.setStaticUniforms(i, this.config, t.width, t.height), this.recalculateViewportLayout();
1342
+ }
1251
1343
  }
1252
1344
  /**
1253
1345
  * Update shader parameters at runtime without re-creating the renderer.
@@ -1262,29 +1354,31 @@ class De extends pt {
1262
1354
  if (!e || !this.effectPass) return;
1263
1355
  t.parallaxStrength !== void 0 && (this.config.parallaxStrength = t.parallaxStrength), t.pomEnabled !== void 0 && (this.config.pomEnabled = t.pomEnabled), t.pomSteps !== void 0 && (this.config.pomSteps = t.pomSteps), t.overscanPadding !== void 0 && (this.config.overscanPadding = t.overscanPadding), t.contrastLow !== void 0 && (this.config.contrastLow = t.contrastLow), t.contrastHigh !== void 0 && (this.config.contrastHigh = t.contrastHigh), t.verticalReduction !== void 0 && (this.config.verticalReduction = t.verticalReduction), t.dofStart !== void 0 && (this.config.dofStart = t.dofStart), t.dofStrength !== void 0 && (this.config.dofStrength = t.dofStrength), t.blurRadius !== void 0 && (this.config.blurRadius = t.blurRadius), t.glowColor !== void 0 && (this.config.glowColor = t.glowColor), t.glowRadius !== void 0 && (this.config.glowRadius = t.glowRadius), t.glowSoftness !== void 0 && (this.config.glowSoftness = t.glowSoftness), t.tiltEnabled !== void 0 && (this.config.tiltEnabled = t.tiltEnabled), t.tiltHalfTanFov !== void 0 && (this.config.tiltHalfTanFov = t.tiltHalfTanFov), t.tiltTransitionWidth !== void 0 && (this.config.tiltTransitionWidth = t.tiltTransitionWidth), t.tiltPeakIntensity !== void 0 && (this.config.tiltPeakIntensity = t.tiltPeakIntensity);
1264
1356
  const { uniforms: n, program: i } = this.effectPass;
1265
- e.useProgram(i), e.uniform1f(n.uStrength, this.config.parallaxStrength), e.uniform1i(n.uPomEnabled, this.config.pomEnabled ? 1 : 0), e.uniform1i(n.uPomSteps, this.config.pomSteps), e.uniform1f(n.uContrastLow, this.config.contrastLow), e.uniform1f(n.uContrastHigh, this.config.contrastHigh), e.uniform1f(n.uVerticalReduction, this.config.verticalReduction), e.uniform1f(n.uDofStart, this.config.dofStart), e.uniform1f(n.uDofStrength, this.config.dofStrength), e.uniform1f(n.uBlurRadius, this.config.blurRadius), e.uniform3f(n.uGlowColor, this.config.glowColor[0], this.config.glowColor[1], this.config.glowColor[2]), e.uniform1f(n.uGlowRadius, this.config.glowRadius), e.uniform1f(n.uGlowSoftness, this.config.glowSoftness), e.uniform1i(n.uTiltEnabled, this.config.tiltEnabled ? 1 : 0), e.uniform1f(n.uTiltHalfTanFov, this.config.tiltHalfTanFov), e.uniform1f(n.uTiltTransitionWidth, this.config.tiltTransitionWidth), e.uniform1f(n.uTiltPeakIntensity, this.config.tiltPeakIntensity), (t.parallaxStrength !== void 0 || t.overscanPadding !== void 0) && this.recalculateViewportLayout();
1357
+ e.useProgram(i), e.uniform1f(n.uStrength, this.config.parallaxStrength), e.uniform1i(n.uPomEnabled, this.config.pomEnabled ? 1 : 0), e.uniform1i(n.uPomSteps, this.config.pomSteps), e.uniform1f(n.uContrastLow, this.config.contrastLow), e.uniform1f(n.uContrastHigh, this.config.contrastHigh), e.uniform1f(n.uVerticalReduction, this.config.verticalReduction), e.uniform1f(n.uDofStart, this.config.dofStart), e.uniform1f(n.uDofStrength, this.config.dofStrength), e.uniform1f(n.uBlurRadius, this.config.blurRadius), e.uniform3f(n.uGlowColor, this.config.glowColor[0], this.config.glowColor[1], this.config.glowColor[2]), e.uniform1f(n.uGlowRadius, this.config.glowRadius), e.uniform1f(n.uGlowSoftness, this.config.glowSoftness), e.uniform1i(n.uTiltEnabled, this.config.tiltEnabled ? 1 : 0), e.uniform1f(n.uTiltHalfTanFov, this.config.tiltHalfTanFov), e.uniform1f(n.uTiltTransitionWidth, this.config.tiltTransitionWidth), e.uniform1f(n.uTiltPeakIntensity, this.config.tiltPeakIntensity), t.glowRadius !== void 0 && (this.glowBlurHPass && (e.useProgram(this.glowBlurHPass.program), e.uniform1f(this.glowBlurHPass.uniforms.uGlowRadius, this.config.glowRadius)), this.glowBlurVPass && (e.useProgram(this.glowBlurVPass.program), e.uniform1f(this.glowBlurVPass.uniforms.uGlowRadius, this.config.glowRadius)), this.refreshGlowBlur()), (t.parallaxStrength !== void 0 || t.overscanPadding !== void 0) && this.recalculateViewportLayout();
1266
1358
  }
1267
1359
  /**
1268
1360
  * Upload new curve LUT data to the GPU.
1269
1361
  * Call this whenever the curve editor changes.
1270
1362
  */
1271
1363
  updateCurveLUTs(t, e, n, i, r) {
1272
- const s = this.gl;
1273
- if (!s || !this.effectPass) return;
1274
- const a = !!(t || e), l = !!n, u = !!i;
1275
- if (t && this.uploadLUT(this.displacementLutSlot, t), e && this.uploadLUT(this.blurLutSlot, e), n && this.uploadLUT(this.glowLutSlot, n), i && this.uploadLUT(this.colorShiftLutSlot, i), s.useProgram(this.effectPass.program), s.uniform1i(
1364
+ const o = this.gl;
1365
+ if (!o || !this.effectPass) return;
1366
+ const l = !!(t || e), a = !!n, h = !!i;
1367
+ t && this.uploadLUT(this.displacementLutSlot, t), e && this.uploadLUT(this.blurLutSlot, e), n && this.uploadLUT(this.glowLutSlot, n), i && this.uploadLUT(this.colorShiftLutSlot, i), o.useProgram(this.effectPass.program), o.uniform1i(
1276
1368
  this.effectPass.uniforms.uCurvesEnabled,
1277
- a ? 1 : 0
1278
- ), s.uniform1i(
1279
- this.effectPass.uniforms.uGlowEnabled,
1280
1369
  l ? 1 : 0
1281
- ), s.uniform1i(
1370
+ ), o.uniform1i(
1371
+ this.effectPass.uniforms.uGlowEnabled,
1372
+ a ? 1 : 0
1373
+ ), o.uniform1i(
1282
1374
  this.effectPass.uniforms.uColorShiftEnabled,
1283
- u ? 1 : 0
1284
- ), u && r) {
1285
- const h = this.effectPass.uniforms;
1286
- s.uniform1f(h.uColorShiftHue, r.hueShift * (Math.PI / 180)), s.uniform1f(h.uColorShiftSaturation, r.saturation), s.uniform1f(h.uColorShiftBrightness, r.brightness), s.uniform1f(h.uColorShiftTintStrength, r.tintStrength), s.uniform3f(
1287
- h.uColorShiftTintColor,
1375
+ h ? 1 : 0
1376
+ );
1377
+ const c = this.glowEnabled !== a;
1378
+ if (this.glowEnabled = a, a && (c || n) && this.refreshGlowBlur(), h && r) {
1379
+ const f = this.effectPass.uniforms;
1380
+ o.uniform1f(f.uColorShiftHue, r.hueShift * (Math.PI / 180)), o.uniform1f(f.uColorShiftSaturation, r.saturation), o.uniform1f(f.uColorShiftBrightness, r.brightness), o.uniform1f(f.uColorShiftTintStrength, r.tintStrength), o.uniform3f(
1381
+ f.uColorShiftTintColor,
1288
1382
  r.tintColor[0],
1289
1383
  r.tintColor[1],
1290
1384
  r.tintColor[2]
@@ -1302,7 +1396,49 @@ class De extends pt {
1302
1396
  */
1303
1397
  initGPUResources() {
1304
1398
  const t = this.gl;
1305
- t && (this.bilateralPass = Se(t, this.qualityParams.bilateralRadius), this.effectPass = Re(t), this.quadVao = Nt(t, this.effectPass.program), t.disable(t.DEPTH_TEST));
1399
+ if (!t) return;
1400
+ this.bilateralPass = be(t, this.qualityParams.bilateralRadius), this.effectPass = we(t);
1401
+ const e = Ft.replace(
1402
+ "#version 300 es",
1403
+ `#version 300 es
1404
+ #define PASS_HORIZONTAL`
1405
+ ), n = [
1406
+ "uDepth",
1407
+ "uGlowCurve",
1408
+ "uHorizResult",
1409
+ "uTexelSize",
1410
+ "uGlowRadius",
1411
+ "uBlurDir"
1412
+ ];
1413
+ this.glowBlurHPass = Dt(
1414
+ t,
1415
+ "glow-blur-h",
1416
+ bt,
1417
+ e,
1418
+ n,
1419
+ {
1420
+ internalFormat: t.R8,
1421
+ format: t.RED,
1422
+ type: t.UNSIGNED_BYTE,
1423
+ textureUnit: this.glowBlurHorizSlot.unit,
1424
+ width: 0,
1425
+ height: 0
1426
+ }
1427
+ ), this.glowBlurVPass = Dt(
1428
+ t,
1429
+ "glow-blur-v",
1430
+ bt,
1431
+ Ft,
1432
+ n,
1433
+ {
1434
+ internalFormat: t.R8,
1435
+ format: t.RED,
1436
+ type: t.UNSIGNED_BYTE,
1437
+ textureUnit: this.glowBlurResultSlot.unit,
1438
+ width: 0,
1439
+ height: 0
1440
+ }
1441
+ ), this.quadVao = Ot(t, this.effectPass.program), t.disable(t.DEPTH_TEST);
1306
1442
  }
1307
1443
  // -----------------------------------------------------------------------
1308
1444
  // Curve LUT texture management
@@ -1368,7 +1504,24 @@ class De extends pt {
1368
1504
  this.depthHeight,
1369
1505
  this.canvas.width,
1370
1506
  this.canvas.height
1371
- );
1507
+ ), this.glowEnabled && this.executeGlowBlur(e);
1508
+ }
1509
+ /**
1510
+ * Execute the 2-pass separable glow blur (H then V).
1511
+ * Runs at depth resolution into R8 FBOs.
1512
+ */
1513
+ executeGlowBlur(t) {
1514
+ if (!this.glowBlurHPass?.fbo || !this.glowBlurVPass?.fbo || !this.quadVao) return;
1515
+ const e = this.depthWidth, n = this.depthHeight;
1516
+ t.bindFramebuffer(t.FRAMEBUFFER, this.glowBlurHPass.fbo), t.viewport(0, 0, e, n), t.useProgram(this.glowBlurHPass.program), t.bindVertexArray(this.quadVao), t.drawArrays(t.TRIANGLE_STRIP, 0, 4), t.bindFramebuffer(t.FRAMEBUFFER, this.glowBlurVPass.fbo), t.useProgram(this.glowBlurVPass.program), t.drawArrays(t.TRIANGLE_STRIP, 0, 4), t.bindFramebuffer(t.FRAMEBUFFER, null), t.viewport(0, 0, this.canvas.width, this.canvas.height);
1517
+ }
1518
+ /**
1519
+ * Re-execute glow blur on demand (when glow LUT or radius changes).
1520
+ * Only runs if depth data has been uploaded at least once.
1521
+ */
1522
+ refreshGlowBlur() {
1523
+ const t = this.gl;
1524
+ !t || !this.glowEnabled || this.depthWidth === 0 || this.executeGlowBlur(t);
1372
1525
  }
1373
1526
  /**
1374
1527
  * Recalculate the WebGL canvas size and UV transform to match the
@@ -1380,8 +1533,8 @@ class De extends pt {
1380
1533
  recalculateViewportLayout() {
1381
1534
  const t = this.gl;
1382
1535
  if (!t) return;
1383
- const { width: e, height: n } = this.getViewportSize(), i = Math.min(window.devicePixelRatio, this.qualityParams.dprCap), r = Math.round(e * i), s = Math.round(n * i);
1384
- (this.canvas.width !== r || this.canvas.height !== s) && (this.canvas.width = r, this.canvas.height = s, t.viewport(0, 0, r, s)), this.computeCoverFitUV(this.config.parallaxStrength, this.config.overscanPadding), this.effectPass && this.effectPass.updateUvTransform(t, this.uvOffset, this.uvScale);
1536
+ const { width: e, height: n } = this.getViewportSize(), i = Math.min(window.devicePixelRatio, this.qualityParams.dprCap), r = Math.round(e * i), o = Math.round(n * i);
1537
+ (this.canvas.width !== r || this.canvas.height !== o) && (this.canvas.width = r, this.canvas.height = o, t.viewport(0, 0, r, o)), this.computeCoverFitUV(this.config.parallaxStrength, this.config.overscanPadding), this.effectPass && this.effectPass.updateUvTransform(t, this.uvOffset, this.uvScale);
1385
1538
  }
1386
1539
  /** Release all GPU resources. */
1387
1540
  disposeRenderer() {
@@ -1403,18 +1556,18 @@ class De extends pt {
1403
1556
  /** Dispose render passes and shared VAO. */
1404
1557
  disposeGPUResources() {
1405
1558
  const t = this.gl;
1406
- t && (this.bilateralPass && (this.bilateralPass.dispose(t), this.bilateralPass = null), this.effectPass && (this.effectPass.dispose(t), this.effectPass = null), this.quadVao && (t.deleteVertexArray(this.quadVao), this.quadVao = null));
1559
+ t && (this.bilateralPass && (this.bilateralPass.dispose(t), this.bilateralPass = null), this.effectPass && (this.effectPass.dispose(t), this.effectPass = null), this.glowBlurHPass && (this.glowBlurHPass.dispose(t), this.glowBlurHPass = null), this.glowBlurVPass && (this.glowBlurVPass.dispose(t), this.glowBlurVPass = null), this.quadVao && (t.deleteVertexArray(this.quadVao), this.quadVao = null));
1407
1560
  }
1408
1561
  }
1409
- async function ft(o, t = {}) {
1562
+ async function ht(s, t = {}) {
1410
1563
  const {
1411
1564
  parent: e = document.body,
1412
1565
  loop: n = !0,
1413
1566
  muted: i = !0
1414
1567
  } = t, r = document.createElement("video");
1415
- return r.crossOrigin = "anonymous", r.setAttribute("crossorigin", "anonymous"), r.playsInline = !0, r.setAttribute("playsinline", ""), r.setAttribute("webkit-playsinline", "true"), r.muted = i, r.defaultMuted = i, i && r.setAttribute("muted", ""), r.loop = n, r.preload = "auto", r.style.display = "none", r.src = o, e.appendChild(r), await Wt(r), new Pe(r);
1568
+ return r.crossOrigin = "anonymous", r.setAttribute("crossorigin", "anonymous"), r.playsInline = !0, r.setAttribute("playsinline", ""), r.setAttribute("webkit-playsinline", "true"), r.muted = i, r.defaultMuted = i, i && r.setAttribute("muted", ""), r.loop = n, r.preload = "auto", r.style.display = "none", r.src = s, e.appendChild(r), await Gt(r), new Ae(r);
1416
1569
  }
1417
- class Pe {
1570
+ class Ae {
1418
1571
  constructor(t) {
1419
1572
  this.video = t;
1420
1573
  }
@@ -1460,17 +1613,17 @@ class Pe {
1460
1613
  this.video.pause(), this.video.removeAttribute("src"), this.video.load(), this.video.remove();
1461
1614
  }
1462
1615
  }
1463
- async function dt(o, t = {}) {
1616
+ async function ft(s, t = {}) {
1464
1617
  const e = new Image();
1465
- return e.crossOrigin = "anonymous", e.src = o, await new Promise((n, i) => {
1618
+ return e.crossOrigin = "anonymous", e.src = s, await new Promise((n, i) => {
1466
1619
  if (e.complete && e.naturalWidth > 0) {
1467
1620
  n();
1468
1621
  return;
1469
1622
  }
1470
- e.addEventListener("load", () => n(), { once: !0 }), e.addEventListener("error", () => i(new Error(`Failed to load image: ${o}`)), { once: !0 });
1471
- }), new Fe(e);
1623
+ e.addEventListener("load", () => n(), { once: !0 }), e.addEventListener("error", () => i(new Error(`Failed to load image: ${s}`)), { once: !0 });
1624
+ }), new Pe(e);
1472
1625
  }
1473
- class Fe {
1626
+ class Pe {
1474
1627
  constructor(t) {
1475
1628
  this.img = t;
1476
1629
  }
@@ -1492,11 +1645,11 @@ class Fe {
1492
1645
  this.img.removeAttribute("src");
1493
1646
  }
1494
1647
  }
1495
- async function Gt(o = { video: !0 }, t = {}) {
1496
- const { parent: e = document.body } = t, n = await navigator.mediaDevices.getUserMedia(o), i = document.createElement("video");
1497
- return i.playsInline = !0, i.setAttribute("playsinline", ""), i.muted = !0, i.defaultMuted = !0, i.style.display = "none", i.srcObject = n, e.appendChild(i), await Wt(i), await i.play(), new Ce(i, n);
1648
+ async function Xt(s = { video: !0 }, t = {}) {
1649
+ const { parent: e = document.body } = t, n = await navigator.mediaDevices.getUserMedia(s), i = document.createElement("video");
1650
+ return i.playsInline = !0, i.setAttribute("playsinline", ""), i.muted = !0, i.defaultMuted = !0, i.style.display = "none", i.srcObject = n, e.appendChild(i), await Gt(i), await i.play(), new De(i, n);
1498
1651
  }
1499
- class Ce {
1652
+ class De {
1500
1653
  constructor(t, e) {
1501
1654
  this.video = t, this.stream = e;
1502
1655
  }
@@ -1542,23 +1695,23 @@ class Ce {
1542
1695
  t.stop();
1543
1696
  }
1544
1697
  }
1545
- async function Wt(o) {
1546
- o.readyState >= HTMLMediaElement.HAVE_METADATA || await new Promise((t, e) => {
1698
+ async function Gt(s) {
1699
+ s.readyState >= HTMLMediaElement.HAVE_METADATA || await new Promise((t, e) => {
1547
1700
  const n = () => {
1548
1701
  r(), t();
1549
1702
  }, i = () => {
1550
1703
  r(), e(new Error("Failed to load video metadata."));
1551
1704
  }, r = () => {
1552
- o.removeEventListener("loadedmetadata", n), o.removeEventListener("error", i);
1705
+ s.removeEventListener("loadedmetadata", n), s.removeEventListener("error", i);
1553
1706
  };
1554
- o.addEventListener("loadedmetadata", n), o.addEventListener("error", i), o.load();
1707
+ s.addEventListener("loadedmetadata", n), s.addEventListener("error", i), s.load();
1555
1708
  });
1556
1709
  }
1557
- const vt = [0.485, 0.456, 0.406], xt = [0.229, 0.224, 0.225], z = 518;
1558
- async function Le() {
1710
+ const Z = 518;
1711
+ async function Fe() {
1559
1712
  return await import("onnxruntime-web/webgpu");
1560
1713
  }
1561
- class Ue {
1714
+ class Ce {
1562
1715
  constructor(t, e) {
1563
1716
  this.depthWidth = t, this.depthHeight = e;
1564
1717
  const n = t * e;
@@ -1583,6 +1736,8 @@ class Ue {
1583
1736
  // Frame capture canvas (reused)
1584
1737
  captureCanvas = null;
1585
1738
  captureCtx = null;
1739
+ // Preprocessing worker (offloads ImageNet norm + depth quantisation)
1740
+ preprocessWorker = null;
1586
1741
  disposed = !1;
1587
1742
  // -----------------------------------------------------------------------
1588
1743
  // Initialisation
@@ -1595,25 +1750,32 @@ class Ue {
1595
1750
  * (GPU-accelerated on main thread), falls back to WASM EP.
1596
1751
  */
1597
1752
  async init(t, e) {
1598
- const n = await Le();
1599
- if (this.ort = n, this.captureCanvas = document.createElement("canvas"), this.captureCanvas.width = z, this.captureCanvas.height = z, this.captureCtx = this.captureCanvas.getContext("2d", {
1753
+ const n = await Fe();
1754
+ if (this.ort = n, this.captureCanvas = document.createElement("canvas"), this.captureCanvas.width = Z, this.captureCanvas.height = Z, this.captureCtx = this.captureCanvas.getContext("2d", {
1600
1755
  willReadFrequently: !0
1601
1756
  }), !this.captureCtx)
1602
1757
  throw new Error("[DepthEstimator] Failed to create 2D canvas context.");
1603
1758
  e?.({ receivedBytes: 0, totalBytes: null, fraction: 0, label: "Downloading depth model…" });
1604
- const i = await _e(t, e);
1759
+ const i = await Ue(t, e);
1605
1760
  e?.({ receivedBytes: i.byteLength, totalBytes: i.byteLength, fraction: 1, label: "Initialising depth model…" });
1606
1761
  let r;
1607
1762
  try {
1608
1763
  r = await n.InferenceSession.create(i, {
1609
1764
  executionProviders: ["webgpu"]
1610
1765
  }), console.log("[DepthEstimator] Using WebGPU execution provider");
1611
- } catch (s) {
1612
- console.warn("[DepthEstimator] WebGPU EP unavailable, falling back to WASM:", s), n.env.wasm.proxy = !0, r = await n.InferenceSession.create(i, {
1766
+ } catch (o) {
1767
+ console.warn("[DepthEstimator] WebGPU EP unavailable, falling back to WASM:", o), n.env.wasm.proxy = !0, r = await n.InferenceSession.create(i, {
1613
1768
  executionProviders: ["wasm"]
1614
1769
  }), console.log("[DepthEstimator] Using WASM execution provider (proxy worker)");
1615
1770
  }
1616
- this.session = r, this.inputName = r.inputNames[0], this.outputName = r.outputNames[0], this.readyResolve?.(), this.readyResolve = null;
1771
+ this.session = r, this.inputName = r.inputNames[0], this.outputName = r.outputNames[0], this.preprocessWorker = new Worker(
1772
+ new URL(
1773
+ /* @vite-ignore */
1774
+ "/assets/preprocess-worker-wra-uI6w.js",
1775
+ import.meta.url
1776
+ ),
1777
+ { type: "module" }
1778
+ ), this.readyResolve?.(), this.readyResolve = null;
1617
1779
  }
1618
1780
  /** Wait for model loading and session creation to complete. */
1619
1781
  waitUntilReady() {
@@ -1651,77 +1813,77 @@ class Ue {
1651
1813
  // Cleanup
1652
1814
  // -----------------------------------------------------------------------
1653
1815
  dispose() {
1654
- this.disposed = !0, this.session?.release(), this.session = null, this.ort = null, this.captureCanvas = null, this.captureCtx = null;
1816
+ this.disposed = !0, this.session?.release(), this.session = null, this.ort = null, this.captureCanvas = null, this.captureCtx = null, this.preprocessWorker?.terminate(), this.preprocessWorker = null;
1655
1817
  }
1656
1818
  // -----------------------------------------------------------------------
1657
1819
  // Internal inference pipeline
1658
1820
  // -----------------------------------------------------------------------
1659
1821
  async runInference(t) {
1660
1822
  try {
1661
- if (!this.session || !this.captureCtx || !this.ort) return;
1823
+ if (!this.session || !this.captureCtx || !this.ort || !this.preprocessWorker) return;
1662
1824
  this.captureCtx.drawImage(
1663
1825
  t,
1664
1826
  0,
1665
1827
  0,
1666
- z,
1667
- z
1828
+ Z,
1829
+ Z
1668
1830
  );
1669
1831
  const e = this.captureCtx.getImageData(
1670
1832
  0,
1671
1833
  0,
1672
- z,
1673
- z
1674
- ), n = this.preprocess(e), r = (await this.session.run({ [this.inputName]: n }))[this.outputName], s = r.data, a = r.dims, l = a.length === 3 ? a[1] : a[2], u = a.length === 3 ? a[2] : a[3];
1675
- this.postProcess(s, u, l);
1676
- const h = this.frontBuffer;
1677
- this.frontBuffer = this.backBuffer, this.backBuffer = h;
1834
+ Z,
1835
+ Z
1836
+ ), n = await this.workerPreprocess(e.data.buffer, e.width, e.height), i = new this.ort.Tensor("float32", new Float32Array(n), [1, 3, e.height, e.width]), o = (await this.session.run({ [this.inputName]: i }))[this.outputName], l = o.data, a = o.dims, h = a.length === 3 ? a[1] : a[2], c = a.length === 3 ? a[2] : a[3], f = await this.workerPostprocess(l.slice(0).buffer, c, h);
1837
+ this.backBuffer.set(new Uint8Array(f));
1838
+ const u = this.frontBuffer;
1839
+ this.frontBuffer = this.backBuffer, this.backBuffer = u;
1678
1840
  } catch (e) {
1679
1841
  console.error("[DepthEstimator] Inference failed:", e);
1680
1842
  } finally {
1681
1843
  this.inferenceInFlight = !1;
1682
1844
  }
1683
1845
  }
1684
- /**
1685
- * Convert RGBA ImageData NCHW float32 tensor with ImageNet normalisation.
1686
- */
1687
- preprocess(t) {
1688
- const { data: e, width: n, height: i } = t, r = n * i, s = new Float32Array(3 * r);
1689
- for (let a = 0; a < r; a++) {
1690
- const l = a * 4;
1691
- s[a] = (e[l] / 255 - vt[0]) / xt[0], s[r + a] = (e[l + 1] / 255 - vt[1]) / xt[1], s[2 * r + a] = (e[l + 2] / 255 - vt[2]) / xt[2];
1692
- }
1693
- return new this.ort.Tensor("float32", s, [1, 3, i, n]);
1846
+ workerPreprocess(t, e, n) {
1847
+ return new Promise((i, r) => {
1848
+ if (!this.preprocessWorker) {
1849
+ r(new Error("Worker not ready"));
1850
+ return;
1851
+ }
1852
+ const o = (a) => {
1853
+ this.preprocessWorker?.removeEventListener("message", o), a.data.type === "preprocessed" ? i(a.data.float32) : a.data.type === "error" && r(new Error(a.data.message));
1854
+ };
1855
+ this.preprocessWorker.addEventListener("message", o);
1856
+ const l = t.slice(0);
1857
+ this.preprocessWorker.postMessage(
1858
+ { type: "preprocess", pixels: l, width: e, height: n },
1859
+ [l]
1860
+ );
1861
+ });
1694
1862
  }
1695
- /**
1696
- * Bilinear resize from model output dimensions → depth texture dimensions,
1697
- * normalise to full [0, 255] range, and write into `backBuffer`.
1698
- *
1699
- * Depth Anything v2 (like v1) outputs inverse depth (disparity-like):
1700
- * higher raw values = closer to camera. This matches the convention used
1701
- * by the precompute pipeline (`normalizeToUint8` in scripts/precompute-depth.ts),
1702
- * so no inversion is applied: 255 = nearest, 0 = farthest.
1703
- */
1704
- postProcess(t, e, n) {
1705
- const { depthWidth: i, depthHeight: r } = this;
1706
- let s = 1 / 0, a = -1 / 0;
1707
- for (let f = 0; f < t.length; f++) {
1708
- const c = t[f];
1709
- c < s && (s = c), c > a && (a = c);
1710
- }
1711
- const l = a - s || 1, u = e / i, h = n / r;
1712
- for (let f = 0; f < r; f++)
1713
- for (let c = 0; c < i; c++) {
1714
- const E = c * u, v = f * h, p = Math.floor(E), P = Math.floor(v), x = Math.min(p + 1, e - 1), y = Math.min(P + 1, n - 1), d = E - p, g = v - P, b = t[P * e + p], T = t[P * e + x], m = t[y * e + p], S = t[y * e + x], F = (b * (1 - d) * (1 - g) + T * d * (1 - g) + m * (1 - d) * g + S * d * g - s) / l;
1715
- this.backBuffer[f * i + c] = F * 255 + 0.5 | 0;
1863
+ workerPostprocess(t, e, n) {
1864
+ return new Promise((i, r) => {
1865
+ if (!this.preprocessWorker) {
1866
+ r(new Error("Worker not ready"));
1867
+ return;
1716
1868
  }
1869
+ const o = (a) => {
1870
+ this.preprocessWorker?.removeEventListener("message", o), a.data.type === "postprocessed" ? i(a.data.depth) : a.data.type === "error" && r(new Error(a.data.message));
1871
+ };
1872
+ this.preprocessWorker.addEventListener("message", o);
1873
+ const l = t.slice(0);
1874
+ this.preprocessWorker.postMessage(
1875
+ { type: "postprocess", depthFloat: l, srcW: e, srcH: n, dstW: this.depthWidth, dstH: this.depthHeight },
1876
+ [l]
1877
+ );
1878
+ });
1717
1879
  }
1718
1880
  }
1719
- async function mt(o, t, e, n) {
1720
- const i = new Ue(t, e);
1721
- return await i.init(o, n), i;
1881
+ async function dt(s, t, e, n) {
1882
+ const i = new Ce(t, e);
1883
+ return await i.init(s, n), i;
1722
1884
  }
1723
- async function _e(o, t) {
1724
- const e = await fetch(o);
1885
+ async function Ue(s, t) {
1886
+ const e = await fetch(s);
1725
1887
  if (!e.ok)
1726
1888
  throw new Error(`[DepthEstimator] Failed to fetch model (${e.status} ${e.statusText}).`);
1727
1889
  const n = e.headers.get("content-length"), i = n ? Number(n) : null, r = e.body;
@@ -1734,73 +1896,73 @@ async function _e(o, t) {
1734
1896
  label: "Downloading depth model…"
1735
1897
  }), f;
1736
1898
  }
1737
- const s = [];
1738
- let a = 0;
1739
- const l = r.getReader();
1899
+ const o = [];
1900
+ let l = 0;
1901
+ const a = r.getReader();
1740
1902
  for (; ; ) {
1741
- const { done: f, value: c } = await l.read();
1903
+ const { done: f, value: u } = await a.read();
1742
1904
  if (f) break;
1743
- c && (s.push(c), a += c.byteLength, t?.({
1744
- receivedBytes: a,
1905
+ u && (o.push(u), l += u.byteLength, t?.({
1906
+ receivedBytes: l,
1745
1907
  totalBytes: i,
1746
- fraction: i ? Math.min(a / i, 1) : 0,
1908
+ fraction: i ? Math.min(l / i, 1) : 0,
1747
1909
  label: "Downloading depth model…"
1748
1910
  }));
1749
1911
  }
1750
- const u = new Uint8Array(a);
1751
- let h = 0;
1752
- for (const f of s)
1753
- u.set(f, h), h += f.byteLength;
1754
- return u.buffer;
1912
+ const h = new Uint8Array(l);
1913
+ let c = 0;
1914
+ for (const f of o)
1915
+ h.set(f, c), c += f.byteLength;
1916
+ return h.buffer;
1755
1917
  }
1756
- const Lt = {
1918
+ const Ct = {
1757
1919
  sensitivityX: 0.4,
1758
1920
  sensitivityY: 1,
1759
1921
  lerpFactor: 0.08
1760
1922
  };
1761
- function yt(o, t) {
1762
- const e = o.points;
1923
+ function St(s, t) {
1924
+ const e = s.points;
1763
1925
  if (e.length === 0) return 0;
1764
1926
  if (e.length === 1 || t <= e[0].x) return e[0].y;
1765
1927
  if (t >= e[e.length - 1].x) return e[e.length - 1].y;
1766
1928
  let n = 0;
1767
1929
  for (; n < e.length - 1 && e[n + 1].x < t; ) n++;
1768
- const i = e[n], r = e[n + 1], s = (t - i.x) / (r.x - i.x);
1769
- switch (o.interpolation) {
1930
+ const i = e[n], r = e[n + 1], o = (t - i.x) / (r.x - i.x);
1931
+ switch (s.interpolation) {
1770
1932
  case "step":
1771
1933
  return i.y;
1772
1934
  case "linear":
1773
- return i.y + (r.y - i.y) * s;
1935
+ return i.y + (r.y - i.y) * o;
1774
1936
  case "smooth": {
1775
- const a = s * s * (3 - 2 * s);
1776
- return i.y + (r.y - i.y) * a;
1937
+ const l = o * o * (3 - 2 * o);
1938
+ return i.y + (r.y - i.y) * l;
1777
1939
  }
1778
1940
  default:
1779
- return i.y + (r.y - i.y) * s;
1941
+ return i.y + (r.y - i.y) * o;
1780
1942
  }
1781
1943
  }
1782
- function at(o, t = 256) {
1944
+ function lt(s, t = 256) {
1783
1945
  const e = new Uint8Array(t);
1784
1946
  for (let n = 0; n < t; n++) {
1785
1947
  const i = n / (t - 1);
1786
- e[n] = Math.round(yt(o, i) * 255);
1948
+ e[n] = Math.round(St(s, i) * 255);
1787
1949
  }
1788
1950
  return e;
1789
1951
  }
1790
- function G(o, t) {
1791
- return o.find((e) => e.channel === t && e.enabled);
1952
+ function q(s, t) {
1953
+ return s.find((e) => e.channel === t && e.enabled);
1792
1954
  }
1793
- function Ut(o, t) {
1794
- const e = G(o, "displacement"), n = G(o, "blur"), i = G(o, "glow"), r = e?.params;
1795
- let s = 0.6, a = 0;
1955
+ function Ut(s, t) {
1956
+ const e = q(s, "displacement"), n = q(s, "blur"), i = q(s, "glow"), r = e?.params;
1957
+ let o = 0.6, l = 0;
1796
1958
  if (n) {
1797
- const l = n.curve;
1798
- for (let u = 0; u <= 1; u += 0.01)
1799
- if (yt(l, u) > 0.01) {
1800
- s = u;
1959
+ const a = n.curve;
1960
+ for (let h = 0; h <= 1; h += 0.01)
1961
+ if (St(a, h) > 0.01) {
1962
+ o = h;
1801
1963
  break;
1802
1964
  }
1803
- a = yt(l, 1);
1965
+ l = St(a, 1);
1804
1966
  }
1805
1967
  return {
1806
1968
  parallaxStrength: r?.strength ?? 0.05,
@@ -1809,8 +1971,8 @@ function Ut(o, t) {
1809
1971
  contrastLow: t.contrastLow,
1810
1972
  contrastHigh: t.contrastHigh,
1811
1973
  verticalReduction: t.verticalReduction,
1812
- dofStart: s,
1813
- dofStrength: a,
1974
+ dofStart: o,
1975
+ dofStrength: l,
1814
1976
  blurRadius: n?.params?.maxRadius ?? 0.01,
1815
1977
  glowColor: i?.params?.color ?? [1, 0.95, 0.85],
1816
1978
  glowRadius: i?.params?.radius ?? 0.02,
@@ -1821,13 +1983,13 @@ function Ut(o, t) {
1821
1983
  tiltPeakIntensity: n?.params?.peakIntensity ?? 0.8
1822
1984
  };
1823
1985
  }
1824
- function _t(o) {
1825
- const t = G(o, "displacement"), e = G(o, "blur"), n = G(o, "glow"), i = G(o, "color-shift"), r = i?.params;
1986
+ function Lt(s) {
1987
+ const t = q(s, "displacement"), e = q(s, "blur"), n = q(s, "glow"), i = q(s, "color-shift"), r = i?.params;
1826
1988
  return {
1827
- displacementLUT: t ? at(t.curve) : null,
1828
- blurLUT: e ? at(e.curve) : null,
1829
- glowLUT: n ? at(n.curve) : null,
1830
- colorShiftLUT: i ? at(i.curve) : null,
1989
+ displacementLUT: t ? lt(t.curve) : null,
1990
+ blurLUT: e ? lt(e.curve) : null,
1991
+ glowLUT: n ? lt(n.curve) : null,
1992
+ colorShiftLUT: i ? lt(i.curve) : null,
1831
1993
  colorShiftParams: r ? {
1832
1994
  hueShift: r.hueShift ?? 0,
1833
1995
  saturation: r.saturation ?? 1,
@@ -1837,7 +1999,7 @@ function _t(o) {
1837
1999
  } : null
1838
2000
  };
1839
2001
  }
1840
- class zt {
2002
+ class Wt {
1841
2003
  abortController = null;
1842
2004
  initialized = !1;
1843
2005
  initializing = !1;
@@ -1887,7 +2049,7 @@ class zt {
1887
2049
  this.abortController?.abort(), this.abortController = null, this.initializing = !1;
1888
2050
  }
1889
2051
  }
1890
- const X = {
2052
+ const z = {
1891
2053
  parallaxX: 0.4,
1892
2054
  parallaxY: 1,
1893
2055
  parallaxMax: 30,
@@ -1895,68 +2057,8 @@ const X = {
1895
2057
  autoplay: !0,
1896
2058
  loop: !0,
1897
2059
  muted: !0
1898
- }, q = 512, Y = 512;
1899
- let Me = class qt {
1900
- constructor(t, e = 0.08, n = 0.06) {
1901
- this.host = t, this.lerpFactor = e, this.motionLerpFactor = n, this.host.addEventListener("mousemove", this.handleMouseMove), this.host.addEventListener("mouseleave", this.resetPointerTarget), this.host.addEventListener("touchstart", this.handleTouchStart, { passive: !0 }), this.host.addEventListener("touchmove", this.handleTouchMove, { passive: !0 }), this.host.addEventListener("touchend", this.handleTouchEnd, { passive: !0 }), this.host.addEventListener("touchcancel", this.handleTouchEnd, { passive: !0 });
1902
- }
1903
- pointerTarget = { x: 0, y: 0 };
1904
- motionTarget = { x: 0, y: 0 };
1905
- smoothedOutput = { x: 0, y: 0 };
1906
- usingMotionInput = !1;
1907
- motionListenerAttached = !1;
1908
- motionRequested = !1;
1909
- touchActive = !1;
1910
- touchAnchorX = 0;
1911
- touchAnchorY = 0;
1912
- lerpFactor;
1913
- motionLerpFactor;
1914
- /** Pixels of finger drag to reach full parallax offset (-1 or 1). */
1915
- static TOUCH_DRAG_RANGE = 100;
1916
- update() {
1917
- const t = this.touchActive ? this.pointerTarget : this.usingMotionInput ? this.motionTarget : this.pointerTarget, e = this.usingMotionInput && !this.touchActive ? this.motionLerpFactor : this.lerpFactor;
1918
- return this.smoothedOutput.x = lt(this.smoothedOutput.x, t.x, e), this.smoothedOutput.y = lt(this.smoothedOutput.y, t.y, e), this.smoothedOutput;
1919
- }
1920
- dispose() {
1921
- this.host.removeEventListener("mousemove", this.handleMouseMove), this.host.removeEventListener("mouseleave", this.resetPointerTarget), this.host.removeEventListener("touchstart", this.handleTouchStart), this.host.removeEventListener("touchmove", this.handleTouchMove), this.host.removeEventListener("touchend", this.handleTouchEnd), this.host.removeEventListener("touchcancel", this.handleTouchEnd), this.motionListenerAttached && (window.removeEventListener("deviceorientation", this.handleDeviceOrientation), this.motionListenerAttached = !1);
1922
- }
1923
- handleMouseMove = (t) => {
1924
- const e = this.host.getBoundingClientRect(), n = (t.clientX - e.left) / e.width * 2 - 1, i = (t.clientY - e.top) / e.height * 2 - 1;
1925
- this.pointerTarget.x = j(n, -1, 1), this.pointerTarget.y = j(i, -1, 1);
1926
- };
1927
- resetPointerTarget = () => {
1928
- this.pointerTarget.x = 0, this.pointerTarget.y = 0;
1929
- };
1930
- handleTouchStart = (t) => {
1931
- const e = t.touches[0];
1932
- e && (this.touchActive = !0, this.touchAnchorX = e.clientX, this.touchAnchorY = e.clientY, this.pointerTarget.x = 0, this.pointerTarget.y = 0, this.motionRequested || (this.motionRequested = !0, this.requestMotionPermission()));
1933
- };
1934
- handleTouchMove = (t) => {
1935
- const e = t.touches[0];
1936
- if (!e) return;
1937
- const n = e.clientX - this.touchAnchorX, i = e.clientY - this.touchAnchorY, r = qt.TOUCH_DRAG_RANGE;
1938
- this.pointerTarget.x = j(n / r, -1, 1), this.pointerTarget.y = j(i / r, -1, 1);
1939
- };
1940
- handleTouchEnd = () => {
1941
- this.touchActive = !1, this.pointerTarget.x = 0, this.pointerTarget.y = 0;
1942
- };
1943
- async requestMotionPermission() {
1944
- if (typeof DeviceOrientationEvent > "u") return;
1945
- const t = DeviceOrientationEvent;
1946
- if (typeof t.requestPermission == "function")
1947
- try {
1948
- if (await t.requestPermission() !== "granted") return;
1949
- } catch {
1950
- return;
1951
- }
1952
- this.motionListenerAttached || (window.addEventListener("deviceorientation", this.handleDeviceOrientation), this.motionListenerAttached = !0), this.usingMotionInput = !0;
1953
- }
1954
- handleDeviceOrientation = (t) => {
1955
- const e = j((t.gamma ?? 0) / 45, -1, 1), n = j((t.beta ?? 0) / 45, -1, 1);
1956
- this.motionTarget.x = lt(this.motionTarget.x, e, this.motionLerpFactor), this.motionTarget.y = lt(this.motionTarget.y, n, this.motionLerpFactor);
1957
- };
1958
- };
1959
- class Tt extends HTMLElement {
2060
+ }, $ = 512, K = 512;
2061
+ class xt extends HTMLElement {
1960
2062
  static TAG_NAME = "layershift-effect";
1961
2063
  static get observedAttributes() {
1962
2064
  return [
@@ -1987,7 +2089,7 @@ class Tt extends HTMLElement {
1987
2089
  shadow;
1988
2090
  container = null;
1989
2091
  renderer = null;
1990
- inputHandler = null;
2092
+ _input = { x: 0, y: 0 };
1991
2093
  source = null;
1992
2094
  depthEstimator = null;
1993
2095
  loopCount = 0;
@@ -1999,7 +2101,14 @@ class Tt extends HTMLElement {
1999
2101
  */
2000
2102
  depthFallback = null;
2001
2103
  constructor() {
2002
- super(), this.shadow = this.attachShadow({ mode: "open" }), this.lifecycle = new zt(this);
2104
+ super(), this.shadow = this.attachShadow({ mode: "open" }), this.lifecycle = new Wt(this);
2105
+ }
2106
+ /** The current input offset. Set this externally to drive the effect. */
2107
+ get input() {
2108
+ return { x: this._input.x, y: this._input.y };
2109
+ }
2110
+ set input(t) {
2111
+ this._input.x = t.x, this._input.y = t.y;
2003
2112
  }
2004
2113
  // --- Attribute helpers ---
2005
2114
  getAttrFloat(t, e) {
@@ -2014,16 +2123,16 @@ class Tt extends HTMLElement {
2014
2123
  return !(n === "false" || n === "0");
2015
2124
  }
2016
2125
  get parallaxX() {
2017
- return this.getAttrFloat("parallax-x", X.parallaxX);
2126
+ return this.getAttrFloat("parallax-x", z.parallaxX);
2018
2127
  }
2019
2128
  get parallaxY() {
2020
- return this.getAttrFloat("parallax-y", X.parallaxY);
2129
+ return this.getAttrFloat("parallax-y", z.parallaxY);
2021
2130
  }
2022
2131
  get parallaxMax() {
2023
- return this.getAttrFloat("parallax-max", X.parallaxMax);
2132
+ return this.getAttrFloat("parallax-max", z.parallaxMax);
2024
2133
  }
2025
2134
  get overscan() {
2026
- return this.getAttrFloat("overscan", X.overscan);
2135
+ return this.getAttrFloat("overscan", z.overscan);
2027
2136
  }
2028
2137
  get quality() {
2029
2138
  const t = this.getAttribute("quality");
@@ -2041,13 +2150,13 @@ class Tt extends HTMLElement {
2041
2150
  return this.getAttribute("depth-model");
2042
2151
  }
2043
2152
  get shouldAutoplay() {
2044
- return this.getAttrBool("autoplay", X.autoplay);
2153
+ return this.getAttrBool("autoplay", z.autoplay);
2045
2154
  }
2046
2155
  get shouldLoop() {
2047
- return this.getAttrBool("loop", X.loop);
2156
+ return this.getAttrBool("loop", z.loop);
2048
2157
  }
2049
2158
  get shouldMute() {
2050
- return this.getAttrBool("muted", X.muted);
2159
+ return this.getAttrBool("muted", z.muted);
2051
2160
  }
2052
2161
  // --- Event dispatching ---
2053
2162
  /**
@@ -2134,7 +2243,7 @@ class Tt extends HTMLElement {
2134
2243
  const i = await n.json();
2135
2244
  return {
2136
2245
  channels: i.channels ?? [],
2137
- motion: i.motion ?? Lt,
2246
+ motion: i.motion ?? Ct,
2138
2247
  overscanPadding: i.overscanPadding ?? 0.05,
2139
2248
  quality: i.quality ?? "auto"
2140
2249
  };
@@ -2165,12 +2274,12 @@ class Tt extends HTMLElement {
2165
2274
  if (!this.container) return;
2166
2275
  const e = this.sourceType === "camera", n = this.depthModel;
2167
2276
  try {
2168
- let i, r, s = null;
2169
- const a = (m) => {
2277
+ let i, r, o = null;
2278
+ const l = (m) => {
2170
2279
  this.emit("layershift-effect:model-progress", m);
2171
2280
  };
2172
2281
  if (e) {
2173
- if (i = await Gt(
2282
+ if (i = await Xt(
2174
2283
  { video: { facingMode: "user" } },
2175
2284
  { parent: this.shadow }
2176
2285
  ), t.aborted) {
@@ -2178,91 +2287,91 @@ class Tt extends HTMLElement {
2178
2287
  return;
2179
2288
  }
2180
2289
  if (n) {
2181
- if (s = await mt(n, q, Y, a), t.aborted) {
2182
- s.dispose(), i.dispose();
2290
+ if (o = await dt(n, $, K, l), t.aborted) {
2291
+ o.dispose(), i.dispose();
2183
2292
  return;
2184
2293
  }
2185
- r = H(q, Y);
2294
+ r = N($, K);
2186
2295
  } else
2187
- r = H(i.width, i.height);
2296
+ r = N(i.width, i.height);
2188
2297
  } else {
2189
- const m = this.getAttribute("src"), S = this.getAttribute("depth-src"), w = this.getAttribute("depth-meta"), F = !!S && !!w, U = this.sourceType === "image" || /\.(jpe?g|png|webp|gif|avif|bmp)(\?|$)/i.test(m);
2190
- if (F) {
2191
- const [_, R] = await Promise.all([
2192
- U ? dt(m) : ft(m, {
2298
+ const m = this.getAttribute("src"), T = this.getAttribute("depth-src"), w = this.getAttribute("depth-meta"), A = !!T && !!w, P = this.sourceType === "image" || /\.(jpe?g|png|webp|gif|avif|bmp)(\?|$)/i.test(m);
2299
+ if (A) {
2300
+ const [F, _] = await Promise.all([
2301
+ P ? ft(m) : ht(m, {
2193
2302
  parent: this.shadow,
2194
2303
  loop: this.shouldLoop,
2195
2304
  muted: this.shouldMute
2196
2305
  }),
2197
- kt(S, w)
2306
+ kt(T, w)
2198
2307
  ]);
2199
2308
  if (t.aborted) {
2200
- _.dispose();
2309
+ F.dispose();
2201
2310
  return;
2202
2311
  }
2203
- i = _, r = R;
2312
+ i = F, r = _;
2204
2313
  } else if (n) {
2205
- const [_, R] = await Promise.all([
2206
- U ? dt(m) : ft(m, {
2314
+ const [F, _] = await Promise.all([
2315
+ P ? ft(m) : ht(m, {
2207
2316
  parent: this.shadow,
2208
2317
  loop: this.shouldLoop,
2209
2318
  muted: this.shouldMute
2210
2319
  }),
2211
- mt(n, q, Y, a)
2320
+ dt(n, $, K, l)
2212
2321
  ]);
2213
2322
  if (t.aborted) {
2214
- _.dispose(), R.dispose();
2323
+ F.dispose(), _.dispose();
2215
2324
  return;
2216
2325
  }
2217
- if (i = _, s = R, U || !i.isLive) {
2218
- const D = i.getImageSource();
2219
- if (D) {
2220
- const L = await s.submitFrameAndWait(D);
2326
+ if (i = F, o = _, P || !i.isLive) {
2327
+ const I = i.getImageSource();
2328
+ if (I) {
2329
+ const C = await o.submitFrameAndWait(I);
2221
2330
  r = {
2222
- meta: { frameCount: 1, fps: 1, width: q, height: Y, sourceFps: 1 },
2223
- frames: [L]
2331
+ meta: { frameCount: 1, fps: 1, width: $, height: K, sourceFps: 1 },
2332
+ frames: [C]
2224
2333
  };
2225
2334
  } else
2226
- r = H(q, Y);
2335
+ r = N($, K);
2227
2336
  } else
2228
- r = H(q, Y);
2337
+ r = N($, K);
2229
2338
  } else
2230
2339
  throw new Error("Either depth-src/depth-meta or depth-model must be provided.");
2231
2340
  }
2232
- this.source = i, this.depthEstimator = s, this.loopCount = 0, this.attachSourceEventListeners(i);
2233
- const l = ae(
2341
+ this.source = i, this.depthEstimator = o, this.loopCount = 0, this.attachSourceEventListeners(i);
2342
+ const a = oe(
2234
2343
  r.frames,
2235
2344
  r.meta.width,
2236
2345
  r.meta.height
2237
- ), u = le(l);
2346
+ ), h = ae(a);
2238
2347
  this.depthFallback = {
2239
- contrastLow: u.contrastLow,
2240
- contrastHigh: u.contrastHigh,
2241
- verticalReduction: u.verticalReduction
2348
+ contrastLow: h.contrastLow,
2349
+ contrastHigh: h.contrastHigh,
2350
+ verticalReduction: h.verticalReduction
2242
2351
  };
2243
- let h;
2244
- if (s)
2245
- h = () => s.getLatestDepth();
2352
+ let c;
2353
+ if (o)
2354
+ c = () => o.getLatestDepth();
2246
2355
  else {
2247
- const m = new Ot(r);
2248
- h = (S) => m.sample(S);
2356
+ const m = new Vt(r);
2357
+ c = (T) => m.sample(T);
2249
2358
  }
2250
2359
  if (t.aborted) return;
2251
- let f, c = null, E = Lt;
2252
- const v = await this.fetchFilterConfig(t);
2360
+ let f, u = null, x = Ct;
2361
+ const p = await this.fetchFilterConfig(t);
2253
2362
  if (t.aborted) return;
2254
- if (v && v.channels.length > 0) {
2255
- const m = Ut(v.channels, {
2256
- contrastLow: u.contrastLow,
2257
- contrastHigh: u.contrastHigh,
2258
- verticalReduction: u.verticalReduction
2363
+ if (p && p.channels.length > 0) {
2364
+ const m = Ut(p.channels, {
2365
+ contrastLow: h.contrastLow,
2366
+ contrastHigh: h.contrastHigh,
2367
+ verticalReduction: h.verticalReduction
2259
2368
  });
2260
2369
  f = {
2261
2370
  parallaxStrength: m.parallaxStrength,
2262
2371
  pomEnabled: m.pomEnabled,
2263
2372
  pomSteps: m.pomSteps,
2264
- overscanPadding: v.overscanPadding,
2265
- quality: v.quality,
2373
+ overscanPadding: p.overscanPadding,
2374
+ quality: p.quality,
2266
2375
  contrastLow: m.contrastLow,
2267
2376
  contrastHigh: m.contrastHigh,
2268
2377
  verticalReduction: m.verticalReduction,
@@ -2276,45 +2385,41 @@ class Tt extends HTMLElement {
2276
2385
  tiltHalfTanFov: m.tiltHalfTanFov,
2277
2386
  tiltTransitionWidth: m.tiltTransitionWidth,
2278
2387
  tiltPeakIntensity: m.tiltPeakIntensity
2279
- }, c = _t(v.channels), E = v.motion;
2388
+ }, u = Lt(p.channels), x = p.motion;
2280
2389
  } else
2281
- f = this.buildLegacyConfig(u, i.width);
2282
- this.renderer = new De(this.container, f), this.renderer.initialize(i, r.meta.width, r.meta.height), c && this.renderer.updateCurveLUTs(
2283
- c.displacementLUT,
2284
- c.blurLUT,
2285
- c.glowLUT,
2286
- c.colorShiftLUT,
2287
- c.colorShiftParams ?? void 0
2288
- ), this.inputHandler = new Me(this, E.lerpFactor);
2289
- const p = E.sensitivityX, P = E.sensitivityY, x = E.tiltPlaneInput ?? !1, y = E.tiltPitchSensitivity ?? 0.35, d = E.tiltYawSensitivity ?? 0.15, b = v?.channels.find((m) => m.channel === "blur" && m.enabled)?.params?.focalCenter ?? 0.5, T = s;
2390
+ f = this.buildLegacyConfig(h, i.width);
2391
+ this.renderer = new Re(this.container, f), this.renderer.initialize(i, r.meta.width, r.meta.height), u && this.renderer.updateCurveLUTs(
2392
+ u.displacementLUT,
2393
+ u.blurLUT,
2394
+ u.glowLUT,
2395
+ u.colorShiftLUT,
2396
+ u.colorShiftParams ?? void 0
2397
+ );
2398
+ const d = x.tiltPlaneInput ?? !1, y = x.tiltPitchSensitivity ?? 0.35, E = x.tiltYawSensitivity ?? 0.15, g = p?.channels.find((m) => m.channel === "blur" && m.enabled)?.params?.focalCenter ?? 0.5, v = o;
2290
2399
  if (this.renderer.start(
2291
2400
  i,
2292
- h,
2401
+ c,
2293
2402
  () => {
2294
- if (!this.inputHandler) return { x: 0, y: 0 };
2295
- const m = this.inputHandler.update();
2296
- if (x) {
2297
- const F = m.y * P * y, U = m.x * p * d, _ = Math.cos(F), R = Math.sin(F), D = Math.cos(U), M = Math.sin(U) * _, V = -R, I = D * _, N = 0.5 + b * (5 - 0.5);
2403
+ const m = this._input;
2404
+ if (d) {
2405
+ const A = m.y * y, P = m.x * E, F = Math.cos(A), _ = Math.sin(A), I = Math.cos(P), S = Math.sin(P) * F, D = -_, U = I * F, M = 0.5 + g * (5 - 0.5);
2298
2406
  return {
2299
- x: m.x * p * 0.3,
2300
- y: m.y * P * 0.3,
2301
- tiltPlaneNormal: [M, V, I],
2302
- tiltPlaneD: I * N
2407
+ x: m.x * 0.3,
2408
+ y: m.y * 0.3,
2409
+ tiltPlaneNormal: [S, D, U],
2410
+ tiltPlaneD: U * M
2303
2411
  };
2304
2412
  }
2305
- return {
2306
- x: m.x * p,
2307
- y: m.y * P
2308
- };
2413
+ return { x: m.x, y: m.y };
2309
2414
  },
2310
- (m, S) => {
2311
- if (T) {
2415
+ (m, T) => {
2416
+ if (v) {
2312
2417
  const w = i.getImageSource();
2313
- w && T.submitFrame(w);
2418
+ w && v.submitFrame(w);
2314
2419
  }
2315
2420
  this.emit("layershift-effect:frame", {
2316
2421
  currentTime: m,
2317
- frameNumber: S
2422
+ frameNumber: T
2318
2423
  });
2319
2424
  }
2320
2425
  ), !e && i.isLive && this.shouldAutoplay && i.play)
@@ -2327,8 +2432,9 @@ class Tt extends HTMLElement {
2327
2432
  videoWidth: i.width,
2328
2433
  videoHeight: i.height,
2329
2434
  duration: i.duration,
2330
- depthProfile: l,
2331
- derivedParams: u
2435
+ depthProfile: a,
2436
+ derivedParams: h,
2437
+ motionConfig: x
2332
2438
  });
2333
2439
  } catch (i) {
2334
2440
  const r = i instanceof Error ? i.message : "Failed to initialize.";
@@ -2353,7 +2459,7 @@ class Tt extends HTMLElement {
2353
2459
  verticalReduction: 0.5
2354
2460
  }, n = Ut(t, e);
2355
2461
  this.renderer.updateConfig(n);
2356
- const i = _t(t);
2462
+ const i = Lt(t);
2357
2463
  this.renderer.updateCurveLUTs(
2358
2464
  i.displacementLUT,
2359
2465
  i.blurLUT,
@@ -2364,16 +2470,10 @@ class Tt extends HTMLElement {
2364
2470
  }
2365
2471
  // --- Cleanup ---
2366
2472
  doDispose() {
2367
- this.renderer?.dispose(), this.renderer = null, this.inputHandler?.dispose(), this.inputHandler = null, this.depthEstimator?.dispose(), this.depthEstimator = null, this.source?.dispose(), this.source = null, this.depthFallback = null, this.loopCount = 0, this.container = null;
2473
+ this.renderer?.dispose(), this.renderer = null, this.depthEstimator?.dispose(), this.depthEstimator = null, this.source?.dispose(), this.source = null, this.depthFallback = null, this.loopCount = 0, this.container = null;
2368
2474
  }
2369
2475
  }
2370
- function j(o, t, e) {
2371
- return Math.min(e, Math.max(t, o));
2372
- }
2373
- function lt(o, t, e) {
2374
- return o + (t - o) * e;
2375
- }
2376
- class Dt {
2476
+ class Rt {
2377
2477
  gl;
2378
2478
  hasColorBufferFloat;
2379
2479
  // FBO / texture resources
@@ -2421,15 +2521,15 @@ class Dt {
2421
2521
  createResources(t, e, n) {
2422
2522
  const i = this.gl;
2423
2523
  this.dispose();
2424
- const r = Math.max(1, Math.round(t / n)), s = Math.max(1, Math.round(e / n));
2425
- this._width = r, this._height = s;
2426
- const a = (u, h, f, c) => {
2427
- const E = i.createFramebuffer();
2428
- return i.bindFramebuffer(i.FRAMEBUFFER, E), i.bindTexture(i.TEXTURE_2D, u), i.texStorage2D(i.TEXTURE_2D, 1, h, f, c), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MIN_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MAG_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_S, i.CLAMP_TO_EDGE), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_T, i.CLAMP_TO_EDGE), i.framebufferTexture2D(i.FRAMEBUFFER, i.COLOR_ATTACHMENT0, i.TEXTURE_2D, u, 0), i.bindFramebuffer(i.FRAMEBUFFER, null), E;
2524
+ const r = Math.max(1, Math.round(t / n)), o = Math.max(1, Math.round(e / n));
2525
+ this._width = r, this._height = o;
2526
+ const l = (h, c, f, u) => {
2527
+ const x = i.createFramebuffer();
2528
+ return i.bindFramebuffer(i.FRAMEBUFFER, x), i.bindTexture(i.TEXTURE_2D, h), i.texStorage2D(i.TEXTURE_2D, 1, c, f, u), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MIN_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MAG_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_S, i.CLAMP_TO_EDGE), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_T, i.CLAMP_TO_EDGE), i.framebufferTexture2D(i.FRAMEBUFFER, i.COLOR_ATTACHMENT0, i.TEXTURE_2D, h, 0), i.bindFramebuffer(i.FRAMEBUFFER, null), x;
2429
2529
  };
2430
- this.maskTex = i.createTexture(), this.maskFbo = a(this.maskTex, i.R8, r, s);
2431
- const l = this.hasColorBufferFloat ? i.RG16F : i.RGBA8;
2432
- this.pingTex = i.createTexture(), this.pingFbo = a(this.pingTex, l, r, s), this.pongTex = i.createTexture(), this.pongFbo = a(this.pongTex, l, r, s), this.distTex = i.createTexture(), this.distFbo = a(this.distTex, i.RGBA8, r, s), this._dirty = !0;
2530
+ this.maskTex = i.createTexture(), this.maskFbo = l(this.maskTex, i.R8, r, o);
2531
+ const a = this.hasColorBufferFloat ? i.RG16F : i.RGBA8;
2532
+ this.pingTex = i.createTexture(), this.pingFbo = l(this.pingTex, a, r, o), this.pongTex = i.createTexture(), this.pongFbo = l(this.pongTex, a, r, o), this.distTex = i.createTexture(), this.distFbo = l(this.distTex, i.RGBA8, r, o), this._dirty = !0;
2433
2533
  }
2434
2534
  // -----------------------------------------------------------------------
2435
2535
  // Distance field computation
@@ -2448,16 +2548,16 @@ class Dt {
2448
2548
  const n = this._width, i = this._height;
2449
2549
  if (n === 0 || i === 0) return;
2450
2550
  e.viewport(0, 0, n, i), e.disable(e.STENCIL_TEST), e.disable(e.BLEND), e.bindFramebuffer(e.FRAMEBUFFER, this.maskFbo), e.clearColor(0, 0, 0, 1), e.clear(e.COLOR_BUFFER_BIT), e.useProgram(t.maskPass.program), e.uniform2f(t.maskPass.uniforms.uMeshScale, t.meshScaleX, t.meshScaleY), e.bindVertexArray(t.maskVao), e.drawElements(e.TRIANGLES, t.stencilIndexCount, e.UNSIGNED_SHORT, 0), e.bindFramebuffer(e.FRAMEBUFFER, this.pingFbo), e.clearColor(-1, -1, 0, 0), e.clear(e.COLOR_BUFFER_BIT), e.useProgram(t.seedPass.program), e.activeTexture(e.TEXTURE5), e.bindTexture(e.TEXTURE_2D, this.maskTex), e.uniform1i(t.seedPass.uniforms.uMask, 5), e.uniform2f(t.seedPass.uniforms.uTexelSize, 1 / n, 1 / i), e.bindVertexArray(t.quadVao), e.drawArrays(e.TRIANGLE_STRIP, 0, 4);
2451
- const r = Dt.computeFloodIterations(n, i);
2551
+ const r = Rt.computeFloodIterations(n, i);
2452
2552
  e.useProgram(t.floodPass.program);
2453
- let s = this.pingTex, a = this.pongFbo, l = this.pongTex;
2454
- for (let u = 0; u < r.length; u++) {
2455
- const h = r[u] / Math.max(n, i);
2456
- e.bindFramebuffer(e.FRAMEBUFFER, a), e.activeTexture(e.TEXTURE5), e.bindTexture(e.TEXTURE_2D, s), e.uniform1i(t.floodPass.uniforms.uSeedTex, 5), e.uniform1f(t.floodPass.uniforms.uStepSize, h), e.bindVertexArray(t.quadVao), e.drawArrays(e.TRIANGLE_STRIP, 0, 4);
2457
- const f = s, c = a;
2458
- s = l, a = c === this.pongFbo ? this.pingFbo : this.pongFbo, l = f;
2553
+ let o = this.pingTex, l = this.pongFbo, a = this.pongTex;
2554
+ for (let h = 0; h < r.length; h++) {
2555
+ const c = r[h] / Math.max(n, i);
2556
+ e.bindFramebuffer(e.FRAMEBUFFER, l), e.activeTexture(e.TEXTURE5), e.bindTexture(e.TEXTURE_2D, o), e.uniform1i(t.floodPass.uniforms.uSeedTex, 5), e.uniform1f(t.floodPass.uniforms.uStepSize, c), e.bindVertexArray(t.quadVao), e.drawArrays(e.TRIANGLE_STRIP, 0, 4);
2557
+ const f = o, u = l;
2558
+ o = a, l = u === this.pongFbo ? this.pingFbo : this.pongFbo, a = f;
2459
2559
  }
2460
- e.bindFramebuffer(e.FRAMEBUFFER, this.distFbo), e.clearColor(0, 0, 0, 1), e.clear(e.COLOR_BUFFER_BIT), e.useProgram(t.distPass.program), e.activeTexture(e.TEXTURE5), e.bindTexture(e.TEXTURE_2D, s), e.uniform1i(t.distPass.uniforms.uSeedTex, 5), e.activeTexture(e.TEXTURE6), e.bindTexture(e.TEXTURE_2D, this.maskTex), e.uniform1i(t.distPass.uniforms.uMask, 6), e.uniform1f(t.distPass.uniforms.uBevelWidth, t.distRange), e.bindVertexArray(t.quadVao), e.drawArrays(e.TRIANGLE_STRIP, 0, 4), e.activeTexture(e.TEXTURE4), e.bindTexture(e.TEXTURE_2D, this.distTex), e.bindFramebuffer(e.FRAMEBUFFER, null), this._dirty = !1;
2560
+ e.bindFramebuffer(e.FRAMEBUFFER, this.distFbo), e.clearColor(0, 0, 0, 1), e.clear(e.COLOR_BUFFER_BIT), e.useProgram(t.distPass.program), e.activeTexture(e.TEXTURE5), e.bindTexture(e.TEXTURE_2D, o), e.uniform1i(t.distPass.uniforms.uSeedTex, 5), e.activeTexture(e.TEXTURE6), e.bindTexture(e.TEXTURE_2D, this.maskTex), e.uniform1i(t.distPass.uniforms.uMask, 6), e.uniform1f(t.distPass.uniforms.uBevelWidth, t.distRange), e.bindVertexArray(t.quadVao), e.drawArrays(e.TRIANGLE_STRIP, 0, 4), e.activeTexture(e.TEXTURE4), e.bindTexture(e.TEXTURE_2D, this.distTex), e.bindFramebuffer(e.FRAMEBUFFER, null), this._dirty = !1;
2461
2561
  }
2462
2562
  // -----------------------------------------------------------------------
2463
2563
  // Flood iteration planning (shared between backends)
@@ -2481,34 +2581,34 @@ class Dt {
2481
2581
  this.maskTex && (t.deleteTexture(this.maskTex), this.maskTex = null), this.maskFbo && (t.deleteFramebuffer(this.maskFbo), this.maskFbo = null), this.pingTex && (t.deleteTexture(this.pingTex), this.pingTex = null), this.pingFbo && (t.deleteFramebuffer(this.pingFbo), this.pingFbo = null), this.pongTex && (t.deleteTexture(this.pongTex), this.pongTex = null), this.pongFbo && (t.deleteFramebuffer(this.pongFbo), this.pongFbo = null), this.distTex && (t.deleteTexture(this.distTex), this.distTex = null), this.distFbo && (t.deleteFramebuffer(this.distFbo), this.distFbo = null), this._width = 0, this._height = 0, this._dirty = !0;
2482
2582
  }
2483
2583
  }
2484
- const Ie = `#version 300 es
2584
+ const Le = `#version 300 es
2485
2585
  in vec2 aPosition;
2486
2586
  uniform vec2 uMeshScale;
2487
2587
  void main() {
2488
2588
  gl_Position = vec4(aPosition * uMeshScale, 0.0, 1.0);
2489
2589
  }
2490
- `, Be = `#version 300 es
2590
+ `, _e = `#version 300 es
2491
2591
  precision lowp float;
2492
2592
  out vec4 fragColor;
2493
2593
  void main() { fragColor = vec4(0.0); }
2494
- `, Ve = `#version 300 es
2594
+ `, Ie = `#version 300 es
2495
2595
  in vec2 aPosition;
2496
2596
  uniform vec2 uMeshScale;
2497
2597
  void main() {
2498
2598
  gl_Position = vec4(aPosition * uMeshScale, 0.0, 1.0);
2499
2599
  }
2500
- `, Oe = `#version 300 es
2600
+ `, Me = `#version 300 es
2501
2601
  precision lowp float;
2502
2602
  out vec4 fragColor;
2503
2603
  void main() { fragColor = vec4(1.0); }
2504
- `, ke = `#version 300 es
2604
+ `, Be = `#version 300 es
2505
2605
  in vec2 aPosition;
2506
2606
  out vec2 vUv;
2507
2607
  void main() {
2508
2608
  vUv = aPosition * 0.5 + 0.5;
2509
2609
  gl_Position = vec4(aPosition, 0.0, 1.0);
2510
2610
  }
2511
- `, Ne = `#version 300 es
2611
+ `, Ve = `#version 300 es
2512
2612
  precision highp float;
2513
2613
  uniform sampler2D uMask;
2514
2614
  uniform vec2 uTexelSize;
@@ -2533,14 +2633,14 @@ void main() {
2533
2633
  fragSeed = vec2(-1.0);
2534
2634
  }
2535
2635
  }
2536
- `, He = `#version 300 es
2636
+ `, ke = `#version 300 es
2537
2637
  in vec2 aPosition;
2538
2638
  out vec2 vUv;
2539
2639
  void main() {
2540
2640
  vUv = aPosition * 0.5 + 0.5;
2541
2641
  gl_Position = vec4(aPosition, 0.0, 1.0);
2542
2642
  }
2543
- `, Xe = `#version 300 es
2643
+ `, Oe = `#version 300 es
2544
2644
  precision highp float;
2545
2645
  uniform sampler2D uSeedTex;
2546
2646
  uniform float uStepSize;
@@ -2569,14 +2669,14 @@ void main() {
2569
2669
 
2570
2670
  fragSeed = bestSeed;
2571
2671
  }
2572
- `, Ge = `#version 300 es
2672
+ `, He = `#version 300 es
2573
2673
  in vec2 aPosition;
2574
2674
  out vec2 vUv;
2575
2675
  void main() {
2576
2676
  vUv = aPosition * 0.5 + 0.5;
2577
2677
  gl_Position = vec4(aPosition, 0.0, 1.0);
2578
2678
  }
2579
- `, We = `#version 300 es
2679
+ `, Ne = `#version 300 es
2580
2680
  precision highp float;
2581
2681
  uniform sampler2D uSeedTex;
2582
2682
  uniform sampler2D uMask;
@@ -2601,7 +2701,7 @@ void main() {
2601
2701
  float normalized = clamp(d / max(uBevelWidth, 0.001), 0.0, 1.0);
2602
2702
  fragDist = vec4(normalized, 0.0, 0.0, 1.0);
2603
2703
  }
2604
- `, ze = `#version 300 es
2704
+ `, Xe = `#version 300 es
2605
2705
  in vec2 aPosition;
2606
2706
  uniform vec2 uUvOffset;
2607
2707
  uniform vec2 uUvScale;
@@ -2613,7 +2713,7 @@ void main() {
2613
2713
  vScreenUv = baseUv;
2614
2714
  gl_Position = vec4(aPosition, 0.0, 1.0);
2615
2715
  }
2616
- `, qe = `#version 300 es
2716
+ `, Ge = `#version 300 es
2617
2717
  precision highp float;
2618
2718
 
2619
2719
  #define MAX_POM_STEPS 32
@@ -2744,14 +2844,14 @@ void main() {
2744
2844
  // Write lens-transformed depth to second attachment for boundary effects
2745
2845
  fragDepth = vec4(lensD, 0.0, 0.0, 1.0);
2746
2846
  }
2747
- `, Ye = `#version 300 es
2847
+ `, We = `#version 300 es
2748
2848
  in vec2 aPosition;
2749
2849
  out vec2 vUv;
2750
2850
  void main() {
2751
2851
  vUv = aPosition * 0.5 + 0.5;
2752
2852
  gl_Position = vec4(aPosition, 0.0, 1.0);
2753
2853
  }
2754
- `, je = `#version 300 es
2854
+ `, ze = `#version 300 es
2755
2855
  precision highp float;
2756
2856
  uniform sampler2D uInteriorColor;
2757
2857
  uniform sampler2D uDistField;
@@ -2781,7 +2881,7 @@ void main() {
2781
2881
 
2782
2882
  fragColor = vec4(toSRGB(linear), color.a);
2783
2883
  }
2784
- `, Ze = `#version 300 es
2884
+ `, qe = `#version 300 es
2785
2885
  in vec2 aPosition;
2786
2886
  in vec2 aNormal;
2787
2887
  uniform float uRimWidth;
@@ -2804,7 +2904,7 @@ void main() {
2804
2904
 
2805
2905
  gl_Position = vec4(pos, 0.0, 1.0);
2806
2906
  }
2807
- `, $e = `#version 300 es
2907
+ `, Ye = `#version 300 es
2808
2908
  precision highp float;
2809
2909
 
2810
2910
  uniform sampler2D uInteriorColor;
@@ -2906,7 +3006,7 @@ void main() {
2906
3006
 
2907
3007
  fragColor = vec4(color * alpha, alpha);
2908
3008
  }
2909
- `, Ke = `#version 300 es
3009
+ `, je = `#version 300 es
2910
3010
  in vec2 aPosition;
2911
3011
  in vec3 aNormal3;
2912
3012
  in float aLerpT; // 0 = inner (at silhouette), 1 = outer edge
@@ -2922,7 +3022,7 @@ void main() {
2922
3022
  vLerpT = aLerpT;
2923
3023
  gl_Position = vec4(sp, 0.0, 1.0);
2924
3024
  }
2925
- `, Je = `#version 300 es
3025
+ `, Ze = `#version 300 es
2926
3026
  precision highp float;
2927
3027
  uniform vec3 uLightDir3;
2928
3028
  uniform vec3 uChamferColor;
@@ -2990,38 +3090,38 @@ void main() {
2990
3090
  fragColor = vec4(toSRGB(lit), 1.0);
2991
3091
  }
2992
3092
  `;
2993
- function Qe(o) {
3093
+ function $e(s) {
2994
3094
  const t = [];
2995
3095
  let e = 0;
2996
- for (let n = 0; n < o.length - 2; n += 2) {
2997
- const i = o[n], r = o[n + 1], s = o[n + 2], a = o[n + 3], l = s - i, u = a - r, h = Math.sqrt(l * l + u * u);
2998
- if (h < 1e-6) continue;
2999
- const f = -u / h, c = l / h;
3096
+ for (let n = 0; n < s.length - 2; n += 2) {
3097
+ const i = s[n], r = s[n + 1], o = s[n + 2], l = s[n + 3], a = o - i, h = l - r, c = Math.sqrt(a * a + h * h);
3098
+ if (c < 1e-6) continue;
3099
+ const f = -h / c, u = a / c;
3000
3100
  t.push(
3001
3101
  i,
3002
3102
  r,
3003
3103
  f,
3004
- c,
3104
+ u,
3005
3105
  i,
3006
3106
  r,
3007
3107
  -f,
3008
- -c,
3009
- s,
3010
- a,
3108
+ -u,
3109
+ o,
3110
+ l,
3011
3111
  f,
3012
- c,
3013
- s,
3014
- a,
3112
+ u,
3113
+ o,
3114
+ l,
3015
3115
  f,
3016
- c,
3116
+ u,
3017
3117
  i,
3018
3118
  r,
3019
3119
  -f,
3020
- -c,
3021
- s,
3022
- a,
3120
+ -u,
3121
+ o,
3122
+ l,
3023
3123
  -f,
3024
- -c
3124
+ -u
3025
3125
  ), e += 6;
3026
3126
  }
3027
3127
  return {
@@ -3029,43 +3129,43 @@ function Qe(o) {
3029
3129
  count: e
3030
3130
  };
3031
3131
  }
3032
- function tn(o, t, e, n, i) {
3132
+ function Ke(s, t, e, n, i) {
3033
3133
  if (n <= 0)
3034
3134
  return { vertices: new Float32Array(0), count: 0 };
3035
- const r = i * Math.PI / 180, s = -Math.cos(r), a = Math.sin(r), l = [];
3036
- let u = 0;
3037
- for (let h = 0; h < t.length; h++) {
3038
- const f = t[h], v = ((h + 1 < t.length ? t[h + 1] : o.length) - f) / 2;
3039
- if (v < 3) continue;
3040
- const p = v - 1;
3041
- let P = 0;
3042
- for (let T = 0; T < p; T++) {
3043
- const m = f + T * 2, S = o[m], w = o[m + 1], F = o[m + 2], U = o[m + 3];
3044
- P += S * U - F * w;
3135
+ const r = i * Math.PI / 180, o = -Math.cos(r), l = Math.sin(r), a = [];
3136
+ let h = 0;
3137
+ for (let c = 0; c < t.length; c++) {
3138
+ const f = t[c], p = ((c + 1 < t.length ? t[c + 1] : s.length) - f) / 2;
3139
+ if (p < 3) continue;
3140
+ const d = p - 1;
3141
+ let y = 0;
3142
+ for (let T = 0; T < d; T++) {
3143
+ const w = f + T * 2, A = s[w], P = s[w + 1], F = s[w + 2], _ = s[w + 3];
3144
+ y += A * _ - F * P;
3045
3145
  }
3046
- const x = P >= 0 ? 1 : -1, y = [], d = [];
3047
- for (let T = 0; T < p; T++) {
3048
- const m = f + T * 2, S = o[m + 2] - o[m], w = o[m + 3] - o[m + 1], F = Math.sqrt(S * S + w * w);
3049
- F < 1e-8 ? (y.push(T > 0 ? y[T - 1] : 0), d.push(T > 0 ? d[T - 1] : 0)) : (y.push(-w / F * x), d.push(S / F * x));
3146
+ const E = y >= 0 ? 1 : -1, b = [], g = [];
3147
+ for (let T = 0; T < d; T++) {
3148
+ const w = f + T * 2, A = s[w + 2] - s[w], P = s[w + 3] - s[w + 1], F = Math.sqrt(A * A + P * P);
3149
+ F < 1e-8 ? (b.push(T > 0 ? b[T - 1] : 0), g.push(T > 0 ? g[T - 1] : 0)) : (b.push(-P / F * E), g.push(A / F * E));
3050
3150
  }
3051
- const g = [], b = [];
3052
- for (let T = 0; T < p; T++) {
3053
- const m = (T - 1 + p) % p;
3054
- let S = y[m] + y[T], w = d[m] + d[T];
3055
- const F = Math.sqrt(S * S + w * w);
3056
- F > 1e-8 ? (S /= F, w /= F) : (S = y[T], w = d[T]), g.push(S), b.push(w);
3151
+ const v = [], m = [];
3152
+ for (let T = 0; T < d; T++) {
3153
+ const w = (T - 1 + d) % d;
3154
+ let A = b[w] + b[T], P = g[w] + g[T];
3155
+ const F = Math.sqrt(A * A + P * P);
3156
+ F > 1e-8 ? (A /= F, P /= F) : (A = b[T], P = g[T]), v.push(A), m.push(P);
3057
3157
  }
3058
- for (let T = 0; T < p; T++) {
3059
- const m = T, S = (T + 1) % p, w = f + T * 2, F = f + (T + 1) % p * 2, U = o[w], _ = o[w + 1], R = o[F], D = o[F + 1], L = g[m] * a, M = b[m] * a, V = s, I = g[S] * a, N = b[S] * a, tt = s, st = U + g[m] * n, Ft = _ + b[m] * n, Qt = R + g[S] * n, te = D + b[S] * n;
3060
- l.push(U, _, L, M, V, 0), l.push(st, Ft, L, M, V, 1), l.push(R, D, I, N, tt, 0), l.push(R, D, I, N, tt, 0), l.push(st, Ft, L, M, V, 1), l.push(Qt, te, I, N, tt, 1), u += 6;
3158
+ for (let T = 0; T < d; T++) {
3159
+ const w = T, A = (T + 1) % d, P = f + T * 2, F = f + (T + 1) % d * 2, _ = s[P], I = s[P + 1], C = s[F], S = s[F + 1], D = v[w] * l, U = m[w] * l, M = o, k = v[A] * l, j = m[A] * l, et = o, at = _ + v[w] * n, At = I + m[w] * n, Jt = C + v[A] * n, Qt = S + m[A] * n;
3160
+ a.push(_, I, D, U, M, 0), a.push(at, At, D, U, M, 1), a.push(C, S, k, j, et, 0), a.push(C, S, k, j, et, 0), a.push(at, At, D, U, M, 1), a.push(Jt, Qt, k, j, et, 1), h += 6;
3061
3161
  }
3062
3162
  }
3063
3163
  return {
3064
- vertices: new Float32Array(l),
3065
- count: u
3164
+ vertices: new Float32Array(a),
3165
+ count: h
3066
3166
  };
3067
3167
  }
3068
- class en extends pt {
3168
+ class Je extends gt {
3069
3169
  gl = null;
3070
3170
  // Render passes (each owns its program + cached uniforms)
3071
3171
  stencilPass = null;
@@ -3114,7 +3214,7 @@ class en extends pt {
3114
3214
  this.lightDirX = Math.cos(n), this.lightDirY = Math.sin(n);
3115
3215
  const i = this.config.lightDirection, r = Math.sqrt(i[0] * i[0] + i[1] * i[1] + i[2] * i[2]);
3116
3216
  r > 1e-6 && (this.lightDir3 = [i[0] / r, i[1] / r, i[2] / r]);
3117
- const s = this.canvas.getContext("webgl2", {
3217
+ const o = this.canvas.getContext("webgl2", {
3118
3218
  antialias: !0,
3119
3219
  alpha: !0,
3120
3220
  premultipliedAlpha: !0,
@@ -3122,8 +3222,8 @@ class en extends pt {
3122
3222
  desynchronized: !0,
3123
3223
  powerPreference: "high-performance"
3124
3224
  });
3125
- if (!s) throw new Error("WebGL 2 is not supported.");
3126
- this.gl = s, this.qualityParams = Xt(s, e.quality), "drawingBufferColorSpace" in s && (s.drawingBufferColorSpace = "srgb"), this.hasColorBufferFloat = !!s.getExtension("EXT_color_buffer_float"), s.clearColor(0, 0, 0, 0), s.pixelStorei(s.UNPACK_FLIP_Y_WEBGL, !0), this.initGPUResources(), this.setupResizeHandling();
3225
+ if (!o) throw new Error("WebGL 2 is not supported.");
3226
+ this.gl = o, this.qualityParams = Nt(o, e.quality), "drawingBufferColorSpace" in o && (o.drawingBufferColorSpace = "srgb"), this.hasColorBufferFloat = !!o.getExtension("EXT_color_buffer_float"), o.clearColor(0, 0, 0, 0), o.pixelStorei(o.UNPACK_FLIP_Y_WEBGL, !0), this.initGPUResources(), this.setupResizeHandling();
3127
3227
  }
3128
3228
  initialize(t, e, n, i) {
3129
3229
  const r = this.gl;
@@ -3157,20 +3257,20 @@ class en extends pt {
3157
3257
  uploadBoundaryMesh(t) {
3158
3258
  const e = this.gl;
3159
3259
  if (!e || !this.boundaryPass) return;
3160
- const n = Qe(t.edgeVertices);
3260
+ const n = $e(t.edgeVertices);
3161
3261
  if (n.count === 0) return;
3162
3262
  this.boundaryVao = e.createVertexArray(), e.bindVertexArray(this.boundaryVao);
3163
3263
  const i = e.createBuffer();
3164
3264
  e.bindBuffer(e.ARRAY_BUFFER, i), e.bufferData(e.ARRAY_BUFFER, n.vertices, e.STATIC_DRAW);
3165
- const r = 16, s = e.getAttribLocation(this.boundaryPass.program, "aPosition");
3166
- e.enableVertexAttribArray(s), e.vertexAttribPointer(s, 2, e.FLOAT, !1, r, 0);
3167
- const a = e.getAttribLocation(this.boundaryPass.program, "aNormal");
3168
- a >= 0 && (e.enableVertexAttribArray(a), e.vertexAttribPointer(a, 2, e.FLOAT, !1, r, 8)), this.boundaryVertexCount = n.count, e.bindVertexArray(null);
3265
+ const r = 16, o = e.getAttribLocation(this.boundaryPass.program, "aPosition");
3266
+ e.enableVertexAttribArray(o), e.vertexAttribPointer(o, 2, e.FLOAT, !1, r, 0);
3267
+ const l = e.getAttribLocation(this.boundaryPass.program, "aNormal");
3268
+ l >= 0 && (e.enableVertexAttribArray(l), e.vertexAttribPointer(l, 2, e.FLOAT, !1, r, 8)), this.boundaryVertexCount = n.count, e.bindVertexArray(null);
3169
3269
  }
3170
3270
  uploadChamferMesh(t) {
3171
3271
  const e = this.gl;
3172
3272
  if (!e || !this.chamferPass || this.config.chamferWidth <= 0) return;
3173
- const n = tn(
3273
+ const n = Ke(
3174
3274
  t.edgeVertices,
3175
3275
  t.contourOffsets,
3176
3276
  t.contourIsHole,
@@ -3181,12 +3281,12 @@ class en extends pt {
3181
3281
  this.chamferVao = e.createVertexArray(), e.bindVertexArray(this.chamferVao);
3182
3282
  const i = e.createBuffer();
3183
3283
  e.bindBuffer(e.ARRAY_BUFFER, i), e.bufferData(e.ARRAY_BUFFER, n.vertices, e.STATIC_DRAW);
3184
- const r = 24, s = e.getAttribLocation(this.chamferPass.program, "aPosition");
3185
- e.enableVertexAttribArray(s), e.vertexAttribPointer(s, 2, e.FLOAT, !1, r, 0);
3186
- const a = e.getAttribLocation(this.chamferPass.program, "aNormal3");
3187
- a >= 0 && (e.enableVertexAttribArray(a), e.vertexAttribPointer(a, 3, e.FLOAT, !1, r, 8));
3188
- const l = e.getAttribLocation(this.chamferPass.program, "aLerpT");
3189
- l >= 0 && (e.enableVertexAttribArray(l), e.vertexAttribPointer(l, 1, e.FLOAT, !1, r, 20)), this.chamferVertexCount = n.count, e.bindVertexArray(null);
3284
+ const r = 24, o = e.getAttribLocation(this.chamferPass.program, "aPosition");
3285
+ e.enableVertexAttribArray(o), e.vertexAttribPointer(o, 2, e.FLOAT, !1, r, 0);
3286
+ const l = e.getAttribLocation(this.chamferPass.program, "aNormal3");
3287
+ l >= 0 && (e.enableVertexAttribArray(l), e.vertexAttribPointer(l, 3, e.FLOAT, !1, r, 8));
3288
+ const a = e.getAttribLocation(this.chamferPass.program, "aLerpT");
3289
+ a >= 0 && (e.enableVertexAttribArray(a), e.vertexAttribPointer(a, 1, e.FLOAT, !1, r, 20)), this.chamferVertexCount = n.count, e.bindVertexArray(null);
3190
3290
  }
3191
3291
  disposeChamferGeometry() {
3192
3292
  const t = this.gl;
@@ -3207,7 +3307,7 @@ class en extends pt {
3207
3307
  // -----------------------------------------------------------------------
3208
3308
  createJFAResources(t, e) {
3209
3309
  const n = this.gl;
3210
- n && (this.jfa || (this.jfa = new Dt(n, this.hasColorBufferFloat)), this.jfa.createResources(t, e, this.qualityParams.jfaDivisor));
3310
+ n && (this.jfa || (this.jfa = new Rt(n, this.hasColorBufferFloat)), this.jfa.createResources(t, e, this.qualityParams.jfaDivisor));
3211
3311
  }
3212
3312
  computeDistanceField() {
3213
3313
  !this.jfa || !this.maskPass || !this.jfaSeedPass || !this.jfaFloodPass || !this.jfaDistPass || !this.maskVao || !this.quadVao || this.jfa.compute({
@@ -3228,7 +3328,7 @@ class en extends pt {
3228
3328
  // -----------------------------------------------------------------------
3229
3329
  initGPUResources() {
3230
3330
  const t = this.gl;
3231
- t && (this.stencilPass = O(t, "stencil", Ie, Be, ["uMeshScale"]), this.maskPass = O(t, "mask", Ve, Oe, ["uMeshScale"]), this.jfaSeedPass = O(t, "jfa-seed", ke, Ne, ["uMask", "uTexelSize"]), this.jfaFloodPass = O(t, "jfa-flood", He, Xe, ["uSeedTex", "uStepSize"]), this.jfaDistPass = O(t, "jfa-dist", Ge, We, ["uSeedTex", "uMask", "uBevelWidth"]), this.interiorPass = O(t, "interior", ze, qe, [
3331
+ t && (this.stencilPass = O(t, "stencil", Le, _e, ["uMeshScale"]), this.maskPass = O(t, "mask", Ie, Me, ["uMeshScale"]), this.jfaSeedPass = O(t, "jfa-seed", Be, Ve, ["uMask", "uTexelSize"]), this.jfaFloodPass = O(t, "jfa-flood", ke, Oe, ["uSeedTex", "uStepSize"]), this.jfaDistPass = O(t, "jfa-dist", He, Ne, ["uSeedTex", "uMask", "uBevelWidth"]), this.interiorPass = O(t, "interior", Xe, Ge, [
3232
3332
  "uImage",
3233
3333
  "uDepth",
3234
3334
  "uOffset",
@@ -3249,12 +3349,12 @@ class en extends pt {
3249
3349
  "uBrightnessBias",
3250
3350
  "uUvOffset",
3251
3351
  "uUvScale"
3252
- ]), this.compositePass = O(t, "composite", Ye, je, [
3352
+ ]), this.compositePass = O(t, "composite", We, ze, [
3253
3353
  "uInteriorColor",
3254
3354
  "uDistField",
3255
3355
  "uEdgeOcclusionWidth",
3256
3356
  "uEdgeOcclusionStrength"
3257
- ]), this.boundaryPass = O(t, "boundary", Ze, $e, [
3357
+ ]), this.boundaryPass = O(t, "boundary", qe, Ye, [
3258
3358
  "uInteriorColor",
3259
3359
  "uInteriorDepth",
3260
3360
  "uDistField",
@@ -3271,7 +3371,7 @@ class en extends pt {
3271
3371
  "uEdgeColor",
3272
3372
  "uLightDir",
3273
3373
  "uBevelIntensity"
3274
- ]), this.chamferPass = O(t, "chamfer", Ke, Je, [
3374
+ ]), this.chamferPass = O(t, "chamfer", je, Ze, [
3275
3375
  "uMeshScale",
3276
3376
  "uLightDir3",
3277
3377
  "uChamferColor",
@@ -3280,7 +3380,7 @@ class en extends pt {
3280
3380
  "uChamferShininess",
3281
3381
  "uInteriorColor",
3282
3382
  "uTexelSize"
3283
- ]), this.quadVao = Nt(t, this.interiorPass.program), t.disable(t.DEPTH_TEST));
3383
+ ]), this.quadVao = Ot(t, this.interiorPass.program), t.disable(t.DEPTH_TEST));
3284
3384
  }
3285
3385
  // -----------------------------------------------------------------------
3286
3386
  // Abstract method implementations (RendererBase)
@@ -3296,11 +3396,15 @@ class en extends pt {
3296
3396
  if (!t || !this.interiorPass || !this.quadVao) return;
3297
3397
  const n = e?.getImageSource();
3298
3398
  if (!n || !this.interiorFbo || !this.interiorColorTex || !this.interiorDepthTex) return;
3299
- this.jfa?.isDirty && this.maskVao && (this.computeDistanceField(), t.viewport(0, 0, this.canvas.width, this.canvas.height)), t.activeTexture(t.TEXTURE0 + this.videoSlot.unit), t.bindTexture(t.TEXTURE_2D, this.videoSlot.texture), t.texImage2D(t.TEXTURE_2D, 0, t.RGBA, t.RGBA, t.UNSIGNED_BYTE, n), this.rvfcSupported || this.onDepthUpdate(e.currentTime);
3399
+ if (this.jfa?.isDirty && this.maskVao) {
3400
+ const o = this.qualityParams.jfaDivisor, l = Math.max(1, Math.round(this.canvas.width / o)), a = Math.max(1, Math.round(this.canvas.height / o));
3401
+ (this.jfa.width !== l || this.jfa.height !== a) && this.createJFAResources(this.canvas.width, this.canvas.height), this.computeDistanceField(), t.viewport(0, 0, this.canvas.width, this.canvas.height);
3402
+ }
3403
+ t.activeTexture(t.TEXTURE0 + this.videoSlot.unit), t.bindTexture(t.TEXTURE_2D, this.videoSlot.texture), t.texImage2D(t.TEXTURE_2D, 0, t.RGBA, t.RGBA, t.UNSIGNED_BYTE, n), this.rvfcSupported || this.onDepthUpdate(e.currentTime);
3300
3404
  let i = 0, r = 0;
3301
3405
  if (this.readInput) {
3302
- const s = this.readInput();
3303
- i = -s.x, r = s.y;
3406
+ const o = this.readInput();
3407
+ i = -o.x, r = o.y;
3304
3408
  }
3305
3409
  if (t.bindFramebuffer(t.FRAMEBUFFER, this.interiorFbo), t.checkFramebufferStatus(t.FRAMEBUFFER) !== t.FRAMEBUFFER_COMPLETE) {
3306
3410
  t.bindFramebuffer(t.FRAMEBUFFER, null);
@@ -3326,7 +3430,7 @@ class en extends pt {
3326
3430
  e.RED,
3327
3431
  e.UNSIGNED_BYTE,
3328
3432
  n
3329
- );
3433
+ ), this.jfa && this.jfa.markDirty();
3330
3434
  }
3331
3435
  // -----------------------------------------------------------------------
3332
3436
  // Resize handling
@@ -3334,12 +3438,10 @@ class en extends pt {
3334
3438
  recalculateViewportLayout() {
3335
3439
  const t = this.gl;
3336
3440
  if (!t) return;
3337
- const { width: e, height: n } = this.getViewportSize(), i = Math.min(window.devicePixelRatio, this.qualityParams.dprCap), r = Math.round(e * i), s = Math.round(n * i);
3338
- (this.canvas.width !== r || this.canvas.height !== s) && (this.canvas.width = r, this.canvas.height = s, t.viewport(0, 0, r, s)), (this.fboWidth !== r || this.fboHeight !== s) && this.createFBO(r, s);
3339
- const a = this.qualityParams.jfaDivisor, l = Math.max(1, Math.round(r / a)), u = Math.max(1, Math.round(s / a));
3340
- (!this.jfa || this.jfa.width !== l || this.jfa.height !== u) && this.createJFAResources(r, s), this.computeCoverFitUV(this.config.parallaxStrength, this.config.overscanPadding), this.interiorPass && (t.useProgram(this.interiorPass.program), t.uniform2f(this.interiorPass.uniforms.uUvOffset, this.uvOffset[0], this.uvOffset[1]), t.uniform2f(this.interiorPass.uniforms.uUvScale, this.uvScale[0], this.uvScale[1]));
3341
- const h = e / n, f = 0.65;
3342
- this.meshScaleX = f, this.meshScaleY = f, h > this.meshAspect ? this.meshScaleX = f * (this.meshAspect / h) : this.meshScaleY = f * (h / this.meshAspect), this.stencilPass && (t.useProgram(this.stencilPass.program), t.uniform2f(this.stencilPass.uniforms.uMeshScale, this.meshScaleX, this.meshScaleY)), this.boundaryPass && (t.useProgram(this.boundaryPass.program), t.uniform2f(this.boundaryPass.uniforms.uMeshScale, this.meshScaleX, this.meshScaleY), t.uniform1f(this.boundaryPass.uniforms.uRimWidth, this.config.rimLightWidth), t.uniform2f(this.boundaryPass.uniforms.uTexelSize, 1 / r, 1 / s)), this.chamferPass && (t.useProgram(this.chamferPass.program), t.uniform2f(this.chamferPass.uniforms.uMeshScale, this.meshScaleX, this.meshScaleY)), this.jfa && this.jfa.markDirty();
3441
+ const { width: e, height: n } = this.getViewportSize(), i = Math.min(window.devicePixelRatio, this.qualityParams.dprCap), r = Math.round(e * i), o = Math.round(n * i);
3442
+ (this.canvas.width !== r || this.canvas.height !== o) && (this.canvas.width = r, this.canvas.height = o, t.viewport(0, 0, r, o)), (this.fboWidth !== r || this.fboHeight !== o) && this.createFBO(r, o), this.jfa || this.createJFAResources(r, o), this.computeCoverFitUV(this.config.parallaxStrength, this.config.overscanPadding), this.interiorPass && (t.useProgram(this.interiorPass.program), t.uniform2f(this.interiorPass.uniforms.uUvOffset, this.uvOffset[0], this.uvOffset[1]), t.uniform2f(this.interiorPass.uniforms.uUvScale, this.uvScale[0], this.uvScale[1]));
3443
+ const l = e / n, a = 0.65;
3444
+ this.meshScaleX = a, this.meshScaleY = a, l > this.meshAspect ? this.meshScaleX = a * (this.meshAspect / l) : this.meshScaleY = a * (l / this.meshAspect), this.stencilPass && (t.useProgram(this.stencilPass.program), t.uniform2f(this.stencilPass.uniforms.uMeshScale, this.meshScaleX, this.meshScaleY)), this.boundaryPass && (t.useProgram(this.boundaryPass.program), t.uniform2f(this.boundaryPass.uniforms.uMeshScale, this.meshScaleX, this.meshScaleY), t.uniform1f(this.boundaryPass.uniforms.uRimWidth, this.config.rimLightWidth), t.uniform2f(this.boundaryPass.uniforms.uTexelSize, 1 / r, 1 / o)), this.chamferPass && (t.useProgram(this.chamferPass.program), t.uniform2f(this.chamferPass.uniforms.uMeshScale, this.meshScaleX, this.meshScaleY));
3343
3445
  }
3344
3446
  // -----------------------------------------------------------------------
3345
3447
  // Context loss
@@ -3397,336 +3499,336 @@ class en extends pt {
3397
3499
  this.stencilPass = null, this.maskPass = null, this.jfaSeedPass = null, this.jfaFloodPass = null, this.jfaDistPass = null, this.interiorPass = null, this.compositePass = null, this.boundaryPass = null, this.chamferPass = null, this.quadVao && (t.deleteVertexArray(this.quadVao), this.quadVao = null);
3398
3500
  }
3399
3501
  }
3400
- async function Et(o) {
3401
- const t = await fetch(o);
3502
+ async function Tt(s) {
3503
+ const t = await fetch(s);
3402
3504
  if (!t.ok)
3403
3505
  throw new Error(`Failed to fetch SVG: ${t.status} ${t.statusText}`);
3404
3506
  const e = await t.text();
3405
- return nn(e);
3507
+ return Qe(e);
3406
3508
  }
3407
- function nn(o) {
3408
- const n = new DOMParser().parseFromString(o, "image/svg+xml").querySelector("svg");
3509
+ function Qe(s) {
3510
+ const n = new DOMParser().parseFromString(s, "image/svg+xml").querySelector("svg");
3409
3511
  if (!n)
3410
3512
  throw new Error("No <svg> element found in document.");
3411
- const i = rn(n);
3513
+ const i = tn(n);
3412
3514
  if (i.length === 0)
3413
3515
  throw new Error("No path data found in SVG.");
3414
- let r = 1 / 0, s = 1 / 0, a = -1 / 0, l = -1 / 0;
3415
- for (const R of i)
3416
- for (let D = 0; D < R.length; D += 2)
3417
- r = Math.min(r, R[D]), a = Math.max(a, R[D]), s = Math.min(s, R[D + 1]), l = Math.max(l, R[D + 1]);
3418
- const u = a - r, h = l - s, f = (r + a) / 2, c = (s + l) / 2, E = 2 / Math.max(u, h), v = u / h, p = i.map((R) => {
3419
- const D = [];
3420
- for (let L = 0; L < R.length; L += 2)
3421
- D.push((R[L] - f) * E), D.push(-((R[L + 1] - c) * E));
3422
- return D;
3423
- }), P = fn(p), x = [], y = [];
3424
- for (const R of P) {
3425
- const { flatCoords: D, holeIndices: L } = cn(R), M = dn(D, L), V = x.length / 2;
3426
- for (const I of M)
3427
- y.push(I + V);
3428
- for (const I of D)
3429
- x.push(I);
3430
- }
3431
- const d = x, g = y, b = [], T = [], m = [], S = Yt(p);
3432
- for (let R = 0; R < p.length; R++) {
3433
- const D = p[R];
3434
- T.push(b.length), m.push(S[R]);
3435
- for (let L = 0; L < D.length; L++)
3436
- b.push(D[L]);
3437
- D.length >= 2 && b.push(D[0], D[1]);
3438
- }
3439
- let w = 1 / 0, F = 1 / 0, U = -1 / 0, _ = -1 / 0;
3440
- for (let R = 0; R < d.length; R += 2)
3441
- w = Math.min(w, d[R]), U = Math.max(U, d[R]), F = Math.min(F, d[R + 1]), _ = Math.max(_, d[R + 1]);
3516
+ let r = 1 / 0, o = 1 / 0, l = -1 / 0, a = -1 / 0;
3517
+ for (const C of i)
3518
+ for (let S = 0; S < C.length; S += 2)
3519
+ r = Math.min(r, C[S]), l = Math.max(l, C[S]), o = Math.min(o, C[S + 1]), a = Math.max(a, C[S + 1]);
3520
+ const h = l - r, c = a - o, f = (r + l) / 2, u = (o + a) / 2, x = 2 / Math.max(h, c), p = h / c, d = i.map((C) => {
3521
+ const S = [];
3522
+ for (let D = 0; D < C.length; D += 2)
3523
+ S.push((C[D] - f) * x), S.push(-((C[D + 1] - u) * x));
3524
+ return S;
3525
+ }), y = un(d), E = [], b = [];
3526
+ for (const C of y) {
3527
+ const { flatCoords: S, holeIndices: D } = ln(C), U = cn(S, D), M = E.length / 2;
3528
+ for (const k of U)
3529
+ b.push(k + M);
3530
+ for (const k of S)
3531
+ E.push(k);
3532
+ }
3533
+ const g = E, v = b, m = [], T = [], w = [], A = zt(d);
3534
+ for (let C = 0; C < d.length; C++) {
3535
+ const S = d[C];
3536
+ T.push(m.length), w.push(A[C]);
3537
+ for (let D = 0; D < S.length; D++)
3538
+ m.push(S[D]);
3539
+ S.length >= 2 && m.push(S[0], S[1]);
3540
+ }
3541
+ let P = 1 / 0, F = 1 / 0, _ = -1 / 0, I = -1 / 0;
3542
+ for (let C = 0; C < g.length; C += 2)
3543
+ P = Math.min(P, g[C]), _ = Math.max(_, g[C]), F = Math.min(F, g[C + 1]), I = Math.max(I, g[C + 1]);
3442
3544
  return {
3443
- vertices: new Float32Array(d),
3444
- indices: new Uint16Array(g),
3445
- edgeVertices: new Float32Array(b),
3545
+ vertices: new Float32Array(g),
3546
+ indices: new Uint16Array(v),
3547
+ edgeVertices: new Float32Array(m),
3446
3548
  contourOffsets: T,
3447
- contourIsHole: m,
3448
- bounds: { minX: w, maxX: U, minY: F, maxY: _ },
3449
- aspect: v
3549
+ contourIsHole: w,
3550
+ bounds: { minX: P, maxX: _, minY: F, maxY: I },
3551
+ aspect: p
3450
3552
  };
3451
3553
  }
3452
- function rn(o) {
3554
+ function tn(s) {
3453
3555
  const t = [];
3454
- return o.querySelectorAll("path").forEach((l) => {
3455
- const u = l.getAttribute("d");
3456
- if (!u) return;
3457
- const h = an(u);
3458
- t.push(...h);
3459
- }), o.querySelectorAll("polygon").forEach((l) => {
3460
- const u = l.getAttribute("points");
3461
- if (!u) return;
3462
- const h = Mt(u);
3463
- h.length >= 6 && t.push(h);
3464
- }), o.querySelectorAll("polyline").forEach((l) => {
3465
- const u = l.getAttribute("points");
3466
- if (!u) return;
3467
- const h = Mt(u);
3468
- h.length >= 6 && t.push(h);
3469
- }), o.querySelectorAll("rect").forEach((l) => {
3470
- const u = parseFloat(l.getAttribute("x") || "0"), h = parseFloat(l.getAttribute("y") || "0"), f = parseFloat(l.getAttribute("width") || "0"), c = parseFloat(l.getAttribute("height") || "0");
3471
- f > 0 && c > 0 && t.push([u, h, u + f, h, u + f, h + c, u, h + c]);
3472
- }), o.querySelectorAll("circle").forEach((l) => {
3473
- const u = parseFloat(l.getAttribute("cx") || "0"), h = parseFloat(l.getAttribute("cy") || "0"), f = parseFloat(l.getAttribute("r") || "0");
3474
- f > 0 && t.push(on(u, h, f));
3475
- }), o.querySelectorAll("ellipse").forEach((l) => {
3476
- const u = parseFloat(l.getAttribute("cx") || "0"), h = parseFloat(l.getAttribute("cy") || "0"), f = parseFloat(l.getAttribute("rx") || "0"), c = parseFloat(l.getAttribute("ry") || "0");
3477
- f > 0 && c > 0 && t.push(sn(u, h, f, c));
3556
+ return s.querySelectorAll("path").forEach((a) => {
3557
+ const h = a.getAttribute("d");
3558
+ if (!h) return;
3559
+ const c = rn(h);
3560
+ t.push(...c);
3561
+ }), s.querySelectorAll("polygon").forEach((a) => {
3562
+ const h = a.getAttribute("points");
3563
+ if (!h) return;
3564
+ const c = _t(h);
3565
+ c.length >= 6 && t.push(c);
3566
+ }), s.querySelectorAll("polyline").forEach((a) => {
3567
+ const h = a.getAttribute("points");
3568
+ if (!h) return;
3569
+ const c = _t(h);
3570
+ c.length >= 6 && t.push(c);
3571
+ }), s.querySelectorAll("rect").forEach((a) => {
3572
+ const h = parseFloat(a.getAttribute("x") || "0"), c = parseFloat(a.getAttribute("y") || "0"), f = parseFloat(a.getAttribute("width") || "0"), u = parseFloat(a.getAttribute("height") || "0");
3573
+ f > 0 && u > 0 && t.push([h, c, h + f, c, h + f, c + u, h, c + u]);
3574
+ }), s.querySelectorAll("circle").forEach((a) => {
3575
+ const h = parseFloat(a.getAttribute("cx") || "0"), c = parseFloat(a.getAttribute("cy") || "0"), f = parseFloat(a.getAttribute("r") || "0");
3576
+ f > 0 && t.push(en(h, c, f));
3577
+ }), s.querySelectorAll("ellipse").forEach((a) => {
3578
+ const h = parseFloat(a.getAttribute("cx") || "0"), c = parseFloat(a.getAttribute("cy") || "0"), f = parseFloat(a.getAttribute("rx") || "0"), u = parseFloat(a.getAttribute("ry") || "0");
3579
+ f > 0 && u > 0 && t.push(nn(h, c, f, u));
3478
3580
  }), t;
3479
3581
  }
3480
- function Mt(o) {
3481
- const t = [], e = o.trim().split(/[\s,]+/);
3582
+ function _t(s) {
3583
+ const t = [], e = s.trim().split(/[\s,]+/);
3482
3584
  for (let n = 0; n < e.length - 1; n += 2) {
3483
3585
  const i = parseFloat(e[n]), r = parseFloat(e[n + 1]);
3484
3586
  Number.isFinite(i) && Number.isFinite(r) && t.push(i, r);
3485
3587
  }
3486
3588
  return t;
3487
3589
  }
3488
- function on(o, t, e, n = 64) {
3590
+ function en(s, t, e, n = 64) {
3489
3591
  const i = [];
3490
3592
  for (let r = 0; r < n; r++) {
3491
- const s = 2 * Math.PI * r / n;
3492
- i.push(o + e * Math.cos(s), t + e * Math.sin(s));
3593
+ const o = 2 * Math.PI * r / n;
3594
+ i.push(s + e * Math.cos(o), t + e * Math.sin(o));
3493
3595
  }
3494
3596
  return i;
3495
3597
  }
3496
- function sn(o, t, e, n, i = 64) {
3598
+ function nn(s, t, e, n, i = 64) {
3497
3599
  const r = [];
3498
- for (let s = 0; s < i; s++) {
3499
- const a = 2 * Math.PI * s / i;
3500
- r.push(o + e * Math.cos(a), t + n * Math.sin(a));
3600
+ for (let o = 0; o < i; o++) {
3601
+ const l = 2 * Math.PI * o / i;
3602
+ r.push(s + e * Math.cos(l), t + n * Math.sin(l));
3501
3603
  }
3502
3604
  return r;
3503
3605
  }
3504
- function an(o) {
3606
+ function rn(s) {
3505
3607
  const t = [];
3506
- let e = [], n = 0, i = 0, r = 0, s = 0, a = 0, l = 0, u = "";
3507
- const h = ln(o);
3608
+ let e = [], n = 0, i = 0, r = 0, o = 0, l = 0, a = 0, h = "";
3609
+ const c = sn(s);
3508
3610
  let f = 0;
3509
- function c() {
3510
- return f >= h.length ? 0 : parseFloat(h[f++]);
3511
- }
3512
- for (; f < h.length; ) {
3513
- const E = h[f];
3514
- let v;
3515
- /^[a-zA-Z]$/.test(E) ? (v = E, f++) : v = u === "M" ? "L" : u === "m" ? "l" : u;
3516
- const p = v === v.toLowerCase();
3517
- switch (v.toUpperCase()) {
3611
+ function u() {
3612
+ return f >= c.length ? 0 : parseFloat(c[f++]);
3613
+ }
3614
+ for (; f < c.length; ) {
3615
+ const x = c[f];
3616
+ let p;
3617
+ /^[a-zA-Z]$/.test(x) ? (p = x, f++) : p = h === "M" ? "L" : h === "m" ? "l" : h;
3618
+ const d = p === p.toLowerCase();
3619
+ switch (p.toUpperCase()) {
3518
3620
  case "M": {
3519
3621
  e.length > 0 && t.push(e), e = [];
3520
- const x = c() + (p ? n : 0), y = c() + (p ? i : 0);
3521
- n = x, i = y, r = x, s = y, e.push(n, i), a = n, l = i;
3622
+ const E = u() + (d ? n : 0), b = u() + (d ? i : 0);
3623
+ n = E, i = b, r = E, o = b, e.push(n, i), l = n, a = i;
3522
3624
  break;
3523
3625
  }
3524
3626
  case "L": {
3525
- n = c() + (p ? n : 0), i = c() + (p ? i : 0), e.push(n, i), a = n, l = i;
3627
+ n = u() + (d ? n : 0), i = u() + (d ? i : 0), e.push(n, i), l = n, a = i;
3526
3628
  break;
3527
3629
  }
3528
3630
  case "H": {
3529
- n = c() + (p ? n : 0), e.push(n, i), a = n, l = i;
3631
+ n = u() + (d ? n : 0), e.push(n, i), l = n, a = i;
3530
3632
  break;
3531
3633
  }
3532
3634
  case "V": {
3533
- i = c() + (p ? i : 0), e.push(n, i), a = n, l = i;
3635
+ i = u() + (d ? i : 0), e.push(n, i), l = n, a = i;
3534
3636
  break;
3535
3637
  }
3536
3638
  case "C": {
3537
- const x = c() + (p ? n : 0), y = c() + (p ? i : 0), d = c() + (p ? n : 0), g = c() + (p ? i : 0), b = c() + (p ? n : 0), T = c() + (p ? i : 0);
3538
- nt(e, n, i, x, y, d, g, b, T), n = b, i = T, a = d, l = g;
3639
+ const E = u() + (d ? n : 0), b = u() + (d ? i : 0), g = u() + (d ? n : 0), v = u() + (d ? i : 0), m = u() + (d ? n : 0), T = u() + (d ? i : 0);
3640
+ it(e, n, i, E, b, g, v, m, T), n = m, i = T, l = g, a = v;
3539
3641
  break;
3540
3642
  }
3541
3643
  case "S": {
3542
- const x = 2 * n - a, y = 2 * i - l, d = c() + (p ? n : 0), g = c() + (p ? i : 0), b = c() + (p ? n : 0), T = c() + (p ? i : 0);
3543
- nt(e, n, i, x, y, d, g, b, T), n = b, i = T, a = d, l = g;
3644
+ const E = 2 * n - l, b = 2 * i - a, g = u() + (d ? n : 0), v = u() + (d ? i : 0), m = u() + (d ? n : 0), T = u() + (d ? i : 0);
3645
+ it(e, n, i, E, b, g, v, m, T), n = m, i = T, l = g, a = v;
3544
3646
  break;
3545
3647
  }
3546
3648
  case "Q": {
3547
- const x = c() + (p ? n : 0), y = c() + (p ? i : 0), d = c() + (p ? n : 0), g = c() + (p ? i : 0);
3548
- It(e, n, i, x, y, d, g), n = d, i = g, a = x, l = y;
3649
+ const E = u() + (d ? n : 0), b = u() + (d ? i : 0), g = u() + (d ? n : 0), v = u() + (d ? i : 0);
3650
+ It(e, n, i, E, b, g, v), n = g, i = v, l = E, a = b;
3549
3651
  break;
3550
3652
  }
3551
3653
  case "T": {
3552
- const x = 2 * n - a, y = 2 * i - l, d = c() + (p ? n : 0), g = c() + (p ? i : 0);
3553
- It(e, n, i, x, y, d, g), n = d, i = g, a = x, l = y;
3654
+ const E = 2 * n - l, b = 2 * i - a, g = u() + (d ? n : 0), v = u() + (d ? i : 0);
3655
+ It(e, n, i, E, b, g, v), n = g, i = v, l = E, a = b;
3554
3656
  break;
3555
3657
  }
3556
3658
  case "A": {
3557
- const x = c(), y = c(), d = c(), g = c(), b = c(), T = c() + (p ? n : 0), m = c() + (p ? i : 0);
3558
- un(e, n, i, x, y, d, !!g, !!b, T, m), n = T, i = m, a = n, l = i;
3659
+ const E = u(), b = u(), g = u(), v = u(), m = u(), T = u() + (d ? n : 0), w = u() + (d ? i : 0);
3660
+ an(e, n, i, E, b, g, !!v, !!m, T, w), n = T, i = w, l = n, a = i;
3559
3661
  break;
3560
3662
  }
3561
3663
  case "Z": {
3562
- n = r, i = s, e.length > 0 && t.push(e), e = [], a = n, l = i;
3664
+ n = r, i = o, e.length > 0 && t.push(e), e = [], l = n, a = i;
3563
3665
  break;
3564
3666
  }
3565
3667
  default:
3566
3668
  f++;
3567
3669
  break;
3568
3670
  }
3569
- u = v;
3671
+ h = p;
3570
3672
  }
3571
3673
  return e.length >= 6 && t.push(e), t;
3572
3674
  }
3573
- function ln(o) {
3675
+ function sn(s) {
3574
3676
  const t = [], e = /([a-zA-Z])|([+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?)/g;
3575
3677
  let n;
3576
- for (; (n = e.exec(o)) !== null; )
3678
+ for (; (n = e.exec(s)) !== null; )
3577
3679
  t.push(n[0]);
3578
3680
  return t;
3579
3681
  }
3580
- const hn = 0.5;
3581
- function nt(o, t, e, n, i, r, s, a, l, u = 0) {
3582
- if (u > 12) {
3583
- o.push(a, l);
3682
+ const on = 0.5;
3683
+ function it(s, t, e, n, i, r, o, l, a, h = 0) {
3684
+ if (h > 12) {
3685
+ s.push(l, a);
3584
3686
  return;
3585
3687
  }
3586
- const h = a - t, f = l - e, c = Math.sqrt(h * h + f * f);
3587
- if (c < 1e-6) {
3588
- o.push(a, l);
3688
+ const c = l - t, f = a - e, u = Math.sqrt(c * c + f * f);
3689
+ if (u < 1e-6) {
3690
+ s.push(l, a);
3589
3691
  return;
3590
3692
  }
3591
- const E = Math.abs((n - a) * f - (i - l) * h) / c, v = Math.abs((r - a) * f - (s - l) * h) / c;
3592
- if (E + v < hn) {
3593
- o.push(a, l);
3693
+ const x = Math.abs((n - l) * f - (i - a) * c) / u, p = Math.abs((r - l) * f - (o - a) * c) / u;
3694
+ if (x + p < on) {
3695
+ s.push(l, a);
3594
3696
  return;
3595
3697
  }
3596
- const p = (t + n) / 2, P = (e + i) / 2, x = (n + r) / 2, y = (i + s) / 2, d = (r + a) / 2, g = (s + l) / 2, b = (p + x) / 2, T = (P + y) / 2, m = (x + d) / 2, S = (y + g) / 2, w = (b + m) / 2, F = (T + S) / 2;
3597
- nt(o, t, e, p, P, b, T, w, F, u + 1), nt(o, w, F, m, S, d, g, a, l, u + 1);
3698
+ const d = (t + n) / 2, y = (e + i) / 2, E = (n + r) / 2, b = (i + o) / 2, g = (r + l) / 2, v = (o + a) / 2, m = (d + E) / 2, T = (y + b) / 2, w = (E + g) / 2, A = (b + v) / 2, P = (m + w) / 2, F = (T + A) / 2;
3699
+ it(s, t, e, d, y, m, T, P, F, h + 1), it(s, P, F, w, A, g, v, l, a, h + 1);
3598
3700
  }
3599
- function It(o, t, e, n, i, r, s) {
3600
- const a = t + 0.6666666666666666 * (n - t), l = e + 2 / 3 * (i - e), u = r + 2 / 3 * (n - r), h = s + 2 / 3 * (i - s);
3601
- nt(o, t, e, a, l, u, h, r, s);
3701
+ function It(s, t, e, n, i, r, o) {
3702
+ const l = t + 0.6666666666666666 * (n - t), a = e + 2 / 3 * (i - e), h = r + 2 / 3 * (n - r), c = o + 2 / 3 * (i - o);
3703
+ it(s, t, e, l, a, h, c, r, o);
3602
3704
  }
3603
- function un(o, t, e, n, i, r, s, a, l, u) {
3705
+ function an(s, t, e, n, i, r, o, l, a, h) {
3604
3706
  if (n === 0 || i === 0) {
3605
- o.push(l, u);
3707
+ s.push(a, h);
3606
3708
  return;
3607
3709
  }
3608
- let h = Math.abs(n), f = Math.abs(i);
3609
- const c = r * Math.PI / 180, E = Math.cos(c), v = Math.sin(c), p = (t - l) / 2, P = (e - u) / 2, x = E * p + v * P, y = -v * p + E * P;
3610
- let d = x * x / (h * h) + y * y / (f * f);
3611
- if (d > 1) {
3612
- const M = Math.sqrt(d);
3613
- h *= M, f *= M, d = 1;
3614
- }
3615
- const g = h * h, b = f * f, T = x * x, m = y * y;
3616
- let S = Math.max(0, (g * b - g * m - b * T) / (g * m + b * T));
3617
- S = Math.sqrt(S), s === a && (S = -S);
3618
- const w = S * (h * y) / f, F = S * -(f * x) / h, U = E * w - v * F + (t + l) / 2, _ = v * w + E * F + (e + u) / 2, R = Bt(1, 0, (x - w) / h, (y - F) / f);
3619
- let D = Bt(
3620
- (x - w) / h,
3621
- (y - F) / f,
3622
- (-x - w) / h,
3623
- (-y - F) / f
3710
+ let c = Math.abs(n), f = Math.abs(i);
3711
+ const u = r * Math.PI / 180, x = Math.cos(u), p = Math.sin(u), d = (t - a) / 2, y = (e - h) / 2, E = x * d + p * y, b = -p * d + x * y;
3712
+ let g = E * E / (c * c) + b * b / (f * f);
3713
+ if (g > 1) {
3714
+ const U = Math.sqrt(g);
3715
+ c *= U, f *= U, g = 1;
3716
+ }
3717
+ const v = c * c, m = f * f, T = E * E, w = b * b;
3718
+ let A = Math.max(0, (v * m - v * w - m * T) / (v * w + m * T));
3719
+ A = Math.sqrt(A), o === l && (A = -A);
3720
+ const P = A * (c * b) / f, F = A * -(f * E) / c, _ = x * P - p * F + (t + a) / 2, I = p * P + x * F + (e + h) / 2, C = Mt(1, 0, (E - P) / c, (b - F) / f);
3721
+ let S = Mt(
3722
+ (E - P) / c,
3723
+ (b - F) / f,
3724
+ (-E - P) / c,
3725
+ (-b - F) / f
3624
3726
  );
3625
- !a && D > 0 && (D -= 2 * Math.PI), a && D < 0 && (D += 2 * Math.PI);
3626
- const L = Math.max(4, Math.ceil(Math.abs(D) / (Math.PI / 16)));
3627
- for (let M = 1; M <= L; M++) {
3628
- const V = R + M / L * D, I = Math.cos(V), N = Math.sin(V), tt = E * h * I - v * f * N + U, st = v * h * I + E * f * N + _;
3629
- o.push(tt, st);
3727
+ !l && S > 0 && (S -= 2 * Math.PI), l && S < 0 && (S += 2 * Math.PI);
3728
+ const D = Math.max(4, Math.ceil(Math.abs(S) / (Math.PI / 16)));
3729
+ for (let U = 1; U <= D; U++) {
3730
+ const M = C + U / D * S, k = Math.cos(M), j = Math.sin(M), et = x * c * k - p * f * j + _, at = p * c * k + x * f * j + I;
3731
+ s.push(et, at);
3630
3732
  }
3631
3733
  }
3632
- function Bt(o, t, e, n) {
3633
- const i = o * n - t * e < 0 ? -1 : 1, r = o * e + t * n, s = Math.sqrt(o * o + t * t), a = Math.sqrt(e * e + n * n), l = r / (s * a);
3634
- return i * Math.acos(Math.max(-1, Math.min(1, l)));
3734
+ function Mt(s, t, e, n) {
3735
+ const i = s * n - t * e < 0 ? -1 : 1, r = s * e + t * n, o = Math.sqrt(s * s + t * t), l = Math.sqrt(e * e + n * n), a = r / (o * l);
3736
+ return i * Math.acos(Math.max(-1, Math.min(1, a)));
3635
3737
  }
3636
- function cn(o) {
3738
+ function ln(s) {
3637
3739
  const t = [], e = [];
3638
- for (let n = 0; n < o.length; n++) {
3740
+ for (let n = 0; n < s.length; n++) {
3639
3741
  n > 0 && e.push(t.length / 2);
3640
- for (const i of o[n])
3742
+ for (const i of s[n])
3641
3743
  t.push(i);
3642
3744
  }
3643
3745
  return { flatCoords: t, holeIndices: e };
3644
3746
  }
3645
- function Yt(o) {
3646
- const t = o.length, e = o.map((i) => Math.abs(jt(i))), n = new Array(t).fill(!1);
3747
+ function zt(s) {
3748
+ const t = s.length, e = s.map((i) => Math.abs(qt(i))), n = new Array(t).fill(!1);
3647
3749
  for (let i = 0; i < t; i++) {
3648
3750
  let r = 0;
3649
- const s = o[i][0], a = o[i][1];
3650
- for (let l = 0; l < t; l++)
3651
- i !== l && e[l] > e[i] && Zt(s, a, o[l]) && r++;
3751
+ const o = s[i][0], l = s[i][1];
3752
+ for (let a = 0; a < t; a++)
3753
+ i !== a && e[a] > e[i] && Yt(o, l, s[a]) && r++;
3652
3754
  n[i] = r % 2 === 1;
3653
3755
  }
3654
3756
  return n;
3655
3757
  }
3656
- function fn(o) {
3657
- if (o.length <= 1)
3658
- return [o];
3659
- const t = Yt(o), e = o.map((s, a) => {
3660
- const l = jt(s);
3661
- return { index: a, contour: s, area: l, isOuter: !t[a] };
3662
- }), n = e.filter((s) => s.isOuter), i = e.filter((s) => !s.isOuter);
3758
+ function un(s) {
3759
+ if (s.length <= 1)
3760
+ return [s];
3761
+ const t = zt(s), e = s.map((o, l) => {
3762
+ const a = qt(o);
3763
+ return { index: l, contour: o, area: a, isOuter: !t[l] };
3764
+ }), n = e.filter((o) => o.isOuter), i = e.filter((o) => !o.isOuter);
3663
3765
  if (n.length === 0)
3664
- return o.map((s) => [s]);
3665
- const r = n.map((s) => ({
3666
- outer: s.contour,
3766
+ return s.map((o) => [o]);
3767
+ const r = n.map((o) => ({
3768
+ outer: o.contour,
3667
3769
  holes: []
3668
3770
  }));
3669
- for (const s of i) {
3670
- const a = s.contour[0], l = s.contour[1];
3671
- let u = -1, h = 1 / 0;
3771
+ for (const o of i) {
3772
+ const l = o.contour[0], a = o.contour[1];
3773
+ let h = -1, c = 1 / 0;
3672
3774
  for (let f = 0; f < n.length; f++)
3673
- if (Zt(a, l, n[f].contour)) {
3674
- const c = Math.abs(n[f].area);
3675
- c < h && (h = c, u = f);
3775
+ if (Yt(l, a, n[f].contour)) {
3776
+ const u = Math.abs(n[f].area);
3777
+ u < c && (c = u, h = f);
3676
3778
  }
3677
- u >= 0 ? r[u].holes.push(s.contour) : r.push({ outer: s.contour, holes: [] });
3779
+ h >= 0 ? r[h].holes.push(o.contour) : r.push({ outer: o.contour, holes: [] });
3678
3780
  }
3679
- return r.map((s) => [s.outer, ...s.holes]);
3781
+ return r.map((o) => [o.outer, ...o.holes]);
3680
3782
  }
3681
- function jt(o) {
3783
+ function qt(s) {
3682
3784
  let t = 0;
3683
- const e = o.length;
3785
+ const e = s.length;
3684
3786
  for (let n = 0; n < e; n += 2) {
3685
- const i = o[n], r = o[n + 1], s = o[(n + 2) % e], a = o[(n + 3) % e];
3686
- t += i * a - s * r;
3787
+ const i = s[n], r = s[n + 1], o = s[(n + 2) % e], l = s[(n + 3) % e];
3788
+ t += i * l - o * r;
3687
3789
  }
3688
3790
  return t / 2;
3689
3791
  }
3690
- function Zt(o, t, e) {
3792
+ function Yt(s, t, e) {
3691
3793
  let n = !1;
3692
3794
  const i = e.length;
3693
- for (let r = 0, s = i - 2; r < i; s = r, r += 2) {
3694
- const a = e[r], l = e[r + 1], u = e[s], h = e[s + 1];
3695
- l > t != h > t && o < (u - a) * (t - l) / (h - l) + a && (n = !n);
3795
+ for (let r = 0, o = i - 2; r < i; o = r, r += 2) {
3796
+ const l = e[r], a = e[r + 1], h = e[o], c = e[o + 1];
3797
+ a > t != c > t && s < (h - l) * (t - a) / (c - a) + l && (n = !n);
3696
3798
  }
3697
3799
  return n;
3698
3800
  }
3699
- function dn(o, t, e = 2) {
3700
- const n = t && t.length > 0, i = n ? t[0] * e : o.length;
3701
- let r = $t(o, 0, i, e, !0);
3702
- const s = [];
3703
- if (!r || r.next === r.prev) return s;
3704
- n && (r = xn(o, t, r, e));
3705
- let a = 1 / 0, l = 1 / 0, u = -1 / 0, h = -1 / 0, f = 0;
3706
- if (o.length > 80 * e) {
3707
- for (let c = 0; c < i; c += e) {
3708
- const E = o[c], v = o[c + 1];
3709
- E < a && (a = E), v < l && (l = v), E > u && (u = E), v > h && (h = v);
3801
+ function cn(s, t, e = 2) {
3802
+ const n = t && t.length > 0, i = n ? t[0] * e : s.length;
3803
+ let r = jt(s, 0, i, e, !0);
3804
+ const o = [];
3805
+ if (!r || r.next === r.prev) return o;
3806
+ n && (r = pn(s, t, r, e));
3807
+ let l = 1 / 0, a = 1 / 0, h = -1 / 0, c = -1 / 0, f = 0;
3808
+ if (s.length > 80 * e) {
3809
+ for (let u = 0; u < i; u += e) {
3810
+ const x = s[u], p = s[u + 1];
3811
+ x < l && (l = x), p < a && (a = p), x > h && (h = x), p > c && (c = p);
3710
3812
  }
3711
- f = Math.max(u - a, h - l), f = f !== 0 ? 32767 / f : 0;
3813
+ f = Math.max(h - l, c - a), f = f !== 0 ? 32767 / f : 0;
3712
3814
  }
3713
- return it(r, s, e, a, l, f, 0), s;
3815
+ return rt(r, o, e, l, a, f, 0), o;
3714
3816
  }
3715
- function $t(o, t, e, n, i) {
3817
+ function jt(s, t, e, n, i) {
3716
3818
  let r = null;
3717
- if (i === Pn(o, t, e, n) > 0)
3718
- for (let s = t; s < e; s += n)
3719
- r = Vt(s, o[s], o[s + 1], r);
3819
+ if (i === Rn(s, t, e, n) > 0)
3820
+ for (let o = t; o < e; o += n)
3821
+ r = Bt(o, s[o], s[o + 1], r);
3720
3822
  else
3721
- for (let s = e - n; s >= t; s -= n)
3722
- r = Vt(s, o[s], o[s + 1], r);
3723
- return r && gt(r, r.next) && (ot(r), r = r.next), r ? (r.next.prev = r, r.prev.next = r, r.next) : null;
3823
+ for (let o = e - n; o >= t; o -= n)
3824
+ r = Bt(o, s[o], s[o + 1], r);
3825
+ return r && vt(r, r.next) && (ot(r), r = r.next), r ? (r.next.prev = r, r.prev.next = r, r.next) : null;
3724
3826
  }
3725
- function W(o, t) {
3726
- t || (t = o);
3727
- let e = o, n;
3827
+ function Y(s, t) {
3828
+ t || (t = s);
3829
+ let e = s, n;
3728
3830
  do
3729
- if (n = !1, !e.steiner && (gt(e, e.next) || C(e.prev, e, e.next) === 0)) {
3831
+ if (n = !1, !e.steiner && (vt(e, e.next) || L(e.prev, e, e.next) === 0)) {
3730
3832
  if (ot(e), e = t = e.prev, e === e.next) break;
3731
3833
  n = !0;
3732
3834
  } else
@@ -3734,215 +3836,215 @@ function W(o, t) {
3734
3836
  while (n || e !== t);
3735
3837
  return t;
3736
3838
  }
3737
- function it(o, t, e, n, i, r, s) {
3738
- if (!o) return;
3739
- !s && r && yn(o, n, i, r);
3740
- let a = o, l, u;
3741
- for (; o.prev !== o.next; ) {
3742
- if (l = o.prev, u = o.next, r ? pn(o, n, i, r) : mn(o)) {
3743
- t.push(l.i / e, o.i / e, u.i / e), ot(o), o = u.next, a = u.next;
3839
+ function rt(s, t, e, n, i, r, o) {
3840
+ if (!s) return;
3841
+ !o && r && Tn(s, n, i, r);
3842
+ let l = s, a, h;
3843
+ for (; s.prev !== s.next; ) {
3844
+ if (a = s.prev, h = s.next, r ? fn(s, n, i, r) : hn(s)) {
3845
+ t.push(a.i / e, s.i / e, h.i / e), ot(s), s = h.next, l = h.next;
3744
3846
  continue;
3745
3847
  }
3746
- if (o = u, o === a) {
3747
- s ? s === 1 ? (o = gn(W(o), t, e), it(o, t, e, n, i, r, 2)) : s === 2 && vn(o, t, e, n, i, r) : it(W(o), t, e, n, i, r, 1);
3848
+ if (s = h, s === l) {
3849
+ o ? o === 1 ? (s = dn(Y(s), t, e), rt(s, t, e, n, i, r, 2)) : o === 2 && mn(s, t, e, n, i, r) : rt(Y(s), t, e, n, i, r, 1);
3748
3850
  break;
3749
3851
  }
3750
3852
  }
3751
3853
  }
3752
- function mn(o) {
3753
- const t = o.prev, e = o, n = o.next;
3754
- if (C(t, e, n) >= 0) return !1;
3755
- const i = t.x, r = e.x, s = n.x, a = t.y, l = e.y, u = n.y, h = i < r ? i < s ? i : s : r < s ? r : s, f = a < l ? a < u ? a : u : l < u ? l : u, c = i > r ? i > s ? i : s : r > s ? r : s, E = a > l ? a > u ? a : u : l > u ? l : u;
3756
- let v = n.next;
3757
- for (; v !== t; ) {
3758
- if (v.x >= h && v.x <= c && v.y >= f && v.y <= E && J(i, a, r, l, s, u, v.x, v.y) && C(v.prev, v, v.next) >= 0)
3854
+ function hn(s) {
3855
+ const t = s.prev, e = s, n = s.next;
3856
+ if (L(t, e, n) >= 0) return !1;
3857
+ const i = t.x, r = e.x, o = n.x, l = t.y, a = e.y, h = n.y, c = i < r ? i < o ? i : o : r < o ? r : o, f = l < a ? l < h ? l : h : a < h ? a : h, u = i > r ? i > o ? i : o : r > o ? r : o, x = l > a ? l > h ? l : h : a > h ? a : h;
3858
+ let p = n.next;
3859
+ for (; p !== t; ) {
3860
+ if (p.x >= c && p.x <= u && p.y >= f && p.y <= x && tt(i, l, r, a, o, h, p.x, p.y) && L(p.prev, p, p.next) >= 0)
3759
3861
  return !1;
3760
- v = v.next;
3862
+ p = p.next;
3761
3863
  }
3762
3864
  return !0;
3763
3865
  }
3764
- function pn(o, t, e, n) {
3765
- const i = o.prev, r = o, s = o.next;
3766
- if (C(i, r, s) >= 0) return !1;
3767
- const a = i.x, l = r.x, u = s.x, h = i.y, f = r.y, c = s.y, E = a < l ? a < u ? a : u : l < u ? l : u, v = h < f ? h < c ? h : c : f < c ? f : c, p = a > l ? a > u ? a : u : l > u ? l : u, P = h > f ? h > c ? h : c : f > c ? f : c, x = St(E, v, t, e, n), y = St(p, P, t, e, n);
3768
- let d = o.prevZ, g = o.nextZ;
3769
- for (; d && d.z >= x && g && g.z <= y; ) {
3770
- if (d.x >= E && d.x <= p && d.y >= v && d.y <= P && d !== i && d !== s && J(a, h, l, f, u, c, d.x, d.y) && C(d.prev, d, d.next) >= 0 || (d = d.prevZ, g.x >= E && g.x <= p && g.y >= v && g.y <= P && g !== i && g !== s && J(a, h, l, f, u, c, g.x, g.y) && C(g.prev, g, g.next) >= 0)) return !1;
3771
- g = g.nextZ;
3866
+ function fn(s, t, e, n) {
3867
+ const i = s.prev, r = s, o = s.next;
3868
+ if (L(i, r, o) >= 0) return !1;
3869
+ const l = i.x, a = r.x, h = o.x, c = i.y, f = r.y, u = o.y, x = l < a ? l < h ? l : h : a < h ? a : h, p = c < f ? c < u ? c : u : f < u ? f : u, d = l > a ? l > h ? l : h : a > h ? a : h, y = c > f ? c > u ? c : u : f > u ? f : u, E = yt(x, p, t, e, n), b = yt(d, y, t, e, n);
3870
+ let g = s.prevZ, v = s.nextZ;
3871
+ for (; g && g.z >= E && v && v.z <= b; ) {
3872
+ if (g.x >= x && g.x <= d && g.y >= p && g.y <= y && g !== i && g !== o && tt(l, c, a, f, h, u, g.x, g.y) && L(g.prev, g, g.next) >= 0 || (g = g.prevZ, v.x >= x && v.x <= d && v.y >= p && v.y <= y && v !== i && v !== o && tt(l, c, a, f, h, u, v.x, v.y) && L(v.prev, v, v.next) >= 0)) return !1;
3873
+ v = v.nextZ;
3772
3874
  }
3773
- for (; d && d.z >= x; ) {
3774
- if (d.x >= E && d.x <= p && d.y >= v && d.y <= P && d !== i && d !== s && J(a, h, l, f, u, c, d.x, d.y) && C(d.prev, d, d.next) >= 0) return !1;
3775
- d = d.prevZ;
3875
+ for (; g && g.z >= E; ) {
3876
+ if (g.x >= x && g.x <= d && g.y >= p && g.y <= y && g !== i && g !== o && tt(l, c, a, f, h, u, g.x, g.y) && L(g.prev, g, g.next) >= 0) return !1;
3877
+ g = g.prevZ;
3776
3878
  }
3777
- for (; g && g.z <= y; ) {
3778
- if (g.x >= E && g.x <= p && g.y >= v && g.y <= P && g !== i && g !== s && J(a, h, l, f, u, c, g.x, g.y) && C(g.prev, g, g.next) >= 0) return !1;
3779
- g = g.nextZ;
3879
+ for (; v && v.z <= b; ) {
3880
+ if (v.x >= x && v.x <= d && v.y >= p && v.y <= y && v !== i && v !== o && tt(l, c, a, f, h, u, v.x, v.y) && L(v.prev, v, v.next) >= 0) return !1;
3881
+ v = v.nextZ;
3780
3882
  }
3781
3883
  return !0;
3782
3884
  }
3783
- function gn(o, t, e) {
3784
- let n = o;
3885
+ function dn(s, t, e) {
3886
+ let n = s;
3785
3887
  do {
3786
3888
  const i = n.prev, r = n.next.next;
3787
- !gt(i, r) && Kt(i, n, n.next, r) && rt(i, r) && rt(r, i) && (t.push(i.i / e, n.i / e, r.i / e), ot(n), ot(n.next), n = o = r), n = n.next;
3788
- } while (n !== o);
3789
- return W(n);
3889
+ !vt(i, r) && Zt(i, n, n.next, r) && st(i, r) && st(r, i) && (t.push(i.i / e, n.i / e, r.i / e), ot(n), ot(n.next), n = s = r), n = n.next;
3890
+ } while (n !== s);
3891
+ return Y(n);
3790
3892
  }
3791
- function vn(o, t, e, n, i, r) {
3792
- let s = o;
3893
+ function mn(s, t, e, n, i, r) {
3894
+ let o = s;
3793
3895
  do {
3794
- let a = s.next.next;
3795
- for (; a !== s.prev; ) {
3796
- if (s.i !== a.i && wn(s, a)) {
3797
- let l = Jt(s, a);
3798
- s = W(s, s.next), l = W(l, l.next), it(s, t, e, n, i, r, 0), it(l, t, e, n, i, r, 0);
3896
+ let l = o.next.next;
3897
+ for (; l !== o.prev; ) {
3898
+ if (o.i !== l.i && Sn(o, l)) {
3899
+ let a = $t(o, l);
3900
+ o = Y(o, o.next), a = Y(a, a.next), rt(o, t, e, n, i, r, 0), rt(a, t, e, n, i, r, 0);
3799
3901
  return;
3800
3902
  }
3801
- a = a.next;
3903
+ l = l.next;
3802
3904
  }
3803
- s = s.next;
3804
- } while (s !== o);
3905
+ o = o.next;
3906
+ } while (o !== s);
3805
3907
  }
3806
- function xn(o, t, e, n) {
3908
+ function pn(s, t, e, n) {
3807
3909
  const i = [];
3808
3910
  for (let r = 0; r < t.length; r++) {
3809
- const s = t[r] * n, a = r < t.length - 1 ? t[r + 1] * n : o.length, l = $t(o, s, a, n, !1);
3810
- l && (l === l.next && (l.steiner = !0), i.push(An(l)));
3911
+ const o = t[r] * n, l = r < t.length - 1 ? t[r + 1] * n : s.length, a = jt(s, o, l, n, !1);
3912
+ a && (a === a.next && (a.steiner = !0), i.push(bn(a)));
3811
3913
  }
3812
- i.sort((r, s) => r.x - s.x);
3914
+ i.sort((r, o) => r.x - o.x);
3813
3915
  for (const r of i)
3814
- e = Tn(r, e);
3916
+ e = gn(r, e);
3815
3917
  return e;
3816
3918
  }
3817
- function Tn(o, t) {
3818
- const e = En(o, t);
3919
+ function gn(s, t) {
3920
+ const e = vn(s, t);
3819
3921
  if (!e) return t;
3820
- const n = Jt(e, o);
3821
- return W(n, n.next), W(e, e.next);
3922
+ const n = $t(e, s);
3923
+ return Y(n, n.next), Y(e, e.next);
3822
3924
  }
3823
- function En(o, t) {
3925
+ function vn(s, t) {
3824
3926
  let e = t;
3825
- const n = o.x, i = o.y;
3826
- let r = -1 / 0, s = null;
3927
+ const n = s.x, i = s.y;
3928
+ let r = -1 / 0, o = null;
3827
3929
  do {
3828
3930
  if (i <= e.y && i >= e.next.y && e.next.y !== e.y) {
3829
3931
  const f = e.x + (i - e.y) / (e.next.y - e.y) * (e.next.x - e.x);
3830
- if (f <= n && f > r && (r = f, s = e.x < e.next.x ? e : e.next, f === n))
3831
- return s;
3932
+ if (f <= n && f > r && (r = f, o = e.x < e.next.x ? e : e.next, f === n))
3933
+ return o;
3832
3934
  }
3833
3935
  e = e.next;
3834
3936
  } while (e !== t);
3835
- if (!s) return null;
3836
- const a = s, l = s.x, u = s.y;
3837
- let h = 1 / 0;
3838
- e = s;
3937
+ if (!o) return null;
3938
+ const l = o, a = o.x, h = o.y;
3939
+ let c = 1 / 0;
3940
+ e = o;
3839
3941
  do {
3840
- if (n >= e.x && e.x >= l && n !== e.x && J(i < u ? n : r, i, l, u, i < u ? r : n, i, e.x, e.y)) {
3942
+ if (n >= e.x && e.x >= a && n !== e.x && tt(i < h ? n : r, i, a, h, i < h ? r : n, i, e.x, e.y)) {
3841
3943
  const f = Math.abs(i - e.y) / (n - e.x);
3842
- rt(e, o) && (f < h || f === h && (e.x > s.x || bn(s, e))) && (s = e, h = f);
3944
+ st(e, s) && (f < c || f === c && (e.x > o.x || xn(o, e))) && (o = e, c = f);
3843
3945
  }
3844
3946
  e = e.next;
3845
- } while (e !== a);
3846
- return s;
3947
+ } while (e !== l);
3948
+ return o;
3847
3949
  }
3848
- function bn(o, t) {
3849
- return C(o.prev, o, t.prev) < 0 && C(t.next, o, o.next) < 0;
3950
+ function xn(s, t) {
3951
+ return L(s.prev, s, t.prev) < 0 && L(t.next, s, s.next) < 0;
3850
3952
  }
3851
- function yn(o, t, e, n) {
3852
- let i = o;
3953
+ function Tn(s, t, e, n) {
3954
+ let i = s;
3853
3955
  do
3854
- i.z === 0 && (i.z = St(i.x, i.y, t, e, n)), i.prevZ = i.prev, i.nextZ = i.next, i = i.next;
3855
- while (i !== o);
3856
- i.prevZ.nextZ = null, i.prevZ = null, Sn(i);
3956
+ i.z === 0 && (i.z = yt(i.x, i.y, t, e, n)), i.prevZ = i.prev, i.nextZ = i.next, i = i.next;
3957
+ while (i !== s);
3958
+ i.prevZ.nextZ = null, i.prevZ = null, En(i);
3857
3959
  }
3858
- function Sn(o) {
3960
+ function En(s) {
3859
3961
  let t = 1, e;
3860
3962
  do {
3861
- let n = o;
3862
- o = null;
3963
+ let n = s;
3964
+ s = null;
3863
3965
  let i = null;
3864
3966
  for (e = 0; n; ) {
3865
3967
  e++;
3866
- let r = n, s = 0;
3867
- for (let l = 0; l < t && (s++, r = r.nextZ, !!r); l++)
3968
+ let r = n, o = 0;
3969
+ for (let a = 0; a < t && (o++, r = r.nextZ, !!r); a++)
3868
3970
  ;
3869
- let a = t;
3870
- for (; s > 0 || a > 0 && r; ) {
3871
- let l;
3872
- s !== 0 && (a === 0 || !r || n.z <= r.z) ? (l = n, n = n.nextZ, s--) : (l = r, r = r.nextZ, a--), i ? i.nextZ = l : o = l, l.prevZ = i, i = l;
3971
+ let l = t;
3972
+ for (; o > 0 || l > 0 && r; ) {
3973
+ let a;
3974
+ o !== 0 && (l === 0 || !r || n.z <= r.z) ? (a = n, n = n.nextZ, o--) : (a = r, r = r.nextZ, l--), i ? i.nextZ = a : s = a, a.prevZ = i, i = a;
3873
3975
  }
3874
3976
  n = r;
3875
3977
  }
3876
3978
  i.nextZ = null, t *= 2;
3877
3979
  } while (e > 1);
3878
- return o;
3980
+ return s;
3879
3981
  }
3880
- function St(o, t, e, n, i) {
3881
- let r = (o - e) * i | 0, s = (t - n) * i | 0;
3882
- return r = (r | r << 8) & 16711935, r = (r | r << 4) & 252645135, r = (r | r << 2) & 858993459, r = (r | r << 1) & 1431655765, s = (s | s << 8) & 16711935, s = (s | s << 4) & 252645135, s = (s | s << 2) & 858993459, s = (s | s << 1) & 1431655765, r | s << 1;
3982
+ function yt(s, t, e, n, i) {
3983
+ let r = (s - e) * i | 0, o = (t - n) * i | 0;
3984
+ return r = (r | r << 8) & 16711935, r = (r | r << 4) & 252645135, r = (r | r << 2) & 858993459, r = (r | r << 1) & 1431655765, o = (o | o << 8) & 16711935, o = (o | o << 4) & 252645135, o = (o | o << 2) & 858993459, o = (o | o << 1) & 1431655765, r | o << 1;
3883
3985
  }
3884
- function An(o) {
3885
- let t = o, e = o;
3986
+ function bn(s) {
3987
+ let t = s, e = s;
3886
3988
  do
3887
3989
  (t.x < e.x || t.x === e.x && t.y < e.y) && (e = t), t = t.next;
3888
- while (t !== o);
3990
+ while (t !== s);
3889
3991
  return e;
3890
3992
  }
3891
- function J(o, t, e, n, i, r, s, a) {
3892
- return (i - s) * (t - a) - (o - s) * (r - a) >= 0 && (o - s) * (n - a) - (e - s) * (t - a) >= 0 && (e - s) * (r - a) - (i - s) * (n - a) >= 0;
3993
+ function tt(s, t, e, n, i, r, o, l) {
3994
+ return (i - o) * (t - l) - (s - o) * (r - l) >= 0 && (s - o) * (n - l) - (e - o) * (t - l) >= 0 && (e - o) * (r - l) - (i - o) * (n - l) >= 0;
3893
3995
  }
3894
- function wn(o, t) {
3895
- return o.next.i !== t.i && o.prev.i !== t.i && !Rn(o, t) && (rt(o, t) && rt(t, o) && Dn(o, t) && (C(o.prev, o, t.prev) !== 0 || C(o, t.prev, t) !== 0) || gt(o, t) && C(o.prev, o, o.next) > 0 && C(t.prev, t, t.next) > 0);
3996
+ function Sn(s, t) {
3997
+ return s.next.i !== t.i && s.prev.i !== t.i && !yn(s, t) && (st(s, t) && st(t, s) && wn(s, t) && (L(s.prev, s, t.prev) !== 0 || L(s, t.prev, t) !== 0) || vt(s, t) && L(s.prev, s, s.next) > 0 && L(t.prev, t, t.next) > 0);
3896
3998
  }
3897
- function C(o, t, e) {
3898
- return (t.y - o.y) * (e.x - t.x) - (t.x - o.x) * (e.y - t.y);
3999
+ function L(s, t, e) {
4000
+ return (t.y - s.y) * (e.x - t.x) - (t.x - s.x) * (e.y - t.y);
3899
4001
  }
3900
- function gt(o, t) {
3901
- return o.x === t.x && o.y === t.y;
4002
+ function vt(s, t) {
4003
+ return s.x === t.x && s.y === t.y;
3902
4004
  }
3903
- function Kt(o, t, e, n) {
3904
- const i = ut(C(o, t, e)), r = ut(C(o, t, n)), s = ut(C(e, n, o)), a = ut(C(e, n, t));
3905
- return !!(i !== r && s !== a || i === 0 && ht(o, e, t) || r === 0 && ht(o, n, t) || s === 0 && ht(e, o, n) || a === 0 && ht(e, t, n));
4005
+ function Zt(s, t, e, n) {
4006
+ const i = ct(L(s, t, e)), r = ct(L(s, t, n)), o = ct(L(e, n, s)), l = ct(L(e, n, t));
4007
+ return !!(i !== r && o !== l || i === 0 && ut(s, e, t) || r === 0 && ut(s, n, t) || o === 0 && ut(e, s, n) || l === 0 && ut(e, t, n));
3906
4008
  }
3907
- function ht(o, t, e) {
3908
- return t.x <= Math.max(o.x, e.x) && t.x >= Math.min(o.x, e.x) && t.y <= Math.max(o.y, e.y) && t.y >= Math.min(o.y, e.y);
4009
+ function ut(s, t, e) {
4010
+ return t.x <= Math.max(s.x, e.x) && t.x >= Math.min(s.x, e.x) && t.y <= Math.max(s.y, e.y) && t.y >= Math.min(s.y, e.y);
3909
4011
  }
3910
- function ut(o) {
3911
- return o > 0 ? 1 : o < 0 ? -1 : 0;
4012
+ function ct(s) {
4013
+ return s > 0 ? 1 : s < 0 ? -1 : 0;
3912
4014
  }
3913
- function Rn(o, t) {
3914
- let e = o;
4015
+ function yn(s, t) {
4016
+ let e = s;
3915
4017
  do {
3916
- if (e.i !== o.i && e.next.i !== o.i && e.i !== t.i && e.next.i !== t.i && Kt(e, e.next, o, t)) return !0;
4018
+ if (e.i !== s.i && e.next.i !== s.i && e.i !== t.i && e.next.i !== t.i && Zt(e, e.next, s, t)) return !0;
3917
4019
  e = e.next;
3918
- } while (e !== o);
4020
+ } while (e !== s);
3919
4021
  return !1;
3920
4022
  }
3921
- function rt(o, t) {
3922
- return C(o.prev, o, o.next) < 0 ? C(o, t, o.next) >= 0 && C(o, o.prev, t) >= 0 : C(o, t, o.prev) < 0 || C(o, o.next, t) < 0;
4023
+ function st(s, t) {
4024
+ return L(s.prev, s, s.next) < 0 ? L(s, t, s.next) >= 0 && L(s, s.prev, t) >= 0 : L(s, t, s.prev) < 0 || L(s, s.next, t) < 0;
3923
4025
  }
3924
- function Dn(o, t) {
3925
- let e = o, n = !1;
3926
- const i = (o.x + t.x) / 2, r = (o.y + t.y) / 2;
4026
+ function wn(s, t) {
4027
+ let e = s, n = !1;
4028
+ const i = (s.x + t.x) / 2, r = (s.y + t.y) / 2;
3927
4029
  do
3928
4030
  e.y > r != e.next.y > r && e.next.y !== e.y && i < (e.next.x - e.x) * (r - e.y) / (e.next.y - e.y) + e.x && (n = !n), e = e.next;
3929
- while (e !== o);
4031
+ while (e !== s);
3930
4032
  return n;
3931
4033
  }
3932
- function Jt(o, t) {
3933
- const e = At(o.i, o.x, o.y), n = At(t.i, t.x, t.y), i = o.next, r = t.prev;
3934
- return o.next = t, t.prev = o, e.next = i, i.prev = e, n.next = e, e.prev = n, r.next = n, n.prev = r, n;
4034
+ function $t(s, t) {
4035
+ const e = wt(s.i, s.x, s.y), n = wt(t.i, t.x, t.y), i = s.next, r = t.prev;
4036
+ return s.next = t, t.prev = s, e.next = i, i.prev = e, n.next = e, e.prev = n, r.next = n, n.prev = r, n;
3935
4037
  }
3936
- function Vt(o, t, e, n) {
3937
- const i = At(o, t, e);
4038
+ function Bt(s, t, e, n) {
4039
+ const i = wt(s, t, e);
3938
4040
  return n ? (i.next = n.next, i.prev = n, n.next.prev = i, n.next = i) : (i.prev = i, i.next = i), i;
3939
4041
  }
3940
- function ot(o) {
3941
- o.next.prev = o.prev, o.prev.next = o.next, o.prevZ && (o.prevZ.nextZ = o.nextZ), o.nextZ && (o.nextZ.prevZ = o.prevZ);
4042
+ function ot(s) {
4043
+ s.next.prev = s.prev, s.prev.next = s.next, s.prevZ && (s.prevZ.nextZ = s.nextZ), s.nextZ && (s.nextZ.prevZ = s.prevZ);
3942
4044
  }
3943
- function At(o, t, e) {
4045
+ function wt(s, t, e) {
3944
4046
  return {
3945
- i: o,
4047
+ i: s,
3946
4048
  x: t,
3947
4049
  y: e,
3948
4050
  prev: null,
@@ -3953,13 +4055,13 @@ function At(o, t, e) {
3953
4055
  steiner: !1
3954
4056
  };
3955
4057
  }
3956
- function Pn(o, t, e, n) {
4058
+ function Rn(s, t, e, n) {
3957
4059
  let i = 0;
3958
- for (let r = t, s = e - n; r < e; r += n)
3959
- i += (o[s] - o[r]) * (o[r + 1] + o[s + 1]), s = r;
4060
+ for (let r = t, o = e - n; r < e; r += n)
4061
+ i += (s[o] - s[r]) * (s[r + 1] + s[o + 1]), o = r;
3960
4062
  return i;
3961
4063
  }
3962
- const A = {
4064
+ const R = {
3963
4065
  parallaxX: 0.4,
3964
4066
  parallaxY: 0.8,
3965
4067
  parallaxMax: 30,
@@ -4014,67 +4116,8 @@ const A = {
4014
4116
  autoplay: !0,
4015
4117
  loop: !0,
4016
4118
  muted: !0
4017
- }, Z = 512, $ = 512;
4018
- class Pt {
4019
- constructor(t, e = 0.08, n = 0.06) {
4020
- this.host = t, this.lerpFactor = e, this.motionLerpFactor = n, this.host.addEventListener("mousemove", this.handleMouseMove), this.host.addEventListener("mouseleave", this.resetPointerTarget), this.host.addEventListener("touchstart", this.handleTouchStart, { passive: !0 }), this.host.addEventListener("touchmove", this.handleTouchMove, { passive: !0 }), this.host.addEventListener("touchend", this.handleTouchEnd, { passive: !0 }), this.host.addEventListener("touchcancel", this.handleTouchEnd, { passive: !0 });
4021
- }
4022
- pointerTarget = { x: 0, y: 0 };
4023
- motionTarget = { x: 0, y: 0 };
4024
- smoothedOutput = { x: 0, y: 0 };
4025
- usingMotionInput = !1;
4026
- motionListenerAttached = !1;
4027
- motionRequested = !1;
4028
- touchActive = !1;
4029
- touchAnchorX = 0;
4030
- touchAnchorY = 0;
4031
- lerpFactor;
4032
- motionLerpFactor;
4033
- static TOUCH_DRAG_RANGE = 100;
4034
- update() {
4035
- const t = this.touchActive ? this.pointerTarget : this.usingMotionInput ? this.motionTarget : this.pointerTarget, e = this.usingMotionInput && !this.touchActive ? this.motionLerpFactor : this.lerpFactor;
4036
- return this.smoothedOutput.x = ct(this.smoothedOutput.x, t.x, e), this.smoothedOutput.y = ct(this.smoothedOutput.y, t.y, e), this.smoothedOutput;
4037
- }
4038
- dispose() {
4039
- this.host.removeEventListener("mousemove", this.handleMouseMove), this.host.removeEventListener("mouseleave", this.resetPointerTarget), this.host.removeEventListener("touchstart", this.handleTouchStart), this.host.removeEventListener("touchmove", this.handleTouchMove), this.host.removeEventListener("touchend", this.handleTouchEnd), this.host.removeEventListener("touchcancel", this.handleTouchEnd), this.motionListenerAttached && (window.removeEventListener("deviceorientation", this.handleDeviceOrientation), this.motionListenerAttached = !1);
4040
- }
4041
- handleMouseMove = (t) => {
4042
- const e = this.host.getBoundingClientRect(), n = (t.clientX - e.left) / e.width * 2 - 1, i = (t.clientY - e.top) / e.height * 2 - 1;
4043
- this.pointerTarget.x = K(n, -1, 1), this.pointerTarget.y = K(i, -1, 1);
4044
- };
4045
- resetPointerTarget = () => {
4046
- this.pointerTarget.x = 0, this.pointerTarget.y = 0;
4047
- };
4048
- handleTouchStart = (t) => {
4049
- const e = t.touches[0];
4050
- e && (this.touchActive = !0, this.touchAnchorX = e.clientX, this.touchAnchorY = e.clientY, this.pointerTarget.x = 0, this.pointerTarget.y = 0, this.motionRequested || (this.motionRequested = !0, this.requestMotionPermission()));
4051
- };
4052
- handleTouchMove = (t) => {
4053
- const e = t.touches[0];
4054
- if (!e) return;
4055
- const n = e.clientX - this.touchAnchorX, i = e.clientY - this.touchAnchorY, r = Pt.TOUCH_DRAG_RANGE;
4056
- this.pointerTarget.x = K(n / r, -1, 1), this.pointerTarget.y = K(i / r, -1, 1);
4057
- };
4058
- handleTouchEnd = () => {
4059
- this.touchActive = !1, this.pointerTarget.x = 0, this.pointerTarget.y = 0;
4060
- };
4061
- async requestMotionPermission() {
4062
- if (typeof DeviceOrientationEvent > "u") return;
4063
- const t = DeviceOrientationEvent;
4064
- if (typeof t.requestPermission == "function")
4065
- try {
4066
- if (await t.requestPermission() !== "granted") return;
4067
- } catch {
4068
- return;
4069
- }
4070
- this.motionListenerAttached || (window.addEventListener("deviceorientation", this.handleDeviceOrientation), this.motionListenerAttached = !0), this.usingMotionInput = !0;
4071
- }
4072
- handleDeviceOrientation = (t) => {
4073
- const e = K((t.gamma ?? 0) / 45, -1, 1), n = K((t.beta ?? 0) / 45, -1, 1);
4074
- this.motionTarget.x = ct(this.motionTarget.x, e, this.motionLerpFactor), this.motionTarget.y = ct(this.motionTarget.y, n, this.motionLerpFactor);
4075
- };
4076
- }
4077
- class bt extends HTMLElement {
4119
+ }, J = 512, Q = 512;
4120
+ class Et extends HTMLElement {
4078
4121
  static TAG_NAME = "layershift-portal";
4079
4122
  static get observedAttributes() {
4080
4123
  return [
@@ -4138,17 +4181,24 @@ class bt extends HTMLElement {
4138
4181
  const e = !!this.getAttribute("src"), n = !!this.getAttribute("depth-src") && !!this.getAttribute("depth-meta"), i = !!this.getAttribute("depth-model");
4139
4182
  return e && t && (n || i);
4140
4183
  }
4184
+ _input = { x: 0, y: 0 };
4185
+ /** The current input offset. Set this externally to drive the effect. */
4186
+ get input() {
4187
+ return { x: this._input.x, y: this._input.y };
4188
+ }
4189
+ set input(t) {
4190
+ this._input.x = t.x, this._input.y = t.y;
4191
+ }
4141
4192
  shadow;
4142
4193
  container = null;
4143
4194
  renderer = null;
4144
- inputHandler = null;
4145
4195
  source = null;
4146
4196
  depthEstimator = null;
4147
4197
  mesh = null;
4148
4198
  loopCount = 0;
4149
4199
  lifecycle;
4150
4200
  constructor() {
4151
- super(), this.shadow = this.attachShadow({ mode: "open" }), this.lifecycle = new zt(this);
4201
+ super(), this.shadow = this.attachShadow({ mode: "open" }), this.lifecycle = new Wt(this);
4152
4202
  }
4153
4203
  // --- Attribute helpers ---
4154
4204
  getAttrFloat(t, e) {
@@ -4164,13 +4214,13 @@ class bt extends HTMLElement {
4164
4214
  }
4165
4215
  getAttrColor(t, e) {
4166
4216
  const n = this.getAttribute(t) ?? e;
4167
- return Fn(n);
4217
+ return An(n);
4168
4218
  }
4169
4219
  getAttrVec3(t, e) {
4170
- const i = (this.getAttribute(t) ?? e).split(",").map((s) => parseFloat(s.trim()));
4220
+ const i = (this.getAttribute(t) ?? e).split(",").map((o) => parseFloat(o.trim()));
4171
4221
  if (i.length >= 3 && i.every(Number.isFinite))
4172
4222
  return [i[0], i[1], i[2]];
4173
- const r = e.split(",").map((s) => parseFloat(s.trim()));
4223
+ const r = e.split(",").map((o) => parseFloat(o.trim()));
4174
4224
  return [r[0], r[1], r[2]];
4175
4225
  }
4176
4226
  get sourceType() {
@@ -4178,19 +4228,19 @@ class bt extends HTMLElement {
4178
4228
  return t === "camera" ? "camera" : t === "image" ? "image" : "video";
4179
4229
  }
4180
4230
  get parallaxX() {
4181
- return this.getAttrFloat("parallax-x", A.parallaxX);
4231
+ return this.getAttrFloat("parallax-x", R.parallaxX);
4182
4232
  }
4183
4233
  get parallaxY() {
4184
- return this.getAttrFloat("parallax-y", A.parallaxY);
4234
+ return this.getAttrFloat("parallax-y", R.parallaxY);
4185
4235
  }
4186
4236
  get parallaxMax() {
4187
- return this.getAttrFloat("parallax-max", A.parallaxMax);
4237
+ return this.getAttrFloat("parallax-max", R.parallaxMax);
4188
4238
  }
4189
4239
  get overscan() {
4190
- return this.getAttrFloat("overscan", A.overscan);
4240
+ return this.getAttrFloat("overscan", R.overscan);
4191
4241
  }
4192
4242
  get pomSteps() {
4193
- return this.getAttrFloat("pom-steps", A.pomSteps);
4243
+ return this.getAttrFloat("pom-steps", R.pomSteps);
4194
4244
  }
4195
4245
  get quality() {
4196
4246
  const t = this.getAttribute("quality");
@@ -4202,128 +4252,128 @@ class bt extends HTMLElement {
4202
4252
  }
4203
4253
  // Boundary
4204
4254
  get rimIntensity() {
4205
- return this.getAttrFloat("rim-intensity", A.rimIntensity);
4255
+ return this.getAttrFloat("rim-intensity", R.rimIntensity);
4206
4256
  }
4207
4257
  get rimWidth() {
4208
- return this.getAttrFloat("rim-width", A.rimWidth);
4258
+ return this.getAttrFloat("rim-width", R.rimWidth);
4209
4259
  }
4210
4260
  get rimColor() {
4211
- return this.getAttrColor("rim-color", A.rimColor);
4261
+ return this.getAttrColor("rim-color", R.rimColor);
4212
4262
  }
4213
4263
  get refractionStrength() {
4214
- return this.getAttrFloat("refraction-strength", A.refractionStrength);
4264
+ return this.getAttrFloat("refraction-strength", R.refractionStrength);
4215
4265
  }
4216
4266
  get chromaticStrength() {
4217
- return this.getAttrFloat("chromatic-strength", A.chromaticStrength);
4267
+ return this.getAttrFloat("chromatic-strength", R.chromaticStrength);
4218
4268
  }
4219
4269
  get occlusionIntensity() {
4220
- return this.getAttrFloat("occlusion-intensity", A.occlusionIntensity);
4270
+ return this.getAttrFloat("occlusion-intensity", R.occlusionIntensity);
4221
4271
  }
4222
4272
  // Lens transform
4223
4273
  get depthPower() {
4224
- return this.getAttrFloat("depth-power", A.depthPower);
4274
+ return this.getAttrFloat("depth-power", R.depthPower);
4225
4275
  }
4226
4276
  get depthScale() {
4227
- return this.getAttrFloat("depth-scale", A.depthScale);
4277
+ return this.getAttrFloat("depth-scale", R.depthScale);
4228
4278
  }
4229
4279
  get depthBias() {
4230
- return this.getAttrFloat("depth-bias", A.depthBias);
4280
+ return this.getAttrFloat("depth-bias", R.depthBias);
4231
4281
  }
4232
4282
  // Interior mood
4233
4283
  get fogDensity() {
4234
- return this.getAttrFloat("fog-density", A.fogDensity);
4284
+ return this.getAttrFloat("fog-density", R.fogDensity);
4235
4285
  }
4236
4286
  get fogColor() {
4237
- return this.getAttrColor("fog-color", A.fogColor);
4287
+ return this.getAttrColor("fog-color", R.fogColor);
4238
4288
  }
4239
4289
  get colorShift() {
4240
- return this.getAttrFloat("color-shift", A.colorShift);
4290
+ return this.getAttrFloat("color-shift", R.colorShift);
4241
4291
  }
4242
4292
  get brightnessBias() {
4243
- return this.getAttrFloat("brightness-bias", A.brightnessBias);
4293
+ return this.getAttrFloat("brightness-bias", R.brightnessBias);
4244
4294
  }
4245
4295
  // Depth-adaptive
4246
4296
  get contrastLow() {
4247
- return this.getAttrFloat("contrast-low", A.contrastLow);
4297
+ return this.getAttrFloat("contrast-low", R.contrastLow);
4248
4298
  }
4249
4299
  get contrastHigh() {
4250
- return this.getAttrFloat("contrast-high", A.contrastHigh);
4300
+ return this.getAttrFloat("contrast-high", R.contrastHigh);
4251
4301
  }
4252
4302
  get verticalReduction() {
4253
- return this.getAttrFloat("vertical-reduction", A.verticalReduction);
4303
+ return this.getAttrFloat("vertical-reduction", R.verticalReduction);
4254
4304
  }
4255
4305
  get dofStart() {
4256
- return this.getAttrFloat("dof-start", A.dofStart);
4306
+ return this.getAttrFloat("dof-start", R.dofStart);
4257
4307
  }
4258
4308
  get dofStrength() {
4259
- return this.getAttrFloat("dof-strength", A.dofStrength);
4309
+ return this.getAttrFloat("dof-strength", R.dofStrength);
4260
4310
  }
4261
4311
  // Bevel / dimensional typography
4262
4312
  get bevelIntensity() {
4263
- return this.getAttrFloat("bevel-intensity", A.bevelIntensity);
4313
+ return this.getAttrFloat("bevel-intensity", R.bevelIntensity);
4264
4314
  }
4265
4315
  get bevelWidth() {
4266
- return this.getAttrFloat("bevel-width", A.bevelWidth);
4316
+ return this.getAttrFloat("bevel-width", R.bevelWidth);
4267
4317
  }
4268
4318
  get bevelDarkening() {
4269
- return this.getAttrFloat("bevel-darkening", A.bevelDarkening);
4319
+ return this.getAttrFloat("bevel-darkening", R.bevelDarkening);
4270
4320
  }
4271
4321
  get bevelDesaturation() {
4272
- return this.getAttrFloat("bevel-desaturation", A.bevelDesaturation);
4322
+ return this.getAttrFloat("bevel-desaturation", R.bevelDesaturation);
4273
4323
  }
4274
4324
  get bevelLightAngle() {
4275
- return this.getAttrFloat("bevel-light-angle", A.bevelLightAngle);
4325
+ return this.getAttrFloat("bevel-light-angle", R.bevelLightAngle);
4276
4326
  }
4277
4327
  // Volumetric edge wall
4278
4328
  get edgeThickness() {
4279
- return this.getAttrFloat("edge-thickness", A.edgeThickness);
4329
+ return this.getAttrFloat("edge-thickness", R.edgeThickness);
4280
4330
  }
4281
4331
  get edgeSpecular() {
4282
- return this.getAttrFloat("edge-specular", A.edgeSpecular);
4332
+ return this.getAttrFloat("edge-specular", R.edgeSpecular);
4283
4333
  }
4284
4334
  get edgeColor() {
4285
- return this.getAttrColor("edge-color", A.edgeColor);
4335
+ return this.getAttrColor("edge-color", R.edgeColor);
4286
4336
  }
4287
4337
  // Chamfer geometry
4288
4338
  get chamferWidth() {
4289
- return this.getAttrFloat("chamfer-width", A.chamferWidth);
4339
+ return this.getAttrFloat("chamfer-width", R.chamferWidth);
4290
4340
  }
4291
4341
  get chamferAngle() {
4292
- return this.getAttrFloat("chamfer-angle", A.chamferAngle);
4342
+ return this.getAttrFloat("chamfer-angle", R.chamferAngle);
4293
4343
  }
4294
4344
  get chamferColor() {
4295
- return this.getAttrColor("chamfer-color", A.chamferColor);
4345
+ return this.getAttrColor("chamfer-color", R.chamferColor);
4296
4346
  }
4297
4347
  get chamferAmbient() {
4298
- return this.getAttrFloat("chamfer-ambient", A.chamferAmbient);
4348
+ return this.getAttrFloat("chamfer-ambient", R.chamferAmbient);
4299
4349
  }
4300
4350
  get chamferSpecular() {
4301
- return this.getAttrFloat("chamfer-specular", A.chamferSpecular);
4351
+ return this.getAttrFloat("chamfer-specular", R.chamferSpecular);
4302
4352
  }
4303
4353
  get chamferShininess() {
4304
- return this.getAttrFloat("chamfer-shininess", A.chamferShininess);
4354
+ return this.getAttrFloat("chamfer-shininess", R.chamferShininess);
4305
4355
  }
4306
4356
  // Edge occlusion
4307
4357
  get edgeOcclusionWidth() {
4308
- return this.getAttrFloat("edge-occlusion-width", A.edgeOcclusionWidth);
4358
+ return this.getAttrFloat("edge-occlusion-width", R.edgeOcclusionWidth);
4309
4359
  }
4310
4360
  get edgeOcclusionStrength() {
4311
- return this.getAttrFloat("edge-occlusion-strength", A.edgeOcclusionStrength);
4361
+ return this.getAttrFloat("edge-occlusion-strength", R.edgeOcclusionStrength);
4312
4362
  }
4313
4363
  get lightDirection3() {
4314
- return this.getAttrVec3("light-direction", A.lightDirection);
4364
+ return this.getAttrVec3("light-direction", R.lightDirection);
4315
4365
  }
4316
4366
  get depthModel() {
4317
4367
  return this.getAttribute("depth-model");
4318
4368
  }
4319
4369
  get shouldAutoplay() {
4320
- return this.getAttrBool("autoplay", A.autoplay);
4370
+ return this.getAttrBool("autoplay", R.autoplay);
4321
4371
  }
4322
4372
  get shouldLoop() {
4323
- return this.getAttrBool("loop", A.loop);
4373
+ return this.getAttrBool("loop", R.loop);
4324
4374
  }
4325
4375
  get shouldMute() {
4326
- return this.getAttrBool("muted", A.muted);
4376
+ return this.getAttrBool("muted", R.muted);
4327
4377
  }
4328
4378
  // --- Event dispatching ---
4329
4379
  emit(t, e) {
@@ -4394,86 +4444,86 @@ class bt extends HTMLElement {
4394
4444
  if (!this.container) return;
4395
4445
  const n = this.sourceType === "camera", i = this.depthModel;
4396
4446
  try {
4397
- let r, s, a, l = null;
4398
- const u = (x) => {
4399
- this.emit("layershift-portal:model-progress", x);
4447
+ let r, o, l, a = null;
4448
+ const h = (d) => {
4449
+ this.emit("layershift-portal:model-progress", d);
4400
4450
  };
4401
4451
  if (n) {
4402
- const [x, y] = await Promise.all([
4403
- Gt(
4452
+ const [d, y] = await Promise.all([
4453
+ Xt(
4404
4454
  { video: { facingMode: "user" } },
4405
4455
  { parent: this.shadow }
4406
4456
  ),
4407
- Et(e)
4457
+ Tt(e)
4408
4458
  ]);
4409
4459
  if (t.aborted) {
4410
- x.dispose();
4460
+ d.dispose();
4411
4461
  return;
4412
4462
  }
4413
- if (r = x, a = y, i) {
4414
- if (l = await mt(i, Z, $, u), t.aborted) {
4415
- l.dispose(), r.dispose();
4463
+ if (r = d, l = y, i) {
4464
+ if (a = await dt(i, J, Q, h), t.aborted) {
4465
+ a.dispose(), r.dispose();
4416
4466
  return;
4417
4467
  }
4418
- s = H(Z, $);
4468
+ o = N(J, Q);
4419
4469
  } else
4420
- s = H(r.width, r.height);
4470
+ o = N(r.width, r.height);
4421
4471
  } else {
4422
- const x = this.getAttribute("src"), y = this.getAttribute("depth-src"), d = this.getAttribute("depth-meta"), g = !!y && !!d, b = this.sourceType === "image" || /\.(jpe?g|png|webp|gif|avif|bmp)(\?|$)/i.test(x);
4423
- if (g) {
4424
- const [T, m, S] = await Promise.all([
4425
- b ? dt(x) : ft(x, {
4472
+ const d = this.getAttribute("src"), y = this.getAttribute("depth-src"), E = this.getAttribute("depth-meta"), b = !!y && !!E, g = this.sourceType === "image" || /\.(jpe?g|png|webp|gif|avif|bmp)(\?|$)/i.test(d);
4473
+ if (b) {
4474
+ const [v, m, T] = await Promise.all([
4475
+ g ? ft(d) : ht(d, {
4426
4476
  parent: this.shadow,
4427
4477
  loop: this.shouldLoop,
4428
4478
  muted: this.shouldMute
4429
4479
  }),
4430
- kt(y, d),
4431
- Et(e)
4480
+ kt(y, E),
4481
+ Tt(e)
4432
4482
  ]);
4433
4483
  if (t.aborted) {
4434
- T.dispose();
4484
+ v.dispose();
4435
4485
  return;
4436
4486
  }
4437
- r = T, s = m, a = S;
4487
+ r = v, o = m, l = T;
4438
4488
  } else if (i) {
4439
- const [T, m, S] = await Promise.all([
4440
- b ? dt(x) : ft(x, {
4489
+ const [v, m, T] = await Promise.all([
4490
+ g ? ft(d) : ht(d, {
4441
4491
  parent: this.shadow,
4442
4492
  loop: this.shouldLoop,
4443
4493
  muted: this.shouldMute
4444
4494
  }),
4445
- mt(i, Z, $, u),
4446
- Et(e)
4495
+ dt(i, J, Q, h),
4496
+ Tt(e)
4447
4497
  ]);
4448
4498
  if (t.aborted) {
4449
- T.dispose(), m.dispose();
4499
+ v.dispose(), m.dispose();
4450
4500
  return;
4451
4501
  }
4452
- if (r = T, l = m, a = S, b || !r.isLive) {
4502
+ if (r = v, a = m, l = T, g || !r.isLive) {
4453
4503
  const w = r.getImageSource();
4454
4504
  if (w) {
4455
- const F = await l.submitFrameAndWait(w);
4456
- s = {
4457
- meta: { frameCount: 1, fps: 1, width: Z, height: $, sourceFps: 1 },
4458
- frames: [F]
4505
+ const A = await a.submitFrameAndWait(w);
4506
+ o = {
4507
+ meta: { frameCount: 1, fps: 1, width: J, height: Q, sourceFps: 1 },
4508
+ frames: [A]
4459
4509
  };
4460
4510
  } else
4461
- s = H(Z, $);
4511
+ o = N(J, Q);
4462
4512
  } else
4463
- s = H(Z, $);
4513
+ o = N(J, Q);
4464
4514
  } else
4465
4515
  throw new Error("Either depth-src/depth-meta or depth-model must be provided.");
4466
4516
  }
4467
- this.source = r, this.depthEstimator = l, this.mesh = a, this.loopCount = 0, this.attachSourceEventListeners(r);
4468
- const h = this.container?.clientWidth || r.width, f = this.parallaxMax / Math.max(h, 1);
4469
- let c;
4470
- if (l)
4471
- c = () => l.getLatestDepth();
4517
+ this.source = r, this.depthEstimator = a, this.mesh = l, this.loopCount = 0, this.attachSourceEventListeners(r);
4518
+ const c = this.container?.clientWidth || r.width, f = this.parallaxMax / Math.max(c, 1);
4519
+ let u;
4520
+ if (a)
4521
+ u = () => a.getLatestDepth();
4472
4522
  else {
4473
- const x = new Ot(s);
4474
- c = (y) => x.sample(y);
4523
+ const d = new Vt(o);
4524
+ u = (y) => d.sample(y);
4475
4525
  }
4476
- const E = {
4526
+ const x = {
4477
4527
  parallaxStrength: f,
4478
4528
  overscanPadding: this.overscan,
4479
4529
  pomSteps: this.pomSteps,
@@ -4515,23 +4565,19 @@ class bt extends HTMLElement {
4515
4565
  lightDirection: this.lightDirection3
4516
4566
  };
4517
4567
  if (t.aborted) return;
4518
- this.renderer = new en(this.container, E), this.renderer.initialize(r, s.meta.width, s.meta.height, a), this.inputHandler = new Pt(this);
4519
- const v = this.parallaxX, p = this.parallaxY, P = l;
4568
+ this.renderer = new Je(this.container, x), this.renderer.initialize(r, o.meta.width, o.meta.height, l);
4569
+ const p = a;
4520
4570
  if (this.renderer.start(
4521
4571
  r,
4522
- c,
4523
- () => {
4524
- if (!this.inputHandler) return { x: 0, y: 0 };
4525
- const x = this.inputHandler.update();
4526
- return { x: x.x * v, y: x.y * p };
4527
- },
4528
- (x, y) => {
4529
- if (P) {
4530
- const d = r.getImageSource();
4531
- d && P.submitFrame(d);
4572
+ u,
4573
+ () => ({ x: this._input.x, y: this._input.y }),
4574
+ (d, y) => {
4575
+ if (p) {
4576
+ const E = r.getImageSource();
4577
+ E && p.submitFrame(E);
4532
4578
  }
4533
4579
  this.emit("layershift-portal:frame", {
4534
- currentTime: x,
4580
+ currentTime: d,
4535
4581
  frameNumber: y
4536
4582
  });
4537
4583
  }
@@ -4547,23 +4593,17 @@ class bt extends HTMLElement {
4547
4593
  duration: r.duration
4548
4594
  });
4549
4595
  } catch (r) {
4550
- const s = r instanceof Error ? r.message : "Failed to initialize.";
4551
- console.error("<layershift-portal>: Failed to initialize.", r), this.emit("layershift-portal:error", { message: s });
4596
+ const o = r instanceof Error ? r.message : "Failed to initialize.";
4597
+ console.error("<layershift-portal>: Failed to initialize.", r), this.emit("layershift-portal:error", { message: o });
4552
4598
  }
4553
4599
  }
4554
4600
  // --- Cleanup ---
4555
4601
  doDispose() {
4556
- this.renderer?.dispose(), this.renderer = null, this.inputHandler?.dispose(), this.inputHandler = null, this.depthEstimator?.dispose(), this.depthEstimator = null, this.source?.dispose(), this.source = null, this.mesh = null, this.loopCount = 0, this.container = null;
4602
+ this.renderer?.dispose(), this.renderer = null, this.depthEstimator?.dispose(), this.depthEstimator = null, this.source?.dispose(), this.source = null, this.mesh = null, this.loopCount = 0, this.container = null;
4557
4603
  }
4558
4604
  }
4559
- function K(o, t, e) {
4560
- return Math.min(e, Math.max(t, o));
4561
- }
4562
- function ct(o, t, e) {
4563
- return o + (t - o) * e;
4564
- }
4565
- function Fn(o) {
4566
- const t = o.replace("#", "");
4605
+ function An(s) {
4606
+ const t = s.replace("#", "");
4567
4607
  if (t.length === 3) {
4568
4608
  const e = parseInt(t[0] + t[0], 16) / 255, n = parseInt(t[1] + t[1], 16) / 255, i = parseInt(t[2] + t[2], 16) / 255;
4569
4609
  return [e, n, i];
@@ -4574,9 +4614,110 @@ function Fn(o) {
4574
4614
  }
4575
4615
  return [0, 0, 0];
4576
4616
  }
4577
- customElements.get(Tt.TAG_NAME) || customElements.define(Tt.TAG_NAME, Tt);
4578
- customElements.get(bt.TAG_NAME) || customElements.define(bt.TAG_NAME, bt);
4617
+ function V(s, t, e) {
4618
+ return Math.min(e, Math.max(t, s));
4619
+ }
4620
+ function W(s, t, e) {
4621
+ return s + (t - s) * e;
4622
+ }
4623
+ const X = 100, Kt = 0.06;
4624
+ function Pn(s, t) {
4625
+ const e = t?.sensitivityX ?? 1, n = t?.sensitivityY ?? 1, i = t?.lerpFactor ?? 0.08;
4626
+ let r = 0, o = 0, l = 0, a = 0, h = 0, c = !0;
4627
+ const f = (p) => {
4628
+ const d = s.getBoundingClientRect(), y = (p.clientX - d.left) / d.width * 2 - 1, E = (p.clientY - d.top) / d.height * 2 - 1;
4629
+ r = V(y, -1, 1), o = V(E, -1, 1);
4630
+ }, u = () => {
4631
+ r = 0, o = 0;
4632
+ }, x = () => {
4633
+ c && (l = W(l, r, i), a = W(a, o, i), s.input = { x: l * e, y: a * n }, h = requestAnimationFrame(x));
4634
+ };
4635
+ return s.addEventListener("mousemove", f), s.addEventListener("mouseleave", u), h = requestAnimationFrame(x), () => {
4636
+ c = !1, cancelAnimationFrame(h), s.removeEventListener("mousemove", f), s.removeEventListener("mouseleave", u);
4637
+ };
4638
+ }
4639
+ function Dn(s, t) {
4640
+ const e = t?.sensitivityX ?? 1, n = t?.sensitivityY ?? 1, i = t?.lerpFactor ?? 0.08;
4641
+ let r = 0, o = 0, l = 0, a = 0, h = 0, c = 0, f = 0, u = !0;
4642
+ const x = (E) => {
4643
+ const b = E.touches[0];
4644
+ b && (h = b.clientX - l * X, c = b.clientY - a * X, r = l, o = a);
4645
+ }, p = (E) => {
4646
+ const b = E.touches[0];
4647
+ if (!b) return;
4648
+ const g = b.clientX - h, v = b.clientY - c;
4649
+ r = V(g / X, -1, 1), o = V(v / X, -1, 1);
4650
+ }, d = () => {
4651
+ r = 0, o = 0;
4652
+ }, y = () => {
4653
+ u && (l = W(l, r, i), a = W(a, o, i), s.input = { x: l * e, y: a * n }, f = requestAnimationFrame(y));
4654
+ };
4655
+ return s.addEventListener("touchstart", x, { passive: !0 }), s.addEventListener("touchmove", p, { passive: !0 }), s.addEventListener("touchend", d, { passive: !0 }), s.addEventListener("touchcancel", d, { passive: !0 }), f = requestAnimationFrame(y), () => {
4656
+ u = !1, cancelAnimationFrame(f), s.removeEventListener("touchstart", x), s.removeEventListener("touchmove", p), s.removeEventListener("touchend", d), s.removeEventListener("touchcancel", d);
4657
+ };
4658
+ }
4659
+ function Fn(s, t) {
4660
+ const e = t?.sensitivityX ?? 1, n = t?.sensitivityY ?? 1, i = t?.lerpFactor ?? Kt;
4661
+ let r = 0, o = 0, l = 0, a = 0, h = 0, c = !0, f = !1;
4662
+ const u = (y) => {
4663
+ r = V((y.gamma ?? 0) / 45, -1, 1), o = V((y.beta ?? 0) / 45, -1, 1);
4664
+ }, x = () => {
4665
+ c && (l = W(l, r, i), a = W(a, o, i), s.input = { x: l * e, y: a * n }, h = requestAnimationFrame(x));
4666
+ }, p = () => {
4667
+ c && !f && (window.addEventListener("deviceorientation", u), f = !0);
4668
+ }, d = DeviceOrientationEvent;
4669
+ return typeof d.requestPermission == "function" ? d.requestPermission().then((y) => {
4670
+ y === "granted" && p();
4671
+ }).catch(() => {
4672
+ }) : p(), h = requestAnimationFrame(x), () => {
4673
+ c = !1, cancelAnimationFrame(h), f && (window.removeEventListener("deviceorientation", u), f = !1);
4674
+ };
4675
+ }
4676
+ function Cn(s, t) {
4677
+ const e = t?.sensitivityX ?? 1, n = t?.sensitivityY ?? 1, i = t?.lerpFactor ?? 0.08, r = t?.lerpFactor ?? Kt;
4678
+ let o = 0, l = 0, a = 0, h = 0, c = 0, f = 0, u = 0, x = 0, p = !1, d = !1, y = !1, E = 0, b = 0, g = 0, v = !0;
4679
+ const m = (S) => {
4680
+ const D = s.getBoundingClientRect(), U = (S.clientX - D.left) / D.width * 2 - 1, M = (S.clientY - D.top) / D.height * 2 - 1;
4681
+ o = V(U, -1, 1), l = V(M, -1, 1);
4682
+ }, T = () => {
4683
+ o = 0, l = 0;
4684
+ }, w = (S) => {
4685
+ const D = S.touches[0];
4686
+ D && (p = !0, E = D.clientX - u * X, b = D.clientY - x * X, a = u, h = x, !d && !y && I());
4687
+ }, A = (S) => {
4688
+ const D = S.touches[0];
4689
+ if (!D) return;
4690
+ const U = D.clientX - E, M = D.clientY - b;
4691
+ a = V(U / X, -1, 1), h = V(M / X, -1, 1);
4692
+ }, P = () => {
4693
+ p = !1, a = 0, h = 0;
4694
+ }, F = (S) => {
4695
+ c = V((S.gamma ?? 0) / 45, -1, 1), f = V((S.beta ?? 0) / 45, -1, 1);
4696
+ }, _ = () => {
4697
+ v && !y && (window.addEventListener("deviceorientation", F), y = !0, d = !0);
4698
+ }, I = () => {
4699
+ if (typeof DeviceOrientationEvent > "u") return;
4700
+ const S = DeviceOrientationEvent;
4701
+ typeof S.requestPermission == "function" ? S.requestPermission().then((D) => {
4702
+ D === "granted" && _();
4703
+ }).catch(() => {
4704
+ }) : _();
4705
+ }, C = () => {
4706
+ if (!v) return;
4707
+ let S, D, U;
4708
+ p ? (S = a, D = h, U = i) : d ? (S = c, D = f, U = r) : (S = o, D = l, U = i), u = W(u, S, U), x = W(x, D, U), s.input = { x: u * e, y: x * n }, g = requestAnimationFrame(C);
4709
+ };
4710
+ return s.addEventListener("mousemove", m), s.addEventListener("mouseleave", T), s.addEventListener("touchstart", w, { passive: !0 }), s.addEventListener("touchmove", A, { passive: !0 }), s.addEventListener("touchend", P, { passive: !0 }), s.addEventListener("touchcancel", P, { passive: !0 }), g = requestAnimationFrame(C), () => {
4711
+ v = !1, cancelAnimationFrame(g), s.removeEventListener("mousemove", m), s.removeEventListener("mouseleave", T), s.removeEventListener("touchstart", w), s.removeEventListener("touchmove", A), s.removeEventListener("touchend", P), s.removeEventListener("touchcancel", P), y && (window.removeEventListener("deviceorientation", F), y = !1);
4712
+ };
4713
+ }
4714
+ customElements.get(xt.TAG_NAME) || customElements.define(xt.TAG_NAME, xt);
4715
+ customElements.get(Et.TAG_NAME) || customElements.define(Et.TAG_NAME, Et);
4579
4716
  export {
4580
- Tt as LayershiftElement,
4581
- bt as LayershiftPortalElement
4717
+ xt as LayershiftElement,
4718
+ Et as LayershiftPortalElement,
4719
+ Fn as connectGyro,
4720
+ Pn as connectMouse,
4721
+ Cn as connectPointer,
4722
+ Dn as connectTouch
4582
4723
  };