@wave3d/core 0.2.2 → 0.4.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 (37) hide show
  1. package/README.md +47 -0
  2. package/dist/config/model.d.ts +138 -1
  3. package/dist/config/model.js +144 -1
  4. package/dist/config/model.js.map +1 -1
  5. package/dist/index.d.ts +3 -2
  6. package/dist/index.js +2 -2
  7. package/dist/presets.js +15 -0
  8. package/dist/presets.js.map +1 -1
  9. package/dist/renderer/WaveRenderer.d.ts +59 -0
  10. package/dist/renderer/WaveRenderer.js +422 -8
  11. package/dist/renderer/WaveRenderer.js.map +1 -1
  12. package/dist/renderer/interaction.d.ts +119 -0
  13. package/dist/renderer/interaction.js +474 -0
  14. package/dist/renderer/interaction.js.map +1 -0
  15. package/dist/renderer/palette.js +14 -0
  16. package/dist/renderer/palette.js.map +1 -1
  17. package/dist/renderer/shaders.js +313 -1
  18. package/dist/renderer/shaders.js.map +1 -1
  19. package/dist/shell/createWave.d.ts +9 -1
  20. package/dist/shell/createWave.js +7 -1
  21. package/dist/shell/createWave.js.map +1 -1
  22. package/dist/shell/poster.d.ts +12 -0
  23. package/dist/shell/poster.js +4 -3
  24. package/dist/shell/poster.js.map +1 -1
  25. package/dist/standalone/wave3d.standalone.js +1016 -223
  26. package/dist/standalone.d.ts +2 -2
  27. package/dist/standalone.js +2 -2
  28. package/dist/studio/StudioWaveRenderer.d.ts +15 -0
  29. package/dist/studio/StudioWaveRenderer.js +32 -1
  30. package/dist/studio/StudioWaveRenderer.js.map +1 -1
  31. package/dist/studio/index.d.ts +2 -2
  32. package/dist/studio/index.js +2 -2
  33. package/dist/studio/randomize.d.ts +7 -4
  34. package/dist/studio/randomize.js +52 -5
  35. package/dist/studio/randomize.js.map +1 -1
  36. package/package.json +1 -1
  37. package/skills/wave3d/SKILL.md +60 -6
@@ -11493,6 +11493,22 @@ function wl() {
11493
11493
  grain: 1.1,
11494
11494
  blur: .02,
11495
11495
  blurSamples: 6,
11496
+ dither: 0,
11497
+ ditherScale: 2,
11498
+ ditherSteps: 4,
11499
+ innerLight: 0,
11500
+ innerLightDensity: .5,
11501
+ innerLightDecay: .95,
11502
+ innerLightX: .5,
11503
+ innerLightY: .15,
11504
+ halftone: 0,
11505
+ halftoneCell: 6,
11506
+ halftoneAngle: .4,
11507
+ heatmap: 0,
11508
+ paperTexture: 0,
11509
+ paperTextureScale: 2,
11510
+ halftoneCmyk: 0,
11511
+ halftoneCmykCell: 6,
11496
11512
  ambient: .45,
11497
11513
  lights: [],
11498
11514
  mirrorH: !1,
@@ -11575,24 +11591,97 @@ function Ol(e) {
11575
11591
  x: 10,
11576
11592
  y: 10,
11577
11593
  z: 7
11578
- }, typeof e.blendMode != "string" && (e.blendMode = "squared"), typeof e.speed != "number" && (e.speed = .04), typeof e.opacity != "number" && (e.opacity = 1), typeof e.seed != "number" && (e.seed = 0);
11594
+ }, typeof e.blendMode != "string" && (e.blendMode = "squared"), typeof e.speed != "number" && (e.speed = .04), typeof e.opacity != "number" && (e.opacity = 1), typeof e.seed != "number" && (e.seed = 0), e.interaction && Nl(e);
11579
11595
  }
11580
11596
  function kl(e) {
11581
- El(e), Dl(e), typeof e.ambient != "number" && (e.ambient = .45), Array.isArray(e.lights) || (e.lights = []), typeof e.quality != "number" && (e.quality = 1), typeof e.dprMax != "number" && (e.dprMax = 2), typeof e.grain != "number" && (e.grain = 1.1), typeof e.blur != "number" && (e.blur = .02), typeof e.blurSamples != "number" && (e.blurSamples = 6), typeof e.bloomStrength != "number" && (e.bloomStrength = 0), typeof e.bloomRadius != "number" && (e.bloomRadius = .4), typeof e.bloomThreshold != "number" && (e.bloomThreshold = .85), typeof e.showCameraRig != "boolean" && (e.showCameraRig = !1), typeof e.paused != "boolean" && (e.paused = !1), typeof e.loopSeconds != "number" && (e.loopSeconds = 0), typeof e.mirrorH != "boolean" && (e.mirrorH = !1), typeof e.mirrorV != "boolean" && (e.mirrorV = !1);
11597
+ El(e), Dl(e), typeof e.ambient != "number" && (e.ambient = .45), Array.isArray(e.lights) || (e.lights = []), typeof e.quality != "number" && (e.quality = 1), typeof e.dprMax != "number" && (e.dprMax = 2), typeof e.grain != "number" && (e.grain = 1.1), typeof e.blur != "number" && (e.blur = .02), typeof e.blurSamples != "number" && (e.blurSamples = 6), typeof e.bloomStrength != "number" && (e.bloomStrength = 0), typeof e.bloomRadius != "number" && (e.bloomRadius = .4), typeof e.bloomThreshold != "number" && (e.bloomThreshold = .85), typeof e.dither != "number" && (e.dither = 0), typeof e.ditherScale != "number" && (e.ditherScale = 2), typeof e.ditherSteps != "number" && (e.ditherSteps = 4), typeof e.innerLight != "number" && (e.innerLight = 0), typeof e.innerLightDensity != "number" && (e.innerLightDensity = .5), typeof e.innerLightDecay != "number" && (e.innerLightDecay = .95), typeof e.innerLightX != "number" && (e.innerLightX = .5), typeof e.innerLightY != "number" && (e.innerLightY = .15), typeof e.halftone != "number" && (e.halftone = 0), typeof e.halftoneCell != "number" && (e.halftoneCell = 6), typeof e.halftoneAngle != "number" && (e.halftoneAngle = .4), typeof e.heatmap != "number" && (e.heatmap = 0), typeof e.paperTexture != "number" && (e.paperTexture = 0), typeof e.paperTextureScale != "number" && (e.paperTextureScale = 2), typeof e.halftoneCmyk != "number" && (e.halftoneCmyk = 0), typeof e.halftoneCmykCell != "number" && (e.halftoneCmykCell = 6), typeof e.showCameraRig != "boolean" && (e.showCameraRig = !1), typeof e.paused != "boolean" && (e.paused = !1), typeof e.loopSeconds != "number" && (e.loopSeconds = 0), typeof e.mirrorH != "boolean" && (e.mirrorH = !1), typeof e.mirrorV != "boolean" && (e.mirrorV = !1);
11582
11598
  }
11583
- function Al(e) {
11599
+ function Al(e, t, n, r) {
11600
+ let i = Number(e);
11601
+ return Number.isFinite(i) ? pl(i, t, n) : r;
11602
+ }
11603
+ function jl(e) {
11604
+ return typeof e == "string" && (Hl.includes(e) || e.startsWith("custom:") && e.length > 7);
11605
+ }
11606
+ function Ml(e, t) {
11607
+ let n = [];
11608
+ if (!Array.isArray(e)) return n;
11609
+ for (let r of e) {
11610
+ if (!r || typeof r != "object") continue;
11611
+ let e = r;
11612
+ if (!jl(e.source) || !t.includes(e.target)) continue;
11613
+ let i = Number(e.to);
11614
+ if (!Number.isFinite(i)) continue;
11615
+ let a = {
11616
+ source: e.source,
11617
+ target: e.target,
11618
+ to: i
11619
+ };
11620
+ if (e.from !== void 0) {
11621
+ let t = Number(e.from);
11622
+ Number.isFinite(t) && (a.from = t);
11623
+ }
11624
+ e.smoothing !== void 0 && (a.smoothing = Al(e.smoothing, 0, 2, .25)), n.push(a);
11625
+ }
11626
+ return n;
11627
+ }
11628
+ function Nl(e) {
11629
+ let t = e.interaction;
11630
+ if (!t) return;
11631
+ let n = t.hover;
11632
+ n && (n.agitate !== void 0 && (n.agitate = Al(n.agitate, 0, 60, 0)), n.push !== void 0 && (n.push = Al(n.push, -40, 40, 0)), n.wake !== void 0 && (n.wake = Al(n.wake, 0, 40, 0)), n.thin !== void 0 && (n.thin = Al(n.thin, 0, 1, 0)), n.hueShift !== void 0 && (n.hueShift = Al(n.hueShift, -360, 360, 0)), n.lighten !== void 0 && (n.lighten = Al(n.lighten, -1, 1, 0)), n.smoothing !== void 0 && (n.smoothing = Al(n.smoothing, 0, 2, .12))), t.press && t.press.ripple !== void 0 && (t.press.ripple = Al(t.press.ripple, 0, 60, 0)), t.bindings !== void 0 && (t.bindings = Ml(t.bindings, Ul));
11633
+ }
11634
+ function Pl(e) {
11635
+ let t = e.interaction;
11636
+ t && (t.radius !== void 0 && (t.radius = Al(t.radius, .02, 2, .3)), t.ribbonFlow !== void 0 && (t.ribbonFlow = Al(t.ribbonFlow, 0, 1, .8)), t.bindings !== void 0 && (t.bindings = Ml(t.bindings, Wl)));
11637
+ }
11638
+ function Fl(e) {
11584
11639
  let t = e;
11585
- return kl(t), (!Array.isArray(t.waves) || t.waves.length === 0) && (t.waves = [Sl()]), t.waves.forEach(Ol), t.waveCount = t.waves.length, t;
11640
+ return kl(t), (!Array.isArray(t.waves) || t.waves.length === 0) && (t.waves = [Sl()]), t.waves.forEach(Ol), t.waveCount = t.waves.length, t.interaction && Pl(t), t;
11586
11641
  }
11587
- var jl, Ml, Nl, Pl, Fl, Il, Ll = t((() => {
11588
- hl(), jl = 8, Ml = 8, Nl = 8, Pl = 4, Fl = 6, Il = {
11642
+ var Il, Ll, Rl, zl, Bl, Vl, Hl, Ul, Wl, Gl = t((() => {
11643
+ hl(), Il = 8, Ll = 8, Rl = 8, zl = 4, Bl = 6, Vl = {
11589
11644
  x: 800,
11590
11645
  y: 900,
11591
11646
  z: 1100
11592
- };
11593
- })), Rl, zl, Bl, Vl, Hl, Ul, Wl, Gl, Kl = t((() => {
11594
- Ll(), Rl = "\nfloat xxhash(vec2 x){\n uvec2 t = floatBitsToUint(x);\n uint h = 0xc2b2ae3du * t.x + 0x165667b9u;\n h = (h << 17u | h >> 15u) * 0x27d4eb2fu;\n h += 0xc2b2ae3du * t.y;\n h = (h << 17u | h >> 15u) * 0x27d4eb2fu;\n h ^= h >> 15u;\n h *= 0x85ebca77u;\n h ^= h >> 13u;\n h *= 0xc2b2ae3du;\n h ^= h >> 16u;\n return uintBitsToFloat(h >> 9u | 0x3f800000u) - 1.0;\n}\nvec2 hash(vec2 x){\n float k = 6.283185307 * xxhash(x);\n return vec2(cos(k), sin(k));\n}\nfloat simplexNoise(in vec2 p){\n const float K1 = 0.366025404; // (sqrt(3)-1)/2\n const float K2 = 0.211324865; // (3-sqrt(3))/6\n vec2 i = floor(p + (p.x + p.y) * K1);\n vec2 a = p - i + (i.x + i.y) * K2;\n float m = step(a.y, a.x);\n vec2 o = vec2(m, 1.0 - m);\n vec2 b = a - o + K2;\n vec2 c = a - 1.0 + 2.0 * K2;\n vec3 h = max(0.5 - vec3(dot(a, a), dot(b, b), dot(c, c)), 0.0);\n vec3 n = h * h * h * vec3(dot(a, hash(i + 0.0)), dot(b, hash(i + o)), dot(c, hash(i + 1.0)));\n return dot(n, vec3(32.99)); // analytic factor (= 2916*sqrt(2)/125)\n}\n", zl = "\nuniform vec3 uColors[MAX_COLORS];\nuniform float uColorPos[MAX_COLORS];\nuniform int uColorCount;\nuniform int uGradType;\nuniform float uGradAngle;\nuniform float uGradShift;\nuniform vec2 uMeshPointPos[MAX_MESH_POINTS];\nuniform vec3 uMeshPointColor[MAX_MESH_POINTS];\nuniform float uMeshPointInfluence[MAX_MESH_POINTS];\nuniform int uMeshPointCount;\nuniform float uMeshSoftness;\nuniform sampler2D uPalette; // baked 2D palette texture\nuniform float uUsePalette; // >0.5 = sample the texture; else procedural grad()\nuniform float uPaletteRaw; // >0.5 = sample palette by raw (uv.x,uv.y), not gradCoord\nuniform vec2 uPaletteScale;\nuniform vec2 uPaletteOffset;\nuniform float uPaletteRotation;\nuniform float uHueShift;\nuniform float uContrast;\nuniform float uSaturation;\nuniform float uOpacity;\nuniform float uSquared; // 1 = square the output colour (the deep \"squared\" hero look)\n", Bl = "\nvec3 contrastFn(vec3 v, float a){ return (v - 0.5) * a + 0.5; }\nvec3 desaturate(vec3 color, float factor){\n vec3 gray = vec3(dot(vec3(0.299, 0.587, 0.114), color));\n return mix(color, gray, factor);\n}\nvec3 hueShift(vec3 color, float shift){\n vec3 g = vec3(0.57735);\n vec3 proj = g * dot(g, color);\n vec3 U = color - proj;\n vec3 W = cross(g, U);\n return U * cos(shift) + W * sin(shift) + proj;\n}\n\n// Our gradient: interpolate stops by their positions (uColorPos sorted ascending).\nvec3 grad(float u){\n u = clamp(u, 0.0, 1.0);\n vec3 col = uColors[0];\n for (int i = 0; i < MAX_COLORS - 1; i++){\n if (i >= uColorCount - 1) break;\n float p0 = uColorPos[i];\n float p1 = uColorPos[i + 1];\n if (u >= p0){\n float t = clamp((u - p0) / max(p1 - p0, 1e-5), 0.0, 1.0);\n col = mix(uColors[i], uColors[i + 1], t);\n }\n }\n return col;\n}\n\n// iOS-style 2D colour field. Each control point contributes an inverse-distance\n// weight; normalising the sum fills the whole surface without dark seams.\nvec3 meshGradient(vec2 uv){\n vec3 colorSum = vec3(0.0);\n float weightSum = 0.0;\n float exponent = mix(4.8, 1.35, clamp(uMeshSoftness, 0.0, 1.0));\n for (int i = 0; i < MAX_MESH_POINTS; i++){\n if (i >= uMeshPointCount) break;\n float influence = max(uMeshPointInfluence[i], 0.05);\n float distanceFromPoint = length(uv - uMeshPointPos[i]) / influence;\n float weight = 1.0 / (pow(max(distanceFromPoint, 0.012), exponent) + 0.002);\n colorSum += uMeshPointColor[i] * weight;\n weightSum += weight;\n }\n return colorSum / max(weightSum, 0.0001);\n}\n\n// Map a surface uv to the 0–1 gradient coordinate per gradient type. uGradShift\n// adds a low-frequency simplex warp so the colour varies in 2D (along the length\n// as well as across the width) — a 2D palette feel instead\n// of flat 1-D bands.\nfloat gradCoord(vec2 uv){\n float warp = uGradShift * simplexNoise(uv * 1.6 + 4.0);\n if (uGradType == 1){ return clamp(length(uv - 0.5) * 2.0 + warp, 0.0, 1.0); } // radial\n if (uGradType == 2){ return fract(atan(uv.y - 0.5, uv.x - 0.5) / (2.0 * PI) + 0.5 + warp); } // conic\n vec2 dir = vec2(sin(uGradAngle), cos(uGradAngle)); // linear, angled\n return clamp(dot(uv - 0.5, dir) + 0.5 + warp, 0.0, 1.0);\n}\n\n// One base-colour sample for the whole surface: rotate/scale/offset the raw-palette uv,\n// then pick the mesh field / baked 2D texture / procedural stops by mode. The raw palette\n// is sampled by (uv.x, uv.y) directly; the stops-generated texture is sampled via\n// gradCoord so its angle/type/warp still apply.\nvec3 waveBaseColor(vec2 uv){\n float gc = gradCoord(uv);\n vec2 mediaUv = uv - 0.5;\n float mediaCos = cos(uPaletteRotation);\n float mediaSin = sin(uPaletteRotation);\n mediaUv = vec2(\n mediaCos * mediaUv.x + mediaSin * mediaUv.y,\n -mediaSin * mediaUv.x + mediaCos * mediaUv.y\n );\n mediaUv = mediaUv * uPaletteScale + 0.5 + uPaletteOffset;\n vec2 puv = uPaletteRaw > 0.5\n ? clamp(mediaUv, 0.0, 1.0)\n : vec2(gc, clamp(uv.y, 0.0, 1.0));\n return uGradType == 3\n ? meshGradient(uv)\n : (uUsePalette > 0.5 ? texture2D(uPalette, puv).rgb : grad(gc));\n}\n\n// The shared colour grade: contrast → desaturate → hue rotate (degrees).\nvec3 applyColorGrade(vec3 c){\n c = contrastFn(c, uContrast);\n c = desaturate(c, 1.0 - uSaturation);\n return hueShift(c, radians(uHueShift));\n}\n", Vl = `
11595
- ${Rl}
11647
+ }, Hl = [
11648
+ "scroll",
11649
+ "hover",
11650
+ "pointerX",
11651
+ "pointerY",
11652
+ "pointerSpeed",
11653
+ "press",
11654
+ "scrollVelocity",
11655
+ "appear"
11656
+ ], Ul = [
11657
+ "displaceAmount",
11658
+ "detailAmount",
11659
+ "twistPowerX",
11660
+ "twistPowerY",
11661
+ "twistPowerZ",
11662
+ "twistFrequencyX",
11663
+ "twistFrequencyY",
11664
+ "twistFrequencyZ",
11665
+ "hueShift",
11666
+ "gradientShift",
11667
+ "colorSaturation",
11668
+ "opacity",
11669
+ "lineThickness",
11670
+ "lineAmount",
11671
+ "fiberStrength",
11672
+ "sheen",
11673
+ "iridescence",
11674
+ "positionX",
11675
+ "positionY"
11676
+ ], Wl = [
11677
+ "timeOffset",
11678
+ "cameraZoom",
11679
+ "blur",
11680
+ "grain"
11681
+ ];
11682
+ })), Kl, ql, Jl, Yl, Xl, Zl, Ql, $l, eu, tu, nu, ru, iu, au, ou = t((() => {
11683
+ Gl(), Kl = "\nfloat xxhash(vec2 x){\n uvec2 t = floatBitsToUint(x);\n uint h = 0xc2b2ae3du * t.x + 0x165667b9u;\n h = (h << 17u | h >> 15u) * 0x27d4eb2fu;\n h += 0xc2b2ae3du * t.y;\n h = (h << 17u | h >> 15u) * 0x27d4eb2fu;\n h ^= h >> 15u;\n h *= 0x85ebca77u;\n h ^= h >> 13u;\n h *= 0xc2b2ae3du;\n h ^= h >> 16u;\n return uintBitsToFloat(h >> 9u | 0x3f800000u) - 1.0;\n}\nvec2 hash(vec2 x){\n float k = 6.283185307 * xxhash(x);\n return vec2(cos(k), sin(k));\n}\nfloat simplexNoise(in vec2 p){\n const float K1 = 0.366025404; // (sqrt(3)-1)/2\n const float K2 = 0.211324865; // (3-sqrt(3))/6\n vec2 i = floor(p + (p.x + p.y) * K1);\n vec2 a = p - i + (i.x + i.y) * K2;\n float m = step(a.y, a.x);\n vec2 o = vec2(m, 1.0 - m);\n vec2 b = a - o + K2;\n vec2 c = a - 1.0 + 2.0 * K2;\n vec3 h = max(0.5 - vec3(dot(a, a), dot(b, b), dot(c, c)), 0.0);\n vec3 n = h * h * h * vec3(dot(a, hash(i + 0.0)), dot(b, hash(i + o)), dot(c, hash(i + 1.0)));\n return dot(n, vec3(32.99)); // analytic factor (= 2916*sqrt(2)/125)\n}\n", ql = "\nuniform vec3 uColors[MAX_COLORS];\nuniform float uColorPos[MAX_COLORS];\nuniform int uColorCount;\nuniform int uGradType;\nuniform float uGradAngle;\nuniform float uGradShift;\nuniform vec2 uMeshPointPos[MAX_MESH_POINTS];\nuniform vec3 uMeshPointColor[MAX_MESH_POINTS];\nuniform float uMeshPointInfluence[MAX_MESH_POINTS];\nuniform int uMeshPointCount;\nuniform float uMeshSoftness;\nuniform sampler2D uPalette; // baked 2D palette texture\nuniform float uUsePalette; // >0.5 = sample the texture; else procedural grad()\nuniform float uPaletteRaw; // >0.5 = sample palette by raw (uv.x,uv.y), not gradCoord\nuniform vec2 uPaletteScale;\nuniform vec2 uPaletteOffset;\nuniform float uPaletteRotation;\nuniform float uHueShift;\nuniform float uContrast;\nuniform float uSaturation;\nuniform float uOpacity;\nuniform float uSquared; // 1 = square the output colour (the deep \"squared\" hero look)\n", Jl = "\nvec3 contrastFn(vec3 v, float a){ return (v - 0.5) * a + 0.5; }\nvec3 desaturate(vec3 color, float factor){\n vec3 gray = vec3(dot(vec3(0.299, 0.587, 0.114), color));\n return mix(color, gray, factor);\n}\nvec3 hueShift(vec3 color, float shift){\n vec3 g = vec3(0.57735);\n vec3 proj = g * dot(g, color);\n vec3 U = color - proj;\n vec3 W = cross(g, U);\n return U * cos(shift) + W * sin(shift) + proj;\n}\n\n// Our gradient: interpolate stops by their positions (uColorPos sorted ascending).\nvec3 grad(float u){\n u = clamp(u, 0.0, 1.0);\n vec3 col = uColors[0];\n for (int i = 0; i < MAX_COLORS - 1; i++){\n if (i >= uColorCount - 1) break;\n float p0 = uColorPos[i];\n float p1 = uColorPos[i + 1];\n if (u >= p0){\n float t = clamp((u - p0) / max(p1 - p0, 1e-5), 0.0, 1.0);\n col = mix(uColors[i], uColors[i + 1], t);\n }\n }\n return col;\n}\n\n// iOS-style 2D colour field. Each control point contributes an inverse-distance\n// weight; normalising the sum fills the whole surface without dark seams.\nvec3 meshGradient(vec2 uv){\n vec3 colorSum = vec3(0.0);\n float weightSum = 0.0;\n float exponent = mix(4.8, 1.35, clamp(uMeshSoftness, 0.0, 1.0));\n for (int i = 0; i < MAX_MESH_POINTS; i++){\n if (i >= uMeshPointCount) break;\n float influence = max(uMeshPointInfluence[i], 0.05);\n float distanceFromPoint = length(uv - uMeshPointPos[i]) / influence;\n float weight = 1.0 / (pow(max(distanceFromPoint, 0.012), exponent) + 0.002);\n colorSum += uMeshPointColor[i] * weight;\n weightSum += weight;\n }\n return colorSum / max(weightSum, 0.0001);\n}\n\n// Map a surface uv to the 0–1 gradient coordinate per gradient type. uGradShift\n// adds a low-frequency simplex warp so the colour varies in 2D (along the length\n// as well as across the width) — a 2D palette feel instead\n// of flat 1-D bands.\nfloat gradCoord(vec2 uv){\n float warp = uGradShift * simplexNoise(uv * 1.6 + 4.0);\n if (uGradType == 1){ return clamp(length(uv - 0.5) * 2.0 + warp, 0.0, 1.0); } // radial\n if (uGradType == 2){ return fract(atan(uv.y - 0.5, uv.x - 0.5) / (2.0 * PI) + 0.5 + warp); } // conic\n vec2 dir = vec2(sin(uGradAngle), cos(uGradAngle)); // linear, angled\n return clamp(dot(uv - 0.5, dir) + 0.5 + warp, 0.0, 1.0);\n}\n\n// One base-colour sample for the whole surface: rotate/scale/offset the raw-palette uv,\n// then pick the mesh field / baked 2D texture / procedural stops by mode. The raw palette\n// is sampled by (uv.x, uv.y) directly; the stops-generated texture is sampled via\n// gradCoord so its angle/type/warp still apply.\nvec3 waveBaseColor(vec2 uv){\n float gc = gradCoord(uv);\n vec2 mediaUv = uv - 0.5;\n float mediaCos = cos(uPaletteRotation);\n float mediaSin = sin(uPaletteRotation);\n mediaUv = vec2(\n mediaCos * mediaUv.x + mediaSin * mediaUv.y,\n -mediaSin * mediaUv.x + mediaCos * mediaUv.y\n );\n mediaUv = mediaUv * uPaletteScale + 0.5 + uPaletteOffset;\n vec2 puv = uPaletteRaw > 0.5\n ? clamp(mediaUv, 0.0, 1.0)\n : vec2(gc, clamp(uv.y, 0.0, 1.0));\n return uGradType == 3\n ? meshGradient(uv)\n : (uUsePalette > 0.5 ? texture2D(uPalette, puv).rgb : grad(gc));\n}\n\n// The shared colour grade: contrast → desaturate → hue rotate (degrees).\nvec3 applyColorGrade(vec3 c){\n c = contrastFn(c, uContrast);\n c = desaturate(c, 1.0 - uSaturation);\n return hueShift(c, radians(uHueShift));\n}\n", Yl = `
11684
+ ${Kl}
11596
11685
 
11597
11686
  uniform float uTime, uSpeed, uSeed;
11598
11687
  uniform float uDispFreqX, uDispFreqZ, uDispAmount;
@@ -11605,6 +11694,34 @@ varying vec3 vWorldPos;
11605
11694
  varying vec3 vViewDir;
11606
11695
  varying vec4 vClipPosition; // = gl_Position, for the wireframe theme's depth fade
11607
11696
 
11697
+ // Pointer field (optional, additive). ALL declarations here sit behind POINTER_FX so a wave with
11698
+ // no interaction config compiles the exact same program (JS-side uniform entries are always present
11699
+ // — see makeUniforms — but three only uploads uniforms the compiled program actually declares).
11700
+ #ifdef POINTER_FX
11701
+ uniform vec2 uPointer; // smoothed pointer, NDC (-1..1)
11702
+ uniform float uPointerActive; // presence ramp 0..1 × per-wave influence
11703
+ uniform float uPointerRadius; // falloff radius in NDC-y units (config radius × 2)
11704
+ uniform float uPointerAspect; // drawing-buffer dw/dh (circular screen falloff)
11705
+ uniform float uPointerAgitate;
11706
+ uniform float uPointerPush; // signed membrane dome at the cursor (+ repel / − attract)
11707
+ uniform float uPointerWake; // drag-wake trough amplitude (behind the moving cursor)
11708
+ uniform vec2 uPointerVel; // smoothed pointer velocity, NDC/s (drag-wake direction)
11709
+ // Ribbon flow: stretch the falloff along the strip's length axis so the field reaches ALONG the
11710
+ // ribbon rather than as a screen disc. 0 = the plain circular smoothstep (byte-identical when off).
11711
+ uniform float uShapeFlow;
11712
+ varying float vPointerFall; // falloff × presence — consumed by both fragment themes
11713
+ #ifdef POINTER_RIPPLES
11714
+ uniform vec2 uRippleOrigin[4]; // NDC
11715
+ uniform float uRippleAge[4]; // seconds since spawn (CPU-computed)
11716
+ uniform float uRippleAmp[4]; // shared 0..1 decay envelope per slot (CPU-computed; 0 = slot free)
11717
+ uniform float uPointerRipple; // THIS wave's ripple amplitude (scales the shared envelope)
11718
+ const float RIPPLE_WAVE_SPEED = 0.85; // NDC/s the ring crest travels outward
11719
+ const float RIPPLE_SIGMA = 0.14; // gaussian half-width of the travelling packet (NDC)
11720
+ const float RIPPLE_FREQ = 11.0; // oscillation within the packet (one crest + faint troughs)
11721
+ const float RIPPLE_MAX_R = 1.2; // reach where the crest has fully left the frame
11722
+ #endif
11723
+ #endif
11724
+
11608
11725
  // expStep: a falloff from 1 (at x=0) toward 0, sharpness set by n. The
11609
11726
  // max() guards pow(0, n) (= Infinity → NaN) so negative n is safe — negative n
11610
11727
  // just concentrates the twist toward the OTHER end instead.
@@ -11684,6 +11801,81 @@ void main(){
11684
11801
  pos = (vec4(pos, 1.0) * rotB).xyz;
11685
11802
  pos = (vec4(pos, 1.0) * rotC).xyz;
11686
11803
 
11804
+ #ifdef POINTER_FX
11805
+ // Pointer field: displace along the wave's own (post-twist) up-axis, weighted by a screen-space
11806
+ // falloff around the smoothed cursor — a circle at uShapeFlow 0, stretched along the ribbon as it
11807
+ // rises. Everything here is ADDITIVE and fenced, so the shared path above/below is untouched and
11808
+ // byte-identical when POINTER_FX is off.
11809
+ // Shared clip-space transform, computed once and reused for the cursor metric and the ribbon
11810
+ // tangent (the compiler is not guaranteed to CSE the triple product otherwise). Associativity is
11811
+ // unchanged, so preClip is bit-for-bit what the plain P*V*M*v product produced.
11812
+ mat4 mvp = projectionMatrix * viewMatrix * modelMatrix;
11813
+ vec4 preClip = mvp * vec4(pos, 1.0);
11814
+ // Screen-space offset from the cursor (aspect-corrected → round in pixels). The DEFAULT metric.
11815
+ vec2 ndcHere = preClip.xy / max(preClip.w, 1.0e-6);
11816
+ vec2 dp = (ndcHere - uPointer) * vec2(uPointerAspect, 1.0);
11817
+ // Ribbon flow: stretch the metric along the strip's own LENGTH axis so the field reaches ALONG the
11818
+ // ribbon and stays tight across it — the "flows with the material" feel, per-vertex (so it follows
11819
+ // the strip's curve) with no CPU surface pick. The length axis is local +X (uv.x runs with x)
11820
+ // carried through the SAME twist as the surface. The camera is orthographic (affine, w=1), so the
11821
+ // axis's screen image is the linear map of the DIRECTION (w=0): one mat·dir, no second
11822
+ // point-projection and no perspective divide. (A true per-pixel uv would need GPU picking — the
11823
+ // visible surface is shader-displaced, so a CPU raycast of the base geometry misses.)
11824
+ if (uShapeFlow > 0.0) {
11825
+ vec3 tangentLocal = (((vec4(1.0, 0.0, 0.0, 0.0) * rotA) * rotB) * rotC).xyz;
11826
+ vec2 tang = (mvp * vec4(tangentLocal, 0.0)).xy * vec2(uPointerAspect, 1.0);
11827
+ float tl = length(tang);
11828
+ if (tl > 1.0e-6) {
11829
+ tang /= tl;
11830
+ vec2 nrm = vec2(-tang.y, tang.x);
11831
+ dp = vec2(dot(dp, tang) / (1.0 + uShapeFlow * 2.5), dot(dp, nrm)); // up to 3.5× reach along length
11832
+ }
11833
+ }
11834
+ float fall = smoothstep(uPointerRadius, 0.0, length(dp));
11835
+ vPointerFall = fall * uPointerActive;
11836
+ // Displacement axis = local +Y carried through the SAME three twist rotations as pos (row-vector
11837
+ // convention). Rotations are linear, so post-twist axis displacement equals pre-twist Y displacement.
11838
+ vec3 dispAxis = (((vec4(0.0, 1.0, 0.0, 0.0) * rotA) * rotB) * rotC).xyz;
11839
+ // Agitation: a fast churn octave near the cursor (additive — never rewrites base noise t, which
11840
+ // would force restructuring the shared path). Loop-safe under both time variants.
11841
+ #ifdef LOOP_MOTION
11842
+ float disp = uPointerAgitate * vPointerFall
11843
+ * simplexNoise(vec2(pos.x * uDispFreqX * 3.0, pos.z * uDispFreqZ * 3.0) + loopOff * 4.0);
11844
+ #else
11845
+ float disp = uPointerAgitate * vPointerFall
11846
+ * simplexNoise(vec2(pos.x * uDispFreqX * 3.0 + t * 4.0, pos.z * uDispFreqZ * 3.0));
11847
+ #endif
11848
+ // Membrane push/pull: a smooth dome (vPointerFall is the falloff) that swells toward you (+ repel)
11849
+ // or dents away (− attract) at the cursor, riding along with the sprung field.
11850
+ disp += uPointerPush * vPointerFall;
11851
+ // Drag-wake: pull the surface just BEHIND the moving cursor into a trailing trough. dp points
11852
+ // from cursor to vertex; "behind" is how far the vertex sits opposite the velocity (0 ahead → 1 a
11853
+ // radius behind), gated by speed so it only forms while dragging and heals when the cursor stops.
11854
+ vec2 velC = uPointerVel * vec2(uPointerAspect, 1.0);
11855
+ float wakeSpeed = length(velC);
11856
+ if (uPointerWake != 0.0 && wakeSpeed > 1.0e-4) {
11857
+ float behind = clamp(dot(-dp, velC) / (wakeSpeed * uPointerRadius), 0.0, 1.0);
11858
+ disp -= uPointerWake * vPointerFall * behind * smoothstep(0.05, 0.6, wakeSpeed);
11859
+ }
11860
+ #ifdef POINTER_RIPPLES
11861
+ for (int i = 0; i < 4; i++) {
11862
+ if (uRippleAmp[i] > 0.0) {
11863
+ float rd = length((preClip.xy / max(preClip.w, 1.0e-6) - uRippleOrigin[i]) * vec2(uPointerAspect, 1.0));
11864
+ // A wave PACKET whose crest travels outward at RIPPLE_WAVE_SPEED: a gaussian window centred on
11865
+ // the moving front carrying a short oscillation (a raised ring with faint trailing troughs),
11866
+ // so the energy radiates instead of throbbing at the click point. The shared uRippleAmp
11867
+ // envelope fades the whole packet over its lifetime; reach fades it as the crest leaves frame.
11868
+ float front = uRippleAge[i] * RIPPLE_WAVE_SPEED;
11869
+ float band = rd - front;
11870
+ float packet = exp(-band * band / (2.0 * RIPPLE_SIGMA * RIPPLE_SIGMA)) * cos(band * RIPPLE_FREQ);
11871
+ float reach = 1.0 - smoothstep(RIPPLE_MAX_R * 0.7, RIPPLE_MAX_R, front);
11872
+ disp += uPointerRipple * uRippleAmp[i] * packet * reach;
11873
+ }
11874
+ }
11875
+ #endif
11876
+ pos += dispAxis * disp;
11877
+ #endif
11878
+
11687
11879
  // The scale / rotation / position transform lives on the mesh (modelMatrix), so the
11688
11880
  // orientation matches THREE's Euler-XYZ rather than an in-shader rotation order.
11689
11881
  vec4 world = modelMatrix * vec4(pos, 1.0);
@@ -11692,16 +11884,16 @@ void main(){
11692
11884
  gl_Position = projectionMatrix * viewMatrix * world;
11693
11885
  vClipPosition = gl_Position;
11694
11886
  }
11695
- `, Hl = `
11887
+ `, Xl = `
11696
11888
  #define MAX_COLORS 8
11697
11889
  #define MAX_MESH_POINTS 8
11698
11890
  #define MAX_LIGHTS 8
11699
11891
  #define MAX_NOISE_BANDS 4
11700
11892
  #define PI 3.14159265359
11701
11893
 
11702
- ${Rl}
11894
+ ${Kl}
11703
11895
 
11704
- ${zl}
11896
+ ${ql}
11705
11897
  uniform float uDebug; // dev: 1 = show crease, 2 = show derivative normal
11706
11898
  uniform float uSheen; // white-lift on the flat (low-crease) areas (1 = full)
11707
11899
  uniform float uRoundness; // pose-robust normal-based roundness/thickness strength
@@ -11735,6 +11927,12 @@ varying vec4 vClipPosition; // clip-space depth (written by the vertex shader fo
11735
11927
  #ifdef EDGE_FEATHER
11736
11928
  uniform float uEdgeFeather; // ribbon long-edge softness (only when it differs from the 0.1 default)
11737
11929
  #endif
11930
+ #ifdef POINTER_FX
11931
+ uniform float uPointerThin; // 0..1 local translucency near the cursor
11932
+ uniform float uPointerHue; // degrees, local hue rotation near the cursor
11933
+ uniform float uPointerLighten; // -1..1 local brightness lift near the cursor
11934
+ varying float vPointerFall; // falloff × presence, written by the vertex shader
11935
+ #endif
11738
11936
 
11739
11937
  // Cheap value hash for the optional grain overlay (distinct from the simplex hash).
11740
11938
  float grainHash(vec2 p){ return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453); }
@@ -11742,7 +11940,7 @@ float grainHash(vec2 p){ return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758
11742
11940
  float parabola(float x, float k){ return pow(4.0 * x * (1.0 - x), k); }
11743
11941
  float mapLinear(float v, float a, float b, float c, float d){ return c + (v - a) * (d - c) / (b - a); }
11744
11942
 
11745
- ${Bl}
11943
+ ${Jl}
11746
11944
 
11747
11945
  // Striations: a subtle high-frequency simplex-noise grain ADDED to the
11748
11946
  // colour — colour-matched (weaker where blue is high), only near folds (crease), and
@@ -11799,6 +11997,12 @@ void main(){
11799
11997
  col = surfaceStreaks(vUv, col, crease);
11800
11998
  col = applyColorGrade(col);
11801
11999
 
12000
+ #ifdef POINTER_FX
12001
+ // Local hue rotation + brightness lift near the cursor (both fade out with vPointerFall).
12002
+ col = hueShift(col, radians(uPointerHue) * vPointerFall);
12003
+ col *= 1.0 + uPointerLighten * vPointerFall;
12004
+ #endif
12005
+
11802
12006
  // Iridescence: a thin-film / holographic hue that shifts with view angle. Reuses the same
11803
12007
  // camera-facing ratio as roundness (recomputed here, since roundness may be off): grazing parts
11804
12008
  // of the ribbon (low facing) shift hue most, so the colour flows as the ribbon curves. Skipped
@@ -11861,6 +12065,9 @@ void main(){
11861
12065
  float ribEdge = smoothstep(0.0, 0.1, vUv.y) * (1.0 - smoothstep(0.9, 1.0, vUv.y));
11862
12066
  #endif
11863
12067
  float alpha = uOpacity * ribEdge;
12068
+ #ifdef POINTER_FX
12069
+ alpha *= clamp(1.0 - uPointerThin * vPointerFall, 0.0, 1.0); // solid: local translucency
12070
+ #endif
11864
12071
  if (uEdgeFade > 0.001) {
11865
12072
  vec2 sc = gl_FragCoord.xy / max(uResolution, vec2(1.0));
11866
12073
  float vig =
@@ -11882,14 +12089,14 @@ void main(){
11882
12089
  gl_FragColor.rgb *= gl_FragColor.a;
11883
12090
  #endif
11884
12091
  }
11885
- `, Ul = `
12092
+ `, Zl = `
11886
12093
  #define MAX_COLORS 8
11887
12094
  #define MAX_MESH_POINTS 8
11888
12095
  #define PI 3.14159265359
11889
12096
 
11890
- ${Rl}
12097
+ ${Kl}
11891
12098
 
11892
- ${zl}
12099
+ ${ql}
11893
12100
  uniform float uLineAmount; // default 425
11894
12101
  uniform float uLineThickness; // default 1
11895
12102
  uniform float uLineDerivativePower; // default 0.95
@@ -11898,16 +12105,30 @@ uniform vec3 uClearColor; // = page background colour (shown between t
11898
12105
 
11899
12106
  varying vec2 vUv;
11900
12107
  varying vec4 vClipPosition;
12108
+ #ifdef POINTER_FX
12109
+ uniform float uPointerThin; // 0..1 — strands taper to hairlines near the cursor
12110
+ uniform float uPointerHue; // degrees, local hue rotation near the cursor
12111
+ uniform float uPointerLighten; // -1..1 local brightness lift near the cursor
12112
+ varying float vPointerFall; // falloff × presence, written by the vertex shader
12113
+ #endif
11901
12114
 
11902
- ${Bl}
12115
+ ${Jl}
11903
12116
 
11904
12117
  void main(){
11905
12118
  // Same 2D palette sample + colour ops as the solid theme.
11906
12119
  vec3 color = applyColorGrade(waveBaseColor(vUv));
11907
12120
 
12121
+ #ifdef POINTER_FX
12122
+ color = hueShift(color, radians(uPointerHue) * vPointerFall);
12123
+ color *= 1.0 + uPointerLighten * vPointerFall;
12124
+ #endif
12125
+
11908
12126
  // Carve into fine vertical lines; thickness from the screen-space uv derivative.
11909
12127
  vec2 dy = dFdy(vUv);
11910
12128
  float lineThickness = uLineThickness * pow(abs(dy.x * uMaxWidth), uLineDerivativePower);
12129
+ #ifdef POINTER_FX
12130
+ lineThickness *= clamp(1.0 - uPointerThin * vPointerFall, 0.0, 1.0); // wireframe: taper strands
12131
+ #endif
11911
12132
  float a = abs(sin(vUv.x * uLineAmount));
11912
12133
  a = smoothstep(lineThickness, 0.0, a);
11913
12134
 
@@ -11924,9 +12145,9 @@ void main(){
11924
12145
  gl_FragColor.rgb *= gl_FragColor.a;
11925
12146
  #endif
11926
12147
  }
11927
- `, Wl = "\nvarying vec2 vUv;\nvoid main(){\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n", Gl = "\nuniform sampler2D tDiffuse;\nuniform vec2 uResolution;\nuniform float uBlurAmount;\nuniform int uBlurSamples;\nuniform float uGrainAmount;\nuniform float uTime;\nvarying vec2 vUv;\n\nfloat random2(vec2 st){ return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453); }\n\n// Angular (spin) blur: rotate the sample coord around the centre and\n// accumulate — a tangential smear that grows toward the edges. Carries alpha so a\n// transparent background survives the post pass.\nvec4 blurAngular(sampler2D tex, vec2 uv, float angle, int samples){\n vec4 total = vec4(0.0);\n vec2 coord = uv - 0.5;\n float dist = 1.0 / float(samples);\n vec2 dir = vec2(cos(angle * dist), sin(angle * dist));\n mat2 rot = mat2(dir.x, dir.y, -dir.y, dir.x);\n for (int i = 0; i < 64; i++){\n if (i >= samples) break;\n total += texture2D(tex, coord + 0.5);\n coord = coord * rot; // row-vector order (coord * rot) sets the spin direction\n }\n return total * dist;\n}\n\nvoid main(){\n vec4 sceneColor = texture2D(tDiffuse, vUv);\n vec4 blurColor = blurAngular(tDiffuse, vUv, uBlurAmount, uBlurSamples);\n // blurPower: keep a sharp band weighted to the middle, blurring toward top & bottom.\n float blurPower = smoothstep(0.0, 0.7, vUv.y) - smoothstep(0.2, 1.0, vUv.y);\n vec4 color = mix(blurColor, sceneColor, blurPower);\n // Static film grain: keyed off gl_FragCoord only (no uTime), so it doesn't flicker.\n color.rgb += mix(uGrainAmount, -uGrainAmount, random2(gl_FragCoord.xy * 0.01)) * (4.0 / 255.0);\n gl_FragColor = color; // preserve alpha → transparent background works\n}\n";
11928
- })), ql, Jl, Yl, Xl, Zl, Ql, $l = t((() => {
11929
- Vc(), ql = 400, Jl = 16, Yl = ql / 4, Xl = new K(1, 0, 0), Zl = new K(0, 1, 0), Ql = class {
12148
+ `, Ql = "\nvarying vec2 vUv;\nvoid main(){\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n", $l = "\nuniform sampler2D tDiffuse;\nuniform vec2 uResolution;\nuniform float uBlurAmount;\nuniform int uBlurSamples;\nuniform float uGrainAmount;\nuniform float uTime;\nvarying vec2 vUv;\n\nfloat random2(vec2 st){ return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453); }\n\n// Angular (spin) blur: rotate the sample coord around the centre and\n// accumulate — a tangential smear that grows toward the edges. Carries alpha so a\n// transparent background survives the post pass.\nvec4 blurAngular(sampler2D tex, vec2 uv, float angle, int samples){\n vec4 total = vec4(0.0);\n vec2 coord = uv - 0.5;\n float dist = 1.0 / float(samples);\n vec2 dir = vec2(cos(angle * dist), sin(angle * dist));\n mat2 rot = mat2(dir.x, dir.y, -dir.y, dir.x);\n for (int i = 0; i < 64; i++){\n if (i >= samples) break;\n total += texture2D(tex, coord + 0.5);\n coord = coord * rot; // row-vector order (coord * rot) sets the spin direction\n }\n return total * dist;\n}\n\nvoid main(){\n vec4 sceneColor = texture2D(tDiffuse, vUv);\n vec4 blurColor = blurAngular(tDiffuse, vUv, uBlurAmount, uBlurSamples);\n // blurPower: keep a sharp band weighted to the middle, blurring toward top & bottom.\n float blurPower = smoothstep(0.0, 0.7, vUv.y) - smoothstep(0.2, 1.0, vUv.y);\n vec4 color = mix(blurColor, sceneColor, blurPower);\n // Static film grain: keyed off gl_FragCoord only (no uTime), so it doesn't flicker.\n color.rgb += mix(uGrainAmount, -uGrainAmount, random2(gl_FragCoord.xy * 0.01)) * (4.0 / 255.0);\n gl_FragColor = color; // preserve alpha → transparent background works\n}\n", eu = "\nuniform sampler2D tDiffuse;\nuniform vec2 uResolution;\nuniform float uDitherStrength; // 0..1 mix back toward the original\nuniform float uDitherScale; // pixel-block size in device px (paper: u_pxSize)\nuniform float uDitherSteps; // quantization levels (paper: u_colorSteps)\nvarying vec2 vUv;\n\nconst int bayer2x2[4] = int[4](0, 2, 3, 1);\nconst int bayer4x4[16] = int[16](0, 8, 2, 10, 12, 4, 14, 6, 3, 11, 1, 9, 15, 7, 13, 5);\nconst int bayer8x8[64] = int[64](\n 0, 32, 8, 40, 2, 34, 10, 42, 48, 16, 56, 24, 50, 18, 58, 26,\n 12, 44, 4, 36, 14, 46, 6, 38, 60, 28, 52, 20, 62, 30, 54, 22,\n 3, 35, 11, 43, 1, 33, 9, 41, 51, 19, 59, 27, 49, 17, 57, 25,\n 15, 47, 7, 39, 13, 45, 5, 37, 63, 31, 55, 23, 61, 29, 53, 21\n);\nfloat getBayerValue(vec2 uv, int size){\n ivec2 pos = ivec2(fract(uv / float(size)) * float(size));\n int index = pos.y * size + pos.x;\n if (size == 2) return float(bayer2x2[index]) / 4.0;\n else if (size == 4) return float(bayer4x4[index]) / 16.0;\n else if (size == 8) return float(bayer8x8[index]) / 64.0;\n return 0.0;\n}\n\nvoid main(){\n float pxSize = max(uDitherScale, 1.0);\n vec2 pxSizeUV = gl_FragCoord.xy / pxSize;\n vec2 sampleUV = (floor(gl_FragCoord.xy / pxSize) + 0.5) * pxSize / max(uResolution, vec2(1.0));\n vec4 image = texture2D(tDiffuse, sampleUV);\n\n float lum = dot(vec3(0.2126, 0.7152, 0.0722), image.rgb);\n float colorSteps = max(floor(uDitherSteps), 1.0);\n\n float dithering = getBayerValue(pxSizeUV, 8) - 0.5; // paper's default 8x8 ordered screen\n float brightness = clamp(lum + dithering / colorSteps, 0.0, 1.0);\n brightness = mix(0.0, brightness, image.a);\n float quantLum = floor(brightness * colorSteps + 0.5) / colorSteps;\n\n // paper's \"original colours\" path: keep the source hue, quantize luminance.\n vec3 color = image.rgb / max(lum, 0.001) * quantLum;\n float quantAlpha = floor(image.a * colorSteps + 0.5) / colorSteps;\n float opacity = mix(quantLum, 1.0, quantAlpha);\n\n gl_FragColor = mix(image, vec4(color, opacity), clamp(uDitherStrength, 0.0, 1.0));\n}\n", tu = "\nuniform sampler2D tDiffuse;\nuniform float uInnerLight; // 0..1 strength of the added light\nuniform float uInnerLightDensity; // ray length / spread\nuniform float uInnerLightDecay; // per-sample falloff (<1)\nuniform vec2 uInnerLightCenter; // light source, UV (0..1)\nvarying vec2 vUv;\n\nconst int LIGHT_SAMPLES = 24;\n\nfloat luma(vec3 c){ return dot(c, vec3(0.2126, 0.7152, 0.0722)); }\n\nvoid main(){\n vec4 src = texture2D(tDiffuse, vUv);\n vec2 delta = (vUv - uInnerLightCenter) * (uInnerLightDensity / float(LIGHT_SAMPLES));\n vec2 coord = vUv;\n float decay = 1.0;\n vec3 rays = vec3(0.0);\n for (int i = 0; i < LIGHT_SAMPLES; i++){\n coord -= delta;\n vec4 s = texture2D(tDiffuse, coord);\n rays += s.rgb * s.a * decay; // only opaque (wave) pixels emit light\n decay *= uInnerLightDecay;\n }\n rays /= float(LIGHT_SAMPLES);\n vec3 outc = src.rgb + rays * uInnerLight;\n float outA = max(src.a, luma(rays) * uInnerLight); // shafts stay visible over the transparent bg\n gl_FragColor = vec4(outc, clamp(outA, 0.0, 1.0));\n}\n", nu = "\nuniform sampler2D tDiffuse;\nuniform vec2 uResolution;\nuniform float uHalftone; // 0..1 mix\nuniform float uHalftoneCell; // dot cell size in device px (paper: u_size)\nuniform float uHalftoneAngle; // screen rotation (radians, paper: u_rotation)\nvarying vec2 vUv;\n\nfloat sigmoid(float x, float k){ return 1.0 / (1.0 + exp(-k * (x - 0.5))); }\n// paper's classic dot: radius grows as the sampled cell darkens (1 - lum), soft edge via fwidth.\nfloat getCircle(vec2 uv, float lum, float baseR){\n float r = mix(0.25 * baseR, 0.0, lum);\n float d = length(uv - 0.5);\n float aa = fwidth(d);\n return 1.0 - smoothstep(r - aa, r + aa, d);\n}\n\nvoid main(){\n float ca = cos(uHalftoneAngle);\n float sa = sin(uHalftoneAngle);\n mat2 rot = mat2(ca, sa, -sa, ca);\n float cell = max(uHalftoneCell, 2.0);\n vec2 gridPx = rot * gl_FragCoord.xy; // rotate the screen into the dot grid\n vec2 cellId = floor(gridPx / cell);\n vec2 inCell = fract(gridPx / cell); // position within the cell (0..1)\n vec2 centrePx = transpose(rot) * ((cellId + 0.5) * cell); // cell centre, back in screen px\n vec4 tex = texture2D(tDiffuse, centrePx / max(uResolution, vec2(1.0)));\n\n float k = 2.0; // sigmoid contrast (paper default)\n vec3 c = vec3(sigmoid(tex.r, k), sigmoid(tex.g, k), sigmoid(tex.b, k));\n float lum = dot(vec3(0.2126, 0.7152, 0.0722), c);\n lum = mix(1.0, lum, tex.a);\n float dot = getCircle(inCell, lum, 1.3); // baseR 1.3 ≈ paper original-colours default\n vec4 dots = vec4(tex.rgb, tex.a * dot); // wave-coloured dots, transparent between\n gl_FragColor = mix(texture2D(tDiffuse, vUv), dots, clamp(uHalftone, 0.0, 1.0));\n}\n", ru = "\nuniform sampler2D tDiffuse;\nuniform float uHeatmap; // 0..1 mix\nvarying vec2 vUv;\nvec3 heat(float t){\n t = clamp(t, 0.0, 1.0);\n vec3 c = mix(vec3(0.0, 0.0, 0.4), vec3(0.0, 0.6, 1.0), smoothstep(0.0, 0.25, t));\n c = mix(c, vec3(0.0, 1.0, 0.4), smoothstep(0.25, 0.5, t));\n c = mix(c, vec3(1.0, 1.0, 0.0), smoothstep(0.5, 0.75, t));\n c = mix(c, vec3(1.0, 0.1, 0.0), smoothstep(0.75, 1.0, t));\n return c;\n}\nvoid main(){\n vec4 src = texture2D(tDiffuse, vUv);\n float l = dot(src.rgb, vec3(0.299, 0.587, 0.114));\n gl_FragColor = vec4(mix(src.rgb, heat(l), clamp(uHeatmap, 0.0, 1.0)), src.a);\n}\n", iu = "\nuniform sampler2D tDiffuse;\nuniform float uPaper; // 0..1 strength\nuniform float uPaperScale; // grain scale\nvarying vec2 vUv;\nfloat h21(vec2 p){ return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453); }\nvoid main(){\n vec4 src = texture2D(tDiffuse, vUv);\n vec2 p = gl_FragCoord.xy / max(uPaperScale, 0.5);\n float fiber = h21(floor(p)) * 0.5 + h21(floor(p * vec2(0.3, 3.0))) * 0.5; // directional fibers\n float tex = mix(fiber, h21(gl_FragCoord.xy), 0.3); // + fine speckle\n float shade = 1.0 - (tex - 0.5) * 0.35;\n gl_FragColor = vec4(src.rgb * mix(1.0, shade, clamp(uPaper, 0.0, 1.0)), src.a);\n}\n", au = "\nuniform sampler2D tDiffuse;\nuniform float uHalftoneCmyk; // 0..1 mix\nuniform float uHalftoneCmykCell; // dot cell size in device px\nvarying vec2 vUv;\n// One rotated halftone dot screen for a channel value.\nfloat dotScreen(vec2 coord, float value, float angle, float cell){\n float ca = cos(angle);\n float sa = sin(angle);\n vec2 r = mat2(ca, sa, -sa, ca) * coord;\n vec2 c = fract(r / max(cell, 2.0)) - 0.5;\n float radius = sqrt(clamp(value, 0.0, 1.0)) * 0.5;\n return smoothstep(radius, radius - 0.06, length(c));\n}\nvoid main(){\n vec4 src = texture2D(tDiffuse, vUv);\n float k = 1.0 - max(max(src.r, src.g), src.b); // RGB → CMYK\n float invK = max(1.0 - k, 1e-3);\n float cyan = (1.0 - src.r - k) / invK;\n float mag = (1.0 - src.g - k) / invK;\n float yel = (1.0 - src.b - k) / invK;\n vec2 coord = gl_FragCoord.xy;\n float cell = uHalftoneCmykCell;\n float dc = dotScreen(coord, cyan, 1.309, cell); // 75°\n float dm = dotScreen(coord, mag, 0.262, cell); // 15°\n float dy = dotScreen(coord, yel, 0.0, cell); // 0°\n float dk = dotScreen(coord, k, 0.785, cell); // 45°\n // Subtractive: cyan ink absorbs red, magenta absorbs green, yellow absorbs blue, black absorbs all.\n vec3 outc = vec3(1.0) - vec3(dc, 0.0, 0.0) - vec3(0.0, dm, 0.0) - vec3(0.0, 0.0, dy) - vec3(dk);\n outc = clamp(outc, 0.0, 1.0);\n gl_FragColor = vec4(mix(src.rgb, outc, clamp(uHalftoneCmyk, 0.0, 1.0)), src.a);\n}\n";
12149
+ })), su, cu, lu, uu, du, fu, pu = t((() => {
12150
+ Vc(), su = 400, cu = 16, lu = su / 4, uu = new K(1, 0, 0), du = new K(0, 1, 0), fu = class {
11930
12151
  geometry;
11931
12152
  segments = -1;
11932
12153
  constructor(e) {
@@ -11935,11 +12156,11 @@ void main(){
11935
12156
  resize(e) {
11936
12157
  if (e === this.segments) return;
11937
12158
  this.segments = e;
11938
- let t = Gt.clamp(Math.round(e), 48, 200), n = t * 2, r = new wi(ql, ql, t, n), i = r.attributes.position, a = r.attributes.uv, o = new K();
12159
+ let t = Gt.clamp(Math.round(e), 48, 200), n = t * 2, r = new wi(su, su, t, n), i = r.attributes.position, a = r.attributes.uv, o = new K();
11939
12160
  for (let e = 0; e < i.count; e++) {
11940
12161
  o.fromBufferAttribute(i, e);
11941
12162
  let t = a.getY(e), n = 4 - 2 * (4 * t * (1 - t)) ** 9.5;
11942
- o.x < -16 ? o.z += n : o.x < Jl ? (o.z = Math.cos(Gt.mapLinear(o.x, -16, Jl, 0, Math.PI)) * n, o.x = Math.cos(Gt.mapLinear(o.x, -16, Jl, -Math.PI / 2, Math.PI / 2)) * n - Jl) : (o.z -= n, o.x = -o.x), o.x += Yl, o.applyAxisAngle(Xl, -Math.PI / 2), o.applyAxisAngle(Zl, -Math.PI / 2), i.setXYZ(e, o.x, o.y, o.z);
12163
+ o.x < -16 ? o.z += n : o.x < cu ? (o.z = Math.cos(Gt.mapLinear(o.x, -16, cu, 0, Math.PI)) * n, o.x = Math.cos(Gt.mapLinear(o.x, -16, cu, -Math.PI / 2, Math.PI / 2)) * n - cu) : (o.z -= n, o.x = -o.x), o.x += lu, o.applyAxisAngle(uu, -Math.PI / 2), o.applyAxisAngle(du, -Math.PI / 2), i.setXYZ(e, o.x, o.y, o.z);
11943
12164
  }
11944
12165
  i.needsUpdate = !0;
11945
12166
  let s = t + 1, c = r.getIndex(), l = c ? Array.from(c.array) : [];
@@ -11959,43 +12180,356 @@ void main(){
11959
12180
  };
11960
12181
  }));
11961
12182
  //#endregion
12183
+ //#region src/renderer/interaction.ts
12184
+ function mu(e, t) {
12185
+ return e > 0 ? 1 - Math.exp(-t / e) : 1;
12186
+ }
12187
+ function hu(e, t, n, r, i, a) {
12188
+ if (a <= 0) return;
12189
+ let o = a > ju ? Math.min(Math.ceil(a / ju), Mu) : 1, s = a / o, c = r * r, l = 2 * i * r;
12190
+ for (let r = 0; r < o; r++) t.x += (c * (n.x - e.x) - l * t.x) * s, t.y += (c * (n.y - e.y) - l * t.y) * s, e.x += t.x * s, e.y += t.y * s;
12191
+ }
12192
+ function gu(e) {
12193
+ return e.interaction?.enabled !== !1;
12194
+ }
12195
+ function _u(e) {
12196
+ let t = e.interaction;
12197
+ return !!t && (!!t.hover || (t.press?.ripple ?? 0) > 0);
12198
+ }
12199
+ function vu(e, t) {
12200
+ return gu(e) && _u(t);
12201
+ }
12202
+ function yu(e, t) {
12203
+ return gu(e) && (t.interaction?.press?.ripple ?? 0) > 0;
12204
+ }
12205
+ function bu(e) {
12206
+ return gu(e) && e.waves.some(_u);
12207
+ }
12208
+ function xu(e) {
12209
+ return gu(e) ? (e.interaction?.bindings?.length ?? 0) > 0 ? !0 : e.waves.some((e) => {
12210
+ let t = e.interaction;
12211
+ return !!t && (!!t.hover || (t.press?.ripple ?? 0) > 0 || (t.bindings?.length ?? 0) > 0);
12212
+ }) : !1;
12213
+ }
12214
+ var Su, Cu, wu, Tu, Eu, Du, Ou, ku, Au, ju, Mu, Nu, Pu, Fu, Iu, Lu, Ru = t((() => {
12215
+ Vc(), hl(), Su = 1.5, Cu = .08, wu = 4, Tu = 2, Eu = .15, Du = .12, Ou = .25, ku = .7, Au = .02, ju = 1 / 120, Mu = 6, Nu = (e, t) => ({
12216
+ base: e,
12217
+ apply: t
12218
+ }), Pu = (e, t) => ({
12219
+ base: e,
12220
+ apply: t
12221
+ }), Fu = {
12222
+ displaceAmount: Nu((e) => e.displaceAmount, (e, t) => {
12223
+ t.u.uDispAmount.value = e;
12224
+ }),
12225
+ detailAmount: Nu((e) => e.detailAmount ?? 0, (e, t) => {
12226
+ t.u.uDetailAmount.value = e;
12227
+ }),
12228
+ twistPowerX: Nu((e) => e.twistPower.x, (e, t) => {
12229
+ t.u.uTwPowX.value = e;
12230
+ }),
12231
+ twistPowerY: Nu((e) => e.twistPower.y, (e, t) => {
12232
+ t.u.uTwPowY.value = e;
12233
+ }),
12234
+ twistPowerZ: Nu((e) => e.twistPower.z, (e, t) => {
12235
+ t.u.uTwPowZ.value = e;
12236
+ }),
12237
+ twistFrequencyX: Nu((e) => e.twistFrequency.x, (e, t) => {
12238
+ t.u.uTwFreqX.value = e;
12239
+ }),
12240
+ twistFrequencyY: Nu((e) => e.twistFrequency.y, (e, t) => {
12241
+ t.u.uTwFreqY.value = e;
12242
+ }),
12243
+ twistFrequencyZ: Nu((e) => e.twistFrequency.z, (e, t) => {
12244
+ t.u.uTwFreqZ.value = e;
12245
+ }),
12246
+ hueShift: Nu((e) => e.hueShift, (e, t) => {
12247
+ t.u.uHueShift.value = e;
12248
+ }),
12249
+ gradientShift: Nu((e) => e.gradientShift ?? 0, (e, t) => {
12250
+ t.u.uGradShift.value = e;
12251
+ }),
12252
+ colorSaturation: Nu((e) => e.colorSaturation, (e, t) => {
12253
+ t.u.uSaturation.value = e;
12254
+ }),
12255
+ opacity: Nu((e) => e.opacity, (e, t) => {
12256
+ t.u.uOpacity.value = e;
12257
+ }),
12258
+ lineThickness: Nu((e) => e.lineThickness ?? 1, (e, t) => {
12259
+ t.u.uLineThickness.value = e;
12260
+ }),
12261
+ lineAmount: Nu((e) => e.lineAmount ?? 425, (e, t) => {
12262
+ t.u.uLineAmount.value = e;
12263
+ }),
12264
+ fiberStrength: Nu((e) => e.fiberStrength, (e, t) => {
12265
+ t.u.uFiberStrength.value = e;
12266
+ }),
12267
+ sheen: Nu((e) => e.sheen ?? 1, (e, t) => {
12268
+ t.u.uSheen.value = e;
12269
+ }),
12270
+ iridescence: Nu((e) => e.iridescence ?? 0, (e, t) => {
12271
+ t.u.uIridescence.value = e;
12272
+ }),
12273
+ positionX: Nu((e) => e.position.x, (e, t) => {
12274
+ t.mesh.position.x = e;
12275
+ }),
12276
+ positionY: Nu((e) => e.position.y, (e, t) => {
12277
+ t.mesh.position.y = e;
12278
+ })
12279
+ }, Iu = {
12280
+ timeOffset: Pu((e) => e.timeOffset ?? 0, (e, t) => {
12281
+ t.out.timeOffset = e;
12282
+ }),
12283
+ cameraZoom: Pu((e) => e.cameraZoom ?? 1, (e, t) => {
12284
+ t.out.zoom = e;
12285
+ }),
12286
+ blur: Pu((e) => e.blur, (e, t) => {
12287
+ t.post.uBlurAmount.value = e;
12288
+ }),
12289
+ grain: Pu((e) => e.grain, (e, t) => {
12290
+ t.post.uGrainAmount.value = e;
12291
+ })
12292
+ }, Lu = class {
12293
+ container;
12294
+ cfg;
12295
+ scrollOverride = null;
12296
+ ndc = new G();
12297
+ ndcTarget = new G();
12298
+ ndcPrev = new G();
12299
+ velNdc = new G();
12300
+ presence = 0;
12301
+ presenceTarget = 0;
12302
+ press = 0;
12303
+ pressTarget = 0;
12304
+ pointerSpeed = 0;
12305
+ scroll = 0;
12306
+ scrollPrev = 0;
12307
+ scrollVel = 0;
12308
+ appearLatched = !1;
12309
+ customInputs = /* @__PURE__ */ new Map();
12310
+ ripples = [];
12311
+ fields = [];
12312
+ bindingState = /* @__PURE__ */ new Map();
12313
+ seenBindings = /* @__PURE__ */ new Set();
12314
+ out;
12315
+ constructor(e, t) {
12316
+ this.container = e, this.cfg = t;
12317
+ for (let e = 0; e < 4; e++) this.ripples.push({
12318
+ origin: new G(),
12319
+ age: 0,
12320
+ amp: 0,
12321
+ active: !1
12322
+ });
12323
+ this.out = {
12324
+ ndc: this.ndc,
12325
+ presence: 0,
12326
+ ripples: this.ripples
12327
+ };
12328
+ let n = { passive: !0 };
12329
+ e.addEventListener("pointerenter", this.onPointerEnter, n), e.addEventListener("pointermove", this.onPointerMove, n), e.addEventListener("pointerleave", this.onPointerLeave, n), e.addEventListener("pointercancel", this.onPointerCancel, n), e.addEventListener("pointerdown", this.onPointerDown, n), e.addEventListener("pointerup", this.onPointerUp, n);
12330
+ }
12331
+ ignore(e) {
12332
+ return e.pointerType === "touch" && this.cfg()?.interaction?.touch !== !0;
12333
+ }
12334
+ setNdcTarget(e) {
12335
+ let t = this.container.getBoundingClientRect();
12336
+ t.width <= 0 || t.height <= 0 || this.ndcTarget.set((e.clientX - t.left) / t.width * 2 - 1, -((e.clientY - t.top) / t.height * 2 - 1));
12337
+ }
12338
+ onPointerEnter = (e) => {
12339
+ this.ignore(e) || (this.presenceTarget = 1, this.setNdcTarget(e));
12340
+ };
12341
+ onPointerMove = (e) => {
12342
+ this.ignore(e) || e.pointerType === "touch" && this.pressTarget < .5 || (this.presenceTarget = 1, this.setNdcTarget(e));
12343
+ };
12344
+ onPointerLeave = (e) => {
12345
+ this.ignore(e) || (this.presenceTarget = 0, this.ndcTarget.set(0, 0));
12346
+ };
12347
+ onPointerCancel = (e) => {
12348
+ this.ignore(e) || (this.pressTarget = 0, this.presenceTarget = 0, this.ndcTarget.set(0, 0));
12349
+ };
12350
+ onPointerDown = (e) => {
12351
+ if (this.ignore(e)) return;
12352
+ this.pressTarget = 1, this.presenceTarget = 1, this.setNdcTarget(e);
12353
+ let t = this.cfg();
12354
+ t && t.waves.some((e) => (e.interaction?.press?.ripple ?? 0) > 0) && this.spawnRipple();
12355
+ };
12356
+ onPointerUp = (e) => {
12357
+ this.ignore(e) || (this.pressTarget = 0, e.pointerType === "touch" && (this.presenceTarget = 0, this.ndcTarget.set(0, 0)));
12358
+ };
12359
+ spawnRipple() {
12360
+ let e = this.ripples.find((e) => !e.active);
12361
+ if (!e) {
12362
+ e = this.ripples[0];
12363
+ for (let t of this.ripples) t.age > e.age && (e = t);
12364
+ }
12365
+ e.origin.copy(this.ndcTarget), e.age = 0, e.amp = 1, e.active = !0;
12366
+ }
12367
+ update(e) {
12368
+ let t = this.cfg();
12369
+ if (!t) return;
12370
+ let n = Math.max(e, 0), r = mu(Du, n);
12371
+ if (this.ndcPrev.copy(this.ndc), this.ndc.lerp(this.ndcTarget, r), this.presence += (this.presenceTarget - this.presence) * r, this.press += (this.pressTarget - this.press) * r, n > 1e-5) {
12372
+ let e = mu(Cu, n);
12373
+ this.velNdc.x += ((this.ndc.x - this.ndcPrev.x) / n - this.velNdc.x) * e, this.velNdc.y += ((this.ndc.y - this.ndcPrev.y) / n - this.velNdc.y) * e;
12374
+ }
12375
+ this.pointerSpeed = this.presence * ml(this.velNdc.length() / wu);
12376
+ let i = t.waves;
12377
+ this.fields.length > i.length && (this.fields.length = i.length);
12378
+ for (let e = 0; e < i.length; e++) {
12379
+ let t = this.fields[e];
12380
+ t || (t = {
12381
+ ndc: this.ndcTarget.clone(),
12382
+ vel: new G(),
12383
+ presence: this.presenceTarget
12384
+ }, this.fields[e] = t);
12385
+ let r = Math.max(i[e].interaction?.hover?.smoothing ?? Du, Au);
12386
+ hu(t.ndc, t.vel, this.ndcTarget, 1 / r, ku, n), t.presence += (this.presenceTarget - t.presence) * mu(r, n);
12387
+ }
12388
+ let a = this.scrollOverride ?? this.computeScroll();
12389
+ if (n > 1e-5) {
12390
+ let e = Math.abs(a - this.scrollPrev) / n;
12391
+ this.scrollVel += (e - this.scrollVel) * mu(Eu, n);
12392
+ }
12393
+ this.scrollPrev = a, this.scroll = a, this.appearLatched = !0;
12394
+ for (let e of this.ripples) {
12395
+ if (!e.active) continue;
12396
+ e.age += n;
12397
+ let t = Math.max(0, 1 - e.age / Su);
12398
+ e.amp = t * t, e.amp <= 0 && (e.active = !1);
12399
+ }
12400
+ this.updateBindings(t, n);
12401
+ }
12402
+ updateBindings(e, t) {
12403
+ let n = this.seenBindings;
12404
+ n.clear();
12405
+ let r = e.interaction?.bindings;
12406
+ if (r) for (let e = 0; e < r.length; e++) this.advanceBinding(r[e], t);
12407
+ for (let n = 0; n < e.waves.length; n++) {
12408
+ let r = e.waves[n].interaction?.bindings;
12409
+ if (r) for (let e = 0; e < r.length; e++) this.advanceBinding(r[e], t);
12410
+ }
12411
+ if (this.bindingState.size > n.size) for (let e of this.bindingState.keys()) n.has(e) || this.bindingState.delete(e);
12412
+ }
12413
+ advanceBinding(e, t) {
12414
+ this.seenBindings.add(e);
12415
+ let n = this.rawSource(e.source), r = this.bindingState.get(e);
12416
+ (!r || r.source !== e.source) && (r = {
12417
+ value: e.source === "appear" ? 0 : n,
12418
+ source: e.source
12419
+ }, this.bindingState.set(e, r)), r.value += (n - r.value) * mu(e.smoothing ?? Ou, t);
12420
+ }
12421
+ bindingValue(e) {
12422
+ return this.bindingState.get(e)?.value ?? 0;
12423
+ }
12424
+ rawSource(e) {
12425
+ switch (e) {
12426
+ case "scroll": return this.scroll;
12427
+ case "hover": return this.presence;
12428
+ case "pointerX": return (this.ndc.x + 1) * .5;
12429
+ case "pointerY": return (this.ndc.y + 1) * .5;
12430
+ case "pointerSpeed": return this.pointerSpeed;
12431
+ case "press": return this.press;
12432
+ case "scrollVelocity": return ml(this.scrollVel / Tu);
12433
+ case "appear": return +!!this.appearLatched;
12434
+ default: return this.customInputs.get(e.slice(7)) ?? 0;
12435
+ }
12436
+ }
12437
+ computeScroll() {
12438
+ let e = this.container.getBoundingClientRect(), t = window.innerHeight || document.documentElement.clientHeight || 1;
12439
+ return ml((t - e.top) / (t + e.height));
12440
+ }
12441
+ sample() {
12442
+ return this.out.presence = this.presence, this.out;
12443
+ }
12444
+ fieldFor(e) {
12445
+ return this.fields[e] ?? null;
12446
+ }
12447
+ pointerFlux() {
12448
+ return this.pointerSpeed;
12449
+ }
12450
+ pointerVelocity() {
12451
+ return this.velNdc;
12452
+ }
12453
+ setInput(e, t) {
12454
+ typeof e != "string" || !Number.isFinite(t) || this.customInputs.set(e, t);
12455
+ }
12456
+ settle() {
12457
+ this.presence = this.presenceTarget = 0, this.press = this.pressTarget = 0, this.pointerSpeed = 0, this.velNdc.set(0, 0), this.ndc.set(0, 0), this.ndcTarget.set(0, 0), this.ndcPrev.set(0, 0);
12458
+ for (let e of this.fields) e.ndc.set(0, 0), e.vel.set(0, 0), e.presence = 0;
12459
+ for (let e of this.ripples) e.age = 0, e.amp = 0, e.active = !1;
12460
+ let e = this.scrollOverride ?? this.computeScroll();
12461
+ this.scroll = this.scrollPrev = e, this.scrollVel = 0, this.appearLatched = !0;
12462
+ let t = this.cfg();
12463
+ if (t) {
12464
+ this.bindingState.clear();
12465
+ let e = (e) => {
12466
+ this.bindingState.set(e, {
12467
+ value: this.rawSource(e.source),
12468
+ source: e.source
12469
+ });
12470
+ };
12471
+ for (let n of t.interaction?.bindings ?? []) e(n);
12472
+ for (let n of t.waves) for (let t of n.interaction?.bindings ?? []) e(t);
12473
+ }
12474
+ }
12475
+ snapScroll() {
12476
+ let e = this.scrollOverride ?? this.computeScroll();
12477
+ this.scroll = this.scrollPrev = e, this.scrollVel = 0;
12478
+ let t = this.cfg();
12479
+ if (!t) return;
12480
+ let n = (e) => {
12481
+ (e.source === "scroll" || e.source === "scrollVelocity") && this.bindingState.set(e, {
12482
+ value: this.rawSource(e.source),
12483
+ source: e.source
12484
+ });
12485
+ };
12486
+ for (let e of t.interaction?.bindings ?? []) n(e);
12487
+ for (let e of t.waves) for (let t of e.interaction?.bindings ?? []) n(t);
12488
+ }
12489
+ dispose() {
12490
+ let e = this.container;
12491
+ e.removeEventListener("pointerenter", this.onPointerEnter), e.removeEventListener("pointermove", this.onPointerMove), e.removeEventListener("pointerleave", this.onPointerLeave), e.removeEventListener("pointercancel", this.onPointerCancel), e.removeEventListener("pointerdown", this.onPointerDown), e.removeEventListener("pointerup", this.onPointerUp), this.customInputs.clear(), this.bindingState.clear();
12492
+ }
12493
+ };
12494
+ }));
12495
+ //#endregion
11962
12496
  //#region src/renderer/palette.ts
11963
- function eu(e) {
12497
+ function zu(e) {
11964
12498
  return e * e * (3 - 2 * e);
11965
12499
  }
11966
- function tu(e, t) {
12500
+ function Bu(e, t) {
11967
12501
  let n = new X(e).clone().convertLinearToSRGB();
11968
12502
  return `rgba(${Math.round(n.r * 255)}, ${Math.round(n.g * 255)}, ${Math.round(n.b * 255)}, ${t})`;
11969
12503
  }
11970
- function nu(e) {
12504
+ function Vu(e) {
11971
12505
  let t = document.createElement("canvas");
11972
- t.width = xu, t.height = Su;
12506
+ t.width = od, t.height = sd;
11973
12507
  let n = t.getContext("2d");
11974
12508
  if (!n) return t;
11975
- let r = [...e.stops].sort((e, t) => e.pos - t.pos), i = n.createLinearGradient(0, 0, xu, 0);
12509
+ let r = [...e.stops].sort((e, t) => e.pos - t.pos), i = n.createLinearGradient(0, 0, od, 0);
11976
12510
  if (r.length === 0) i.addColorStop(0, "#ffffff");
11977
12511
  else for (let e of r) i.addColorStop(ml(e.pos), e.color);
11978
- n.fillStyle = i, n.fillRect(0, 0, xu, Su);
12512
+ n.fillStyle = i, n.fillRect(0, 0, od, sd);
11979
12513
  let a = ml(e.edgeAmount);
11980
12514
  if (a > .001) {
11981
- let t = n.createLinearGradient(0, 0, 0, Su);
11982
- t.addColorStop(0, tu(e.edgeColor, a)), t.addColorStop(.5, tu(e.edgeColor, 0)), t.addColorStop(1, tu(e.edgeColor, a)), n.fillStyle = t, n.fillRect(0, 0, xu, Su);
12515
+ let t = n.createLinearGradient(0, 0, 0, sd);
12516
+ t.addColorStop(0, Bu(e.edgeColor, a)), t.addColorStop(.5, Bu(e.edgeColor, 0)), t.addColorStop(1, Bu(e.edgeColor, a)), n.fillStyle = t, n.fillRect(0, 0, od, sd);
11983
12517
  }
11984
12518
  return t;
11985
12519
  }
11986
- function ru(e) {
12520
+ function Hu(e) {
11987
12521
  return `${e.stops.map((e) => `${e.color}@${e.pos.toFixed(3)}`).join(",")}|${e.edgeColor}|${e.edgeAmount.toFixed(3)}`;
11988
12522
  }
11989
- function iu(e) {
12523
+ function Uu(e) {
11990
12524
  return e.colorSpace = At, e.minFilter = z, e.magFilter = z, e.wrapS = he, e.wrapT = he, e.generateMipmaps = !1, e;
11991
12525
  }
11992
- function au(e) {
11993
- return iu(new yi(e));
12526
+ function Wu(e) {
12527
+ return Uu(new yi(e));
11994
12528
  }
11995
- function ou(e) {
11996
- return au(nu(e));
12529
+ function Gu(e) {
12530
+ return Wu(Vu(e));
11997
12531
  }
11998
- function su(e) {
12532
+ function Ku(e) {
11999
12533
  let t = document.createElement("canvas");
12000
12534
  t.width = Math.max(1, Math.round(e.width)), t.height = Math.max(1, Math.round(e.height));
12001
12535
  let n = t.getContext("2d");
@@ -12012,11 +12546,11 @@ function su(e) {
12012
12546
  else for (let e of l) c.addColorStop(ml(e.pos), e.color);
12013
12547
  return n.fillStyle = c, n.fillRect(0, 0, r, i), t;
12014
12548
  }
12015
- function cu(e) {
12549
+ function qu(e) {
12016
12550
  let t = ml(e), n = t <= .0031308 ? t * 12.92 : 1.055 * t ** (1 / 2.4) - .055;
12017
12551
  return Math.round(ml(n) * 255);
12018
12552
  }
12019
- function lu(e, t, n, r) {
12553
+ function Ju(e, t, n, r) {
12020
12554
  let i = Math.max(1, Math.round(n)), a = Math.max(1, Math.round(r)), o = new ImageData(i, a), s = o.data, c = e.length >= 2 ? e : yl(), l = c.map((e) => new X(e.color)), u = 4.8 + -3.4499999999999997 * ml(t);
12021
12555
  for (let e = 0; e < a; e++) {
12022
12556
  let t = 1 - e / Math.max(1, a - 1);
@@ -12027,12 +12561,12 @@ function lu(e, t, n, r) {
12027
12561
  a += l[e].r * s, o += l[e].g * s, d += l[e].b * s, f += s;
12028
12562
  }
12029
12563
  let p = Math.max(f, 1e-4), m = (e * i + n) * 4;
12030
- s[m] = cu(a / p), s[m + 1] = cu(o / p), s[m + 2] = cu(d / p), s[m + 3] = 255;
12564
+ s[m] = qu(a / p), s[m + 1] = qu(o / p), s[m + 2] = qu(d / p), s[m + 3] = 255;
12031
12565
  }
12032
12566
  }
12033
12567
  return o;
12034
12568
  }
12035
- function uu(e, t, n, r) {
12569
+ function Yu(e, t, n, r) {
12036
12570
  let i = document.createElement("canvas");
12037
12571
  i.width = Math.max(1, Math.round(n)), i.height = Math.max(1, Math.round(r));
12038
12572
  let a = i.getContext("2d");
@@ -12040,42 +12574,42 @@ function uu(e, t, n, r) {
12040
12574
  let o = Math.min(1, 320 / Math.max(i.width, i.height)), s = Math.max(2, Math.round(i.width * o)), c = Math.max(2, Math.round(i.height * o)), l = document.createElement("canvas");
12041
12575
  l.width = s, l.height = c;
12042
12576
  let u = l.getContext("2d");
12043
- return u ? (u.putImageData(lu(e, t, s, c), 0, 0), a.imageSmoothingEnabled = !0, a.imageSmoothingQuality = "high", a.drawImage(l, 0, 0, s, c, 0, 0, i.width, i.height), i) : i;
12577
+ return u ? (u.putImageData(Ju(e, t, s, c), 0, 0), a.imageSmoothingEnabled = !0, a.imageSmoothingQuality = "high", a.drawImage(l, 0, 0, s, c, 0, 0, i.width, i.height), i) : i;
12044
12578
  }
12045
- function du(e, t, n, r, i, a, o, s = 1, c = 0, l = 0) {
12579
+ function Xu(e, t, n, r, i, a, o, s = 1, c = 0, l = 0) {
12046
12580
  let u = document.createElement("canvas");
12047
- return u.width = Math.max(1, Math.round(r)), u.height = Math.max(1, Math.round(i)), fu(u, e, t, n, a, o, s, c, l), u;
12581
+ return u.width = Math.max(1, Math.round(r)), u.height = Math.max(1, Math.round(i)), Zu(u, e, t, n, a, o, s, c, l), u;
12048
12582
  }
12049
- function fu(e, t, n, r, i, a, o = 1, s = 0, c = 0) {
12583
+ function Zu(e, t, n, r, i, a, o = 1, s = 0, c = 0) {
12050
12584
  let l = e.getContext("2d");
12051
12585
  if (!l) return;
12052
12586
  l.fillStyle = a, l.fillRect(0, 0, e.width, e.height);
12053
12587
  let u = Math.max(.1, o), d = i === "stretch" ? e.width : n * (i === "contain" ? Math.min(e.width / n, e.height / r) : Math.max(e.width / n, e.height / r)), f = i === "stretch" ? e.height : r * (i === "contain" ? Math.min(e.width / n, e.height / r) : Math.max(e.width / n, e.height / r)), p = d * u, m = f * u, h = s / 100 * e.width, g = c / 100 * e.height;
12054
12588
  l.drawImage(t, (e.width - p) / 2 + h, (e.height - m) / 2 + g, p, m);
12055
12589
  }
12056
- function pu(e) {
12590
+ function Qu(e) {
12057
12591
  let t = (t, n) => {
12058
12592
  let r = t * 374761393 + n * 668265263 + e * 1442695041 | 0;
12059
12593
  return r = Math.imul(r ^ r >>> 13, 1274126177), ((r ^ r >>> 16) >>> 0) / 4294967295;
12060
12594
  };
12061
12595
  return (e, n) => {
12062
- let r = Math.floor(e), i = Math.floor(n), a = eu(e - r), o = eu(n - i), s = t(r, i), c = t(r + 1, i), l = t(r, i + 1), u = t(r + 1, i + 1);
12596
+ let r = Math.floor(e), i = Math.floor(n), a = zu(e - r), o = zu(n - i), s = t(r, i), c = t(r + 1, i), l = t(r, i + 1), u = t(r + 1, i + 1);
12063
12597
  return s * (1 - a) * (1 - o) + c * a * (1 - o) + l * (1 - a) * o + u * a * o;
12064
12598
  };
12065
12599
  }
12066
- function mu(e, t, n, r) {
12600
+ function $u(e, t, n, r) {
12067
12601
  let i = 0, a = .5, o = 1, s = 0;
12068
12602
  for (let c = 0; c < r; c++) i += a * e(t * o, n * o), s += a, o *= 2, a *= .5;
12069
12603
  return i / s;
12070
12604
  }
12071
- function hu(e = 220) {
12072
- let t = Math.max(64, Math.min(1280, Math.round(e))), n = wu.get(t);
12605
+ function ed(e = 220) {
12606
+ let t = Math.max(64, Math.min(1280, Math.round(e))), n = ld.get(t);
12073
12607
  if (n) return n;
12074
12608
  let r = document.createElement("canvas");
12075
12609
  r.width = t, r.height = t;
12076
12610
  let i = r.getContext("2d");
12077
12611
  if (!i) return r;
12078
- let a = i.createImageData(t, t), o = pu(11), s = pu(91), c = pu(47), l = [
12612
+ let a = i.createImageData(t, t), o = Qu(11), s = Qu(91), c = Qu(47), l = [
12079
12613
  [0, [
12080
12614
  34,
12081
12615
  26,
@@ -12119,24 +12653,24 @@ function hu(e = 220) {
12119
12653
  return l[l.length - 1][1];
12120
12654
  };
12121
12655
  for (let e = 0; e < t; e++) for (let n = 0; n < t; n++) {
12122
- let r = n / t * 3, i = e / t * 3, l = r + .7 * s(r * .7 + 5, i * .7), d = i + .7 * s(r * .7, i * .7 + 9), [f, p, m] = u(mu(o, l, d, 4)), h = Math.max(0, mu(c, l * 1.6 + 3, d * 1.6, 3) - .55) * 1.7;
12656
+ let r = n / t * 3, i = e / t * 3, l = r + .7 * s(r * .7 + 5, i * .7), d = i + .7 * s(r * .7, i * .7 + 9), [f, p, m] = u($u(o, l, d, 4)), h = Math.max(0, $u(c, l * 1.6 + 3, d * 1.6, 3) - .55) * 1.7;
12123
12657
  f = f * (1 - h) + 70 * h, p = p * (1 - h) + 210 * h, m = m * (1 - h) + 200 * h;
12124
12658
  let g = (e * t + n) * 4;
12125
12659
  a.data[g] = f, a.data[g + 1] = p, a.data[g + 2] = m, a.data[g + 3] = 255;
12126
12660
  }
12127
- return i.putImageData(a, 0, 0), wu.set(t, r), r;
12661
+ return i.putImageData(a, 0, 0), ld.set(t, r), r;
12128
12662
  }
12129
- function gu(e, t, n, r) {
12130
- let i = `${e}|${t}x${n}`, a = Tu.get(i);
12663
+ function td(e, t, n, r) {
12664
+ let i = `${e}|${t}x${n}`, a = ud.get(i);
12131
12665
  if (a) return a;
12132
12666
  let o = document.createElement("canvas");
12133
12667
  o.width = t, o.height = n;
12134
12668
  let s = o.getContext("2d");
12135
- return s && r(s, t, n), Tu.set(i, o), o;
12669
+ return s && r(s, t, n), ud.set(i, o), o;
12136
12670
  }
12137
- function _u(e = 240) {
12671
+ function nd(e = 240) {
12138
12672
  let t = Math.max(120, Math.min(2048, Math.round(e)));
12139
- return gu("vaporwave", t, Math.round(t * 2 / 3), (e, t, n) => {
12673
+ return td("vaporwave", t, Math.round(t * 2 / 3), (e, t, n) => {
12140
12674
  let r = t / 240, i = e.createLinearGradient(0, 0, 0, n);
12141
12675
  i.addColorStop(0, "#120638"), i.addColorStop(.56, "#8e2de2"), i.addColorStop(1, "#ff2fa8"), e.fillStyle = i, e.fillRect(0, 0, t, n);
12142
12676
  let a = n * .48, o = n * .28, s = e.createLinearGradient(0, a - o, 0, a + o);
@@ -12152,9 +12686,9 @@ function _u(e = 240) {
12152
12686
  e.globalAlpha = 1;
12153
12687
  });
12154
12688
  }
12155
- function vu(e = 220) {
12689
+ function rd(e = 220) {
12156
12690
  let t = Math.max(110, Math.min(2048, Math.round(e)));
12157
- return gu("kaleidoscope", t, t, (e, t, n) => {
12691
+ return td("kaleidoscope", t, t, (e, t, n) => {
12158
12692
  let r = t / 220, i = [
12159
12693
  "#00e5ff",
12160
12694
  "#6c3bff",
@@ -12170,25 +12704,25 @@ function vu(e = 220) {
12170
12704
  for (let t = 1; t <= 4; t++) e.strokeStyle = t % 2 ? "rgba(255,255,255,.55)" : "rgba(8,5,35,.6)", e.lineWidth = 5 * r, e.beginPath(), e.arc(a, o, t * 25 * r, 0, Math.PI * 2), e.stroke();
12171
12705
  });
12172
12706
  }
12173
- function yu(e, t) {
12174
- return e.build ? e.build(t) : nu({
12707
+ function id(e, t) {
12708
+ return e.build ? e.build(t) : Vu({
12175
12709
  stops: e.stops ?? [],
12176
12710
  edgeColor: e.edgeColor ?? "#8e9dff",
12177
12711
  edgeAmount: e.edgeAmount ?? 0
12178
12712
  });
12179
12713
  }
12180
- function bu(e) {
12181
- return iu(new Zi().load(e));
12714
+ function ad(e) {
12715
+ return Uu(new Zi().load(e));
12182
12716
  }
12183
- var xu, Su, Cu, wu, Tu, Eu, Du = t((() => {
12184
- Vc(), hl(), Ll(), xu = 256, Su = 64, Cu = (e) => e.map(([e, t]) => ({
12717
+ var od, sd, cd, ld, ud, dd, fd = t((() => {
12718
+ Vc(), hl(), Gl(), od = 256, sd = 64, cd = (e) => e.map(([e, t]) => ({
12185
12719
  color: e,
12186
12720
  pos: t
12187
- })), wu = /* @__PURE__ */ new Map(), Tu = /* @__PURE__ */ new Map(), Eu = {
12721
+ })), ld = /* @__PURE__ */ new Map(), ud = /* @__PURE__ */ new Map(), dd = {
12188
12722
  palestine: {
12189
12723
  label: "Palestine",
12190
12724
  kind: "gradient",
12191
- stops: Cu([
12725
+ stops: cd([
12192
12726
  ["#000000", 0],
12193
12727
  ["#f7f7f2", .34],
12194
12728
  ["#149954", .67],
@@ -12197,10 +12731,24 @@ var xu, Su, Cu, wu, Tu, Eu, Du = t((() => {
12197
12731
  edgeColor: "#e4312b",
12198
12732
  edgeAmount: .22
12199
12733
  },
12734
+ spain: {
12735
+ label: "Spain",
12736
+ kind: "gradient",
12737
+ stops: cd([
12738
+ ["#aa151b", 0],
12739
+ ["#aa151b", .24],
12740
+ ["#f1bf00", .34],
12741
+ ["#f1bf00", .66],
12742
+ ["#aa151b", .76],
12743
+ ["#aa151b", 1]
12744
+ ]),
12745
+ edgeColor: "#7a0f14",
12746
+ edgeAmount: .22
12747
+ },
12200
12748
  grandLine: {
12201
12749
  label: "Grand Line",
12202
12750
  kind: "gradient",
12203
- stops: Cu([
12751
+ stops: cd([
12204
12752
  ["#071b33", 0],
12205
12753
  ["#087ea4", .22],
12206
12754
  ["#45d4c5", .4],
@@ -12215,22 +12763,22 @@ var xu, Su, Cu, wu, Tu, Eu, Du = t((() => {
12215
12763
  vaporwave: {
12216
12764
  label: "Vaporwave Sunset",
12217
12765
  kind: "image",
12218
- build: _u
12766
+ build: nd
12219
12767
  },
12220
12768
  kaleidoscope: {
12221
12769
  label: "Kaleidoscope",
12222
12770
  kind: "image",
12223
- build: vu
12771
+ build: rd
12224
12772
  },
12225
12773
  nebula: {
12226
12774
  label: "Nebula (2D)",
12227
12775
  kind: "image",
12228
- build: hu
12776
+ build: ed
12229
12777
  },
12230
12778
  sunset: {
12231
12779
  label: "Sunset",
12232
12780
  kind: "gradient",
12233
- stops: Cu([
12781
+ stops: cd([
12234
12782
  ["#3b1c6b", 0],
12235
12783
  ["#8b2fa0", .3],
12236
12784
  ["#e0457a", .56],
@@ -12243,7 +12791,7 @@ var xu, Su, Cu, wu, Tu, Eu, Du = t((() => {
12243
12791
  aurora: {
12244
12792
  label: "Aurora",
12245
12793
  kind: "gradient",
12246
- stops: Cu([
12794
+ stops: cd([
12247
12795
  ["#0b3d4f", 0],
12248
12796
  ["#1fb89e", .3],
12249
12797
  ["#5ee0a0", .52],
@@ -12256,7 +12804,7 @@ var xu, Su, Cu, wu, Tu, Eu, Du = t((() => {
12256
12804
  ocean: {
12257
12805
  label: "Ocean",
12258
12806
  kind: "gradient",
12259
- stops: Cu([
12807
+ stops: cd([
12260
12808
  ["#0a1f4d", 0],
12261
12809
  ["#1f6fb8", .36],
12262
12810
  ["#2bd0d0", .66],
@@ -12268,7 +12816,7 @@ var xu, Su, Cu, wu, Tu, Eu, Du = t((() => {
12268
12816
  ember: {
12269
12817
  label: "Ember",
12270
12818
  kind: "gradient",
12271
- stops: Cu([
12819
+ stops: cd([
12272
12820
  ["#2a0707", 0],
12273
12821
  ["#a81e1e", .34],
12274
12822
  ["#ff5a2e", .64],
@@ -12280,7 +12828,7 @@ var xu, Su, Cu, wu, Tu, Eu, Du = t((() => {
12280
12828
  iris: {
12281
12829
  label: "Iris",
12282
12830
  kind: "gradient",
12283
- stops: Cu([
12831
+ stops: cd([
12284
12832
  ["#2e1065", 0],
12285
12833
  ["#7c3aed", .34],
12286
12834
  ["#db2777", .64],
@@ -12292,7 +12840,7 @@ var xu, Su, Cu, wu, Tu, Eu, Du = t((() => {
12292
12840
  mono: {
12293
12841
  label: "Mono",
12294
12842
  kind: "gradient",
12295
- stops: Cu([
12843
+ stops: cd([
12296
12844
  ["#16161e", 0],
12297
12845
  ["#6b7280", .4],
12298
12846
  ["#c2c8d2", .72],
@@ -12305,39 +12853,39 @@ var xu, Su, Cu, wu, Tu, Eu, Du = t((() => {
12305
12853
  }));
12306
12854
  //#endregion
12307
12855
  //#region src/util/base64.ts
12308
- function Ou(e) {
12856
+ function pd(e) {
12309
12857
  let t = atob(e.replace(/-/g, "+").replace(/_/g, "/")), n = new Uint8Array(new ArrayBuffer(t.length));
12310
12858
  for (let e = 0; e < t.length; e++) n[e] = t.charCodeAt(e);
12311
12859
  return n;
12312
12860
  }
12313
- var ku = t((() => {}));
12861
+ var md = t((() => {}));
12314
12862
  //#endregion
12315
12863
  //#region src/renderer/heroPalette.ts
12316
- function Au() {
12864
+ function hd() {
12317
12865
  let e = document.createElement("canvas");
12318
- e.width = Mu, e.height = Mu;
12866
+ e.width = _d, e.height = _d;
12319
12867
  let t = e.getContext("2d");
12320
12868
  if (t) {
12321
- let e = Ou(Nu);
12322
- t.putImageData(new ImageData(new Uint8ClampedArray(e.buffer), Mu, Mu), 0, 0);
12869
+ let e = pd(vd);
12870
+ t.putImageData(new ImageData(new Uint8ClampedArray(e.buffer), _d, _d), 0, 0);
12323
12871
  }
12324
12872
  return e;
12325
12873
  }
12326
- function ju() {
12327
- let e = iu(new ci(Ou(Nu), Mu, Mu, U, Se));
12874
+ function gd() {
12875
+ let e = Uu(new ci(pd(vd), _d, _d, U, Se));
12328
12876
  return e.needsUpdate = !0, e;
12329
12877
  }
12330
- var Mu, Nu, Pu = t((() => {
12331
- Vc(), ku(), Du(), Mu = 32, Nu = "7PP//97s///O4/7/xt77/8vc7f/Y1sr/5c2f/+/EcP/2vEX/+rQp//2xGP/+rRv//J5M//uUf//7jp7/+4a3//2Ax//9g83//4vD//2bu//5kpv/83V+//Nbb//3VnT/81Sf/+tdxf/pid3/56Pr/+a58v/q1/P/6On3/+Xy/P/o8f//2ur+/8/j/P/O4ff/1tzc/+PSr//sx4X/879d//i3Of/8siD//rEP//6vD//9nz7//JJ4//uNnP/6h7f//IDJ//yEz//+jMX//Jq8//aOnf/xa3n/9Fxq//dief/1Y5v/8G62/+2K0v/tq+b/6Lby/+rP8v/q5fb/5vH7/+Pv///X6P7/0uT6/9bi8P/h2sf/682R//LCa//3ukn/+rQs//yxGv/+sQ7//q4T//2eRP/8knv/+o2e//eIuf/6g8v/+obR//yMx//6mb3/84uh//Bnef/1YWn/+nVx//lzj//1g6X/8pjC//Gz3f/stO//6cDx/+rf9P/m8fv/3uz//9Xm/f/V4vj/3d/r/+fWtP/xyHT/9r9R//m3N//7siP//bAW//6xDv/+qxr//ZpP//yPf//4jZ//9Yq6//eHzP/4itL/+o/K//iYvv/wiab/7mZ9//Zpbv/7gG///Il+//iYk//1pa//9LTO//Cx5v/qru7/69fy/+fw+v/Y6f7/1eL7/9nb9v/h2Of/7M+n//XCW//5uj3/+7Ur//yxHf/9rhX//q8Q//6mJP/9k1f/+4x///aNnv/zjbr/9Y3N//aR1f/4lM7/+JnC//COrv/ua4f/9m5y//uGc//8k3z/+qKI//aupP/1tMT/8J3b/+iJ6v/qzfD/6O75/9fl/f/Y3vn/3NPz/+TM4P/uxpr/+LxJ//u3MP/8syX//a8c//2sF//+rBb//p8w//2OX//7ioD/9o6e//KQu//zk8//9ZjX//ec0//4nsn/85i7//B3mf/1cHz/+oZ4//uSgf/6oYX/97Kg//Wpvv/vcdH/5W7n/+vG7f/p6vf/1d78/9nX9//fyu3/6MDN//O8fv/6uDv/+7Qr//yxJf/9rB///akd//6oIP/+mz3//oxm//uMg//2kaD/8pW9//Ob0f/2oNj/+aPX//ul1P/4o83/9Iyy//d7kP/6in3/+5OB//qhgv/5rpX/9pyy/+9czf/kZ+D/7L7q/+vk9f/S0/v/2s30/+O+4//ttK3/+LRW//u0Mf/8si7//K8q//2pJv/9pSj//qMu//6WSP/+jWv/+46F//aVo//zmr//9KHS//em2v/8qNr//qra//2q2P/5n8z/+Iuv//uOjP/7loH//KGA//ukjf/5kab/8VjD/+dq2P/tt+b/7t3y/9XJ+P/gwvD/6bPa//Osmf/6sEn/+7E1//ywNf/8ri///agu//2jNf/+nz3//pRT//6Pb//8k4j/95um//Shwv/1p9T/+Krc//yr2//+rdv//q3c//yp2v/5mM3/+pKp//ubhv/8oIH//J6L//yPmv/2a7D/63fL/++z4//w1u7/48D0/+257f/zr9n/96ic//urU//8rT//+689//yyMv/9ry///qk///6jUP/+nGT//pt6//yfj//4pKz/9ajG//at1v/6r9z//azb//+u3f//r93//q7e//ug3P/6lcn/+52g//ujhP/9nIz//ZKb//qJpP/zjrr/8rHc//PN6v/zuO//+7Ts//uw4f/7qK7//KVo//ynTf/7rEb//bU0//27Jv/9tz3//bJj//6weP/+sIj//a+a//mwsv/2scn/+LTY//uz3f/9rtz//7De//6w3//+reL//aXl//ya4P/8nML//KSZ//2cm//9mrD//aGz//uitf/4r87/9sPk//u07f//tO3//rLo//ymwP/8nYL//J9g//unU//8skL//b0v//zBQP/8xHD//saJ//7FlP/9waP/+725//i5y//5u9j/+rjd//yv3f/+r9///q7i//6r5v/9quj//aTp//2e2v/9oLr//aC1//2ouv/+s7b//rSz//ywwP/6uNn//bPs//6z6//+ruP//J7G//uRmv/7knn/+51m//yrUv/9tkb//MBZ//3Lf//+0pP//tSa//7PqP/8yb7/+sLM//vC1v/6v9z/+bHd//io4v/7pej//arp//2x6P/8ren//KHg//2hxf/9p7v//rC3//+4s///u7D//rS5//2x0f//tO3//7Lr//6n3f/8ksL/+oKl//mDkf/5kXz//KNi//2vWP/+vnH//suQ//7Umv/+2Zz//tan//7SwP/9ysn//srO//vF1P/3sdH/7p7b/+2c6P/2o+3/9Kvs//Gn7f/xn+L//KXF//6uuv//sLj//7S1//+5sf/+tLn//q7Q//+z7f//sen//p/W//uEuv/5daf/9ned//aFjv/6l3f//adp//65ff/+ypr//tGh//7Vn//+1af//ta9///Rv///0r///cvD//m1uP/vn8n/5Jff/96b6//Um/H/zZvy/9Wb6v/ypc7//6+8//+xuf//tLb//7mx//22vf/+rtT//q/q//2n4v/9jsr/+3Wy//drqP/0cKL/9H2Z//iOhv/8oHT//rV///7Hnv/+zqf//tGm//7Uqv/+2Ln//9az///Xsv/90bT//MSj//m6r//tqcn/0aDh/76a8v+9m/b/vZn0/9ue4f/8q8L//rO0//+5rv/+vqn//LrB//6v2v/8qef//JnY//x7vv/6Zq3/9mSn//NtpP/ze53/94qN//yceP/+sn3//sWb//7Oqf/+0an//tas//7cuf//27D//96r//7aqv/+1Jz//tSe//rLrP/htc3/waPr/7if9v+ymvn/zJzt//eoxf/+t6D//8WV//7Kmf/8v8L//a/c//yk5f/7jtL/+224//lcqv/2X6b/9Gyj//R8mv/4jIr//J53//6zfv/+xZr//s2o//7Sqf/+2K7//uC8///htf//46z//t2m//7XnP/+2Z///tmh//XLt//Osdr/s6Lx/7Kd9v/Ro+z/9qvH//64mf//y4j//s+S//zBwf/9sNv//aHk//uI0P/7Zbf/+Feq//Vdpv/0bqD/+IKR//uWfv/+qHf//rqI//7Gnv/+zaf//tSp//7bsP/+477//+W4///mrv//3qT//tic//7Yn//+2qH//NWr/967zP+6pOj/waTt/+Gt4P/4r8j//bWi///Hiv/+zpP//cDB//6v2//9oOT/+4bR//pkuf/3WK3/9F+o//Vynf/6jIX//qR1//61fv/+v5H//seg//7Npv/+1an//t2y//7kwP//5rj//+ex///fpv/+2J3//tie//7ZoP/91qb/5r7E/8am3//Yq97/9LbN//qzxf/8sa///r+R//7MlP/9vcL//q7b//yh5f/6iNP/+Gi8//Vdr//0Zan/93qW//yXev/+rXH//rp///6/kf/+xp///s6l//7WrP/+37j//uXE///kuP//57X//+Os//7Znv/+2J3//tme//3Sof/vu7z/4KvW/+6xz//7tsP/+7PC//uruf/9rJ7//bWd//yzxv/+rtv/+6Ll//iM1P/2b77/9GWw//Vvpf/5hoz//KBy//6ya//+unn//r+Q//7HoP/+z6n//tmz//7iwv/+58j//+K2///mt//+5rT//9ui//7Wnv/+057//smg//u5rv/4ssX/+rTF//u0wP/7sL//+p+7//mRrf/5lK3/+qXL//6u2//4o+X/9JDU//R5vf/1cq7/93ud//qQhf/7pW///bJm//67dP/+wY///smj//7Sr//+3Lz//uXK//7ny///37T//+O0//7isv/+0Jb//8WH///AjP/+upf//rSh//2zsf/7tLz/+7S7//yttf/6lbX/94Oz//WEtv/2n8///a7c//Gn5f/wltH/9IO5//h+pv/7h5X/+5WD//ukcP/9smL//r1t//7Dif/+yaD//tOy//7gw//+6M3//ujM///dsv//3q3//tur//7Agf//r2j//6px//+og//+pY3//qiX//ywov/8r6f//Kei//yVo//6hKv/9Ie3//Og0P/8rtz/563k/+mZzv/zibP/+oag//qLlf/5k4n/+6Jx//2zXf/+vWL//sJ5//7Hkv/+0av//uDC//3pyv/96Mz//tux///apf/+1qb//7h+//+lZf//nGf//5dt//+Tc///lXn//qN+//unjP/5nJ3//JWb//2Knv/2i7L/8KLR//uu3P/druT/4ZXN/+2FtP/1g6X/94Wd//iMj//6nXX//a5f//64Xv/+vW3//sKB//7KmP/+2bP//ebE//3nzf/+2bH//tWf//7Vpf/+toX//5xk//+RW///iFj//4Nc//+FYv/+l2j/+599//eQmv/3iKT/94aj/++HtP/tn9H/+q7d/9aq5f/ajND/5Hq7/+13rv/yeaL/9YCU//mPgf/8oW3//q1m//60a//+uHb//sKJ//7Spv/+48D//ufO//7Xsv/+0Zr//tSk//68kv//mGn//4ZP//9+S///elD//oJa//2Qav/5kIT/9YOX//N7pP/ueK7/5nu7/+iX0//5rd3/0aXp/9KB1v/ba8P/5Wa2/+xoqf/yb5v/936M//uUef/9pWz//qxr//6ucf/+u4X//tGl//7jwv/959H//tez//7PmP/+0KL//sWh//6rh//+i2D//3xQ//59VP/+iF///It1//d9j//ybpv/7Wmn/+Zmtv/dasP/447W//es3v/LpO7/yHnd/89czf/bU8H/5VW1/+5dpv/1cJT/+419//6ibf/+pWj//qZt//63hf/+0ar//eTJ//3o1f/+1rX//c2X//3Lof/+x6b//cCh//6dev/+hlz//ohd//6TZP/8iXn/9m2V/+5apv/mVbb/20/B/89YzP/ahdv/9are/8eo8v+/eeX/xFXW/9FIzP/fSML/6VC0//Nlnv/7ioH//qFt//6jaP/+q3H//rqL//3Ssf/95s///efa//7WuP/8y5j//Mik//7FqP/9xan//a6J//6caf/+kmL//ptn//yKe//0X5//6ky2/99Ew//RQcv/wk/V/9CB4f/yq+D/x7L3/76I7f/AZOH/zFXX/9pS0P/mVsb/8Guw//mRkP/8p3z//K15//y4hP/8w5v/+9W7//vm1v/75t///NbC//nMpP/6yq7//Mmy//vIs//7vZv//LWC//yldf/8o3X/+paM//FgtP/kT8n/20zR/8pN1v+9W+D/y4jn//Cs4f/Pw/v/xqL0/8aF6//PeeT/23Xf/+V32P/uhsf/9qWs//i3mv/4v5j/+Meh//jPsv/43Mn/9+jf//fm5v/31tb/9dXB//XWyP/31sr/99XI//fOt//3yqj/98Of//e9nv/2r6//7oXO/+R63f/beeH/z3vl/8aF7P/Soe3/8bHj/w==";
12878
+ var _d, vd, yd = t((() => {
12879
+ Vc(), md(), fd(), _d = 32, vd = "7PP//97s///O4/7/xt77/8vc7f/Y1sr/5c2f/+/EcP/2vEX/+rQp//2xGP/+rRv//J5M//uUf//7jp7/+4a3//2Ax//9g83//4vD//2bu//5kpv/83V+//Nbb//3VnT/81Sf/+tdxf/pid3/56Pr/+a58v/q1/P/6On3/+Xy/P/o8f//2ur+/8/j/P/O4ff/1tzc/+PSr//sx4X/879d//i3Of/8siD//rEP//6vD//9nz7//JJ4//uNnP/6h7f//IDJ//yEz//+jMX//Jq8//aOnf/xa3n/9Fxq//dief/1Y5v/8G62/+2K0v/tq+b/6Lby/+rP8v/q5fb/5vH7/+Pv///X6P7/0uT6/9bi8P/h2sf/682R//LCa//3ukn/+rQs//yxGv/+sQ7//q4T//2eRP/8knv/+o2e//eIuf/6g8v/+obR//yMx//6mb3/84uh//Bnef/1YWn/+nVx//lzj//1g6X/8pjC//Gz3f/stO//6cDx/+rf9P/m8fv/3uz//9Xm/f/V4vj/3d/r/+fWtP/xyHT/9r9R//m3N//7siP//bAW//6xDv/+qxr//ZpP//yPf//4jZ//9Yq6//eHzP/4itL/+o/K//iYvv/wiab/7mZ9//Zpbv/7gG///Il+//iYk//1pa//9LTO//Cx5v/qru7/69fy/+fw+v/Y6f7/1eL7/9nb9v/h2Of/7M+n//XCW//5uj3/+7Ur//yxHf/9rhX//q8Q//6mJP/9k1f/+4x///aNnv/zjbr/9Y3N//aR1f/4lM7/+JnC//COrv/ua4f/9m5y//uGc//8k3z/+qKI//aupP/1tMT/8J3b/+iJ6v/qzfD/6O75/9fl/f/Y3vn/3NPz/+TM4P/uxpr/+LxJ//u3MP/8syX//a8c//2sF//+rBb//p8w//2OX//7ioD/9o6e//KQu//zk8//9ZjX//ec0//4nsn/85i7//B3mf/1cHz/+oZ4//uSgf/6oYX/97Kg//Wpvv/vcdH/5W7n/+vG7f/p6vf/1d78/9nX9//fyu3/6MDN//O8fv/6uDv/+7Qr//yxJf/9rB///akd//6oIP/+mz3//oxm//uMg//2kaD/8pW9//Ob0f/2oNj/+aPX//ul1P/4o83/9Iyy//d7kP/6in3/+5OB//qhgv/5rpX/9pyy/+9czf/kZ+D/7L7q/+vk9f/S0/v/2s30/+O+4//ttK3/+LRW//u0Mf/8si7//K8q//2pJv/9pSj//qMu//6WSP/+jWv/+46F//aVo//zmr//9KHS//em2v/8qNr//qra//2q2P/5n8z/+Iuv//uOjP/7loH//KGA//ukjf/5kab/8VjD/+dq2P/tt+b/7t3y/9XJ+P/gwvD/6bPa//Osmf/6sEn/+7E1//ywNf/8ri///agu//2jNf/+nz3//pRT//6Pb//8k4j/95um//Shwv/1p9T/+Krc//yr2//+rdv//q3c//yp2v/5mM3/+pKp//ubhv/8oIH//J6L//yPmv/2a7D/63fL/++z4//w1u7/48D0/+257f/zr9n/96ic//urU//8rT//+689//yyMv/9ry///qk///6jUP/+nGT//pt6//yfj//4pKz/9ajG//at1v/6r9z//azb//+u3f//r93//q7e//ug3P/6lcn/+52g//ujhP/9nIz//ZKb//qJpP/zjrr/8rHc//PN6v/zuO//+7Ts//uw4f/7qK7//KVo//ynTf/7rEb//bU0//27Jv/9tz3//bJj//6weP/+sIj//a+a//mwsv/2scn/+LTY//uz3f/9rtz//7De//6w3//+reL//aXl//ya4P/8nML//KSZ//2cm//9mrD//aGz//uitf/4r87/9sPk//u07f//tO3//rLo//ymwP/8nYL//J9g//unU//8skL//b0v//zBQP/8xHD//saJ//7FlP/9waP/+725//i5y//5u9j/+rjd//yv3f/+r9///q7i//6r5v/9quj//aTp//2e2v/9oLr//aC1//2ouv/+s7b//rSz//ywwP/6uNn//bPs//6z6//+ruP//J7G//uRmv/7knn/+51m//yrUv/9tkb//MBZ//3Lf//+0pP//tSa//7PqP/8yb7/+sLM//vC1v/6v9z/+bHd//io4v/7pej//arp//2x6P/8ren//KHg//2hxf/9p7v//rC3//+4s///u7D//rS5//2x0f//tO3//7Lr//6n3f/8ksL/+oKl//mDkf/5kXz//KNi//2vWP/+vnH//suQ//7Umv/+2Zz//tan//7SwP/9ysn//srO//vF1P/3sdH/7p7b/+2c6P/2o+3/9Kvs//Gn7f/xn+L//KXF//6uuv//sLj//7S1//+5sf/+tLn//q7Q//+z7f//sen//p/W//uEuv/5daf/9ned//aFjv/6l3f//adp//65ff/+ypr//tGh//7Vn//+1af//ta9///Rv///0r///cvD//m1uP/vn8n/5Jff/96b6//Um/H/zZvy/9Wb6v/ypc7//6+8//+xuf//tLb//7mx//22vf/+rtT//q/q//2n4v/9jsr/+3Wy//drqP/0cKL/9H2Z//iOhv/8oHT//rV///7Hnv/+zqf//tGm//7Uqv/+2Ln//9az///Xsv/90bT//MSj//m6r//tqcn/0aDh/76a8v+9m/b/vZn0/9ue4f/8q8L//rO0//+5rv/+vqn//LrB//6v2v/8qef//JnY//x7vv/6Zq3/9mSn//NtpP/ze53/94qN//yceP/+sn3//sWb//7Oqf/+0an//tas//7cuf//27D//96r//7aqv/+1Jz//tSe//rLrP/htc3/waPr/7if9v+ymvn/zJzt//eoxf/+t6D//8WV//7Kmf/8v8L//a/c//yk5f/7jtL/+224//lcqv/2X6b/9Gyj//R8mv/4jIr//J53//6zfv/+xZr//s2o//7Sqf/+2K7//uC8///htf//46z//t2m//7XnP/+2Z///tmh//XLt//Osdr/s6Lx/7Kd9v/Ro+z/9qvH//64mf//y4j//s+S//zBwf/9sNv//aHk//uI0P/7Zbf/+Feq//Vdpv/0bqD/+IKR//uWfv/+qHf//rqI//7Gnv/+zaf//tSp//7bsP/+477//+W4///mrv//3qT//tic//7Yn//+2qH//NWr/967zP+6pOj/waTt/+Gt4P/4r8j//bWi///Hiv/+zpP//cDB//6v2//9oOT/+4bR//pkuf/3WK3/9F+o//Vynf/6jIX//qR1//61fv/+v5H//seg//7Npv/+1an//t2y//7kwP//5rj//+ex///fpv/+2J3//tie//7ZoP/91qb/5r7E/8am3//Yq97/9LbN//qzxf/8sa///r+R//7MlP/9vcL//q7b//yh5f/6iNP/+Gi8//Vdr//0Zan/93qW//yXev/+rXH//rp///6/kf/+xp///s6l//7WrP/+37j//uXE///kuP//57X//+Os//7Znv/+2J3//tme//3Sof/vu7z/4KvW/+6xz//7tsP/+7PC//uruf/9rJ7//bWd//yzxv/+rtv/+6Ll//iM1P/2b77/9GWw//Vvpf/5hoz//KBy//6ya//+unn//r+Q//7HoP/+z6n//tmz//7iwv/+58j//+K2///mt//+5rT//9ui//7Wnv/+057//smg//u5rv/4ssX/+rTF//u0wP/7sL//+p+7//mRrf/5lK3/+qXL//6u2//4o+X/9JDU//R5vf/1cq7/93ud//qQhf/7pW///bJm//67dP/+wY///smj//7Sr//+3Lz//uXK//7ny///37T//+O0//7isv/+0Jb//8WH///AjP/+upf//rSh//2zsf/7tLz/+7S7//yttf/6lbX/94Oz//WEtv/2n8///a7c//Gn5f/wltH/9IO5//h+pv/7h5X/+5WD//ukcP/9smL//r1t//7Dif/+yaD//tOy//7gw//+6M3//ujM///dsv//3q3//tur//7Agf//r2j//6px//+og//+pY3//qiX//ywov/8r6f//Kei//yVo//6hKv/9Ie3//Og0P/8rtz/563k/+mZzv/zibP/+oag//qLlf/5k4n/+6Jx//2zXf/+vWL//sJ5//7Hkv/+0av//uDC//3pyv/96Mz//tux///apf/+1qb//7h+//+lZf//nGf//5dt//+Tc///lXn//qN+//unjP/5nJ3//JWb//2Knv/2i7L/8KLR//uu3P/druT/4ZXN/+2FtP/1g6X/94Wd//iMj//6nXX//a5f//64Xv/+vW3//sKB//7KmP/+2bP//ebE//3nzf/+2bH//tWf//7Vpf/+toX//5xk//+RW///iFj//4Nc//+FYv/+l2j/+599//eQmv/3iKT/94aj/++HtP/tn9H/+q7d/9aq5f/ajND/5Hq7/+13rv/yeaL/9YCU//mPgf/8oW3//q1m//60a//+uHb//sKJ//7Spv/+48D//ufO//7Xsv/+0Zr//tSk//68kv//mGn//4ZP//9+S///elD//oJa//2Qav/5kIT/9YOX//N7pP/ueK7/5nu7/+iX0//5rd3/0aXp/9KB1v/ba8P/5Wa2/+xoqf/yb5v/936M//uUef/9pWz//qxr//6ucf/+u4X//tGl//7jwv/959H//tez//7PmP/+0KL//sWh//6rh//+i2D//3xQ//59VP/+iF///It1//d9j//ybpv/7Wmn/+Zmtv/dasP/447W//es3v/LpO7/yHnd/89czf/bU8H/5VW1/+5dpv/1cJT/+419//6ibf/+pWj//qZt//63hf/+0ar//eTJ//3o1f/+1rX//c2X//3Lof/+x6b//cCh//6dev/+hlz//ohd//6TZP/8iXn/9m2V/+5apv/mVbb/20/B/89YzP/ahdv/9are/8eo8v+/eeX/xFXW/9FIzP/fSML/6VC0//Nlnv/7ioH//qFt//6jaP/+q3H//rqL//3Ssf/95s///efa//7WuP/8y5j//Mik//7FqP/9xan//a6J//6caf/+kmL//ptn//yKe//0X5//6ky2/99Ew//RQcv/wk/V/9CB4f/yq+D/x7L3/76I7f/AZOH/zFXX/9pS0P/mVsb/8Guw//mRkP/8p3z//K15//y4hP/8w5v/+9W7//vm1v/75t///NbC//nMpP/6yq7//Mmy//vIs//7vZv//LWC//yldf/8o3X/+paM//FgtP/kT8n/20zR/8pN1v+9W+D/y4jn//Cs4f/Pw/v/xqL0/8aF6//PeeT/23Xf/+V32P/uhsf/9qWs//i3mv/4v5j/+Meh//jPsv/43Mn/9+jf//fm5v/31tb/9dXB//XWyP/31sr/99XI//fOt//3yqj/98Of//e9nv/2r6//7oXO/+R63f/beeH/z3vl/8aF7P/Soe3/8bHj/w==";
12332
12880
  }));
12333
12881
  //#endregion
12334
12882
  //#region src/renderer/WaveRenderer.ts
12335
- function Fu(e, t) {
12336
- let n = zu.set(e);
12883
+ function bd(e, t) {
12884
+ let n = wd.set(e);
12337
12885
  return t.set(n.r, n.g, n.b);
12338
12886
  }
12339
- var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12340
- Vc(), nl(), il(), cl(), Zc(), fl(), Kl(), $l(), Du(), Pu(), Ll(), Iu = 220, Lu = 1333, Ru = class {
12887
+ var xd, Sd, Cd, wd, Td, Ed = t((() => {
12888
+ Vc(), nl(), il(), cl(), Zc(), fl(), ou(), pu(), Ru(), fd(), yd(), Gl(), xd = 220, Sd = 1333, Cd = class {
12341
12889
  makeVideo;
12342
12890
  onVideoReady;
12343
12891
  texture;
@@ -12350,8 +12898,8 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12350
12898
  }
12351
12899
  apply(e, t) {
12352
12900
  let n = e.paletteVideoUrl, r = e.paletteImageUrl, i = e.paletteSource ?? "hero", a, o;
12353
- if (n) this.ensureVideo(n), this.video?.readyState && this.video.readyState >= 2 ? (a = "video|" + n, o = () => iu(new _i(this.video))) : (a = "video-loading|" + n, o = () => ju());
12354
- else if (r) this.clearVideo(), a = "url|" + r, o = () => bu(r);
12901
+ if (n) this.ensureVideo(n), this.video?.readyState && this.video.readyState >= 2 ? (a = "video|" + n, o = () => Uu(new _i(this.video))) : (a = "video-loading|" + n, o = () => gd());
12902
+ else if (r) this.clearVideo(), a = "url|" + r, o = () => ad(r);
12355
12903
  else if (i === "stops") {
12356
12904
  this.clearVideo();
12357
12905
  let t = {
@@ -12359,8 +12907,8 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12359
12907
  edgeColor: e.paletteEdgeColor ?? "#8e9dff",
12360
12908
  edgeAmount: e.paletteEdgeAmount ?? .3
12361
12909
  };
12362
- a = "stops|" + ru(t), o = () => ou(t);
12363
- } else Eu[i] ? (this.clearVideo(), a = "map|" + i, o = () => au(yu(Eu[i]))) : (this.clearVideo(), a = "hero", o = () => ju());
12910
+ a = "stops|" + Hu(t), o = () => Gu(t);
12911
+ } else dd[i] ? (this.clearVideo(), a = "map|" + i, o = () => Wu(id(dd[i]))) : (this.clearVideo(), a = "hero", o = () => gd());
12364
12912
  (a !== this.sig || !this.texture) && (this.texture?.dispose(), this.texture = o(), this.sig = a), t.uPalette.value = this.texture, t.uUsePalette.value = e.usePaletteTexture === !1 ? 0 : 1, t.uPaletteRaw.value = 1;
12365
12913
  }
12366
12914
  syncPlayback(e, t) {
@@ -12383,7 +12931,7 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12383
12931
  dispose() {
12384
12932
  this.texture?.dispose(), this.texture = void 0, this.clearVideo(), this.failedUrl = "";
12385
12933
  }
12386
- }, zu = new X(), Bu = class {
12934
+ }, wd = new X(), Td = class {
12387
12935
  renderer;
12388
12936
  scene = new Gn();
12389
12937
  camera;
@@ -12391,6 +12939,12 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12391
12939
  composer;
12392
12940
  postPass;
12393
12941
  bloomPass;
12942
+ ditherPass;
12943
+ innerLightPass;
12944
+ halftonePass;
12945
+ heatmapPass;
12946
+ paperTexturePass;
12947
+ halftoneCmykPass;
12394
12948
  container;
12395
12949
  respectReducedMotion;
12396
12950
  skipIntroRamp;
@@ -12411,6 +12965,13 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12411
12965
  clipSphere = new Ar();
12412
12966
  clipTmpA = new K();
12413
12967
  clipTmpB = new K();
12968
+ interaction;
12969
+ interactionZoom = 1;
12970
+ interactionTimeOffset = 0;
12971
+ interactionSceneOut = {
12972
+ timeOffset: 0,
12973
+ zoom: 1
12974
+ };
12414
12975
  timer = new da();
12415
12976
  time = 0;
12416
12977
  rafId = 0;
@@ -12426,7 +12987,7 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12426
12987
  capturing = !1;
12427
12988
  outputSize;
12428
12989
  constructor(e, t, n = {}) {
12429
- this.container = e, this.config = Al(t), this.respectReducedMotion = n.respectReducedMotion ?? !0, this.skipIntroRamp = n.skipIntroRamp ?? !1, this.renderer = new Bc({
12990
+ this.container = e, this.config = Fl(t), this.respectReducedMotion = n.respectReducedMotion ?? !0, this.skipIntroRamp = n.skipIntroRamp ?? !1, this.renderer = new Bc({
12430
12991
  antialias: !0,
12431
12992
  alpha: !0,
12432
12993
  preserveDrawingBuffer: !0,
@@ -12440,15 +13001,15 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12440
13001
  uGrainAmount: { value: t.grain },
12441
13002
  uTime: { value: 0 }
12442
13003
  },
12443
- vertexShader: Wl,
12444
- fragmentShader: Gl
13004
+ vertexShader: Ql,
13005
+ fragmentShader: $l
12445
13006
  }), this.composer.addPass(this.postPass), this.composer.addPass(new sl()), this.motionQuery = window.matchMedia("(prefers-reduced-motion: reduce)"), this.reducedMotion = this.respectReducedMotion && this.motionQuery.matches, this.motionQuery.addEventListener("change", this.onMotionChange), document.addEventListener("visibilitychange", this.onVisibilityChange), this.intersectionObserver = new IntersectionObserver((e) => {
12446
13007
  this.visible = e[0]?.isIntersecting ?? !0, this.updateRunning();
12447
13008
  }, { rootMargin: "100px" }), this.intersectionObserver.observe(e), this.resizeObserver = new ResizeObserver(this.onResize), this.resizeObserver.observe(e), this.applyBackground(), this.buildWaves(), this.resize();
12448
13009
  }
12449
13010
  get segments() {
12450
13011
  let e = this.config.quality / Math.sqrt(Math.max(1, this.config.waves.length));
12451
- return Gt.clamp(Math.round(Iu * e), 24, 360);
13012
+ return Gt.clamp(Math.round(xd * e), 24, 360);
12452
13013
  }
12453
13014
  makeUniforms() {
12454
13015
  let e = [], t = [];
@@ -12459,6 +13020,8 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12459
13020
  for (let e = 0; e < 8; e++) a.push(new K()), o.push(new K(1, 1, 1)), s.push(0);
12460
13021
  let c = [], l = [], u = [];
12461
13022
  for (let e = 0; e < 4; e++) c.push(new Y()), l.push(new Y()), u.push(0);
13023
+ let d = [], f = [], p = [];
13024
+ for (let e = 0; e < 4; e++) d.push(new G()), f.push(0), p.push(0);
12462
13025
  return {
12463
13026
  uTime: { value: 0 },
12464
13027
  uSpeed: { value: .05 },
@@ -12525,19 +13088,37 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12525
13088
  uLineThickness: { value: 1 },
12526
13089
  uLineDerivativePower: { value: .95 },
12527
13090
  uMaxWidth: { value: 1232 },
12528
- uClearColor: { value: new K(1, 1, 1) }
13091
+ uClearColor: { value: new K(1, 1, 1) },
13092
+ uPointer: { value: new G(0, 0) },
13093
+ uPointerActive: { value: 0 },
13094
+ uPointerRadius: { value: .6 },
13095
+ uPointerAspect: { value: 1 },
13096
+ uPointerAgitate: { value: 0 },
13097
+ uPointerPush: { value: 0 },
13098
+ uPointerWake: { value: 0 },
13099
+ uPointerVel: { value: new G(0, 0) },
13100
+ uShapeFlow: { value: 0 },
13101
+ uPointerThin: { value: 0 },
13102
+ uPointerHue: { value: 0 },
13103
+ uPointerLighten: { value: 0 },
13104
+ uPointerRipple: { value: 0 },
13105
+ uRippleOrigin: { value: d },
13106
+ uRippleAge: { value: f },
13107
+ uRippleAmp: { value: p }
12529
13108
  };
12530
13109
  }
12531
13110
  waveDefines(e) {
12532
13111
  let t = {};
12533
- return e?.twistMotion && (t.TWIST_MOTION = ""), (this.config.loopSeconds ?? 0) > 0 && (t.LOOP_MOTION = ""), (e?.detailAmount ?? 0) !== 0 && (t.DETAIL_OCTAVE = ""), (e?.depthTint ?? 0) > 0 && (t.DEPTH_TINT = ""), (e?.edgeFeather ?? .1) !== .1 && (t.EDGE_FEATHER = ""), t;
13112
+ e?.twistMotion && (t.TWIST_MOTION = ""), (this.config.loopSeconds ?? 0) > 0 && (t.LOOP_MOTION = "");
13113
+ let n = e?.interaction?.bindings?.some((e) => e.target === "detailAmount") ?? !1;
13114
+ return ((e?.detailAmount ?? 0) !== 0 || n) && (t.DETAIL_OCTAVE = ""), (e?.depthTint ?? 0) > 0 && (t.DEPTH_TINT = ""), (e?.edgeFeather ?? .1) !== .1 && (t.EDGE_FEATHER = ""), e && vu(this.config, e) && (t.POINTER_FX = "", yu(this.config, e) && (t.POINTER_RIPPLES = "")), t;
12534
13115
  }
12535
13116
  addWave() {
12536
- let e = new Ql(this.segments), t = this.config.waves[this.waves.length] ?? this.config.waves[0], n = new Oi({
13117
+ let e = new fu(this.segments), t = this.config.waves[this.waves.length] ?? this.config.waves[0], n = new Oi({
12537
13118
  uniforms: this.makeUniforms(),
12538
13119
  defines: this.waveDefines(t),
12539
- vertexShader: Vl,
12540
- fragmentShader: t?.theme === "wireframe" ? Ul : Hl,
13120
+ vertexShader: Yl,
13121
+ fragmentShader: t?.theme === "wireframe" ? Zl : Xl,
12541
13122
  transparent: !0,
12542
13123
  depthTest: !0,
12543
13124
  depthWrite: !0,
@@ -12546,7 +13127,7 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12546
13127
  this.applyBlendMode(n, t?.blendMode ?? "squared");
12547
13128
  let r = new si(e.geometry, n);
12548
13129
  r.frustumCulled = !1, this.group.add(r);
12549
- let i = new Ru((e) => this.createLoopingVideo(e), () => {
13130
+ let i = new Cd((e) => this.createLoopingVideo(e), () => {
12550
13131
  this.updatePaletteTextures(), this.syncVideoPlayback(), this.running || this.renderOnce();
12551
13132
  });
12552
13133
  this.waves.push({
@@ -12578,7 +13159,7 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12578
13159
  }), this.refresh();
12579
13160
  }
12580
13161
  refresh() {
12581
- if (this.applyBackground(), this.applyPost(), !this.isCameraExternallyDriven()) {
13162
+ if (this.applyBackground(), this.applyPost(), this.syncInteraction(), !this.isCameraExternallyDriven()) {
12582
13163
  let e = this.config.cameraPosition, t = this.config.cameraTarget;
12583
13164
  this.camera.position.set(e.x, e.y, e.z), this.camera.lookAt(t.x, t.y, t.z);
12584
13165
  }
@@ -12587,7 +13168,7 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12587
13168
  this.applyBlendMode(e.material, n.blendMode) && (e.material.needsUpdate = !0);
12588
13169
  let i = this.waveDefines(n), a = e.material.defines ?? {};
12589
13170
  Object.keys(i).sort().join(",") !== Object.keys(a).sort().join(",") && (e.material.defines = i, e.material.needsUpdate = !0);
12590
- let o = n.theme === "wireframe" ? Ul : Hl;
13171
+ let o = n.theme === "wireframe" ? Zl : Xl;
12591
13172
  e.material.fragmentShader !== o && (e.material.fragmentShader = o, e.material.needsUpdate = !0);
12592
13173
  let s = [...n.palette].sort((e, t) => e.pos - t.pos), c = Math.max(1, Math.min(s.length, 8)), l = r.uColors.value, u = r.uColorPos.value;
12593
13174
  for (let e = 0; e < 8; e++) {
@@ -12595,21 +13176,21 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12595
13176
  color: "#ffffff",
12596
13177
  pos: 0
12597
13178
  };
12598
- Fu(t.color, l[e]), u[e] = t.pos;
13179
+ bd(t.color, l[e]), u[e] = t.pos;
12599
13180
  }
12600
13181
  r.uColorCount.value = c, r.uGradType.value = n.gradientType === "radial" ? 1 : n.gradientType === "conic" ? 2 : n.gradientType === "mesh" ? 3 : 0, r.uGradAngle.value = (n.gradientAngle ?? 0) * Math.PI / 180, r.uGradShift.value = n.gradientShift ?? 0;
12601
13182
  let d = n.meshGradientPoints.slice(0, 8), f = r.uMeshPointPos.value, p = r.uMeshPointColor.value, m = r.uMeshPointInfluence.value;
12602
13183
  for (let e = 0; e < 8; e++) {
12603
13184
  let t = d[e] ?? d[d.length - 1];
12604
- t && (f[e].set(t.x, t.y), Fu(t.color, p[e]), m[e] = t.influence);
13185
+ t && (f[e].set(t.x, t.y), bd(t.color, p[e]), m[e] = t.influence);
12605
13186
  }
12606
- r.uMeshPointCount.value = d.length, r.uMeshSoftness.value = n.meshGradientSoftness, r.uPaletteScale.value.set(n.paletteTextureScale?.x ?? 1, n.paletteTextureScale?.y ?? 1), r.uPaletteOffset.value.set(n.paletteTextureOffset?.x ?? 0, n.paletteTextureOffset?.y ?? 0), r.uPaletteRotation.value = (n.paletteTextureRotation ?? 0) * Math.PI / 180, r.uHueShift.value = n.hueShift, r.uContrast.value = n.colorContrast, r.uSaturation.value = n.colorSaturation, r.uLineAmount.value = n.lineAmount ?? 425, r.uLineThickness.value = n.lineThickness ?? 1, r.uLineDerivativePower.value = n.lineDerivativePower ?? .95, r.uMaxWidth.value = n.maxWidth ?? 1232, Fu(this.config.background, r.uClearColor.value), r.uFiberCount.value = n.fiberCount, r.uFiberStrength.value = n.fiberStrength, r.uTexture.value = n.texture, r.uCreaseLight.value = n.creaseLight, r.uCreaseSharpness.value = n.creaseSharpness, r.uCreaseSoftness.value = n.creaseSoftness, r.uSheen.value = n.sheen ?? 1, r.uRoundness.value = n.roundness ?? .35, r.uIridescence.value = n.iridescence ?? 0, r.uDepthTint.value = n.depthTint ?? 0, Fu(n.depthTintColor ?? "#0a2540", r.uDepthTintColor.value), r.uEdgeFade.value = n.edgeFade, r.uEdgeFeather.value = n.edgeFeather ?? .1;
13187
+ r.uMeshPointCount.value = d.length, r.uMeshSoftness.value = n.meshGradientSoftness, r.uPaletteScale.value.set(n.paletteTextureScale?.x ?? 1, n.paletteTextureScale?.y ?? 1), r.uPaletteOffset.value.set(n.paletteTextureOffset?.x ?? 0, n.paletteTextureOffset?.y ?? 0), r.uPaletteRotation.value = (n.paletteTextureRotation ?? 0) * Math.PI / 180, r.uHueShift.value = n.hueShift, r.uContrast.value = n.colorContrast, r.uSaturation.value = n.colorSaturation, r.uLineAmount.value = n.lineAmount ?? 425, r.uLineThickness.value = n.lineThickness ?? 1, r.uLineDerivativePower.value = n.lineDerivativePower ?? .95, r.uMaxWidth.value = n.maxWidth ?? 1232, bd(this.config.background, r.uClearColor.value), r.uFiberCount.value = n.fiberCount, r.uFiberStrength.value = n.fiberStrength, r.uTexture.value = n.texture, r.uCreaseLight.value = n.creaseLight, r.uCreaseSharpness.value = n.creaseSharpness, r.uCreaseSoftness.value = n.creaseSoftness, r.uSheen.value = n.sheen ?? 1, r.uRoundness.value = n.roundness ?? .35, r.uIridescence.value = n.iridescence ?? 0, r.uDepthTint.value = n.depthTint ?? 0, bd(n.depthTintColor ?? "#0a2540", r.uDepthTintColor.value), r.uEdgeFade.value = n.edgeFade, r.uEdgeFeather.value = n.edgeFeather ?? .1;
12607
13188
  let h = this.config.lights ?? [];
12608
13189
  r.uAmbient.value = this.config.ambient ?? .45, r.uNumLights.value = Math.min(h.length, 8);
12609
13190
  let g = r.uLightPos.value, _ = r.uLightColor.value, v = r.uLightIntensity.value;
12610
13191
  for (let e = 0; e < 8; e++) {
12611
13192
  let t = h[e];
12612
- t ? (g[e].set(t.position.x, t.position.y, t.position.z), Fu(t.color, _[e]), v[e] = t.intensity) : v[e] = 0;
13193
+ t ? (g[e].set(t.position.x, t.position.y, t.position.z), bd(t.color, _[e]), v[e] = t.intensity) : v[e] = 0;
12613
13194
  }
12614
13195
  let y = n.noiseBands ?? [];
12615
13196
  r.uNumNoiseBands.value = Math.min(y.length, 4);
@@ -12619,6 +13200,13 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12619
13200
  t && (b[e].set(t.startX, t.endX, t.startY, t.endY), x[e].set(t.feather, t.strength, t.frequency, t.colorAttenuation), S[e] = t.parabolaPower);
12620
13201
  }
12621
13202
  r.uSpeed.value = n.speed, r.uSeed.value = n.seed, r.uLoopSeconds.value = this.config.loopSeconds ?? 0, r.uDispFreqX.value = n.displaceFrequency.x, r.uDispFreqZ.value = n.displaceFrequency.y, r.uDispAmount.value = n.displaceAmount, r.uDetailFreq.value = n.detailFrequency ?? .04, r.uDetailAmount.value = n.detailAmount ?? 0, r.uTwFreqX.value = n.twistFrequency.x, r.uTwFreqY.value = n.twistFrequency.y, r.uTwFreqZ.value = n.twistFrequency.z, r.uTwPowX.value = n.twistPower.x, r.uTwPowY.value = n.twistPower.y, r.uTwPowZ.value = n.twistPower.z, e.mesh.scale.set(n.scale.x, n.scale.y, n.scale.z), e.mesh.rotation.set(Gt.degToRad(n.rotation.x), Gt.degToRad(n.rotation.y), Gt.degToRad(n.rotation.z)), e.mesh.position.set(n.position.x, n.position.y, n.position.z), r.uOpacity.value = n.opacity;
13203
+ });
13204
+ let e = (this.config.interaction?.radius ?? .3) * 2, t = this.config.interaction?.ribbonFlow ?? .8;
13205
+ this.waves.forEach((n, r) => {
13206
+ let i = this.config.waves[r] ?? this.config.waves[this.config.waves.length - 1];
13207
+ if (!vu(this.config, i)) return;
13208
+ let a = n.material.uniforms, o = i.interaction?.hover;
13209
+ a.uPointerRadius.value = e, a.uPointerAgitate.value = o?.agitate ?? 0, a.uPointerPush.value = o?.push ?? 0, a.uPointerWake.value = o?.wake ?? 0, a.uPointerThin.value = o?.thin ?? 0, a.uPointerHue.value = o?.hueShift ?? 0, a.uPointerLighten.value = o?.lighten ?? 0, a.uPointerRipple.value = i.interaction?.press?.ripple ?? 0, a.uShapeFlow.value = t;
12622
13210
  }), this.updatePaletteTextures(), this.syncVideoPlayback(), this.group.scale.set(this.config.mirrorH ? -1 : 1, this.config.mirrorV ? -1 : 1, 1), this.onAfterRefresh(), this.running || this.renderOnce();
12623
13211
  }
12624
13212
  updatePaletteTextures() {
@@ -12662,13 +13250,13 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12662
13250
  t
12663
13251
  ].join("|");
12664
13252
  if (a !== this.backgroundSig || !this.backgroundTexture) {
12665
- let i = uu(n, r, e, t);
12666
- this.backgroundTexture?.dispose(), this.backgroundTexture = au(i), this.backgroundSig = a;
13253
+ let i = Yu(n, r, e, t);
13254
+ this.backgroundTexture?.dispose(), this.backgroundTexture = Wu(i), this.backgroundSig = a;
12667
13255
  }
12668
13256
  this.scene.background = this.backgroundTexture;
12669
13257
  return;
12670
13258
  }
12671
- let r = this.config.backgroundGradientSource ?? "stops", i = Eu[r], a = r !== "stops" && i?.kind === "gradient" && i.stops ? i.stops : this.config.backgroundPalette, o = a.map((e) => `${e.color}@${e.pos.toFixed(3)}`).join(","), s = [
13259
+ let r = this.config.backgroundGradientSource ?? "stops", i = dd[r], a = r !== "stops" && i?.kind === "gradient" && i.stops ? i.stops : this.config.backgroundPalette, o = a.map((e) => `${e.color}@${e.pos.toFixed(3)}`).join(","), s = [
12672
13260
  "gradient",
12673
13261
  r,
12674
13262
  n,
@@ -12678,14 +13266,14 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12678
13266
  t
12679
13267
  ].join("|");
12680
13268
  if (s !== this.backgroundSig || !this.backgroundTexture) {
12681
- let r = su({
13269
+ let r = Ku({
12682
13270
  stops: a,
12683
13271
  type: n,
12684
13272
  angle: this.config.backgroundGradientAngle,
12685
13273
  width: e,
12686
13274
  height: t
12687
13275
  });
12688
- this.backgroundTexture?.dispose(), this.backgroundTexture = au(r), this.backgroundSig = s;
13276
+ this.backgroundTexture?.dispose(), this.backgroundTexture = Wu(r), this.backgroundSig = s;
12689
13277
  }
12690
13278
  this.scene.background = this.backgroundTexture;
12691
13279
  }
@@ -12708,7 +13296,7 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12708
13296
  c = this.backgroundImage, l = this.backgroundImage.naturalWidth, u = this.backgroundImage.naturalHeight, d = `custom|${s}`;
12709
13297
  } else {
12710
13298
  this.clearBackgroundVideo();
12711
- let r = this.config.backgroundImageSource ?? "vaporwave", i = r === "hero" ? Au() : Eu[r]?.kind === "image" ? yu(Eu[r], Math.max(t, n)) : null;
13299
+ let r = this.config.backgroundImageSource ?? "vaporwave", i = r === "hero" ? hd() : dd[r]?.kind === "image" ? id(dd[r], Math.max(t, n)) : null;
12712
13300
  if (!i) {
12713
13301
  this.scene.background = e;
12714
13302
  return;
@@ -12727,8 +13315,8 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12727
13315
  n
12728
13316
  ].join("|");
12729
13317
  if (f !== this.backgroundSig || !this.backgroundTexture) {
12730
- let e = du(c, l, u, t, n, r, this.config.background, i, a.x, a.y);
12731
- this.backgroundTexture?.dispose(), this.backgroundTexture = au(e), this.backgroundSig = f, this.backgroundVideoCanvas = o ? e : void 0;
13318
+ let e = Xu(c, l, u, t, n, r, this.config.background, i, a.x, a.y);
13319
+ this.backgroundTexture?.dispose(), this.backgroundTexture = Wu(e), this.backgroundSig = f, this.backgroundVideoCanvas = o ? e : void 0;
12732
13320
  }
12733
13321
  this.scene.background = this.backgroundTexture;
12734
13322
  }
@@ -12780,11 +13368,11 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12780
13368
  x: 0,
12781
13369
  y: 0
12782
13370
  };
12783
- fu(t, e, e.videoWidth, e.videoHeight, this.config.backgroundImageFit ?? "cover", this.config.background, this.config.backgroundImageZoom ?? 1, n.x, n.y), this.backgroundTexture.needsUpdate = !0;
13371
+ Zu(t, e, e.videoWidth, e.videoHeight, this.config.backgroundImageFit ?? "cover", this.config.background, this.config.backgroundImageZoom ?? 1, n.x, n.y), this.backgroundTexture.needsUpdate = !0;
12784
13372
  }
12785
13373
  applyPost() {
12786
13374
  let e = this.postPass.uniforms;
12787
- e.uBlurAmount.value = this.config.blur, e.uGrainAmount.value = this.config.grain, e.uBlurSamples.value = Math.round(this.config.blurSamples ?? 6), this.applyBloom();
13375
+ e.uBlurAmount.value = this.config.blur, e.uGrainAmount.value = this.config.grain, e.uBlurSamples.value = Math.round(this.config.blurSamples ?? 6), this.applyBloom(), this.applyInnerLight(), this.applyHalftone(), this.applyHeatmap(), this.applyHalftoneCmyk(), this.applyPaperTexture(), this.applyDither();
12788
13376
  }
12789
13377
  applyBloom() {
12790
13378
  let e = this.config.bloomStrength ?? 0;
@@ -12796,6 +13384,104 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12796
13384
  this.bloomPass.strength = e, this.bloomPass.radius = this.config.bloomRadius ?? .4, this.bloomPass.threshold = this.config.bloomThreshold ?? .85;
12797
13385
  } else this.bloomPass &&= (this.composer.removePass(this.bloomPass), this.bloomPass.dispose(), void 0);
12798
13386
  }
13387
+ applyDither() {
13388
+ let e = this.config.dither ?? 0;
13389
+ if (e > 0) {
13390
+ this.ditherPass || (this.ditherPass = new Xc({
13391
+ uniforms: {
13392
+ tDiffuse: { value: null },
13393
+ uResolution: { value: this.renderer.getDrawingBufferSize(new G()) },
13394
+ uDitherStrength: { value: e },
13395
+ uDitherScale: { value: this.config.ditherScale ?? 2 },
13396
+ uDitherSteps: { value: this.config.ditherSteps ?? 4 }
13397
+ },
13398
+ vertexShader: Ql,
13399
+ fragmentShader: eu
13400
+ }), this.composer.addPass(this.ditherPass));
13401
+ let t = this.ditherPass.uniforms;
13402
+ t.uDitherStrength.value = e, t.uDitherScale.value = Math.max(1, this.config.ditherScale ?? 2), t.uDitherSteps.value = Math.max(2, Math.round(this.config.ditherSteps ?? 4));
13403
+ } else this.ditherPass &&= (this.composer.removePass(this.ditherPass), this.ditherPass.dispose(), void 0);
13404
+ }
13405
+ applyInnerLight() {
13406
+ let e = this.config.innerLight ?? 0;
13407
+ if (e > 0) {
13408
+ let t = this.config.innerLightX ?? .5, n = this.config.innerLightY ?? .15;
13409
+ this.innerLightPass || (this.innerLightPass = new Xc({
13410
+ uniforms: {
13411
+ tDiffuse: { value: null },
13412
+ uInnerLight: { value: e },
13413
+ uInnerLightDensity: { value: this.config.innerLightDensity ?? .5 },
13414
+ uInnerLightDecay: { value: this.config.innerLightDecay ?? .95 },
13415
+ uInnerLightCenter: { value: new G(t, n) }
13416
+ },
13417
+ vertexShader: Ql,
13418
+ fragmentShader: tu
13419
+ }), this.composer.insertPass(this.innerLightPass, 1));
13420
+ let r = this.innerLightPass.uniforms;
13421
+ r.uInnerLight.value = e, r.uInnerLightDensity.value = this.config.innerLightDensity ?? .5, r.uInnerLightDecay.value = this.config.innerLightDecay ?? .95, r.uInnerLightCenter.value.set(t, n);
13422
+ } else this.innerLightPass &&= (this.composer.removePass(this.innerLightPass), this.innerLightPass.dispose(), void 0);
13423
+ }
13424
+ applyHalftone() {
13425
+ let e = this.config.halftone ?? 0;
13426
+ if (e > 0) {
13427
+ this.halftonePass || (this.halftonePass = new Xc({
13428
+ uniforms: {
13429
+ tDiffuse: { value: null },
13430
+ uResolution: { value: this.renderer.getDrawingBufferSize(new G()) },
13431
+ uHalftone: { value: e },
13432
+ uHalftoneCell: { value: this.config.halftoneCell ?? 6 },
13433
+ uHalftoneAngle: { value: this.config.halftoneAngle ?? .4 }
13434
+ },
13435
+ vertexShader: Ql,
13436
+ fragmentShader: nu
13437
+ }), this.composer.addPass(this.halftonePass));
13438
+ let t = this.halftonePass.uniforms;
13439
+ t.uHalftone.value = e, t.uHalftoneCell.value = Math.max(2, this.config.halftoneCell ?? 6), t.uHalftoneAngle.value = this.config.halftoneAngle ?? .4;
13440
+ } else this.halftonePass &&= (this.composer.removePass(this.halftonePass), this.halftonePass.dispose(), void 0);
13441
+ }
13442
+ applyHeatmap() {
13443
+ let e = this.config.heatmap ?? 0;
13444
+ e > 0 ? (this.heatmapPass || (this.heatmapPass = new Xc({
13445
+ uniforms: {
13446
+ tDiffuse: { value: null },
13447
+ uHeatmap: { value: e }
13448
+ },
13449
+ vertexShader: Ql,
13450
+ fragmentShader: ru
13451
+ }), this.composer.addPass(this.heatmapPass)), this.heatmapPass.uniforms.uHeatmap.value = e) : this.heatmapPass &&= (this.composer.removePass(this.heatmapPass), this.heatmapPass.dispose(), void 0);
13452
+ }
13453
+ applyPaperTexture() {
13454
+ let e = this.config.paperTexture ?? 0;
13455
+ if (e > 0) {
13456
+ this.paperTexturePass || (this.paperTexturePass = new Xc({
13457
+ uniforms: {
13458
+ tDiffuse: { value: null },
13459
+ uPaper: { value: e },
13460
+ uPaperScale: { value: this.config.paperTextureScale ?? 2 }
13461
+ },
13462
+ vertexShader: Ql,
13463
+ fragmentShader: iu
13464
+ }), this.composer.addPass(this.paperTexturePass));
13465
+ let t = this.paperTexturePass.uniforms;
13466
+ t.uPaper.value = e, t.uPaperScale.value = Math.max(.5, this.config.paperTextureScale ?? 2);
13467
+ } else this.paperTexturePass &&= (this.composer.removePass(this.paperTexturePass), this.paperTexturePass.dispose(), void 0);
13468
+ }
13469
+ applyHalftoneCmyk() {
13470
+ let e = this.config.halftoneCmyk ?? 0;
13471
+ if (e > 0) {
13472
+ this.halftoneCmykPass || (this.halftoneCmykPass = new Xc({
13473
+ uniforms: {
13474
+ tDiffuse: { value: null },
13475
+ uHalftoneCmyk: { value: e },
13476
+ uHalftoneCmykCell: { value: this.config.halftoneCmykCell ?? 6 }
13477
+ },
13478
+ vertexShader: Ql,
13479
+ fragmentShader: au
13480
+ }), this.composer.addPass(this.halftoneCmykPass));
13481
+ let t = this.halftoneCmykPass.uniforms;
13482
+ t.uHalftoneCmyk.value = e, t.uHalftoneCmykCell.value = Math.max(2, this.config.halftoneCmykCell ?? 6);
13483
+ } else this.halftoneCmykPass &&= (this.composer.removePass(this.halftoneCmykPass), this.halftoneCmykPass.dispose(), void 0);
13484
+ }
12799
13485
  onResize = () => {
12800
13486
  this.resize();
12801
13487
  };
@@ -12809,7 +13495,7 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12809
13495
  let e = this.outputSize?.width ?? Math.max(1, this.container.clientWidth), t = this.outputSize?.height ?? Math.max(1, this.container.clientHeight), n = this.outputSize ? 1 : Math.min(window.devicePixelRatio || 1, this.config.dprMax);
12810
13496
  this.renderer.setPixelRatio(n), this.renderer.setSize(e, t, !this.outputSize), this.outputSize && (this.renderer.domElement.style.width = "100%", this.renderer.domElement.style.height = "100%"), this.composer.setPixelRatio(n), this.composer.setSize(e, t);
12811
13497
  let r = e * n, i = t * n;
12812
- this.postPass.uniforms.uResolution.value.set(r, i);
13498
+ this.postPass.uniforms.uResolution.value.set(r, i), this.ditherPass && this.ditherPass.uniforms.uResolution.value.set(r, i), this.halftonePass && this.halftonePass.uniforms.uResolution.value.set(r, i);
12813
13499
  for (let e of this.waves) e.material.uniforms.uResolution.value.set(r, i);
12814
13500
  this.camera.left = -r / 2, this.camera.right = r / 2, this.camera.top = i / 2, this.camera.bottom = -i / 2, this.applyZoom(), this.applyBackground(), this.onAfterResize(), this.running || this.renderOnce();
12815
13501
  }
@@ -12833,13 +13519,16 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12833
13519
  };
12834
13520
  updateRunning() {
12835
13521
  let e = this.started && this.visible && this.pageVisible && !this.config.paused && !this.reducedMotion;
12836
- e && !this.running ? (this.running = !0, this.timer.update(), this.rafId = requestAnimationFrame(this.loop)) : !e && this.running && (this.running = !1, cancelAnimationFrame(this.rafId)), this.running || (this.introTimeRamp = 1, this.renderOnce()), this.syncVideoPlayback();
13522
+ e && !this.running ? (this.running = !0, this.timer.update(), this.rafId = requestAnimationFrame(this.loop)) : !e && this.running && (this.running = !1, cancelAnimationFrame(this.rafId)), this.running || (this.introTimeRamp = 1, this.interaction?.settle(), this.renderOnce()), this.syncVideoPlayback();
12837
13523
  }
12838
13524
  loop = () => {
12839
- this.running && (this.timer.update(), this.time += this.timer.getDelta(), this.introTimeRamp < 1 && (this.introTimeRamp = Math.min(1, this.introTimeRamp + .016)), this.renderOnce(), this.rafId = requestAnimationFrame(this.loop));
13525
+ if (!this.running) return;
13526
+ this.timer.update();
13527
+ let e = this.timer.getDelta();
13528
+ this.time += e, this.interaction?.update(e), this.introTimeRamp < 1 && (this.introTimeRamp = Math.min(1, this.introTimeRamp + .016)), this.renderOnce(), this.rafId = requestAnimationFrame(this.loop);
12840
13529
  };
12841
13530
  updateTime() {
12842
- let e = this.config.introRamp === !1 || this.skipIntroRamp ? 1 : this.introTimeRamp, t = this.time * e + (this.config.timeOffset ?? 0);
13531
+ let e = this.config.introRamp === !1 || this.skipIntroRamp ? 1 : this.introTimeRamp, t = this.time * e + (this.config.timeOffset ?? 0) + this.interactionTimeOffset;
12843
13532
  for (let e = 0; e < this.waves.length; e++) {
12844
13533
  let n = this.waves[e].material.uniforms;
12845
13534
  n.uTime.value = t;
@@ -12852,7 +13541,97 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12852
13541
  this.postPass.uniforms.uTime.value = t;
12853
13542
  }
12854
13543
  renderOnce() {
12855
- this.updateBackgroundVideoFrame(), this.updateTime(), this.updateClipPlanes(), this.composer.render(), this.onAfterRenderFrame();
13544
+ this.updateBackgroundVideoFrame(), this.updateTime(), this.applyInteraction(), this.updateClipPlanes(), this.composer.render(), this.onAfterRenderFrame();
13545
+ }
13546
+ syncInteraction() {
13547
+ let e = xu(this.config);
13548
+ e && !this.interaction ? this.interaction = new Lu(this.container, () => this.config) : !e && this.interaction && (this.interaction.dispose(), this.interaction = void 0, this.interactionTimeOffset = 0, this.interactionZoom !== 1 && (this.interactionZoom = 1, this.applyZoom()));
13549
+ }
13550
+ applyInteraction() {
13551
+ if (this.interaction) {
13552
+ if (this.capturing) {
13553
+ this.applyInteractionRest();
13554
+ return;
13555
+ }
13556
+ bu(this.config) && this.applyPointerField(this.interaction), this.applyBindings(this.interaction);
13557
+ }
13558
+ }
13559
+ applyInteractionRest() {
13560
+ for (let e = 0; e < this.waves.length; e++) {
13561
+ let t = this.config.waves[e] ?? this.config.waves[this.config.waves.length - 1];
13562
+ if (!vu(this.config, t)) continue;
13563
+ let n = this.waves[e].material.uniforms;
13564
+ n.uPointerActive.value = 0;
13565
+ let r = n.uRippleAmp.value;
13566
+ for (let e = 0; e < 4; e++) r[e] = 0;
13567
+ }
13568
+ let e = this.config.interaction?.bindings;
13569
+ if (e) {
13570
+ this.interactionSceneOut.timeOffset = this.config.timeOffset ?? 0, this.interactionSceneOut.zoom = this.config.cameraZoom ?? 1;
13571
+ let t = {
13572
+ post: this.postPass.uniforms,
13573
+ out: this.interactionSceneOut
13574
+ };
13575
+ for (let n of e) {
13576
+ let e = Iu[n.target];
13577
+ e.apply(e.base(this.config), t);
13578
+ }
13579
+ }
13580
+ this.interactionTimeOffset !== 0 && (this.interactionTimeOffset = 0, this.updateTime());
13581
+ for (let e = 0; e < this.waves.length; e++) {
13582
+ let t = this.config.waves[e], n = t?.interaction?.bindings;
13583
+ if (!t || !n || n.length === 0) continue;
13584
+ let r = this.waves[e];
13585
+ for (let e of n) {
13586
+ let n = Fu[e.target];
13587
+ n.apply(n.base(t), {
13588
+ u: r.material.uniforms,
13589
+ mesh: r.mesh
13590
+ });
13591
+ }
13592
+ }
13593
+ }
13594
+ applyPointerField(e) {
13595
+ let t = this.camera.right - this.camera.left, n = this.camera.top - this.camera.bottom, r = n === 0 ? 1 : t / n, i = e.sample().ripples, a = Math.min(1, .2 + .85 * e.pointerFlux()), o = e.pointerVelocity();
13596
+ for (let t = 0; t < this.waves.length; t++) {
13597
+ let n = this.config.waves[t] ?? this.config.waves[this.config.waves.length - 1];
13598
+ if (!vu(this.config, n)) continue;
13599
+ let s = this.waves[t].material.uniforms;
13600
+ s.uPointerAgitate.value = (n.interaction?.hover?.agitate ?? 0) * a, s.uPointerVel.value.copy(o);
13601
+ let c = e.fieldFor(t);
13602
+ c ? (s.uPointer.value.copy(c.ndc), s.uPointerActive.value = c.presence) : s.uPointerActive.value = 0, s.uPointerAspect.value = r;
13603
+ let l = s.uRippleOrigin.value, u = s.uRippleAge.value, d = s.uRippleAmp.value;
13604
+ for (let e = 0; e < 4; e++) l[e].copy(i[e].origin), u[e] = i[e].age, d[e] = i[e].amp;
13605
+ }
13606
+ }
13607
+ applyBindings(e) {
13608
+ this.interactionSceneOut.timeOffset = this.config.timeOffset ?? 0, this.interactionSceneOut.zoom = this.config.cameraZoom ?? 1;
13609
+ let t = {
13610
+ post: this.postPass.uniforms,
13611
+ out: this.interactionSceneOut
13612
+ };
13613
+ for (let n of this.config.interaction?.bindings ?? []) {
13614
+ let r = Iu[n.target], i = Gt.lerp(n.from ?? r.base(this.config), n.to, e.bindingValue(n));
13615
+ r.apply(i, t);
13616
+ }
13617
+ for (let t = 0; t < this.waves.length; t++) {
13618
+ let n = this.config.waves[t], r = n?.interaction?.bindings;
13619
+ if (!n || !r || r.length === 0) continue;
13620
+ let i = this.waves[t];
13621
+ for (let t of r) {
13622
+ let r = Fu[t.target], a = Gt.lerp(t.from ?? r.base(n), t.to, e.bindingValue(t));
13623
+ r.apply(a, {
13624
+ u: i.material.uniforms,
13625
+ mesh: i.mesh
13626
+ });
13627
+ }
13628
+ }
13629
+ this.interactionTimeOffset = this.interactionSceneOut.timeOffset - (this.config.timeOffset ?? 0);
13630
+ let n = this.interactionSceneOut.zoom / (this.config.cameraZoom || 1);
13631
+ n !== this.interactionZoom && (this.interactionZoom = n, this.applyZoom());
13632
+ }
13633
+ setInteractionInput(e, t) {
13634
+ this.interaction?.setInput(e, t);
12856
13635
  }
12857
13636
  refreshPlayback() {
12858
13637
  this.updateRunning();
@@ -12869,17 +13648,22 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12869
13648
  onAfterResize() {}
12870
13649
  applyZoom() {
12871
13650
  let e = this.camera.right - this.camera.left, t = this.camera.top - this.camera.bottom;
12872
- this.camera.zoom = Math.max(e / Lu, t / 750) * (this.config.cameraZoom ?? 1), this.camera.updateProjectionMatrix();
13651
+ this.camera.zoom = Math.max(e / Sd, t / 750) * (this.config.cameraZoom ?? 1) * this.interactionZoom, this.camera.updateProjectionMatrix();
12873
13652
  }
12874
13653
  updateClipPlanes() {
12875
13654
  this.clipBox.makeEmpty();
12876
- for (let e of this.waves) {
12877
- let t = e.mesh;
12878
- t.updateWorldMatrix(!0, !1);
12879
- let n = t.geometry.boundingSphere;
12880
- if (!n) continue;
12881
- let r = this.clipTmpA.setFromMatrixPosition(t.matrixWorld), i = Math.abs(Number(e.material.uniforms.uDispAmount.value) || 0), a = (n.center.length() + n.radius + i) * t.matrixWorld.getMaxScaleOnAxis() * 1.2;
12882
- this.clipBox.expandByPoint(this.clipTmpB.copy(r).addScalar(a)), this.clipBox.expandByPoint(this.clipTmpB.copy(r).addScalar(-a));
13655
+ for (let e = 0; e < this.waves.length; e++) {
13656
+ let t = this.waves[e], n = t.mesh;
13657
+ n.updateWorldMatrix(!0, !1);
13658
+ let r = n.geometry.boundingSphere;
13659
+ if (!r) continue;
13660
+ let i = this.clipTmpA.setFromMatrixPosition(n.matrixWorld), a = Math.abs(Number(t.material.uniforms.uDispAmount.value) || 0), o = this.config.waves[e] ?? this.config.waves[this.config.waves.length - 1], s = 0;
13661
+ if (vu(this.config, o)) {
13662
+ let e = o.interaction?.hover;
13663
+ s = (e?.agitate ?? 0) + Math.abs(e?.push ?? 0) + (e?.wake ?? 0) + (o.interaction?.press?.ripple ?? 0);
13664
+ }
13665
+ let c = (r.center.length() + r.radius + a + s) * n.matrixWorld.getMaxScaleOnAxis() * 1.2;
13666
+ this.clipBox.expandByPoint(this.clipTmpB.copy(i).addScalar(c)), this.clipBox.expandByPoint(this.clipTmpB.copy(i).addScalar(-c));
12883
13667
  }
12884
13668
  if (this.clipBox.isEmpty()) return;
12885
13669
  this.clipBox.getBoundingSphere(this.clipSphere);
@@ -12891,11 +13675,11 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12891
13675
  t !== i && (this.config.transparentBackground = t, this.applyBackground());
12892
13676
  let a = r !== void 0, o = this.time, s = this.introTimeRamp;
12893
13677
  a && (this.time = r, this.introTimeRamp = 1);
12894
- let c = null;
13678
+ let c = null, l = this.camera.zoom, u = this.interactionZoom !== 1;
12895
13679
  try {
12896
- this.capturing = !0, this.renderOnce(), c = await new Promise((t) => this.canvas.toBlob(t, e, n));
13680
+ this.capturing = !0, u && (this.camera.zoom = l / this.interactionZoom, this.camera.updateProjectionMatrix()), this.renderOnce(), c = await new Promise((t) => this.canvas.toBlob(t, e, n));
12897
13681
  } finally {
12898
- this.capturing = !1, t !== i && (this.config.transparentBackground = i, this.applyBackground()), a && (this.time = o, this.introTimeRamp = s), this.renderOnce();
13682
+ this.capturing = !1, u && (this.camera.zoom = l, this.camera.updateProjectionMatrix()), t !== i && (this.config.transparentBackground = i, this.applyBackground()), a && (this.time = o, this.introTimeRamp = s), this.renderOnce();
12899
13683
  }
12900
13684
  if (!c || c.type !== e) throw Error(`Failed to capture ${e}`);
12901
13685
  return c;
@@ -12910,25 +13694,25 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12910
13694
  return this.config;
12911
13695
  }
12912
13696
  setConfig(e) {
12913
- let t = Al(e), n = t.waves.length !== this.waves.length || t.quality !== this.config.quality;
13697
+ let t = Fl(e), n = t.waves.length !== this.waves.length || t.quality !== this.config.quality;
12914
13698
  this.config = t, n ? this.rebuild() : this.refresh(), this.applyCameraFromConfig();
12915
13699
  }
12916
13700
  dispose() {
12917
- cancelAnimationFrame(this.rafId), this.running = !1, this.resizeObserver.disconnect(), this.intersectionObserver.disconnect(), this.motionQuery.removeEventListener("change", this.onMotionChange), document.removeEventListener("visibilitychange", this.onVisibilityChange), this.renderer.domElement.removeEventListener("webglcontextlost", this.onContextLost), this.renderer.domElement.removeEventListener("webglcontextrestored", this.onContextRestored), this.clearBackgroundVideo(), this.backgroundTexture?.dispose();
13701
+ cancelAnimationFrame(this.rafId), this.running = !1, this.interaction?.dispose(), this.interaction = void 0, this.resizeObserver.disconnect(), this.intersectionObserver.disconnect(), this.motionQuery.removeEventListener("change", this.onMotionChange), document.removeEventListener("visibilitychange", this.onVisibilityChange), this.renderer.domElement.removeEventListener("webglcontextlost", this.onContextLost), this.renderer.domElement.removeEventListener("webglcontextrestored", this.onContextRestored), this.clearBackgroundVideo(), this.backgroundTexture?.dispose();
12918
13702
  for (let e of this.waves) e.material.dispose(), e.geometry.dispose(), e.palette.dispose();
12919
- this.bloomPass?.dispose(), this.composer.dispose(), this.renderer.dispose(), this.renderer.domElement.remove();
13703
+ this.bloomPass?.dispose(), this.ditherPass?.dispose(), this.innerLightPass?.dispose(), this.halftonePass?.dispose(), this.heatmapPass?.dispose(), this.paperTexturePass?.dispose(), this.halftoneCmykPass?.dispose(), this.composer.dispose(), this.renderer.dispose(), this.renderer.domElement.remove();
12920
13704
  }
12921
13705
  };
12922
- })), Hu = /* @__PURE__ */ n({
12923
- WaveRenderer: () => Bu,
13706
+ })), Dd = /* @__PURE__ */ n({
13707
+ WaveRenderer: () => Td,
12924
13708
  createDefaultConfig: () => wl
12925
13709
  });
12926
13710
  //#endregion
12927
13711
  //#region src/shell/probe.ts
12928
13712
  t((() => {
12929
- Vu(), Ll();
13713
+ Ed(), Gl();
12930
13714
  }))();
12931
- function Uu() {
13715
+ function Od() {
12932
13716
  if (typeof document > "u") return !1;
12933
13717
  try {
12934
13718
  let e = document.createElement("canvas"), t = { failIfMajorPerformanceCaveat: !0 }, n = e.getContext("webgl2", t) ?? e.getContext("webgl", t);
@@ -12937,122 +13721,124 @@ function Uu() {
12937
13721
  return !1;
12938
13722
  }
12939
13723
  }
12940
- function Wu() {
13724
+ function kd() {
12941
13725
  return typeof window < "u" && typeof window.matchMedia == "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
12942
13726
  }
12943
- function Gu() {
13727
+ function Ad() {
12944
13728
  return typeof navigator > "u" ? !1 : navigator.connection?.saveData === !0;
12945
13729
  }
12946
13730
  //#endregion
12947
13731
  //#region src/shell/poster.ts
12948
- var Ku = "data-wave3d-poster";
12949
- function qu(e) {
13732
+ var jd = "data-wave3d-poster";
13733
+ function Md(e) {
12950
13734
  getComputedStyle(e).position === "static" && (e.style.position = "relative");
12951
13735
  }
12952
- function Ju(e, t) {
12953
- let n = e.querySelector(`img[${Ku}]`);
12954
- if (!n && !t) return null;
12955
- n || (n = document.createElement("img"), n.setAttribute(Ku, ""), n.decoding = "async", n.alt = "", n.setAttribute("aria-hidden", "true"), e.appendChild(n)), t && (n.src = t), Object.assign(n.style, {
13736
+ function Nd(e, t, n = "fill") {
13737
+ let r = e.querySelector(`img[${jd}]`);
13738
+ if (!r && !t) return null;
13739
+ r || (r = document.createElement("img"), r.setAttribute(jd, ""), r.decoding = "async", r.alt = "", r.setAttribute("aria-hidden", "true"), e.appendChild(r)), t && (r.src = t), Object.assign(r.style, {
12956
13740
  position: "absolute",
12957
13741
  inset: "0",
12958
13742
  width: "100%",
12959
13743
  height: "100%",
12960
- objectFit: "cover",
13744
+ objectFit: n,
12961
13745
  pointerEvents: "none",
12962
13746
  zIndex: "1",
12963
13747
  opacity: "1",
12964
13748
  visibility: "visible"
12965
13749
  });
12966
- let r = n;
13750
+ let i = r;
12967
13751
  return {
12968
- el: r,
13752
+ el: i,
12969
13753
  fadeOut(e) {
12970
13754
  if (e <= 0) {
12971
- r.style.opacity = "0", r.style.visibility = "hidden";
13755
+ i.style.opacity = "0", i.style.visibility = "hidden";
12972
13756
  return;
12973
13757
  }
12974
- r.style.transition = `opacity ${e}ms ease`, r.offsetWidth, r.style.opacity = "0", setTimeout(() => {
12975
- r.style.visibility = "hidden";
13758
+ i.style.transition = `opacity ${e}ms ease`, i.offsetWidth, i.style.opacity = "0", setTimeout(() => {
13759
+ i.style.visibility = "hidden";
12976
13760
  }, e + 50);
12977
13761
  },
12978
13762
  show() {
12979
- r.style.transition = "", r.style.opacity = "1", r.style.visibility = "visible";
13763
+ i.style.transition = "", i.style.opacity = "1", i.style.visibility = "visible";
12980
13764
  },
12981
13765
  remove() {
12982
- r.remove();
13766
+ i.remove();
12983
13767
  }
12984
13768
  };
12985
13769
  }
12986
13770
  //#endregion
12987
13771
  //#region src/shell/createWave.ts
12988
- function Yu(e, t, n, r) {
13772
+ function Pd(e, t, n, r) {
12989
13773
  let { lazy: i = !0, rootMargin: a = "200px", webgl: o = "auto", respectReducedMotion: s = !0, reducedMotionBehavior: c = "static", respectSaveData: l = !0, fadeMs: u = 300 } = r, d = "poster", f = null, p = { ...n };
12990
13774
  r.paused !== void 0 && (p.paused = r.paused);
12991
- let m = !1, h = null, g, _ = 0;
12992
- qu(t);
12993
- let v = Ju(t, r.poster);
12994
- function y(e) {
12995
- d !== e && (d = e, r.onStateChange?.(e));
12996
- }
13775
+ let m = /* @__PURE__ */ new Map(), h = !1, g = null, _, v = 0;
13776
+ Md(t);
13777
+ let y = Nd(t, r.poster, r.posterFit);
12997
13778
  function b(e) {
12998
- y("fallback"), v?.show(), r.onFallback?.(e);
13779
+ d !== e && (d = e, r.onStateChange?.(e));
12999
13780
  }
13000
- function x() {
13001
- clearTimeout(g);
13781
+ function x(e) {
13782
+ b("fallback"), y?.show(), r.onFallback?.(e);
13002
13783
  }
13003
13784
  function S() {
13004
- if (_ += 1, clearTimeout(g), _ >= 2) {
13005
- C(), b("context-lost");
13785
+ clearTimeout(_);
13786
+ }
13787
+ function C() {
13788
+ if (v += 1, clearTimeout(_), v >= 2) {
13789
+ w(), x("context-lost");
13006
13790
  return;
13007
13791
  }
13008
- g = setTimeout(() => {
13009
- C(), b("context-lost");
13792
+ _ = setTimeout(() => {
13793
+ w(), x("context-lost");
13010
13794
  }, 4e3);
13011
13795
  }
13012
- function C() {
13796
+ function w() {
13013
13797
  if (!f) return;
13014
13798
  let e = f.renderer.domElement;
13015
- e.removeEventListener("webglcontextlost", S), e.removeEventListener("webglcontextrestored", x), f.dispose(), f = null;
13799
+ e.removeEventListener("webglcontextlost", C), e.removeEventListener("webglcontextrestored", S), f.dispose(), f = null;
13016
13800
  }
13017
- async function w() {
13018
- y("loading");
13801
+ async function T() {
13802
+ b("loading");
13019
13803
  let n;
13020
13804
  try {
13021
13805
  n = await e();
13022
13806
  } catch {
13023
- m || b("load-error");
13807
+ h || x("load-error");
13024
13808
  return;
13025
13809
  }
13026
- if (m) return;
13810
+ if (h) return;
13027
13811
  let i = {
13028
13812
  ...n.createDefaultConfig(),
13029
13813
  ...p
13030
13814
  }, a = { respectReducedMotion: s };
13031
13815
  f = new n.WaveRenderer(t, i, a);
13032
13816
  let o = f.renderer.domElement;
13033
- o.addEventListener("webglcontextlost", S, !1), o.addEventListener("webglcontextrestored", x, !1), f.start(), y("running"), r.onReady?.(f), v && requestAnimationFrame(() => requestAnimationFrame(() => {
13034
- !m && f && v.fadeOut(u);
13817
+ o.addEventListener("webglcontextlost", C, !1), o.addEventListener("webglcontextrestored", S, !1), f.start();
13818
+ for (let [e, t] of m) f.setInteractionInput(e, t);
13819
+ b("running"), r.onReady?.(f), y && requestAnimationFrame(() => requestAnimationFrame(() => {
13820
+ !h && f && y.fadeOut(u);
13035
13821
  }));
13036
13822
  }
13037
- function T() {
13038
- if (!m) {
13039
- if (o === "auto" && !Uu()) {
13040
- b("no-webgl");
13823
+ function E() {
13824
+ if (!h) {
13825
+ if (o === "auto" && !Od()) {
13826
+ x("no-webgl");
13041
13827
  return;
13042
13828
  }
13043
- w();
13829
+ T();
13044
13830
  }
13045
13831
  }
13046
- function E() {
13832
+ function D() {
13047
13833
  if (o !== "off") {
13048
- if (l && Gu()) return b("save-data");
13049
- if (s && c === "poster" && Wu()) return b("reduced-motion");
13050
- i && typeof IntersectionObserver < "u" ? (h = new IntersectionObserver((e) => {
13051
- e.some((e) => e.isIntersecting) && (h?.disconnect(), h = null, T());
13052
- }, { rootMargin: a }), h.observe(t)) : T();
13834
+ if (l && Ad()) return x("save-data");
13835
+ if (s && c === "poster" && kd()) return x("reduced-motion");
13836
+ i && typeof IntersectionObserver < "u" ? (g = new IntersectionObserver((e) => {
13837
+ e.some((e) => e.isIntersecting) && (g?.disconnect(), g = null, E());
13838
+ }, { rootMargin: a }), g.observe(t)) : E();
13053
13839
  }
13054
13840
  }
13055
- return E(), {
13841
+ return D(), {
13056
13842
  get state() {
13057
13843
  return d;
13058
13844
  },
@@ -13073,6 +13859,9 @@ function Yu(e, t, n, r) {
13073
13859
  ...e
13074
13860
  };
13075
13861
  },
13862
+ setInteractionInput(e, t) {
13863
+ f ? f.setInteractionInput(e, t) : m.set(e, t);
13864
+ },
13076
13865
  play() {
13077
13866
  f ? (f.getConfig().paused = !1, f.refreshPlayback()) : p.paused = !1;
13078
13867
  },
@@ -13080,17 +13869,17 @@ function Yu(e, t, n, r) {
13080
13869
  f ? (f.getConfig().paused = !0, f.refreshPlayback()) : p.paused = !0;
13081
13870
  },
13082
13871
  destroy() {
13083
- m = !0, h?.disconnect(), h = null, clearTimeout(g), C(), v?.remove();
13872
+ h = !0, g?.disconnect(), g = null, clearTimeout(_), w(), y?.remove();
13084
13873
  }
13085
13874
  };
13086
13875
  }
13087
13876
  //#endregion
13088
13877
  //#region src/presets.ts
13089
- Ll();
13090
- var Xu = 180 / Math.PI;
13091
- function Zu(e) {
13878
+ Gl();
13879
+ var Fd = 180 / Math.PI;
13880
+ function Id(e) {
13092
13881
  let t = wl(), n = t.waves[0];
13093
- return n.speed = e.speed, n.colorContrast = e.contrast, n.colorSaturation = e.sat, n.hueShift = e.hueRad * Xu, n.displaceFrequency = {
13882
+ return n.speed = e.speed, n.colorContrast = e.contrast, n.colorSaturation = e.sat, n.hueShift = e.hueRad * Fd, n.displaceFrequency = {
13094
13883
  x: e.dispX,
13095
13884
  y: e.dispZ
13096
13885
  }, n.displaceAmount = e.dispAmt, n.position = {
@@ -13098,9 +13887,9 @@ function Zu(e) {
13098
13887
  y: e.pos[1],
13099
13888
  z: e.pos[2]
13100
13889
  }, n.rotation = {
13101
- x: e.rotRad[0] * Xu,
13102
- y: e.rotRad[1] * Xu,
13103
- z: e.rotRad[2] * Xu
13890
+ x: e.rotRad[0] * Fd,
13891
+ y: e.rotRad[1] * Fd,
13892
+ z: e.rotRad[2] * Fd
13104
13893
  }, n.scale = {
13105
13894
  x: e.scale[0],
13106
13895
  y: e.scale[1],
@@ -13123,8 +13912,8 @@ function Zu(e) {
13123
13912
  z: 0
13124
13913
  }, t.cameraZoom = e.zoom, t;
13125
13914
  }
13126
- var Qu = {
13127
- Hero: () => Zu({
13915
+ var Ld = {
13916
+ Hero: () => Id({
13128
13917
  speed: .04,
13129
13918
  contrast: 1,
13130
13919
  sat: 1,
@@ -13168,7 +13957,7 @@ var Qu = {
13168
13957
  camTarget: [-420, -200]
13169
13958
  }),
13170
13959
  "Wave 2": () => wl(),
13171
- "Wave 3": () => Zu({
13960
+ "Wave 3": () => Id({
13172
13961
  speed: .08,
13173
13962
  contrast: 1,
13174
13963
  sat: 1,
@@ -13211,7 +14000,7 @@ var Qu = {
13211
14000
  zoom: 1.3,
13212
14001
  camTarget: [-104, 13]
13213
14002
  }),
13214
- "Wave 4": () => Zu({
14003
+ "Wave 4": () => Id({
13215
14004
  speed: .0525,
13216
14005
  contrast: .969,
13217
14006
  sat: 1.383,
@@ -13291,7 +14080,7 @@ var Qu = {
13291
14080
  ]), t.creaseLight = 1, e.background = "#05060c", e.transparentBackground = !1, e.waves = bl(t, 3), e.waveCount = 3, e;
13292
14081
  },
13293
14082
  "Mesh Gradient": () => {
13294
- let e = Qu.Hero(), t = e.waves[0];
14083
+ let e = Ld.Hero(), t = e.waves[0];
13295
14084
  return t.gradientType = "mesh", t.meshGradientPoints = [
13296
14085
  {
13297
14086
  color: "#0a84ff",
@@ -13332,7 +14121,7 @@ var Qu = {
13332
14121
  ], t.meshGradientSoftness = .68, t.blendMode = "normal", t.hueShift = 0, t.colorContrast = 1.06, t.colorSaturation = 1.12, t.fiberStrength = .14, e.grain = .3, e.blur = .008, e.background = "#070914", e.backgroundMode = "color", e.transparentBackground = !1, e;
13333
14122
  },
13334
14123
  "Solar Bloom": () => {
13335
- let e = Qu.Hero(), t = e.waves[0];
14124
+ let e = Ld.Hero(), t = e.waves[0];
13336
14125
  return t.usePaletteTexture = !1, t.gradientType = "radial", t.gradientShift = .14, t.palette = [
13337
14126
  {
13338
14127
  color: "#fff3c4",
@@ -13361,7 +14150,7 @@ var Qu = {
13361
14150
  ], t.blendMode = "normal", t.hueShift = 0, t.colorContrast = 1.05, t.colorSaturation = 1.18, t.fiberStrength = .12, e.grain = .3, e.blur = .01, e.background = "#0a0714", e.backgroundMode = "gradient", e.backgroundGradientType = "radial", e.backgroundGradientSource = "stops", e.backgroundPalette = vl(["#2a1330", "#08040f"]), e.transparentBackground = !1, e;
13362
14151
  },
13363
14152
  Holographic: () => {
13364
- let e = Qu.Hero(), t = e.waves[0];
14153
+ let e = Ld.Hero(), t = e.waves[0];
13365
14154
  return t.usePaletteTexture = !1, t.gradientType = "conic", t.gradientShift = .08, t.palette = [
13366
14155
  {
13367
14156
  color: "#8ef6e4",
@@ -13394,7 +14183,7 @@ var Qu = {
13394
14183
  ], t.blendMode = "normal", t.hueShift = 0, t.colorContrast = 1.04, t.colorSaturation = 1.12, t.fiberStrength = .12, e.grain = .28, e.blur = .01, e.background = "#05060c", e.backgroundMode = "gradient", e.backgroundGradientType = "linear", e.backgroundGradientAngle = 135, e.backgroundGradientSource = "stops", e.backgroundPalette = vl(["#04121a", "#0a0518"]), e.transparentBackground = !1, e;
13395
14184
  },
13396
14185
  Aurora: () => {
13397
- let e = Qu.Hero(), t = e.waves[0];
14186
+ let e = Ld.Hero(), t = e.waves[0];
13398
14187
  return t.gradientType = "mesh", t.meshGradientPoints = [
13399
14188
  {
13400
14189
  color: "#0a1f3c",
@@ -13466,27 +14255,31 @@ var Qu = {
13466
14255
  ], e.backgroundMeshSoftness = .75, e.transparentBackground = !1, e;
13467
14256
  },
13468
14257
  Palestine: () => {
13469
- let e = Qu.Hero(), t = e.waves[0];
14258
+ let e = Ld.Hero(), t = e.waves[0];
13470
14259
  return t.paletteSource = "palestine", t.blendMode = "normal", t.hueShift = 0, t.colorContrast = 1, t.colorSaturation = 1, e.grain = .35, e.background = "#f2efe8", e.transparentBackground = !0, e;
13471
14260
  },
14261
+ Spain: () => {
14262
+ let e = Ld.Hero(), t = e.waves[0];
14263
+ return t.paletteSource = "spain", t.blendMode = "normal", t.hueShift = 0, t.colorContrast = 1.18, t.colorSaturation = 1.25, t.creaseLight = 1.6, e.grain = .3, e.background = "#1a0608", e.backgroundMode = "color", e.transparentBackground = !1, e;
14264
+ },
13472
14265
  "Vaporwave Sunset": () => {
13473
- let e = Qu.Hero(), t = e.waves[0];
13474
- return t.position.x = 525, t.rotation.x = -.64 * Xu, t.rotation.z = 1.68 * Xu, t.paletteSource = "vaporwave", t.blendMode = "normal", t.hueShift = 0, t.colorContrast = 1.08, t.colorSaturation = 1.15, t.creaseLight = 1.25, e.cameraZoom = 1.1, e.cameraTarget = {
14266
+ let e = Ld.Hero(), t = e.waves[0];
14267
+ return t.position.x = 525, t.rotation.x = -.64 * Fd, t.rotation.z = 1.68 * Fd, t.paletteSource = "vaporwave", t.blendMode = "normal", t.hueShift = 0, t.colorContrast = 1.08, t.colorSaturation = 1.15, t.creaseLight = 1.25, e.cameraZoom = 1.1, e.cameraTarget = {
13475
14268
  x: 150,
13476
14269
  y: 360,
13477
14270
  z: 0
13478
14271
  }, e.background = "#09051f", e.transparentBackground = !1, e;
13479
14272
  },
13480
14273
  Kaleidoscope: () => {
13481
- let e = Qu["Wave 3"](), t = e.waves[0];
14274
+ let e = Ld["Wave 3"](), t = e.waves[0];
13482
14275
  return t.paletteSource = "kaleidoscope", t.blendMode = "normal", t.hueShift = 0, t.colorContrast = 1.05, t.colorSaturation = 1.12, e.grain = .5, e;
13483
14276
  }
13484
14277
  };
13485
- Vu(), Ll();
13486
- var $u = () => Promise.resolve(Hu);
13487
- function ed(e, t = {}, n = {}) {
13488
- return Yu($u, e, t, n);
14278
+ Ed(), Gl();
14279
+ var Rd = () => Promise.resolve(Dd);
14280
+ function zd(e, t = {}, n = {}) {
14281
+ return Pd(Rd, e, t, n);
13489
14282
  }
13490
- var td = ed;
14283
+ var Bd = zd;
13491
14284
  //#endregion
13492
- export { Il as DEFAULT_LIGHT_POSITION, jl as MAX_COLORS, Nl as MAX_LIGHTS, Ml as MAX_MESH_POINTS, Pl as MAX_NOISE_BANDS, Fl as MAX_WAVES, Qu as PRESETS, Bu as WaveRenderer, wl as createDefaultConfig, yl as createDefaultMeshPoints, gl as createLight, _l as createNoiseBand, ed as createWave, Dl as ensureCamera, kl as ensureSceneDefaults, Al as ensureStudioConfig, vl as makeStops, Sl as makeWave, bl as makeWaveSpread, td as mountWave, El as normalizeBackground, Ol as normalizeWave, Cl as resizeWaves };
14285
+ export { Vl as DEFAULT_LIGHT_POSITION, Il as MAX_COLORS, Rl as MAX_LIGHTS, Ll as MAX_MESH_POINTS, zl as MAX_NOISE_BANDS, Bl as MAX_WAVES, Ld as PRESETS, Td as WaveRenderer, wl as createDefaultConfig, yl as createDefaultMeshPoints, gl as createLight, _l as createNoiseBand, zd as createWave, Dl as ensureCamera, kl as ensureSceneDefaults, Fl as ensureStudioConfig, vl as makeStops, Sl as makeWave, bl as makeWaveSpread, Bd as mountWave, El as normalizeBackground, Pl as normalizeSceneInteraction, Ol as normalizeWave, Nl as normalizeWaveInteraction, Cl as resizeWaves };