@jayf0x/fluidity-js 0.2.7 → 0.2.8

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.
package/dist/index.js CHANGED
@@ -1,18 +1,18 @@
1
- var aC = Object.defineProperty;
2
- var uC = (e, g, C) => g in e ? aC(e, g, { enumerable: !0, configurable: !0, writable: !0, value: C }) : e[g] = C;
3
- var nI = (e, g, C) => (uC(e, typeof g != "symbol" ? g + "" : g, C), C), kI = (e, g, C) => {
1
+ var mC = Object.defineProperty;
2
+ var SC = (e, g, C) => g in e ? mC(e, g, { enumerable: !0, configurable: !0, writable: !0, value: C }) : e[g] = C;
3
+ var LI = (e, g, C) => (SC(e, typeof g != "symbol" ? g + "" : g, C), C), fI = (e, g, C) => {
4
4
  if (!g.has(e))
5
5
  throw TypeError("Cannot " + C);
6
6
  };
7
- var I = (e, g, C) => (kI(e, g, "read from private field"), C ? C.call(e) : g.get(e)), d = (e, g, C) => {
7
+ var I = (e, g, C) => (fI(e, g, "read from private field"), C ? C.call(e) : g.get(e)), A = (e, g, C) => {
8
8
  if (g.has(e))
9
9
  throw TypeError("Cannot add the same private member more than once");
10
10
  g instanceof WeakSet ? g.add(e) : g.set(e, C);
11
- }, o = (e, g, C, i) => (kI(e, g, "write to private field"), i ? i.call(e, C) : g.set(e, C), C);
12
- var L = (e, g, C) => (kI(e, g, "access private method"), C);
13
- import { jsx as $I } from "react/jsx-runtime";
14
- import { useRef as Qg, useEffect as tg, forwardRef as gC, useImperativeHandle as IC } from "react";
15
- const mC = {
11
+ }, o = (e, g, C, i) => (fI(e, g, "write to private field"), i ? i.call(e, C) : g.set(e, C), C);
12
+ var h = (e, g, C) => (fI(e, g, "access private method"), C);
13
+ import { jsx as IC } from "react/jsx-runtime";
14
+ import { useRef as Ng, useEffect as lg, forwardRef as CC, useImperativeHandle as iC } from "react";
15
+ const BC = {
16
16
  densityDissipation: [0.94, 1],
17
17
  velocityDissipation: [0.9, 0.999],
18
18
  splatRadius: [1e-3, 0.04],
@@ -23,13 +23,13 @@ const mC = {
23
23
  };
24
24
  function Eg(e) {
25
25
  const g = { ...e };
26
- for (const [C, [i, s]] of Object.entries(mC)) {
27
- const l = e[C];
28
- l !== void 0 && l >= 0 && l <= 1 && (g[C] = i + (s - i) * l);
26
+ for (const [C, [i, s]] of Object.entries(BC)) {
27
+ const t = e[C];
28
+ t !== void 0 && t >= 0 && t <= 1 && (g[C] = i + (s - i) * t);
29
29
  }
30
30
  return g;
31
31
  }
32
- const CC = {
32
+ const eC = {
33
33
  densityDissipation: 0.83,
34
34
  velocityDissipation: 0.91,
35
35
  pressureIterations: 1,
@@ -43,8 +43,8 @@ const CC = {
43
43
  glowColor: "#b3d9ff",
44
44
  algorithm: "aurora",
45
45
  warpStrength: 0.04
46
- }, EI = {
47
- ...CC,
46
+ }, jI = {
47
+ ...eC,
48
48
  densityDissipation: 0.9,
49
49
  velocityDissipation: 0.9,
50
50
  pressureIterations: 3,
@@ -59,22 +59,22 @@ const CC = {
59
59
  }, gI = {
60
60
  dpr: typeof window < "u" ? 1 / (window.devicePixelRatio || 1) : 1,
61
61
  sim: 0.5
62
- }, iC = {
62
+ }, sC = {
63
63
  backgroundColor: "#0a0a0a",
64
64
  backgroundSize: "cover",
65
65
  mouseEnabled: !0,
66
66
  workerEnabled: !0
67
- }, Gg = {
68
- ...iC,
67
+ }, rg = {
68
+ ...sC,
69
69
  effect: 0,
70
70
  imageSize: "cover"
71
71
  }, mg = {
72
- ...iC,
72
+ ...sC,
73
73
  fontSize: 100,
74
74
  color: "#ffffff",
75
75
  fontFamily: "sans-serif",
76
76
  fontWeight: 900
77
- }, pC = {
77
+ }, nC = {
78
78
  calm: {
79
79
  densityDissipation: 0.98,
80
80
  velocityDissipation: 0.81,
@@ -133,7 +133,7 @@ const CC = {
133
133
  waterColor: "#0f0f0f"
134
134
  }
135
135
  };
136
- function bI(e) {
136
+ function wI(e) {
137
137
  if (Array.isArray(e))
138
138
  return e;
139
139
  const g = e.slice(1, 7);
@@ -147,88 +147,88 @@ function bI(e) {
147
147
  parseInt(g.slice(4, 6), 16) / 255
148
148
  ];
149
149
  }
150
- function uI(e = {}, g, C = CC) {
151
- return { ...g ? { ...C, ...pC[g] } : C, ...e };
150
+ function ZI(e = {}, g, C = eC) {
151
+ return { ...g ? { ...C, ...nC[g] } : C, ...e };
152
152
  }
153
153
  function II(e, g, C, i, s = "cover") {
154
- let l;
155
- s === "cover" ? l = Math.max(C / e, i / g) : s === "contain" ? l = Math.min(C / e, i / g) : typeof s == "string" && s.endsWith("%") ? l = Math.min(C / e, i / g) * (parseFloat(s) / 100) : typeof s == "string" && s.endsWith("px") ? l = parseFloat(s) / Math.max(e, g) : typeof s == "number" ? l = s : l = Math.max(C / e, i / g);
156
- const t = e * l, S = g * l;
157
- return { x: (C - t) / 2, y: (i - S) / 2, drawW: t, drawH: S };
154
+ let t;
155
+ s === "cover" ? t = Math.max(C / e, i / g) : s === "contain" ? t = Math.min(C / e, i / g) : typeof s == "string" && s.endsWith("%") ? t = Math.min(C / e, i / g) * (parseFloat(s) / 100) : typeof s == "string" && s.endsWith("px") ? t = parseFloat(s) / Math.max(e, g) : typeof s == "number" ? t = s : t = Math.max(C / e, i / g);
156
+ const l = e * t, u = g * t;
157
+ return { x: (C - l) / 2, y: (i - u) / 2, drawW: l, drawH: u };
158
158
  }
159
- function ZC(e, g, C, i, s = null, l = "cover") {
160
- const { text: t, fontSize: S, color: u, fontFamily: c = "sans-serif", fontWeight: p = 900 } = i, a = new OffscreenCanvas(g, C), A = a.getContext("2d");
161
- ((b) => {
159
+ function rC(e, g, C, i, s = null, t = "cover") {
160
+ const { text: l, fontSize: u, color: Z, fontFamily: d = "sans-serif", fontWeight: S = 900 } = i, a = new OffscreenCanvas(g, C), c = a.getContext("2d");
161
+ ((w) => {
162
162
  if (s) {
163
- A.clearRect(0, 0, g, C), A.fillStyle = "black", A.fillRect(0, 0, g, C);
164
- const { x: B, y: K, drawW: W, drawH: x } = II(
163
+ c.clearRect(0, 0, g, C), c.fillStyle = "black", c.fillRect(0, 0, g, C);
164
+ const { x: n, y, drawW: v, drawH: Y } = II(
165
165
  s.width,
166
166
  s.height,
167
167
  g,
168
168
  C,
169
- l
169
+ t
170
170
  );
171
- A.drawImage(s, B, K, W, x);
171
+ c.drawImage(s, n, y, v, Y);
172
172
  } else
173
- A.fillStyle = "black", A.fillRect(0, 0, g, C);
174
- A.fillStyle = b, A.font = `${p} ${S}px ${c}`, A.textAlign = "center", A.textBaseline = "middle", A.fillText(t, g / 2, C / 2);
175
- })(u);
176
- const Z = SI(e, a);
177
- A.fillStyle = "black", A.fillRect(0, 0, g, C), A.fillStyle = "white", A.font = `${p} ${S}px ${c}`, A.textAlign = "center", A.textBaseline = "middle", A.fillText(t, g / 2, C / 2);
178
- const r = SI(e, a);
179
- return { backgroundTex: Z, obstacleTex: r, coverageTex: r };
173
+ c.fillStyle = "black", c.fillRect(0, 0, g, C);
174
+ c.fillStyle = w, c.font = `${S} ${u}px ${d}`, c.textAlign = "center", c.textBaseline = "middle", c.fillText(l, g / 2, C / 2);
175
+ })(Z);
176
+ const B = uI(e, a);
177
+ c.fillStyle = "black", c.fillRect(0, 0, g, C), c.fillStyle = "white", c.font = `${S} ${u}px ${d}`, c.textAlign = "center", c.textBaseline = "middle", c.fillText(l, g / 2, C / 2);
178
+ const r = uI(e, a);
179
+ return { backgroundTex: B, obstacleTex: r, coverageTex: r };
180
180
  }
181
- function BC(e, g, C, i, s = 0, l = "cover", t = null, S = "cover") {
182
- const u = new OffscreenCanvas(C, i), c = u.getContext("2d"), { x: p, y: a, drawW: A, drawH: m } = II(g.width, g.height, C, i, l);
183
- if (c.clearRect(0, 0, C, i), c.fillStyle = "black", c.fillRect(0, 0, C, i), t) {
181
+ function GC(e, g, C, i, s = 0, t = "cover", l = null, u = "cover") {
182
+ const Z = new OffscreenCanvas(C, i), d = Z.getContext("2d"), { x: S, y: a, drawW: c, drawH: m } = II(g.width, g.height, C, i, t);
183
+ if (d.clearRect(0, 0, C, i), d.fillStyle = "black", d.fillRect(0, 0, C, i), l) {
184
184
  const {
185
- x: B,
186
- y: K,
187
- drawW: W,
188
- drawH: x
189
- } = II(t.width, t.height, C, i, S);
190
- c.filter = `brightness(${s}) blur(8px)`, c.drawImage(t, B, K, W, x), c.filter = "none";
185
+ x: n,
186
+ y,
187
+ drawW: v,
188
+ drawH: Y
189
+ } = II(l.width, l.height, C, i, u);
190
+ d.filter = `brightness(${s}) blur(8px)`, d.drawImage(l, n, y, v, Y), d.filter = "none";
191
191
  }
192
- c.drawImage(g, p, a, A, m);
193
- const Z = SI(e, u);
194
- c.clearRect(0, 0, C, i), c.fillStyle = "black", c.fillRect(0, 0, C, i), c.filter = `brightness(${s}) blur(8px)`, c.drawImage(g, p, a, A, m), c.filter = "none";
195
- const r = SI(e, u);
196
- c.clearRect(0, 0, C, i), c.fillStyle = "black", c.fillRect(0, 0, C, i), c.fillStyle = "white", c.fillRect(
197
- Math.max(0, p),
192
+ d.drawImage(g, S, a, c, m);
193
+ const B = uI(e, Z);
194
+ d.clearRect(0, 0, C, i), d.fillStyle = "black", d.fillRect(0, 0, C, i), d.filter = `brightness(${s}) blur(8px)`, d.drawImage(g, S, a, c, m), d.filter = "none";
195
+ const r = uI(e, Z);
196
+ d.clearRect(0, 0, C, i), d.fillStyle = "black", d.fillRect(0, 0, C, i), d.fillStyle = "white", d.fillRect(
197
+ Math.max(0, S),
198
198
  Math.max(0, a),
199
- Math.min(A, C - Math.max(0, p)),
199
+ Math.min(c, C - Math.max(0, S)),
200
200
  Math.min(m, i - Math.max(0, a))
201
201
  );
202
- const b = SI(e, u);
203
- return { backgroundTex: Z, obstacleTex: r, coverageTex: b };
202
+ const w = uI(e, Z);
203
+ return { backgroundTex: B, obstacleTex: r, coverageTex: w };
204
204
  }
205
- function SI(e, g) {
205
+ function uI(e, g) {
206
206
  const C = e.createTexture();
207
207
  return e.bindTexture(e.TEXTURE_2D, C), e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL, !0), e.texImage2D(e.TEXTURE_2D, 0, e.RGBA, e.RGBA, e.UNSIGNED_BYTE, g), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_S, e.CLAMP_TO_EDGE), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_T, e.CLAMP_TO_EDGE), C;
208
208
  }
209
- function GC(e, g, C, i, s = null, l = "cover") {
210
- const { text: t, fontSize: S, color: u, fontFamily: c = "sans-serif", fontWeight: p = 900 } = i, a = new OffscreenCanvas(g, C), A = a.getContext("2d");
211
- ((b) => {
209
+ function pC(e, g, C, i, s = null, t = "cover") {
210
+ const { text: l, fontSize: u, color: Z, fontFamily: d = "sans-serif", fontWeight: S = 900 } = i, a = new OffscreenCanvas(g, C), c = a.getContext("2d");
211
+ ((w) => {
212
212
  if (s) {
213
- A.clearRect(0, 0, g, C), A.fillStyle = "black", A.fillRect(0, 0, g, C);
214
- const { x: B, y: K, drawW: W, drawH: x } = II(
213
+ c.clearRect(0, 0, g, C), c.fillStyle = "black", c.fillRect(0, 0, g, C);
214
+ const { x: n, y, drawW: v, drawH: Y } = II(
215
215
  s.width,
216
216
  s.height,
217
217
  g,
218
218
  C,
219
- l
219
+ t
220
220
  );
221
- A.drawImage(s, B, K, W, x);
221
+ c.drawImage(s, n, y, v, Y);
222
222
  } else
223
- A.fillStyle = "black", A.fillRect(0, 0, g, C);
224
- A.fillStyle = b, A.font = `${p} ${S}px ${c}`, A.textAlign = "center", A.textBaseline = "middle", A.fillText(t, g / 2, C / 2);
225
- })(u);
226
- const Z = aI(e, a, g, C);
227
- A.fillStyle = "black", A.fillRect(0, 0, g, C), A.fillStyle = "white", A.font = `${p} ${S}px ${c}`, A.textAlign = "center", A.textBaseline = "middle", A.fillText(t, g / 2, C / 2);
223
+ c.fillStyle = "black", c.fillRect(0, 0, g, C);
224
+ c.fillStyle = w, c.font = `${S} ${u}px ${d}`, c.textAlign = "center", c.textBaseline = "middle", c.fillText(l, g / 2, C / 2);
225
+ })(Z);
226
+ const B = aI(e, a, g, C);
227
+ c.fillStyle = "black", c.fillRect(0, 0, g, C), c.fillStyle = "white", c.font = `${S} ${u}px ${d}`, c.textAlign = "center", c.textBaseline = "middle", c.fillText(l, g / 2, C / 2);
228
228
  const r = aI(e, a, g, C);
229
229
  return {
230
- backgroundTex: Z,
231
- backgroundView: Z.createView(),
230
+ backgroundTex: B,
231
+ backgroundView: B.createView(),
232
232
  obstacleTex: r,
233
233
  obstacleView: r.createView(),
234
234
  coverageTex: r,
@@ -236,31 +236,31 @@ function GC(e, g, C, i, s = null, l = "cover") {
236
236
  sharedCoverage: !0
237
237
  };
238
238
  }
239
- function rC(e, g, C, i, s = 0, l = "cover", t = null, S = "cover") {
240
- const u = new OffscreenCanvas(C, i), c = u.getContext("2d"), { x: p, y: a, drawW: A, drawH: m } = II(g.width, g.height, C, i, l);
241
- if (c.clearRect(0, 0, C, i), c.fillStyle = "black", c.fillRect(0, 0, C, i), t) {
242
- const { x: B, y: K, drawW: W, drawH: x } = II(
243
- t.width,
244
- t.height,
239
+ function LC(e, g, C, i, s = 0, t = "cover", l = null, u = "cover") {
240
+ const Z = new OffscreenCanvas(C, i), d = Z.getContext("2d"), { x: S, y: a, drawW: c, drawH: m } = II(g.width, g.height, C, i, t);
241
+ if (d.clearRect(0, 0, C, i), d.fillStyle = "black", d.fillRect(0, 0, C, i), l) {
242
+ const { x: n, y, drawW: v, drawH: Y } = II(
243
+ l.width,
244
+ l.height,
245
245
  C,
246
246
  i,
247
- S
247
+ u
248
248
  );
249
- c.filter = `brightness(${s}) blur(8px)`, c.drawImage(t, B, K, W, x), c.filter = "none";
249
+ d.filter = `brightness(${s}) blur(8px)`, d.drawImage(l, n, y, v, Y), d.filter = "none";
250
250
  }
251
- c.drawImage(g, p, a, A, m);
252
- const Z = aI(e, u, C, i);
253
- c.clearRect(0, 0, C, i), c.fillStyle = "black", c.fillRect(0, 0, C, i), c.filter = `brightness(${s}) blur(8px)`, c.drawImage(g, p, a, A, m), c.filter = "none";
254
- const r = aI(e, u, C, i);
255
- c.clearRect(0, 0, C, i), c.fillStyle = "black", c.fillRect(0, 0, C, i), c.fillStyle = "white", c.fillRect(Math.max(0, p), Math.max(0, a), Math.min(A, C - Math.max(0, p)), Math.min(m, i - Math.max(0, a)));
256
- const b = aI(e, u, C, i);
251
+ d.drawImage(g, S, a, c, m);
252
+ const B = aI(e, Z, C, i);
253
+ d.clearRect(0, 0, C, i), d.fillStyle = "black", d.fillRect(0, 0, C, i), d.filter = `brightness(${s}) blur(8px)`, d.drawImage(g, S, a, c, m), d.filter = "none";
254
+ const r = aI(e, Z, C, i);
255
+ d.clearRect(0, 0, C, i), d.fillStyle = "black", d.fillRect(0, 0, C, i), d.fillStyle = "white", d.fillRect(Math.max(0, S), Math.max(0, a), Math.min(c, C - Math.max(0, S)), Math.min(m, i - Math.max(0, a)));
256
+ const w = aI(e, Z, C, i);
257
257
  return {
258
- backgroundTex: Z,
259
- backgroundView: Z.createView(),
258
+ backgroundTex: B,
259
+ backgroundView: B.createView(),
260
260
  obstacleTex: r,
261
261
  obstacleView: r.createView(),
262
- coverageTex: b,
263
- coverageView: b.createView(),
262
+ coverageTex: w,
263
+ coverageView: w.createView(),
264
264
  sharedCoverage: !1
265
265
  };
266
266
  }
@@ -276,281 +276,199 @@ function aI(e, g, C, i) {
276
276
  [C, i]
277
277
  ), s;
278
278
  }
279
- async function zI(e) {
279
+ async function NI(e) {
280
280
  const g = await fetch(e);
281
281
  if (!g.ok)
282
282
  throw new Error(`Failed to fetch image: ${e} (${g.status})`);
283
283
  const C = await g.blob();
284
284
  return createImageBitmap(C);
285
285
  }
286
- const pg = (
287
- /* glsl */
288
- `
289
- precision highp float;
290
- attribute vec2 aPosition;
291
- varying vec2 vUv;
292
- varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;
293
- uniform vec2 texelSize;
294
- void main () {
295
- vUv = aPosition * 0.5 + 0.5;
296
- vL = vUv - vec2(texelSize.x, 0.0);
297
- vR = vUv + vec2(texelSize.x, 0.0);
298
- vT = vUv + vec2(0.0, texelSize.y);
299
- vB = vUv - vec2(0.0, texelSize.y);
300
- gl_Position = vec4(aPosition, 0.0, 1.0);
301
- }
302
- `
303
- ), nC = (
304
- /* glsl */
305
- `
306
- precision highp float;
307
- varying vec2 vUv;
308
- uniform sampler2D uVelocity;
309
- uniform sampler2D uSource;
310
- uniform sampler2D uObstacle;
311
- uniform vec2 texelSize;
312
- uniform float dt;
313
- uniform float dissipation;
314
- void main () {
315
- float obs = texture2D(uObstacle, vUv).r;
316
- vec2 coord = vUv - dt * texture2D(uVelocity, vUv).xy * texelSize;
317
- // Smooth damping: obs=0 outside (full flow), obs=1 inside (full stop), blurred
318
- // boundary in between. No branching — multiplying by (1-obs) is equivalent to the
319
- // hard zero-inside check but with a continuous gradient that avoids grid artefacts.
320
- gl_FragColor = dissipation * texture2D(uSource, coord) * (1.0 - obs);
321
- }
322
- `
323
- ), bC = (
324
- /* glsl */
325
- `
326
- precision highp float;
327
- varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;
328
- uniform sampler2D uVelocity;
329
- uniform sampler2D uObstacle;
330
- void main () {
331
- float L = texture2D(uVelocity, vL).x * (1.0 - texture2D(uObstacle, vL).r);
332
- float R = texture2D(uVelocity, vR).x * (1.0 - texture2D(uObstacle, vR).r);
333
- float T = texture2D(uVelocity, vT).y * (1.0 - texture2D(uObstacle, vT).r);
334
- float B = texture2D(uVelocity, vB).y * (1.0 - texture2D(uObstacle, vB).r);
335
- gl_FragColor = vec4(0.5 * (R - L + T - B), 0.0, 0.0, 1.0);
336
- }
337
- `
338
- ), wC = (
339
- /* glsl */
340
- `
341
- precision highp float;
342
- varying vec2 vUv; varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;
343
- uniform sampler2D uPressure;
344
- uniform sampler2D uDivergence;
345
- uniform sampler2D uObstacle;
346
- void main () {
347
- float C = texture2D(uPressure, vUv).x;
348
- float L = mix(texture2D(uPressure, vL).x, C, texture2D(uObstacle, vL).r);
349
- float R = mix(texture2D(uPressure, vR).x, C, texture2D(uObstacle, vR).r);
350
- float T = mix(texture2D(uPressure, vT).x, C, texture2D(uObstacle, vT).r);
351
- float B = mix(texture2D(uPressure, vB).x, C, texture2D(uObstacle, vB).r);
352
- float div = texture2D(uDivergence, vUv).x;
353
- gl_FragColor = vec4((L + R + B + T - div) * 0.25, 0.0, 0.0, 1.0);
354
- }
355
- `
356
- ), LC = (
357
- /* glsl */
358
- `
359
- precision highp float;
360
- varying vec2 vUv; varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;
361
- uniform sampler2D uPressure;
362
- uniform sampler2D uVelocity;
363
- uniform sampler2D uObstacle;
364
- void main () {
365
- float obs = texture2D(uObstacle, vUv).r;
366
- float C = texture2D(uPressure, vUv).x;
367
- float L = mix(texture2D(uPressure, vL).x, C, texture2D(uObstacle, vL).r);
368
- float R = mix(texture2D(uPressure, vR).x, C, texture2D(uObstacle, vR).r);
369
- float T = mix(texture2D(uPressure, vT).x, C, texture2D(uObstacle, vT).r);
370
- float B = mix(texture2D(uPressure, vB).x, C, texture2D(uObstacle, vB).r);
371
- vec2 vel = (texture2D(uVelocity, vUv).xy - vec2(R - L, T - B)) * (1.0 - obs);
372
- gl_FragColor = vec4(vel, 0.0, 1.0);
373
- }
374
- `
375
- ), hC = (
376
- /* glsl */
377
- `
378
- precision highp float;
379
- varying vec2 vUv;
380
- uniform sampler2D uTarget;
381
- uniform float aspectRatio;
382
- uniform vec3 color;
383
- uniform vec2 point;
384
- uniform float radius;
385
- void main () {
386
- vec2 p = vUv - point.xy;
387
- p.x *= aspectRatio;
388
- vec3 splat = exp(-dot(p, p) / radius) * color;
389
- gl_FragColor = vec4(texture2D(uTarget, vUv).xyz + splat, 1.0);
390
- }
391
- `
392
- ), KC = (
393
- /* glsl */
394
- `
395
- precision highp float;
396
- varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;
397
- uniform sampler2D uVelocity;
398
- void main () {
399
- float L = texture2D(uVelocity, vL).y;
400
- float R = texture2D(uVelocity, vR).y;
401
- float T = texture2D(uVelocity, vT).x;
402
- float B = texture2D(uVelocity, vB).x;
403
- gl_FragColor = vec4(0.5 * (R - L - T + B), 0.0, 0.0, 1.0);
404
- }
405
- `
406
- ), yC = (
407
- /* glsl */
408
- `
409
- precision highp float;
410
- varying vec2 vUv; varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;
411
- uniform sampler2D uVelocity;
412
- uniform sampler2D uCurl;
413
- uniform float curl;
414
- uniform float dt;
415
- void main () {
416
- float L = texture2D(uCurl, vL).x;
417
- float R = texture2D(uCurl, vR).x;
418
- float T = texture2D(uCurl, vT).x;
419
- float B = texture2D(uCurl, vB).x;
420
- float C = texture2D(uCurl, vUv).x;
421
- vec2 force = 0.5 * vec2(abs(T) - abs(B), abs(R) - abs(L));
422
- force /= length(force) + 0.0001;
423
- force *= curl * 30.0 * C;
424
- gl_FragColor = vec4(texture2D(uVelocity, vUv).xy + force * dt, 0.0, 1.0);
425
- }
426
- `
427
- ), VC = (
428
- /* glsl */
429
- `
430
- precision highp float;
431
- varying vec2 vUv;
432
-
433
- uniform sampler2D uTexture;
434
- uniform sampler2D uObstacle;
435
- uniform sampler2D uBackground;
436
- uniform sampler2D uCoverage;
437
- uniform sampler2D uVelocity;
438
-
439
- uniform vec2 texelSize;
440
- uniform vec3 uWaterColor;
441
- uniform vec3 uGlowColor;
442
- uniform float uRefraction;
443
- uniform float uSpecularExp;
444
- uniform float uShine;
445
- uniform float uWarpStrength;
446
- uniform int uAlgorithm;
447
- uniform int uEnableAlpha;
448
-
449
- void main () {
450
- float obs = texture2D(uObstacle, vUv).r;
451
- // Smooth fade: density falls off over the blurred obstacle boundary zone
452
- // rather than cutting off at a hard step, eliminating the jagged fringe.
453
- float density = max(texture2D(uTexture, vUv).r, 0.0) * (1.0 - obs);
454
- float coverage = texture2D(uCoverage, vUv).r;
455
-
456
- // 8-tap Sobel normal — computes gradient via 3×3 kernel (no centre sample needed).
457
- // texelSize = 1/displayRes; density FBO is at simScale (0.5×), so s=6 display px
458
- // ≈ 3 sim texels per axis. The Sobel kernel properly averages the gradient in
459
- // every direction no 4-tap cross bias that creates 45° circuit-board artefacts.
460
- float sx = texelSize.x * 6.0, sy = texelSize.y * 6.0;
461
- float d00 = max(texture2D(uTexture, vUv + vec2(-sx, -sy)).r, 0.0);
462
- float d10 = max(texture2D(uTexture, vUv + vec2(0.0, -sy)).r, 0.0);
463
- float d20 = max(texture2D(uTexture, vUv + vec2( sx, -sy)).r, 0.0);
464
- float d01 = max(texture2D(uTexture, vUv + vec2(-sx, 0.0)).r, 0.0);
465
- float d21 = max(texture2D(uTexture, vUv + vec2( sx, 0.0)).r, 0.0);
466
- float d02 = max(texture2D(uTexture, vUv + vec2(-sx, sy)).r, 0.0);
467
- float d12 = max(texture2D(uTexture, vUv + vec2(0.0, sy)).r, 0.0);
468
- float d22 = max(texture2D(uTexture, vUv + vec2( sx, sy)).r, 0.0);
469
- float gx = (d20 + 2.0*d21 + d22) - (d00 + 2.0*d01 + d02);
470
- float gy = (d02 + 2.0*d12 + d22) - (d00 + 2.0*d10 + d20);
471
-
472
- vec3 normal = normalize(vec3(gx, gy, 1.2));
473
- vec3 lightDir = normalize(vec3(0.5, 1.0, 0.5));
474
- vec3 halfV = normalize(lightDir + vec3(0.0, 0.0, 1.0));
475
- // Suppress specular at low / fading density — prevents highlight rings from
476
- // appearing at the dissipating edge of a stroke as its density approaches zero.
477
- float specDen = density * min(density * 5.0, 1.0);
478
- float spec = pow(max(dot(normal, halfV), 0.0), uSpecularExp) * uShine * specDen;
479
-
480
- // In transparent (non-coverage) areas the background texture is empty black canvas.
481
- // Replace it with uWaterColor so fluid colour is not contaminated by that black,
482
- // allowing the CSS backgroundColor to show through correctly via premultiplied alpha.
483
- vec3 bgRaw = texture2D(uBackground, vUv).rgb;
484
- vec3 bg = mix(uWaterColor, bgRaw, coverage);
485
- vec3 color = bg;
486
-
487
- if (uAlgorithm == 1) {
488
- // ── glass ──────────────────────────────────────────────────────────────
489
- // Strong UV distortion only. Image bends but no colour overlay.
490
- vec2 refrUv = clamp(vUv + normal.xy * uRefraction * density * 3.0, 0.0, 1.0);
491
- vec3 refrBg = mix(uWaterColor, texture2D(uBackground, mix(vUv, refrUv, 1.0 - obs)).rgb, coverage);
492
- color = refrBg + spec * uGlowColor * 2.5;
493
- color = mix(color, bg * 0.6, obs * 0.3);
494
-
495
- } else if (uAlgorithm == 2) {
496
- // ── ink ────────────────────────────────────────────────────────────────
497
- // Dense opaque pigment that stains. Subtle refraction underneath.
498
- float inkD = min(density * 4.0, 1.0);
499
- vec2 refrUv = clamp(vUv + normal.xy * uRefraction * density * 0.4, 0.0, 1.0);
500
- vec3 refrBg = mix(uWaterColor, texture2D(uBackground, mix(vUv, refrUv, 1.0 - obs)).rgb, coverage);
501
- color = mix(refrBg, uWaterColor + spec * uGlowColor, inkD);
502
- color = mix(color, bg * 0.5, obs * 0.15);
503
-
504
- } else if (uAlgorithm == 3) {
505
- // ── aurora ─────────────────────────────────────────────────────────────
506
- // Velocity field warps background UVs — liquid metal / lava-lamp feel.
507
- vec2 vel = texture2D(uVelocity, vUv).xy;
508
- float velMag = clamp(length(vel) * 20.0, 0.0, 1.0);
509
- vec2 warpUv = clamp(vUv + vel * uWarpStrength, 0.0, 1.0);
510
- vec3 warpBg = mix(uWaterColor, texture2D(uBackground, warpUv).rgb, coverage);
511
- color = mix(bg, warpBg, velMag * (1.0 - obs));
512
- color += spec * uGlowColor * velMag * 1.5;
513
- color += uWaterColor * density * 0.3;
514
- color = mix(color, bg * 0.5, obs * 0.2);
515
-
516
- } else if (uAlgorithm == 4) {
517
- // ── ripple ─────────────────────────────────────────────────────────────
518
- // Exaggerated normal perturbation + Fresnel rim — calm water surface.
519
- vec2 rippleUv = clamp(vUv + normal.xy * uRefraction * density * 6.0, 0.0, 1.0);
520
- vec3 refrBg = mix(uWaterColor, texture2D(uBackground, mix(vUv, rippleUv, 1.0 - obs)).rgb, coverage);
521
- float fresnel = pow(clamp(1.0 - dot(normal, vec3(0.0, 0.0, 1.0)), 0.0, 1.0), 3.0) * density;
522
- color = refrBg;
523
- color += fresnel * uGlowColor * 2.0;
524
- color += spec * uGlowColor * density * 2.0;
525
- color = mix(color, bg * 0.5, obs * 0.2);
526
-
527
- } else {
528
- // ── standard (0) ───────────────────────────────────────────────────────
529
- // Original: colour overlay blended over refracted background.
530
- vec2 refrUv = vUv + normal.xy * uRefraction * density;
531
- vec3 refrBg = mix(uWaterColor, texture2D(uBackground, mix(vUv, refrUv, 1.0 - obs)).rgb, coverage);
532
- color = mix(refrBg, uWaterColor, min(density * 1.5, 0.8));
533
- color += spec * uGlowColor;
534
- color = mix(color, bg * 0.5, obs * 0.2);
535
- }
536
-
537
- // Output: premultiplied alpha when transparency is enabled (lets CSS backgroundColor
538
- // show through), or straight opaque colour when enableAlpha is off (perf mode).
539
- float alpha = clamp(max(density * 1.5, coverage), 0.0, 1.0);
540
- if (uEnableAlpha == 1) {
541
- gl_FragColor = vec4(color * alpha, alpha);
542
- } else {
543
- gl_FragColor = vec4(color, 1.0);
544
- }
545
- }
546
- `
547
- );
548
- function HC(e, g = !0) {
286
+ const yI = () => {
287
+ }, Sg = `precision highp float;
288
+ attribute vec2 aPosition;
289
+ varying vec2 vUv;
290
+ varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;
291
+ uniform vec2 texelSize;
292
+ void main () {
293
+ vUv = aPosition * 0.5 + 0.5;
294
+ vL = vUv - vec2(texelSize.x, 0.0);
295
+ vR = vUv + vec2(texelSize.x, 0.0);
296
+ vT = vUv + vec2(0.0, texelSize.y);
297
+ vB = vUv - vec2(0.0, texelSize.y);
298
+ gl_Position = vec4(aPosition, 0.0, 1.0);
299
+ }`, wC = `precision highp float;
300
+ varying vec2 vUv;
301
+ uniform sampler2D uVelocity;
302
+ uniform sampler2D uSource;
303
+ uniform sampler2D uObstacle;
304
+ uniform vec2 texelSize;
305
+ uniform float dt;
306
+ uniform float dissipation;
307
+ void main () {
308
+ float obs = texture2D(uObstacle, vUv).r;
309
+ vec2 coord = vUv - dt * texture2D(uVelocity, vUv).xy * texelSize;
310
+ gl_FragColor = dissipation * texture2D(uSource, coord) * (1.0 - obs);
311
+ }`, hC = `precision highp float;
312
+ varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;
313
+ uniform sampler2D uVelocity;
314
+ uniform sampler2D uObstacle;
315
+ void main () {
316
+ float L = texture2D(uVelocity, vL).x * (1.0 - texture2D(uObstacle, vL).r);
317
+ float R = texture2D(uVelocity, vR).x * (1.0 - texture2D(uObstacle, vR).r);
318
+ float T = texture2D(uVelocity, vT).y * (1.0 - texture2D(uObstacle, vT).r);
319
+ float B = texture2D(uVelocity, vB).y * (1.0 - texture2D(uObstacle, vB).r);
320
+ gl_FragColor = vec4(0.5 * (R - L + T - B), 0.0, 0.0, 1.0);
321
+ }`, bC = `precision highp float;
322
+ varying vec2 vUv; varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;
323
+ uniform sampler2D uPressure;
324
+ uniform sampler2D uDivergence;
325
+ uniform sampler2D uObstacle;
326
+ void main () {
327
+ float C = texture2D(uPressure, vUv).x;
328
+ float L = mix(texture2D(uPressure, vL).x, C, texture2D(uObstacle, vL).r);
329
+ float R = mix(texture2D(uPressure, vR).x, C, texture2D(uObstacle, vR).r);
330
+ float T = mix(texture2D(uPressure, vT).x, C, texture2D(uObstacle, vT).r);
331
+ float B = mix(texture2D(uPressure, vB).x, C, texture2D(uObstacle, vB).r);
332
+ float div = texture2D(uDivergence, vUv).x;
333
+ gl_FragColor = vec4((L + R + B + T - div) * 0.25, 0.0, 0.0, 1.0);
334
+ }`, yC = `precision highp float;
335
+ varying vec2 vUv; varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;
336
+ uniform sampler2D uPressure;
337
+ uniform sampler2D uVelocity;
338
+ uniform sampler2D uObstacle;
339
+ void main () {
340
+ float obs = texture2D(uObstacle, vUv).r;
341
+ float C = texture2D(uPressure, vUv).x;
342
+ float L = mix(texture2D(uPressure, vL).x, C, texture2D(uObstacle, vL).r);
343
+ float R = mix(texture2D(uPressure, vR).x, C, texture2D(uObstacle, vR).r);
344
+ float T = mix(texture2D(uPressure, vT).x, C, texture2D(uObstacle, vT).r);
345
+ float B = mix(texture2D(uPressure, vB).x, C, texture2D(uObstacle, vB).r);
346
+ vec2 vel = (texture2D(uVelocity, vUv).xy - vec2(R - L, T - B)) * (1.0 - obs);
347
+ gl_FragColor = vec4(vel, 0.0, 1.0);
348
+ }`, VC = `precision highp float;
349
+ varying vec2 vUv;
350
+ uniform sampler2D uTarget;
351
+ uniform float aspectRatio;
352
+ uniform vec3 color;
353
+ uniform vec2 point;
354
+ uniform float radius;
355
+ void main () {
356
+ vec2 p = vUv - point.xy;
357
+ p.x *= aspectRatio;
358
+ vec3 splat = exp(-dot(p, p) / radius) * color;
359
+ gl_FragColor = vec4(texture2D(uTarget, vUv).xyz + splat, 1.0);
360
+ }`, KC = `precision highp float;
361
+ varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;
362
+ uniform sampler2D uVelocity;
363
+ void main () {
364
+ float L = texture2D(uVelocity, vL).y;
365
+ float R = texture2D(uVelocity, vR).y;
366
+ float T = texture2D(uVelocity, vT).x;
367
+ float B = texture2D(uVelocity, vB).x;
368
+ gl_FragColor = vec4(0.5 * (R - L - T + B), 0.0, 0.0, 1.0);
369
+ }`, XC = `precision highp float;
370
+ varying vec2 vUv; varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;
371
+ uniform sampler2D uVelocity;
372
+ uniform sampler2D uCurl;
373
+ uniform float curl;
374
+ uniform float dt;
375
+ void main () {
376
+ float L = texture2D(uCurl, vL).x;
377
+ float R = texture2D(uCurl, vR).x;
378
+ float T = texture2D(uCurl, vT).x;
379
+ float B = texture2D(uCurl, vB).x;
380
+ float C = texture2D(uCurl, vUv).x;
381
+ vec2 force = 0.5 * vec2(abs(T) - abs(B), abs(R) - abs(L));
382
+ force /= length(force) + 0.0001;
383
+ force *= curl * 30.0 * C;
384
+ gl_FragColor = vec4(texture2D(uVelocity, vUv).xy + force * dt, 0.0, 1.0);
385
+ }`, HC = `precision highp float;
386
+ varying vec2 vUv;
387
+ uniform sampler2D uTexture;
388
+ uniform sampler2D uObstacle;
389
+ uniform sampler2D uBackground;
390
+ uniform sampler2D uCoverage;
391
+ uniform sampler2D uVelocity;
392
+ uniform vec2 texelSize;
393
+ uniform vec3 uWaterColor;
394
+ uniform vec3 uGlowColor;
395
+ uniform float uRefraction;
396
+ uniform float uSpecularExp;
397
+ uniform float uShine;
398
+ uniform float uWarpStrength;
399
+ uniform int uAlgorithm;
400
+ uniform int uEnableAlpha;
401
+ void main () {
402
+ float obs = texture2D(uObstacle, vUv).r;
403
+ float density = max(texture2D(uTexture, vUv).r, 0.0) * (1.0 - obs);
404
+ float coverage = texture2D(uCoverage, vUv).r;
405
+ float sx = texelSize.x * 6.0, sy = texelSize.y * 6.0;
406
+ float d00 = max(texture2D(uTexture, vUv + vec2(-sx, -sy)).r, 0.0);
407
+ float d10 = max(texture2D(uTexture, vUv + vec2(0.0, -sy)).r, 0.0);
408
+ float d20 = max(texture2D(uTexture, vUv + vec2( sx, -sy)).r, 0.0);
409
+ float d01 = max(texture2D(uTexture, vUv + vec2(-sx, 0.0)).r, 0.0);
410
+ float d21 = max(texture2D(uTexture, vUv + vec2( sx, 0.0)).r, 0.0);
411
+ float d02 = max(texture2D(uTexture, vUv + vec2(-sx, sy)).r, 0.0);
412
+ float d12 = max(texture2D(uTexture, vUv + vec2(0.0, sy)).r, 0.0);
413
+ float d22 = max(texture2D(uTexture, vUv + vec2( sx, sy)).r, 0.0);
414
+ float gx = (d20 + 2.0*d21 + d22) - (d00 + 2.0*d01 + d02);
415
+ float gy = (d02 + 2.0*d12 + d22) - (d00 + 2.0*d10 + d20);
416
+ vec3 normal = normalize(vec3(gx, gy, 1.2));
417
+ vec3 lightDir = normalize(vec3(0.5, 1.0, 0.5));
418
+ vec3 halfV = normalize(lightDir + vec3(0.0, 0.0, 1.0));
419
+ float specDen = density * min(density * 5.0, 1.0);
420
+ float spec = pow(max(dot(normal, halfV), 0.0), uSpecularExp) * uShine * specDen;
421
+ vec3 bgRaw = texture2D(uBackground, vUv).rgb;
422
+ vec3 bg = mix(uWaterColor, bgRaw, coverage);
423
+ vec3 color = bg;
424
+ if (uAlgorithm == 1) {
425
+ vec2 refrUv = clamp(vUv + normal.xy * uRefraction * density * 3.0, 0.0, 1.0);
426
+ vec3 refrBg = mix(uWaterColor, texture2D(uBackground, mix(vUv, refrUv, 1.0 - obs)).rgb, coverage);
427
+ color = refrBg + spec * uGlowColor * 2.5;
428
+ color = mix(color, bg * 0.6, obs * 0.3);
429
+ } else if (uAlgorithm == 2) {
430
+ float inkD = min(density * 4.0, 1.0);
431
+ vec2 refrUv = clamp(vUv + normal.xy * uRefraction * density * 0.4, 0.0, 1.0);
432
+ vec3 refrBg = mix(uWaterColor, texture2D(uBackground, mix(vUv, refrUv, 1.0 - obs)).rgb, coverage);
433
+ color = mix(refrBg, uWaterColor + spec * uGlowColor, inkD);
434
+ color = mix(color, bg * 0.5, obs * 0.15);
435
+ } else if (uAlgorithm == 3) {
436
+ vec2 vel = texture2D(uVelocity, vUv).xy;
437
+ float velMag = clamp(length(vel) * 20.0, 0.0, 1.0);
438
+ vec2 warpUv = clamp(vUv + vel * uWarpStrength, 0.0, 1.0);
439
+ vec3 warpBg = mix(uWaterColor, texture2D(uBackground, warpUv).rgb, coverage);
440
+ color = mix(bg, warpBg, velMag * (1.0 - obs));
441
+ color += spec * uGlowColor * velMag * 1.5;
442
+ color += uWaterColor * density * 0.3;
443
+ color = mix(color, bg * 0.5, obs * 0.2);
444
+ } else if (uAlgorithm == 4) {
445
+ vec2 rippleUv = clamp(vUv + normal.xy * uRefraction * density * 6.0, 0.0, 1.0);
446
+ vec3 refrBg = mix(uWaterColor, texture2D(uBackground, mix(vUv, rippleUv, 1.0 - obs)).rgb, coverage);
447
+ float fresnel = pow(clamp(1.0 - dot(normal, vec3(0.0, 0.0, 1.0)), 0.0, 1.0), 3.0) * density;
448
+ color = refrBg;
449
+ color += fresnel * uGlowColor * 2.0;
450
+ color += spec * uGlowColor * density * 2.0;
451
+ color = mix(color, bg * 0.5, obs * 0.2);
452
+ } else {
453
+ vec2 refrUv = vUv + normal.xy * uRefraction * density;
454
+ vec3 refrBg = mix(uWaterColor, texture2D(uBackground, mix(vUv, refrUv, 1.0 - obs)).rgb, coverage);
455
+ color = mix(refrBg, uWaterColor, min(density * 1.5, 0.8));
456
+ color += spec * uGlowColor;
457
+ color = mix(color, bg * 0.5, obs * 0.2);
458
+ }
459
+ float alpha = clamp(max(density * 1.5, coverage), 0.0, 1.0);
460
+ if (uEnableAlpha == 1) {
461
+ gl_FragColor = vec4(color * alpha, alpha);
462
+ } else {
463
+ gl_FragColor = vec4(color, 1.0);
464
+ }
465
+ }`;
466
+ function vC(e, g = !0) {
549
467
  const C = { alpha: g, depth: !1, stencil: !1, antialias: !0, preserveDrawingBuffer: !1 };
550
468
  let i = e.getContext("webgl2", C);
551
469
  const s = !!i;
552
470
  s || (i = e.getContext("webgl", C), i.getExtension("EXT_color_buffer_half_float"));
553
- const l = s ? null : i.getExtension("OES_texture_half_float"), t = s ? i.HALF_FLOAT : l.HALF_FLOAT_OES;
471
+ const t = s ? null : i.getExtension("OES_texture_half_float"), l = s ? i.HALF_FLOAT : t.HALF_FLOAT_OES;
554
472
  return i.getExtension("EXT_color_buffer_float"), i.getExtension("OES_texture_half_float_linear"), {
555
473
  type: s ? "webgl2" : "webgl1",
556
474
  gl: i,
@@ -558,11 +476,11 @@ function HC(e, g = !0) {
558
476
  ext: {
559
477
  internalFormat: s ? i.RGBA16F : i.RGBA,
560
478
  format: i.RGBA,
561
- type: t
479
+ type: l
562
480
  }
563
481
  };
564
482
  }
565
- async function XC(e, g = !0) {
483
+ async function WC(e, g = !0) {
566
484
  if (typeof navigator > "u" || !navigator.gpu)
567
485
  return null;
568
486
  try {
@@ -572,22 +490,22 @@ async function XC(e, g = !0) {
572
490
  const i = await C.requestDevice(), s = e.getContext("webgpu");
573
491
  if (!s)
574
492
  return null;
575
- const l = navigator.gpu.getPreferredCanvasFormat();
576
- return s.configure({ device: i, format: l, alphaMode: g ? "premultiplied" : "opaque" }), { type: "webgpu", adapter: C, device: i, context: s, format: l };
493
+ const t = navigator.gpu.getPreferredCanvasFormat();
494
+ return s.configure({ device: i, format: t, alphaMode: g ? "premultiplied" : "opaque" }), { type: "webgpu", adapter: C, device: i, context: s, format: t };
577
495
  } catch {
578
496
  return null;
579
497
  }
580
498
  }
581
- class Zg {
499
+ class Bg {
582
500
  constructor(g, C, i) {
583
- nI(this, "program");
584
- nI(this, "uniforms", {});
585
- nI(this, "_gl");
501
+ LI(this, "program");
502
+ LI(this, "uniforms", {});
503
+ LI(this, "_gl");
586
504
  this._gl = g, this.program = g.createProgram(), g.attachShader(this.program, this._compile(g.VERTEX_SHADER, C)), g.attachShader(this.program, this._compile(g.FRAGMENT_SHADER, i)), g.linkProgram(this.program);
587
505
  const s = g.getProgramParameter(this.program, g.ACTIVE_UNIFORMS);
588
- for (let l = 0; l < s; l++) {
589
- const t = g.getActiveUniform(this.program, l).name;
590
- this.uniforms[t] = g.getUniformLocation(this.program, t);
506
+ for (let t = 0; t < s; t++) {
507
+ const l = g.getActiveUniform(this.program, t).name;
508
+ this.uniforms[l] = g.getUniformLocation(this.program, l);
591
509
  }
592
510
  }
593
511
  _compile(g, C) {
@@ -601,310 +519,245 @@ class Zg {
601
519
  this._gl.deleteProgram(this.program);
602
520
  }
603
521
  }
604
- function vC(e) {
522
+ function RC(e) {
605
523
  return {
606
- advection: new Zg(e, pg, nC),
607
- divergence: new Zg(e, pg, bC),
608
- pressure: new Zg(e, pg, wC),
609
- gradientSubtract: new Zg(e, pg, LC),
610
- splat: new Zg(e, pg, hC),
611
- curl: new Zg(e, pg, KC),
612
- vorticity: new Zg(e, pg, yC),
613
- display: new Zg(e, pg, VC)
524
+ advection: new Bg(e, Sg, wC),
525
+ divergence: new Bg(e, Sg, hC),
526
+ pressure: new Bg(e, Sg, bC),
527
+ gradientSubtract: new Bg(e, Sg, yC),
528
+ splat: new Bg(e, Sg, VC),
529
+ curl: new Bg(e, Sg, KC),
530
+ vorticity: new Bg(e, Sg, XC),
531
+ display: new Bg(e, Sg, HC)
614
532
  };
615
533
  }
616
- function hI(e, g, C, i) {
534
+ function VI(e, g, C, i) {
617
535
  e.activeTexture(e.TEXTURE0);
618
536
  const s = e.createTexture();
619
537
  e.bindTexture(e.TEXTURE_2D, s), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_S, e.CLAMP_TO_EDGE), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_T, e.CLAMP_TO_EDGE), e.texImage2D(e.TEXTURE_2D, 0, g.internalFormat, C, i, 0, g.format, g.type, null);
620
- const l = e.createFramebuffer();
621
- return e.bindFramebuffer(e.FRAMEBUFFER, l), e.framebufferTexture2D(e.FRAMEBUFFER, e.COLOR_ATTACHMENT0, e.TEXTURE_2D, s, 0), { tex: s, fbo: l, width: C, height: i };
538
+ const t = e.createFramebuffer();
539
+ return e.bindFramebuffer(e.FRAMEBUFFER, t), e.framebufferTexture2D(e.FRAMEBUFFER, e.COLOR_ATTACHMENT0, e.TEXTURE_2D, s, 0), { tex: s, fbo: t, width: C, height: i };
622
540
  }
623
- function MI(e, g, C, i) {
624
- let s = hI(e, g, C, i), l = hI(e, g, C, i);
541
+ function FI(e, g, C, i) {
542
+ let s = VI(e, g, C, i), t = VI(e, g, C, i);
625
543
  return {
626
544
  get read() {
627
545
  return s;
628
546
  },
629
547
  get write() {
630
- return l;
548
+ return t;
631
549
  },
632
550
  swap() {
633
- [s, l] = [l, s];
551
+ [s, t] = [t, s];
634
552
  },
635
553
  dispose() {
636
- e.deleteTexture(s.tex), e.deleteFramebuffer(s.fbo), e.deleteTexture(l.tex), e.deleteFramebuffer(l.fbo);
554
+ e.deleteTexture(s.tex), e.deleteFramebuffer(s.fbo), e.deleteTexture(t.tex), e.deleteFramebuffer(t.fbo);
637
555
  }
638
556
  };
639
557
  }
640
- function RC(e) {
558
+ function UC(e) {
641
559
  const g = e.createBuffer();
642
560
  return e.bindBuffer(e.ARRAY_BUFFER, g), e.bufferData(e.ARRAY_BUFFER, new Float32Array([-1, -1, -1, 1, 1, 1, 1, -1]), e.STATIC_DRAW), e.vertexAttribPointer(0, 2, e.FLOAT, !1, 0, 0), e.enableVertexAttribArray(0), function(i) {
643
561
  e.bindFramebuffer(e.FRAMEBUFFER, i), e.drawArrays(e.TRIANGLE_FAN, 0, 4);
644
562
  };
645
563
  }
646
- const Kg = (
647
- /* wgsl */
648
- `
649
- struct VSOut {
650
- @builtin(position) pos : vec4f,
651
- @location(0) uv : vec2f,
652
- @location(1) vL : vec2f,
653
- @location(2) vR : vec2f,
654
- @location(3) vT : vec2f,
655
- @location(4) vB : vec2f,
656
- }`
657
- ), WC = (
658
- /* wgsl */
659
- `
660
- ${Kg}
661
-
564
+ const yg = `struct VSOut {
565
+ @builtin(position) pos : vec4f,
566
+ @location(0) uv : vec2f,
567
+ @location(1) vL : vec2f,
568
+ @location(2) vR : vec2f,
569
+ @location(3) vT : vec2f,
570
+ @location(4) vB : vec2f,
571
+ }`, YC = `${yg}
662
572
  struct U {
663
- texelSize : vec2f,
664
- dt : f32,
665
- dissipation: f32,
573
+ texelSize : vec2f,
574
+ dt : f32,
575
+ dissipation: f32,
666
576
  }
667
577
  @group(0) @binding(0) var<uniform> u : U;
668
578
  @group(0) @binding(1) var samp : sampler;
669
579
  @group(0) @binding(2) var uVel : texture_2d<f32>;
670
580
  @group(0) @binding(3) var uSrc : texture_2d<f32>;
671
581
  @group(0) @binding(4) var uObs : texture_2d<f32>;
672
-
673
582
  @vertex fn vs(@location(0) a: vec2f) -> VSOut {
674
- var o: VSOut;
675
- o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);
676
- o.vL = o.uv - vec2f(u.texelSize.x, 0.0);
677
- o.vR = o.uv + vec2f(u.texelSize.x, 0.0);
678
- o.vT = o.uv + vec2f(0.0, u.texelSize.y);
679
- o.vB = o.uv - vec2f(0.0, u.texelSize.y);
680
- o.pos = vec4f(a, 0.0, 1.0);
681
- return o;
583
+ var o: VSOut;
584
+ o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);
585
+ o.vL = o.uv - vec2f(u.texelSize.x, 0.0);
586
+ o.vR = o.uv + vec2f(u.texelSize.x, 0.0);
587
+ o.vT = o.uv + vec2f(0.0, u.texelSize.y);
588
+ o.vB = o.uv - vec2f(0.0, u.texelSize.y);
589
+ o.pos = vec4f(a, 0.0, 1.0);
590
+ return o;
682
591
  }
683
-
684
592
  @fragment fn fs(i: VSOut) -> @location(0) vec4f {
685
- let obs = textureSample(uObs, samp, i.uv).r;
686
- let vel = textureSample(uVel, samp, i.uv).xy;
687
- let coord = i.uv - u.dt * vel * u.texelSize;
688
- let src = textureSample(uSrc, samp, coord);
689
- return u.dissipation * src * (1.0 - obs);
690
- }
691
- `
692
- ), YC = (
693
- /* wgsl */
694
- `
695
- ${Kg}
696
-
593
+ let obs = textureSample(uObs, samp, i.uv).r;
594
+ let vel = textureSample(uVel, samp, i.uv).xy;
595
+ let coord = i.uv - u.dt * vel * u.texelSize;
596
+ let src = textureSample(uSrc, samp, coord);
597
+ return u.dissipation * src * (1.0 - obs);
598
+ }`, kC = `${yg}
697
599
  struct U { texelSize: vec2f, _pad: vec2f }
698
600
  @group(0) @binding(0) var<uniform> u : U;
699
601
  @group(0) @binding(1) var samp : sampler;
700
602
  @group(0) @binding(2) var uVel : texture_2d<f32>;
701
603
  @group(0) @binding(3) var uObs : texture_2d<f32>;
702
-
703
604
  @vertex fn vs(@location(0) a: vec2f) -> VSOut {
704
- var o: VSOut;
705
- o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);
706
- o.vL = o.uv - vec2f(u.texelSize.x, 0.0);
707
- o.vR = o.uv + vec2f(u.texelSize.x, 0.0);
708
- o.vT = o.uv + vec2f(0.0, u.texelSize.y);
709
- o.vB = o.uv - vec2f(0.0, u.texelSize.y);
710
- o.pos = vec4f(a, 0.0, 1.0);
711
- return o;
605
+ var o: VSOut;
606
+ o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);
607
+ o.vL = o.uv - vec2f(u.texelSize.x, 0.0);
608
+ o.vR = o.uv + vec2f(u.texelSize.x, 0.0);
609
+ o.vT = o.uv + vec2f(0.0, u.texelSize.y);
610
+ o.vB = o.uv - vec2f(0.0, u.texelSize.y);
611
+ o.pos = vec4f(a, 0.0, 1.0);
612
+ return o;
712
613
  }
713
-
714
614
  @fragment fn fs(i: VSOut) -> @location(0) vec4f {
715
- let L = textureSample(uVel, samp, i.vL).x * (1.0 - textureSample(uObs, samp, i.vL).r);
716
- let R = textureSample(uVel, samp, i.vR).x * (1.0 - textureSample(uObs, samp, i.vR).r);
717
- let T = textureSample(uVel, samp, i.vT).y * (1.0 - textureSample(uObs, samp, i.vT).r);
718
- let B = textureSample(uVel, samp, i.vB).y * (1.0 - textureSample(uObs, samp, i.vB).r);
719
- return vec4f(0.5 * (R - L + T - B), 0.0, 0.0, 1.0);
720
- }
721
- `
722
- ), UC = (
723
- /* wgsl */
724
- `
725
- ${Kg}
726
-
615
+ let L = textureSample(uVel, samp, i.vL).x * (1.0 - textureSample(uObs, samp, i.vL).r);
616
+ let R = textureSample(uVel, samp, i.vR).x * (1.0 - textureSample(uObs, samp, i.vR).r);
617
+ let T = textureSample(uVel, samp, i.vT).y * (1.0 - textureSample(uObs, samp, i.vT).r);
618
+ let B = textureSample(uVel, samp, i.vB).y * (1.0 - textureSample(uObs, samp, i.vB).r);
619
+ return vec4f(0.5 * (R - L + T - B), 0.0, 0.0, 1.0);
620
+ }`, MC = `${yg}
727
621
  struct U { texelSize: vec2f, _pad: vec2f }
728
622
  @group(0) @binding(0) var<uniform> u : U;
729
623
  @group(0) @binding(1) var samp : sampler;
730
624
  @group(0) @binding(2) var uPres: texture_2d<f32>;
731
625
  @group(0) @binding(3) var uDiv : texture_2d<f32>;
732
626
  @group(0) @binding(4) var uObs : texture_2d<f32>;
733
-
734
627
  @vertex fn vs(@location(0) a: vec2f) -> VSOut {
735
- var o: VSOut;
736
- o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);
737
- o.vL = o.uv - vec2f(u.texelSize.x, 0.0);
738
- o.vR = o.uv + vec2f(u.texelSize.x, 0.0);
739
- o.vT = o.uv + vec2f(0.0, u.texelSize.y);
740
- o.vB = o.uv - vec2f(0.0, u.texelSize.y);
741
- o.pos = vec4f(a, 0.0, 1.0);
742
- return o;
628
+ var o: VSOut;
629
+ o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);
630
+ o.vL = o.uv - vec2f(u.texelSize.x, 0.0);
631
+ o.vR = o.uv + vec2f(u.texelSize.x, 0.0);
632
+ o.vT = o.uv + vec2f(0.0, u.texelSize.y);
633
+ o.vB = o.uv - vec2f(0.0, u.texelSize.y);
634
+ o.pos = vec4f(a, 0.0, 1.0);
635
+ return o;
743
636
  }
744
-
745
637
  @fragment fn fs(i: VSOut) -> @location(0) vec4f {
746
- let C = textureSample(uPres, samp, i.uv).x;
747
- let L = mix(textureSample(uPres, samp, i.vL).x, C, textureSample(uObs, samp, i.vL).r);
748
- let R = mix(textureSample(uPres, samp, i.vR).x, C, textureSample(uObs, samp, i.vR).r);
749
- let T = mix(textureSample(uPres, samp, i.vT).x, C, textureSample(uObs, samp, i.vT).r);
750
- let B = mix(textureSample(uPres, samp, i.vB).x, C, textureSample(uObs, samp, i.vB).r);
751
- let dv = textureSample(uDiv, samp, i.uv).x;
752
- return vec4f((L + R + B + T - dv) * 0.25, 0.0, 0.0, 1.0);
753
- }
754
- `
755
- ), xC = (
756
- /* wgsl */
757
- `
758
- ${Kg}
759
-
638
+ let C = textureSample(uPres, samp, i.uv).x;
639
+ let L = mix(textureSample(uPres, samp, i.vL).x, C, textureSample(uObs, samp, i.vL).r);
640
+ let R = mix(textureSample(uPres, samp, i.vR).x, C, textureSample(uObs, samp, i.vR).r);
641
+ let T = mix(textureSample(uPres, samp, i.vT).x, C, textureSample(uObs, samp, i.vT).r);
642
+ let B = mix(textureSample(uPres, samp, i.vB).x, C, textureSample(uObs, samp, i.vB).r);
643
+ let dv = textureSample(uDiv, samp, i.uv).x;
644
+ return vec4f((L + R + B + T - dv) * 0.25, 0.0, 0.0, 1.0);
645
+ }`, xC = `${yg}
760
646
  struct U { texelSize: vec2f, _pad: vec2f }
761
647
  @group(0) @binding(0) var<uniform> u : U;
762
648
  @group(0) @binding(1) var samp : sampler;
763
649
  @group(0) @binding(2) var uPres: texture_2d<f32>;
764
650
  @group(0) @binding(3) var uVel : texture_2d<f32>;
765
651
  @group(0) @binding(4) var uObs : texture_2d<f32>;
766
-
767
652
  @vertex fn vs(@location(0) a: vec2f) -> VSOut {
768
- var o: VSOut;
769
- o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);
770
- o.vL = o.uv - vec2f(u.texelSize.x, 0.0);
771
- o.vR = o.uv + vec2f(u.texelSize.x, 0.0);
772
- o.vT = o.uv + vec2f(0.0, u.texelSize.y);
773
- o.vB = o.uv - vec2f(0.0, u.texelSize.y);
774
- o.pos = vec4f(a, 0.0, 1.0);
775
- return o;
653
+ var o: VSOut;
654
+ o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);
655
+ o.vL = o.uv - vec2f(u.texelSize.x, 0.0);
656
+ o.vR = o.uv + vec2f(u.texelSize.x, 0.0);
657
+ o.vT = o.uv + vec2f(0.0, u.texelSize.y);
658
+ o.vB = o.uv - vec2f(0.0, u.texelSize.y);
659
+ o.pos = vec4f(a, 0.0, 1.0);
660
+ return o;
776
661
  }
777
-
778
662
  @fragment fn fs(i: VSOut) -> @location(0) vec4f {
779
- let obs = textureSample(uObs, samp, i.uv).r;
780
- let C = textureSample(uPres, samp, i.uv).x;
781
- let L = mix(textureSample(uPres, samp, i.vL).x, C, textureSample(uObs, samp, i.vL).r);
782
- let R = mix(textureSample(uPres, samp, i.vR).x, C, textureSample(uObs, samp, i.vR).r);
783
- let T = mix(textureSample(uPres, samp, i.vT).x, C, textureSample(uObs, samp, i.vT).r);
784
- let B = mix(textureSample(uPres, samp, i.vB).x, C, textureSample(uObs, samp, i.vB).r);
785
- let vel = (textureSample(uVel, samp, i.uv).xy - vec2f(R - L, T - B)) * (1.0 - obs);
786
- return vec4f(vel, 0.0, 1.0);
787
- }
788
- `
789
- ), kC = (
790
- /* wgsl */
791
- `
792
- ${Kg}
793
-
794
- // texelSize occupies bytes 0-7 for the shared vertex stage; aspectRatio/radius fill the rest.
663
+ let obs = textureSample(uObs, samp, i.uv).r;
664
+ let C = textureSample(uPres, samp, i.uv).x;
665
+ let L = mix(textureSample(uPres, samp, i.vL).x, C, textureSample(uObs, samp, i.vL).r);
666
+ let R = mix(textureSample(uPres, samp, i.vR).x, C, textureSample(uObs, samp, i.vR).r);
667
+ let T = mix(textureSample(uPres, samp, i.vT).x, C, textureSample(uObs, samp, i.vT).r);
668
+ let B = mix(textureSample(uPres, samp, i.vB).x, C, textureSample(uObs, samp, i.vB).r);
669
+ let vel = (textureSample(uVel, samp, i.uv).xy - vec2f(R - L, T - B)) * (1.0 - obs);
670
+ return vec4f(vel, 0.0, 1.0);
671
+ }`, fC = `${yg}
795
672
  struct U {
796
- texelSize : vec2f,
797
- aspectRatio: f32,
798
- radius : f32,
799
- color : vec4f, // xyz = colour, w unused
800
- point : vec2f,
801
- _pad : vec2f,
673
+ texelSize : vec2f,
674
+ aspectRatio: f32,
675
+ radius : f32,
676
+ color : vec4f,
677
+ point : vec2f,
678
+ _pad : vec2f,
802
679
  }
803
680
  @group(0) @binding(0) var<uniform> u : U;
804
681
  @group(0) @binding(1) var samp : sampler;
805
682
  @group(0) @binding(2) var uTgt : texture_2d<f32>;
806
-
807
683
  @vertex fn vs(@location(0) a: vec2f) -> VSOut {
808
- var o: VSOut;
809
- o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);
810
- o.vL = o.uv - vec2f(u.texelSize.x, 0.0);
811
- o.vR = o.uv + vec2f(u.texelSize.x, 0.0);
812
- o.vT = o.uv + vec2f(0.0, u.texelSize.y);
813
- o.vB = o.uv - vec2f(0.0, u.texelSize.y);
814
- o.pos = vec4f(a, 0.0, 1.0);
815
- return o;
684
+ var o: VSOut;
685
+ o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);
686
+ o.vL = o.uv - vec2f(u.texelSize.x, 0.0);
687
+ o.vR = o.uv + vec2f(u.texelSize.x, 0.0);
688
+ o.vT = o.uv + vec2f(0.0, u.texelSize.y);
689
+ o.vB = o.uv - vec2f(0.0, u.texelSize.y);
690
+ o.pos = vec4f(a, 0.0, 1.0);
691
+ return o;
816
692
  }
817
-
818
693
  @fragment fn fs(i: VSOut) -> @location(0) vec4f {
819
- var p = i.uv - u.point;
820
- p.x *= u.aspectRatio;
821
- let sp = exp(-dot(p, p) / u.radius) * u.color.xyz;
822
- return vec4f(textureSample(uTgt, samp, i.uv).xyz + sp, 1.0);
823
- }
824
- `
825
- ), MC = (
826
- /* wgsl */
827
- `
828
- ${Kg}
829
-
694
+ var p = i.uv - u.point;
695
+ p.x *= u.aspectRatio;
696
+ let sp = exp(-dot(p, p) / u.radius) * u.color.xyz;
697
+ return vec4f(textureSample(uTgt, samp, i.uv).xyz + sp, 1.0);
698
+ }`, FC = `${yg}
830
699
  struct U { texelSize: vec2f, _pad: vec2f }
831
700
  @group(0) @binding(0) var<uniform> u : U;
832
701
  @group(0) @binding(1) var samp : sampler;
833
702
  @group(0) @binding(2) var uVel : texture_2d<f32>;
834
-
835
703
  @vertex fn vs(@location(0) a: vec2f) -> VSOut {
836
- var o: VSOut;
837
- o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);
838
- o.vL = o.uv - vec2f(u.texelSize.x, 0.0);
839
- o.vR = o.uv + vec2f(u.texelSize.x, 0.0);
840
- o.vT = o.uv + vec2f(0.0, u.texelSize.y);
841
- o.vB = o.uv - vec2f(0.0, u.texelSize.y);
842
- o.pos = vec4f(a, 0.0, 1.0);
843
- return o;
704
+ var o: VSOut;
705
+ o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);
706
+ o.vL = o.uv - vec2f(u.texelSize.x, 0.0);
707
+ o.vR = o.uv + vec2f(u.texelSize.x, 0.0);
708
+ o.vT = o.uv + vec2f(0.0, u.texelSize.y);
709
+ o.vB = o.uv - vec2f(0.0, u.texelSize.y);
710
+ o.pos = vec4f(a, 0.0, 1.0);
711
+ return o;
844
712
  }
845
-
846
713
  @fragment fn fs(i: VSOut) -> @location(0) vec4f {
847
- let L = textureSample(uVel, samp, i.vL).y;
848
- let R = textureSample(uVel, samp, i.vR).y;
849
- let T = textureSample(uVel, samp, i.vT).x;
850
- let B = textureSample(uVel, samp, i.vB).x;
851
- return vec4f(0.5 * (R - L - T + B), 0.0, 0.0, 1.0);
852
- }
853
- `
854
- ), fC = (
855
- /* wgsl */
856
- `
857
- ${Kg}
858
-
714
+ let L = textureSample(uVel, samp, i.vL).y;
715
+ let R = textureSample(uVel, samp, i.vR).y;
716
+ let T = textureSample(uVel, samp, i.vT).x;
717
+ let B = textureSample(uVel, samp, i.vB).x;
718
+ return vec4f(0.5 * (R - L - T + B), 0.0, 0.0, 1.0);
719
+ }`, DC = `${yg}
859
720
  struct U {
860
- texelSize: vec2f,
861
- curl : f32,
862
- dt : f32,
721
+ texelSize: vec2f,
722
+ curl : f32,
723
+ dt : f32,
863
724
  }
864
725
  @group(0) @binding(0) var<uniform> u : U;
865
726
  @group(0) @binding(1) var samp : sampler;
866
727
  @group(0) @binding(2) var uVel : texture_2d<f32>;
867
728
  @group(0) @binding(3) var uCrl : texture_2d<f32>;
868
-
869
729
  @vertex fn vs(@location(0) a: vec2f) -> VSOut {
870
- var o: VSOut;
871
- o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);
872
- o.vL = o.uv - vec2f(u.texelSize.x, 0.0);
873
- o.vR = o.uv + vec2f(u.texelSize.x, 0.0);
874
- o.vT = o.uv + vec2f(0.0, u.texelSize.y);
875
- o.vB = o.uv - vec2f(0.0, u.texelSize.y);
876
- o.pos = vec4f(a, 0.0, 1.0);
877
- return o;
730
+ var o: VSOut;
731
+ o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);
732
+ o.vL = o.uv - vec2f(u.texelSize.x, 0.0);
733
+ o.vR = o.uv + vec2f(u.texelSize.x, 0.0);
734
+ o.vT = o.uv + vec2f(0.0, u.texelSize.y);
735
+ o.vB = o.uv - vec2f(0.0, u.texelSize.y);
736
+ o.pos = vec4f(a, 0.0, 1.0);
737
+ return o;
878
738
  }
879
-
880
739
  @fragment fn fs(i: VSOut) -> @location(0) vec4f {
881
- let L = textureSample(uCrl, samp, i.vL).x;
882
- let R = textureSample(uCrl, samp, i.vR).x;
883
- let T = textureSample(uCrl, samp, i.vT).x;
884
- let B = textureSample(uCrl, samp, i.vB).x;
885
- let C = textureSample(uCrl, samp, i.uv).x;
886
- var force = 0.5 * vec2f(abs(T) - abs(B), abs(R) - abs(L));
887
- force /= length(force) + 0.0001;
888
- force *= u.curl * 30.0 * C;
889
- let vel = textureSample(uVel, samp, i.uv).xy + force * u.dt;
890
- return vec4f(vel, 0.0, 1.0);
891
- }
892
- `
893
- ), DC = (
894
- /* wgsl */
895
- `
896
- ${Kg}
897
-
740
+ let L = textureSample(uCrl, samp, i.vL).x;
741
+ let R = textureSample(uCrl, samp, i.vR).x;
742
+ let T = textureSample(uCrl, samp, i.vT).x;
743
+ let B = textureSample(uCrl, samp, i.vB).x;
744
+ let C = textureSample(uCrl, samp, i.uv).x;
745
+ var force = 0.5 * vec2f(abs(T) - abs(B), abs(R) - abs(L));
746
+ force /= length(force) + 0.0001;
747
+ force *= u.curl * 30.0 * C;
748
+ let vel = textureSample(uVel, samp, i.uv).xy + force * u.dt;
749
+ return vec4f(vel, 0.0, 1.0);
750
+ }`, TC = `${yg}
898
751
  struct U {
899
- texelSize : vec2f,
900
- refraction : f32,
901
- specularExp : f32,
902
- waterColor : vec4f,
903
- glowColor : vec4f,
904
- shine : f32,
905
- warpStrength: f32,
906
- algorithm : i32,
907
- enableAlpha : i32,
752
+ texelSize : vec2f,
753
+ refraction : f32,
754
+ specularExp : f32,
755
+ waterColor : vec4f,
756
+ glowColor : vec4f,
757
+ shine : f32,
758
+ warpStrength: f32,
759
+ algorithm : i32,
760
+ enableAlpha : i32,
908
761
  }
909
762
  @group(0) @binding(0) var<uniform> u : U;
910
763
  @group(0) @binding(1) var samp : sampler;
@@ -913,95 +766,86 @@ struct U {
913
766
  @group(0) @binding(4) var uBg : texture_2d<f32>;
914
767
  @group(0) @binding(5) var uCov : texture_2d<f32>;
915
768
  @group(0) @binding(6) var uVel : texture_2d<f32>;
916
-
917
769
  @vertex fn vs(@location(0) a: vec2f) -> VSOut {
918
- var o: VSOut;
919
- o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);
920
- o.vL = o.uv - vec2f(u.texelSize.x, 0.0);
921
- o.vR = o.uv + vec2f(u.texelSize.x, 0.0);
922
- o.vT = o.uv + vec2f(0.0, u.texelSize.y);
923
- o.vB = o.uv - vec2f(0.0, u.texelSize.y);
924
- o.pos = vec4f(a, 0.0, 1.0);
925
- return o;
770
+ var o: VSOut;
771
+ o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);
772
+ o.vL = o.uv - vec2f(u.texelSize.x, 0.0);
773
+ o.vR = o.uv + vec2f(u.texelSize.x, 0.0);
774
+ o.vT = o.uv + vec2f(0.0, u.texelSize.y);
775
+ o.vB = o.uv - vec2f(0.0, u.texelSize.y);
776
+ o.pos = vec4f(a, 0.0, 1.0);
777
+ return o;
926
778
  }
927
-
928
779
  @fragment fn fs(i: VSOut) -> @location(0) vec4f {
929
- let obs = textureSample(uObs, samp, i.uv).r;
930
- let density = max(textureSample(uTex, samp, i.uv).r, 0.0) * (1.0 - obs);
931
- let cov = textureSample(uCov, samp, i.uv).r;
932
-
933
- let sx = u.texelSize.x * 6.0;
934
- let sy = u.texelSize.y * 6.0;
935
- let d00 = max(textureSample(uTex, samp, i.uv + vec2f(-sx, -sy)).r, 0.0);
936
- let d10 = max(textureSample(uTex, samp, i.uv + vec2f(0.0, -sy)).r, 0.0);
937
- let d20 = max(textureSample(uTex, samp, i.uv + vec2f( sx, -sy)).r, 0.0);
938
- let d01 = max(textureSample(uTex, samp, i.uv + vec2f(-sx, 0.0)).r, 0.0);
939
- let d21 = max(textureSample(uTex, samp, i.uv + vec2f( sx, 0.0)).r, 0.0);
940
- let d02 = max(textureSample(uTex, samp, i.uv + vec2f(-sx, sy)).r, 0.0);
941
- let d12 = max(textureSample(uTex, samp, i.uv + vec2f(0.0, sy)).r, 0.0);
942
- let d22 = max(textureSample(uTex, samp, i.uv + vec2f( sx, sy)).r, 0.0);
943
- let gx = (d20 + 2.0*d21 + d22) - (d00 + 2.0*d01 + d02);
944
- let gy = (d02 + 2.0*d12 + d22) - (d00 + 2.0*d10 + d20);
945
-
946
- let norm = normalize(vec3f(gx, gy, 1.2));
947
- let ldir = normalize(vec3f(0.5, 1.0, 0.5));
948
- let halfV = normalize(ldir + vec3f(0.0, 0.0, 1.0));
949
- let specDen = density * min(density * 5.0, 1.0);
950
- let spec = pow(max(dot(norm, halfV), 0.0), u.specularExp) * u.shine * specDen;
951
-
952
- let bgRaw = textureSample(uBg, samp, i.uv).rgb;
953
- let wc = u.waterColor.rgb;
954
- let gc = u.glowColor.rgb;
955
- let bg = mix(wc, bgRaw, cov);
956
- var color = bg;
957
-
958
- if (u.algorithm == 1) {
959
- let ruv = clamp(i.uv + norm.xy * u.refraction * density * 3.0, vec2f(0.0), vec2f(1.0));
960
- let rbg = mix(wc, textureSample(uBg, samp, mix(i.uv, ruv, 1.0 - obs)).rgb, cov);
961
- color = rbg + spec * gc * 2.5;
962
- color = mix(color, bg * 0.6, obs * 0.3);
963
- } else if (u.algorithm == 2) {
964
- let inkD = min(density * 4.0, 1.0);
965
- let ruv = clamp(i.uv + norm.xy * u.refraction * density * 0.4, vec2f(0.0), vec2f(1.0));
966
- let rbg = mix(wc, textureSample(uBg, samp, mix(i.uv, ruv, 1.0 - obs)).rgb, cov);
967
- color = mix(rbg, wc + spec * gc, inkD);
968
- color = mix(color, bg * 0.5, obs * 0.15);
969
- } else if (u.algorithm == 3) {
970
- let vel = textureSample(uVel, samp, i.uv).xy;
971
- let velMag = clamp(length(vel) * 20.0, 0.0, 1.0);
972
- let wuv = clamp(i.uv + vel * u.warpStrength, vec2f(0.0), vec2f(1.0));
973
- let wbg = mix(wc, textureSample(uBg, samp, wuv).rgb, cov);
974
- color = mix(bg, wbg, velMag * (1.0 - obs));
975
- color += spec * gc * velMag * 1.5;
976
- color += wc * density * 0.3;
977
- color = mix(color, bg * 0.5, obs * 0.2);
978
- } else if (u.algorithm == 4) {
979
- let ruv = clamp(i.uv + norm.xy * u.refraction * density * 6.0, vec2f(0.0), vec2f(1.0));
980
- let rbg = mix(wc, textureSample(uBg, samp, mix(i.uv, ruv, 1.0 - obs)).rgb, cov);
981
- let fres = pow(clamp(1.0 - dot(norm, vec3f(0.0, 0.0, 1.0)), 0.0, 1.0), 3.0) * density;
982
- color = rbg;
983
- color += fres * gc * 2.0;
984
- color += spec * gc * density * 2.0;
985
- color = mix(color, bg * 0.5, obs * 0.2);
986
- } else {
987
- let ruv = i.uv + norm.xy * u.refraction * density;
988
- let rbg = mix(wc, textureSample(uBg, samp, mix(i.uv, ruv, 1.0 - obs)).rgb, cov);
989
- color = mix(rbg, wc, min(density * 1.5, 0.8));
990
- color += spec * gc;
991
- color = mix(color, bg * 0.5, obs * 0.2);
992
- }
993
-
994
- let alpha = clamp(max(density * 1.5, cov), 0.0, 1.0);
995
- if (u.enableAlpha == 1) {
996
- return vec4f(color * alpha, alpha);
997
- }
998
- return vec4f(color, 1.0);
780
+ let obs = textureSample(uObs, samp, i.uv).r;
781
+ let density = max(textureSample(uTex, samp, i.uv).r, 0.0) * (1.0 - obs);
782
+ let cov = textureSample(uCov, samp, i.uv).r;
783
+ let sx = u.texelSize.x * 6.0;
784
+ let sy = u.texelSize.y * 6.0;
785
+ let d00 = max(textureSample(uTex, samp, i.uv + vec2f(-sx, -sy)).r, 0.0);
786
+ let d10 = max(textureSample(uTex, samp, i.uv + vec2f(0.0, -sy)).r, 0.0);
787
+ let d20 = max(textureSample(uTex, samp, i.uv + vec2f( sx, -sy)).r, 0.0);
788
+ let d01 = max(textureSample(uTex, samp, i.uv + vec2f(-sx, 0.0)).r, 0.0);
789
+ let d21 = max(textureSample(uTex, samp, i.uv + vec2f( sx, 0.0)).r, 0.0);
790
+ let d02 = max(textureSample(uTex, samp, i.uv + vec2f(-sx, sy)).r, 0.0);
791
+ let d12 = max(textureSample(uTex, samp, i.uv + vec2f(0.0, sy)).r, 0.0);
792
+ let d22 = max(textureSample(uTex, samp, i.uv + vec2f( sx, sy)).r, 0.0);
793
+ let gx = (d20 + 2.0*d21 + d22) - (d00 + 2.0*d01 + d02);
794
+ let gy = (d02 + 2.0*d12 + d22) - (d00 + 2.0*d10 + d20);
795
+ let norm = normalize(vec3f(gx, gy, 1.2));
796
+ let ldir = normalize(vec3f(0.5, 1.0, 0.5));
797
+ let halfV = normalize(ldir + vec3f(0.0, 0.0, 1.0));
798
+ let specDen = density * min(density * 5.0, 1.0);
799
+ let spec = pow(max(dot(norm, halfV), 0.0), u.specularExp) * u.shine * specDen;
800
+ let bgRaw = textureSample(uBg, samp, i.uv).rgb;
801
+ let wc = u.waterColor.rgb;
802
+ let gc = u.glowColor.rgb;
803
+ let bg = mix(wc, bgRaw, cov);
804
+ var color = bg;
805
+ if (u.algorithm == 1) {
806
+ let ruv = clamp(i.uv + norm.xy * u.refraction * density * 3.0, vec2f(0.0), vec2f(1.0));
807
+ let rbg = mix(wc, textureSample(uBg, samp, mix(i.uv, ruv, 1.0 - obs)).rgb, cov);
808
+ color = rbg + spec * gc * 2.5;
809
+ color = mix(color, bg * 0.6, obs * 0.3);
810
+ } else if (u.algorithm == 2) {
811
+ let inkD = min(density * 4.0, 1.0);
812
+ let ruv = clamp(i.uv + norm.xy * u.refraction * density * 0.4, vec2f(0.0), vec2f(1.0));
813
+ let rbg = mix(wc, textureSample(uBg, samp, mix(i.uv, ruv, 1.0 - obs)).rgb, cov);
814
+ color = mix(rbg, wc + spec * gc, inkD);
815
+ color = mix(color, bg * 0.5, obs * 0.15);
816
+ } else if (u.algorithm == 3) {
817
+ let vel = textureSample(uVel, samp, i.uv).xy;
818
+ let velMag = clamp(length(vel) * 20.0, 0.0, 1.0);
819
+ let wuv = clamp(i.uv + vel * u.warpStrength, vec2f(0.0), vec2f(1.0));
820
+ let wbg = mix(wc, textureSample(uBg, samp, wuv).rgb, cov);
821
+ color = mix(bg, wbg, velMag * (1.0 - obs));
822
+ color += spec * gc * velMag * 1.5;
823
+ color += wc * density * 0.3;
824
+ color = mix(color, bg * 0.5, obs * 0.2);
825
+ } else if (u.algorithm == 4) {
826
+ let ruv = clamp(i.uv + norm.xy * u.refraction * density * 6.0, vec2f(0.0), vec2f(1.0));
827
+ let rbg = mix(wc, textureSample(uBg, samp, mix(i.uv, ruv, 1.0 - obs)).rgb, cov);
828
+ let fres = pow(clamp(1.0 - dot(norm, vec3f(0.0, 0.0, 1.0)), 0.0, 1.0), 3.0) * density;
829
+ color = rbg;
830
+ color += fres * gc * 2.0;
831
+ color += spec * gc * density * 2.0;
832
+ color = mix(color, bg * 0.5, obs * 0.2);
833
+ } else {
834
+ let ruv = i.uv + norm.xy * u.refraction * density;
835
+ let rbg = mix(wc, textureSample(uBg, samp, mix(i.uv, ruv, 1.0 - obs)).rgb, cov);
836
+ color = mix(rbg, wc, min(density * 1.5, 0.8));
837
+ color += spec * gc;
838
+ color = mix(color, bg * 0.5, obs * 0.2);
839
+ }
840
+ let alpha = clamp(max(density * 1.5, cov), 0.0, 1.0);
841
+ if (u.enableAlpha == 1) {
842
+ return vec4f(color * alpha, alpha);
999
843
  }
1000
- `
1001
- ), FC = {
844
+ return vec4f(color, 1.0);
845
+ }`, JC = {
1002
846
  arrayStride: 8,
1003
847
  attributes: [{ shaderLocation: 0, offset: 0, format: "float32x2" }]
1004
- }, OI = new Float32Array([
848
+ }, PI = new Float32Array([
1005
849
  -1,
1006
850
  -1,
1007
851
  -1,
@@ -1015,9 +859,9 @@ struct U {
1015
859
  1,
1016
860
  1
1017
861
  ]);
1018
- function JC(e) {
1019
- const g = e.createBuffer({ size: OI.byteLength, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST });
1020
- return e.queue.writeBuffer(g, 0, OI), g;
862
+ function zC(e) {
863
+ const g = e.createBuffer({ size: PI.byteLength, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST });
864
+ return e.queue.writeBuffer(g, 0, PI), g;
1021
865
  }
1022
866
  function KI(e, g, C, i) {
1023
867
  const s = e.createTexture({
@@ -1027,77 +871,77 @@ function KI(e, g, C, i) {
1027
871
  });
1028
872
  return { tex: s, view: s.createView(), width: C, height: i };
1029
873
  }
1030
- function fI(e, g, C, i) {
1031
- let s = KI(e, g, C, i), l = KI(e, g, C, i);
874
+ function DI(e, g, C, i) {
875
+ let s = KI(e, g, C, i), t = KI(e, g, C, i);
1032
876
  return {
1033
877
  get read() {
1034
878
  return s;
1035
879
  },
1036
880
  get write() {
1037
- return l;
881
+ return t;
1038
882
  },
1039
883
  swap() {
1040
- [s, l] = [l, s];
884
+ [s, t] = [t, s];
1041
885
  },
1042
886
  dispose() {
1043
- s.tex.destroy(), l.tex.destroy();
887
+ s.tex.destroy(), t.tex.destroy();
1044
888
  }
1045
889
  };
1046
890
  }
1047
- function Bg(e, g, C, i) {
891
+ function ng(e, g, C, i) {
1048
892
  const s = e.createShaderModule({ code: g });
1049
893
  return e.createRenderPipeline({
1050
894
  layout: "auto",
1051
- vertex: { module: s, entryPoint: "vs", buffers: [FC] },
895
+ vertex: { module: s, entryPoint: "vs", buffers: [JC] },
1052
896
  fragment: { module: s, entryPoint: "fs", targets: [{ format: C, ...i ? { blend: i } : {} }] },
1053
897
  primitive: { topology: "triangle-list" }
1054
898
  });
1055
899
  }
1056
- const TC = {
900
+ const QC = {
1057
901
  color: { operation: "add", srcFactor: "one", dstFactor: "zero" },
1058
902
  alpha: { operation: "add", srcFactor: "one", dstFactor: "zero" }
1059
903
  };
1060
- function zC(e, g, C = !0) {
904
+ function NC(e, g, C = !0) {
1061
905
  const i = "rgba16float";
1062
906
  return {
1063
- advection: Bg(e, WC, i),
1064
- divergence: Bg(e, YC, i),
1065
- pressure: Bg(e, UC, i),
1066
- gradientSubtract: Bg(e, xC, i),
1067
- splat: Bg(e, kC, i),
1068
- curl: Bg(e, MC, i),
1069
- vorticity: Bg(e, fC, i),
1070
- display: Bg(e, DC, g, C ? void 0 : TC)
907
+ advection: ng(e, YC, i),
908
+ divergence: ng(e, kC, i),
909
+ pressure: ng(e, MC, i),
910
+ gradientSubtract: ng(e, xC, i),
911
+ splat: ng(e, fC, i),
912
+ curl: ng(e, FC, i),
913
+ vorticity: ng(e, DC, i),
914
+ display: ng(e, TC, g, C ? void 0 : QC)
1071
915
  };
1072
916
  }
1073
- function NC(e) {
917
+ function EC(e) {
1074
918
  return e.createSampler({ magFilter: "linear", minFilter: "linear", addressModeU: "clamp-to-edge", addressModeV: "clamp-to-edge" });
1075
919
  }
1076
920
  function gg(e, g) {
1077
921
  return e.createBuffer({ size: g, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST });
1078
922
  }
1079
- function jI(e, g, C, i, s, l) {
1080
- const t = new Float32Array([C, i, s, l]);
1081
- e.queue.writeBuffer(g, 0, t);
923
+ function _I(e, g, C, i, s, t) {
924
+ const l = new Float32Array([C, i, s, t]);
925
+ e.queue.writeBuffer(g, 0, l);
1082
926
  }
1083
- function wI(e, g, C, i) {
927
+ function hI(e, g, C, i) {
1084
928
  const s = new Float32Array([C, i, 0, 0]);
1085
929
  e.queue.writeBuffer(g, 0, s);
1086
930
  }
1087
- function QC(e, g, C, i, s, l) {
1088
- const t = new Float32Array([C, i, s, l]);
1089
- e.queue.writeBuffer(g, 0, t);
931
+ function OC(e, g, C, i, s, t) {
932
+ const l = new Float32Array([C, i, s, t]);
933
+ e.queue.writeBuffer(g, 0, l);
1090
934
  }
1091
- function LI(e, g, C, i, s, l, t, S, u, c, p) {
935
+ function bI(e, g, C, i, s, t, l, u, Z, d, S) {
1092
936
  const a = new Float32Array(12);
1093
- a[0] = C, a[1] = i, a[2] = s, a[3] = l, a[4] = t, a[5] = S, a[6] = u, a[7] = 0, a[8] = c, a[9] = p, a[10] = 0, a[11] = 0, e.queue.writeBuffer(g, 0, a);
937
+ a[0] = C, a[1] = i, a[2] = s, a[3] = t, a[4] = l, a[5] = u, a[6] = Z, a[7] = 0, a[8] = d, a[9] = S, a[10] = 0, a[11] = 0, e.queue.writeBuffer(g, 0, a);
1094
938
  }
1095
- function EC(e, g, C, i, s, l, t, S, u, c, p, a) {
1096
- const A = new Float32Array(16), m = new Int32Array(A.buffer);
1097
- A[0] = C, A[1] = i, A[2] = s, A[3] = l, A[4] = t[0], A[5] = t[1], A[6] = t[2], A[7] = 0, A[8] = S[0], A[9] = S[1], A[10] = S[2], A[11] = 0, A[12] = u, A[13] = c, m[14] = p, m[15] = a ? 1 : 0, e.queue.writeBuffer(g, 0, A);
939
+ function jC(e, g, C, i, s, t, l, u, Z, d, S, a) {
940
+ const c = new Float32Array(16), m = new Int32Array(c.buffer);
941
+ c[0] = C, c[1] = i, c[2] = s, c[3] = t, c[4] = l[0], c[5] = l[1], c[6] = l[2], c[7] = 0, c[8] = u[0], c[9] = u[1], c[10] = u[2], c[11] = 0, c[12] = Z, c[13] = d, m[14] = S, m[15] = a ? 1 : 0, e.queue.writeBuffer(g, 0, c);
1098
942
  }
1099
943
  function O(e, g, C, i, s) {
1100
- const l = e.beginRenderPass({
944
+ const t = e.beginRenderPass({
1101
945
  colorAttachments: [{
1102
946
  view: s,
1103
947
  clearValue: [0, 0, 0, 0],
@@ -1105,10 +949,10 @@ function O(e, g, C, i, s) {
1105
949
  storeOp: "store"
1106
950
  }]
1107
951
  });
1108
- l.setPipeline(g), l.setBindGroup(0, C), l.setVertexBuffer(0, i), l.draw(6), l.end();
952
+ t.setPipeline(g), t.setBindGroup(0, C), t.setVertexBuffer(0, i), t.draw(6), t.end();
1109
953
  }
1110
- function OC(e, g, C, i, s) {
1111
- const l = e.beginRenderPass({
954
+ function PC(e, g, C, i, s) {
955
+ const t = e.beginRenderPass({
1112
956
  colorAttachments: [{
1113
957
  view: s,
1114
958
  clearValue: [0, 0, 0, 0],
@@ -1116,148 +960,153 @@ function OC(e, g, C, i, s) {
1116
960
  storeOp: "store"
1117
961
  }]
1118
962
  });
1119
- l.setPipeline(g), l.setBindGroup(0, C), l.setVertexBuffer(0, i), l.draw(6), l.end();
963
+ t.setPipeline(g), t.setBindGroup(0, C), t.setVertexBuffer(0, i), t.draw(6), t.end();
1120
964
  }
1121
- const PI = typeof requestAnimationFrame < "u" ? requestAnimationFrame.bind(globalThis) : (e) => setTimeout(e, 1e3 / 60), jC = typeof cancelAnimationFrame < "u" ? cancelAnimationFrame.bind(globalThis) : clearTimeout, AI = 0.016, _I = { standard: 0, glass: 1, ink: 2, aurora: 3, ripple: 4 };
1122
- var yg, j, mI, Vg, Og, k, H, Ig, Cg, ig, og, z, eg, D, jg, Hg, Pg, M, h, rg, sg, ng, E, Xg, vg, Rg, Wg, Yg, Ag, cg, Ug, xg, kg, V, X, P, _, F, _g, dg, N, bg, Sg, w, U, lg, Mg, pI, fg, VI, eC, Dg, cI, ZI, DI, wg, Ng, Fg, dI, BI, FI, GI, JI, HI, sC, XI, lC, vI, tC, RI, oC, WI, AC;
1123
- const NI = class NI {
965
+ const qI = typeof requestAnimationFrame < "u" ? requestAnimationFrame.bind(globalThis) : (e) => setTimeout(e, 1e3 / 60), _C = typeof cancelAnimationFrame < "u" ? cancelAnimationFrame.bind(globalThis) : clearTimeout, cI = 0.016, $I = { standard: 0, glass: 1, ink: 2, aurora: 3, ripple: 4 };
966
+ var Vg, j, mI, Kg, Og, M, X, Ig, Cg, ig, og, Q, eg, F, jg, Xg, Pg, x, b, Gg, sg, pg, E, Hg, vg, Wg, Rg, Ug, cg, dg, Yg, kg, Mg, K, H, P, _, D, _g, Ag, N, Lg, ug, L, SI, U, tg, xg, BI, fg, HI, tC, Fg, dI, nI, TI, wg, Qg, Dg, AI, rI, JI, GI, zI, vI, lC, WI, oC, RI, cC, UI, dC, YI, AC;
967
+ const EI = class EI {
1124
968
  // ── Constructor ─────────────────────────────────────────────────────────────
1125
- constructor(g, C = {}, i = {}, s, l = !0) {
969
+ constructor(g, C = {}, i = {}, s, t = !0) {
1126
970
  // ---------------------------------------------------------------------------
1127
971
  // Private — GPU initialisation
1128
972
  // ---------------------------------------------------------------------------
1129
- d(this, VI);
973
+ A(this, HI);
1130
974
  // ---------------------------------------------------------------------------
1131
975
  // Private — shared helpers
1132
976
  // ---------------------------------------------------------------------------
1133
- d(this, Dg);
1134
- d(this, ZI);
1135
- d(this, wg);
1136
- d(this, Fg);
1137
- d(this, BI);
1138
- d(this, GI);
977
+ A(this, Fg);
978
+ A(this, nI);
979
+ A(this, wg);
980
+ A(this, Dg);
981
+ A(this, rI);
982
+ A(this, GI);
1139
983
  // ---------------------------------------------------------------------------
1140
984
  // Private — frame dispatch
1141
985
  // ---------------------------------------------------------------------------
1142
- d(this, HI);
986
+ A(this, vI);
1143
987
  // ---------------------------------------------------------------------------
1144
988
  // Private — WebGPU simulation step
1145
989
  // ---------------------------------------------------------------------------
1146
- d(this, XI);
990
+ A(this, WI);
1147
991
  // ---------------------------------------------------------------------------
1148
992
  // Private — WebGPU direct splat
1149
993
  // ---------------------------------------------------------------------------
1150
- d(this, vI);
994
+ A(this, RI);
1151
995
  // ---------------------------------------------------------------------------
1152
996
  // Private — WebGL splat
1153
997
  // ---------------------------------------------------------------------------
1154
- d(this, RI);
998
+ A(this, UI);
1155
999
  // ---------------------------------------------------------------------------
1156
1000
  // Private — WebGL simulation step (unchanged from original)
1157
1001
  // ---------------------------------------------------------------------------
1158
- d(this, WI);
1159
- d(this, yg, void 0);
1002
+ A(this, YI);
1003
+ A(this, Vg, void 0);
1160
1004
  // ── WebGL path ──────────────────────────────────────────────────────────────
1161
- d(this, j, null);
1162
- d(this, mI, null);
1163
- d(this, Vg, null);
1164
- d(this, Og, null);
1165
- d(this, k, null);
1166
- d(this, H, null);
1167
- d(this, Ig, null);
1168
- d(this, Cg, null);
1169
- d(this, ig, null);
1170
- d(this, og, null);
1171
- d(this, z, null);
1172
- d(this, eg, null);
1005
+ A(this, j, null);
1006
+ A(this, mI, null);
1007
+ A(this, Kg, null);
1008
+ A(this, Og, null);
1009
+ A(this, M, null);
1010
+ A(this, X, null);
1011
+ A(this, Ig, null);
1012
+ A(this, Cg, null);
1013
+ A(this, ig, null);
1014
+ A(this, og, null);
1015
+ A(this, Q, null);
1016
+ A(this, eg, null);
1173
1017
  // ── WebGPU path ─────────────────────────────────────────────────────────────
1174
- d(this, D, null);
1175
- d(this, jg, null);
1176
- d(this, Hg, null);
1177
- d(this, Pg, null);
1178
- d(this, M, null);
1179
- d(this, h, null);
1180
- d(this, rg, null);
1181
- d(this, sg, null);
1182
- d(this, ng, null);
1183
- d(this, E, null);
1018
+ A(this, F, null);
1019
+ A(this, jg, null);
1020
+ A(this, Xg, null);
1021
+ A(this, Pg, null);
1022
+ A(this, x, null);
1023
+ A(this, b, null);
1024
+ A(this, Gg, null);
1025
+ A(this, sg, null);
1026
+ A(this, pg, null);
1027
+ A(this, E, null);
1184
1028
  // Pre-allocated uniform buffers (sizes: see gpu-utils writeXxx docs)
1185
1029
  // Velocity/density advection use separate buffers — writeBuffer is a queue op;
1186
1030
  // a second write to the same buffer before queue.submit() aliases both passes.
1187
- d(this, Xg, null);
1031
+ A(this, Hg, null);
1188
1032
  // 16 bytes — velocity advection
1189
- d(this, vg, null);
1033
+ A(this, vg, null);
1190
1034
  // 16 bytes — density advection
1191
- d(this, Rg, null);
1035
+ A(this, Wg, null);
1192
1036
  // 16 bytes
1193
- d(this, Wg, null);
1037
+ A(this, Rg, null);
1194
1038
  // 16 bytes
1195
- d(this, Yg, null);
1039
+ A(this, Ug, null);
1196
1040
  // 16 bytes
1197
- d(this, Ag, null);
1041
+ A(this, cg, null);
1198
1042
  // 48 bytes — velocity splat
1199
- d(this, cg, null);
1043
+ A(this, dg, null);
1200
1044
  // 48 bytes — density splat
1201
- d(this, Ug, null);
1045
+ A(this, Yg, null);
1202
1046
  // 16 bytes
1203
- d(this, xg, null);
1047
+ A(this, kg, null);
1204
1048
  // 16 bytes
1205
- d(this, kg, null);
1049
+ A(this, Mg, null);
1206
1050
  // 64 bytes
1207
1051
  // ── Shared state ────────────────────────────────────────────────────────────
1208
- d(this, V, 0);
1209
- d(this, X, 0);
1210
- d(this, P, 0);
1211
- d(this, _, 0);
1212
- d(this, F, 1);
1213
- d(this, _g, 1);
1214
- d(this, dg, 0.5);
1215
- d(this, N, null);
1216
- d(this, bg, "cover");
1217
- d(this, Sg, void 0);
1218
- d(this, w, { x: 0, y: 0, dx: 0, dy: 0, targetX: 0, targetY: 0, moved: !1 });
1219
- d(this, U, null);
1220
- d(this, lg, null);
1221
- d(this, Mg, !1);
1222
- d(this, pI, !1);
1223
- d(this, fg, !0);
1224
- if (o(this, yg, g), o(this, _g, Math.max(0.1, Math.min(1, i.dpr ?? 1))), o(this, dg, Math.max(0.1, Math.min(1, i.sim ?? 0.5))), o(this, Sg, uI(C)), o(this, fg, l), s)
1225
- o(this, D, s), L(this, VI, eC).call(this, s);
1052
+ A(this, K, 0);
1053
+ A(this, H, 0);
1054
+ A(this, P, 0);
1055
+ A(this, _, 0);
1056
+ A(this, D, 1);
1057
+ A(this, _g, 1);
1058
+ A(this, Ag, 0.5);
1059
+ A(this, N, null);
1060
+ A(this, Lg, "cover");
1061
+ A(this, ug, void 0);
1062
+ A(this, L, { x: 0, y: 0, dx: 0, dy: 0, targetX: 0, targetY: 0, moved: !1 });
1063
+ A(this, SI, !1);
1064
+ A(this, U, null);
1065
+ A(this, tg, null);
1066
+ A(this, xg, !1);
1067
+ A(this, BI, !1);
1068
+ A(this, fg, !0);
1069
+ if (o(this, Vg, g), o(this, _g, Math.max(0.1, Math.min(1, i.dpr ?? 1))), o(this, Ag, Math.max(0.1, Math.min(1, i.sim ?? 0.5))), o(this, ug, ZI(C)), o(this, fg, t), s)
1070
+ o(this, F, s), h(this, HI, tC).call(this, s);
1226
1071
  else {
1227
- const { gl: t, ext: S } = HC(g, l);
1228
- o(this, j, t), o(this, mI, S), o(this, Vg, vC(t)), o(this, Og, RC(t)), t.clearColor(0, 0, 0, l ? 0 : 1);
1072
+ const { gl: l, ext: u } = vC(g, t);
1073
+ o(this, j, l), o(this, mI, u), o(this, Kg, RC(l)), o(this, Og, UC(l)), l.clearColor(0, 0, 0, t ? 0 : 1);
1229
1074
  }
1230
1075
  }
1231
1076
  /**
1232
1077
  * WebGPU-first factory. Tries WebGPU, falls back to WebGL2 → WebGL1.
1233
1078
  * This is the recommended entry point when WebGPU support is desired.
1234
1079
  */
1235
- static async create(g, C = {}, i = {}, s = !0, l = !0) {
1236
- const t = s ? await XC(g, l) : null;
1237
- return new NI(g, C, i, t ?? void 0, l);
1080
+ static async create(g, C = {}, i = {}, s = !0, t = !0) {
1081
+ const l = s ? await WC(g, t) : null;
1082
+ return new EI(g, C, i, l ?? void 0, t);
1238
1083
  }
1239
1084
  // ---------------------------------------------------------------------------
1240
1085
  // Public API
1241
1086
  // ---------------------------------------------------------------------------
1242
1087
  setTextSource(g) {
1243
- o(this, U, { type: "text", opts: g }), L(this, Dg, cI).call(this), L(this, wg, Ng).call(this), L(this, Fg, dI).call(this);
1088
+ o(this, U, { type: "text", opts: g }), h(this, Fg, dI).call(this), h(this, wg, Qg).call(this), h(this, Dg, AI).call(this);
1244
1089
  }
1245
1090
  async setImageSource(g, C = 0, i = "cover") {
1246
- const s = await zI(g);
1247
- if (I(this, pI)) {
1091
+ const s = await NI(g);
1092
+ if (I(this, BI)) {
1248
1093
  s.close();
1249
1094
  return;
1250
1095
  }
1251
- o(this, U, { type: "image", bitmap: s, effect: C, size: i }), L(this, Dg, cI).call(this), L(this, wg, Ng).call(this), L(this, Fg, dI).call(this);
1096
+ o(this, U, { type: "image", bitmap: s, effect: C, size: i }), h(this, Fg, dI).call(this), h(this, wg, Qg).call(this), h(this, Dg, AI).call(this);
1252
1097
  }
1253
1098
  setImageBitmap(g, C = 0, i = "cover") {
1254
- o(this, U, { type: "image", bitmap: g, effect: C, size: i }), L(this, Dg, cI).call(this), L(this, wg, Ng).call(this), L(this, Fg, dI).call(this);
1099
+ o(this, U, { type: "image", bitmap: g, effect: C, size: i }), h(this, Fg, dI).call(this), h(this, wg, Qg).call(this), h(this, Dg, AI).call(this);
1255
1100
  }
1256
1101
  setBackground(g, C = "cover") {
1257
- I(this, N) && I(this, N) !== g && I(this, N).close(), o(this, N, g), o(this, bg, C ?? "cover"), I(this, U) && I(this, V) > 0 && I(this, X) > 0 && L(this, wg, Ng).call(this);
1102
+ I(this, N) && I(this, N) !== g && I(this, N).close(), o(this, N, g), o(this, Lg, C ?? "cover"), I(this, U) && I(this, K) > 0 && I(this, H) > 0 && h(this, wg, Qg).call(this);
1258
1103
  }
1259
1104
  handleMove(g, C, i = 1) {
1260
- I(this, w).moved = !0, I(this, w).dx = (g - I(this, w).targetX) * i, I(this, w).dy = (C - I(this, w).targetY) * i, I(this, w).targetX = g, I(this, w).targetY = C;
1105
+ if (!I(this, SI)) {
1106
+ I(this, L).x = I(this, L).targetX = g, I(this, L).y = I(this, L).targetY = C, o(this, SI, !0);
1107
+ return;
1108
+ }
1109
+ I(this, L).moved = !0, I(this, L).dx = (g - I(this, L).targetX) * i, I(this, L).dy = (C - I(this, L).targetY) * i, I(this, L).targetX = g, I(this, L).targetY = C;
1261
1110
  }
1262
1111
  /**
1263
1112
  * Immediately applies one fluid splat at (x, y) with explicit velocity (vx, vy).
@@ -1266,33 +1115,33 @@ const NI = class NI {
1266
1115
  * where you want N independent injection points per frame without flooding the
1267
1116
  * mouse-state machine or the worker message queue.
1268
1117
  */
1269
- splat(g, C, i, s, l = 1) {
1270
- !I(this, Mg) || I(this, V) === 0 || (I(this, D) ? L(this, vI, tC).call(this, g, C, i, s, l) : L(this, RI, oC).call(this, g, C, i, s, l));
1118
+ splat(g, C, i, s, t = 1) {
1119
+ !I(this, xg) || I(this, K) === 0 || (I(this, F) ? h(this, RI, cC).call(this, g, C, i, s, t) : h(this, UI, dC).call(this, g, C, i, s, t));
1271
1120
  }
1272
1121
  updateQuality(g) {
1273
- g.dpr !== void 0 && o(this, _g, Math.max(0.1, Math.min(1, g.dpr))), g.sim !== void 0 && o(this, dg, Math.max(0.1, Math.min(1, g.sim)));
1122
+ g.dpr !== void 0 && o(this, _g, Math.max(0.1, Math.min(1, g.dpr))), g.sim !== void 0 && o(this, Ag, Math.max(0.1, Math.min(1, g.sim)));
1274
1123
  }
1275
1124
  resize(g, C, i) {
1276
- if (i !== void 0 ? o(this, F, i) : typeof window < "u" && window.devicePixelRatio && o(this, F, window.devicePixelRatio), g !== void 0 && g > 0) {
1125
+ if (i !== void 0 ? o(this, D, i) : typeof window < "u" && window.devicePixelRatio && o(this, D, window.devicePixelRatio), g !== void 0 && g > 0) {
1277
1126
  if (C === void 0 || C <= 0)
1278
1127
  return;
1279
- o(this, V, I(this, yg).width = g), o(this, X, I(this, yg).height = C), o(this, P, Math.max(1, Math.round(g * I(this, dg)))), o(this, _, Math.max(1, Math.round(C * I(this, dg)))), L(this, ZI, DI).call(this);
1128
+ o(this, K, I(this, Vg).width = g), o(this, H, I(this, Vg).height = C), o(this, P, Math.max(1, Math.round(g * I(this, Ag)))), o(this, _, Math.max(1, Math.round(C * I(this, Ag)))), h(this, nI, TI).call(this);
1280
1129
  } else
1281
- L(this, Dg, cI).call(this);
1282
- I(this, U) && L(this, wg, Ng).call(this), L(this, Fg, dI).call(this);
1130
+ h(this, Fg, dI).call(this);
1131
+ I(this, U) && h(this, wg, Qg).call(this), h(this, Dg, AI).call(this);
1283
1132
  }
1284
1133
  updateConfig(g) {
1285
- Object.assign(I(this, Sg), g);
1134
+ Object.assign(I(this, ug), g);
1286
1135
  }
1287
1136
  destroy() {
1288
- var g, C, i, s, l, t, S, u, c, p, a;
1289
- if (o(this, pI, !0), this.stop(), L(this, BI, FI).call(this), L(this, GI, JI).call(this), I(this, N) && (I(this, N).close(), o(this, N, null)), I(this, D))
1290
- (g = I(this, Xg)) == null || g.destroy(), (C = I(this, vg)) == null || C.destroy(), (i = I(this, Rg)) == null || i.destroy(), (s = I(this, Wg)) == null || s.destroy(), (l = I(this, Yg)) == null || l.destroy(), (t = I(this, Ag)) == null || t.destroy(), (S = I(this, cg)) == null || S.destroy(), (u = I(this, Ug)) == null || u.destroy(), (c = I(this, xg)) == null || c.destroy(), (p = I(this, kg)) == null || p.destroy(), (a = I(this, Hg)) == null || a.destroy(), I(this, D).device.destroy();
1137
+ var g, C, i, s, t, l, u, Z, d, S, a;
1138
+ if (o(this, BI, !0), this.stop(), h(this, rI, JI).call(this), h(this, GI, zI).call(this), I(this, N) && (I(this, N).close(), o(this, N, null)), I(this, F))
1139
+ (g = I(this, Hg)) == null || g.destroy(), (C = I(this, vg)) == null || C.destroy(), (i = I(this, Wg)) == null || i.destroy(), (s = I(this, Rg)) == null || s.destroy(), (t = I(this, Ug)) == null || t.destroy(), (l = I(this, cg)) == null || l.destroy(), (u = I(this, dg)) == null || u.destroy(), (Z = I(this, Yg)) == null || Z.destroy(), (d = I(this, kg)) == null || d.destroy(), (S = I(this, Mg)) == null || S.destroy(), (a = I(this, Xg)) == null || a.destroy(), I(this, F).device.destroy();
1291
1140
  else {
1292
- const A = I(this, j);
1293
- for (const Z of Object.values(I(this, Vg)))
1294
- Z.dispose();
1295
- const m = A.getExtension("WEBGL_lose_context");
1141
+ const c = I(this, j);
1142
+ for (const B of Object.values(I(this, Kg)))
1143
+ B.dispose();
1144
+ const m = c.getExtension("WEBGL_lose_context");
1296
1145
  m == null || m.loseContext();
1297
1146
  }
1298
1147
  }
@@ -1300,334 +1149,334 @@ const NI = class NI {
1300
1149
  // Loop control
1301
1150
  // ---------------------------------------------------------------------------
1302
1151
  start() {
1303
- if (I(this, lg) !== null)
1152
+ if (I(this, tg) !== null)
1304
1153
  return;
1305
1154
  const g = () => {
1306
- L(this, HI, sC).call(this), o(this, lg, PI(g));
1155
+ h(this, vI, lC).call(this), o(this, tg, qI(g));
1307
1156
  };
1308
- o(this, lg, PI(g));
1157
+ o(this, tg, qI(g));
1309
1158
  }
1310
1159
  stop() {
1311
- I(this, lg) !== null && (jC(I(this, lg)), o(this, lg, null));
1160
+ I(this, tg) !== null && (_C(I(this, tg)), o(this, tg, null));
1312
1161
  }
1313
1162
  get isRunning() {
1314
- return I(this, lg) !== null;
1163
+ return I(this, tg) !== null;
1315
1164
  }
1316
1165
  };
1317
- yg = new WeakMap(), j = new WeakMap(), mI = new WeakMap(), Vg = new WeakMap(), Og = new WeakMap(), k = new WeakMap(), H = new WeakMap(), Ig = new WeakMap(), Cg = new WeakMap(), ig = new WeakMap(), og = new WeakMap(), z = new WeakMap(), eg = new WeakMap(), D = new WeakMap(), jg = new WeakMap(), Hg = new WeakMap(), Pg = new WeakMap(), M = new WeakMap(), h = new WeakMap(), rg = new WeakMap(), sg = new WeakMap(), ng = new WeakMap(), E = new WeakMap(), Xg = new WeakMap(), vg = new WeakMap(), Rg = new WeakMap(), Wg = new WeakMap(), Yg = new WeakMap(), Ag = new WeakMap(), cg = new WeakMap(), Ug = new WeakMap(), xg = new WeakMap(), kg = new WeakMap(), V = new WeakMap(), X = new WeakMap(), P = new WeakMap(), _ = new WeakMap(), F = new WeakMap(), _g = new WeakMap(), dg = new WeakMap(), N = new WeakMap(), bg = new WeakMap(), Sg = new WeakMap(), w = new WeakMap(), U = new WeakMap(), lg = new WeakMap(), Mg = new WeakMap(), pI = new WeakMap(), fg = new WeakMap(), VI = new WeakSet(), eC = function(g) {
1166
+ Vg = new WeakMap(), j = new WeakMap(), mI = new WeakMap(), Kg = new WeakMap(), Og = new WeakMap(), M = new WeakMap(), X = new WeakMap(), Ig = new WeakMap(), Cg = new WeakMap(), ig = new WeakMap(), og = new WeakMap(), Q = new WeakMap(), eg = new WeakMap(), F = new WeakMap(), jg = new WeakMap(), Xg = new WeakMap(), Pg = new WeakMap(), x = new WeakMap(), b = new WeakMap(), Gg = new WeakMap(), sg = new WeakMap(), pg = new WeakMap(), E = new WeakMap(), Hg = new WeakMap(), vg = new WeakMap(), Wg = new WeakMap(), Rg = new WeakMap(), Ug = new WeakMap(), cg = new WeakMap(), dg = new WeakMap(), Yg = new WeakMap(), kg = new WeakMap(), Mg = new WeakMap(), K = new WeakMap(), H = new WeakMap(), P = new WeakMap(), _ = new WeakMap(), D = new WeakMap(), _g = new WeakMap(), Ag = new WeakMap(), N = new WeakMap(), Lg = new WeakMap(), ug = new WeakMap(), L = new WeakMap(), SI = new WeakMap(), U = new WeakMap(), tg = new WeakMap(), xg = new WeakMap(), BI = new WeakMap(), fg = new WeakMap(), HI = new WeakSet(), tC = function(g) {
1318
1167
  const { device: C, format: i } = g;
1319
- o(this, jg, zC(C, i, I(this, fg))), o(this, Hg, JC(C)), o(this, Pg, NC(C)), o(this, Xg, gg(C, 16)), o(this, vg, gg(C, 16)), o(this, Rg, gg(C, 16)), o(this, Wg, gg(C, 16)), o(this, Yg, gg(C, 16)), o(this, Ag, gg(C, 48)), o(this, cg, gg(C, 48)), o(this, Ug, gg(C, 16)), o(this, xg, gg(C, 16)), o(this, kg, gg(C, 64));
1320
- }, Dg = new WeakSet(), cI = function() {
1321
- const g = I(this, yg);
1322
- "clientWidth" in g && g.clientWidth > 0 ? (o(this, F, (typeof window < "u" && window.devicePixelRatio || 1) * I(this, _g)), o(this, V, g.width = Math.round(g.clientWidth * I(this, F))), o(this, X, g.height = Math.round(g.clientHeight * I(this, F)))) : (o(this, V, g.width), o(this, X, g.height)), !(I(this, V) === 0 || I(this, X) === 0) && (o(this, P, Math.max(1, Math.round(I(this, V) * I(this, dg)))), o(this, _, Math.max(1, Math.round(I(this, X) * I(this, dg)))), L(this, ZI, DI).call(this));
1323
- }, ZI = new WeakSet(), DI = function() {
1324
- if (L(this, BI, FI).call(this), I(this, D)) {
1325
- const { device: g } = I(this, D), C = "rgba16float", i = I(this, P), s = I(this, _);
1326
- o(this, M, fI(g, C, i, s)), o(this, h, fI(g, C, i, s)), o(this, sg, fI(g, C, i, s)), o(this, rg, KI(g, C, i, s)), o(this, ng, KI(g, C, i, s));
1168
+ o(this, jg, NC(C, i, I(this, fg))), o(this, Xg, zC(C)), o(this, Pg, EC(C)), o(this, Hg, gg(C, 16)), o(this, vg, gg(C, 16)), o(this, Wg, gg(C, 16)), o(this, Rg, gg(C, 16)), o(this, Ug, gg(C, 16)), o(this, cg, gg(C, 48)), o(this, dg, gg(C, 48)), o(this, Yg, gg(C, 16)), o(this, kg, gg(C, 16)), o(this, Mg, gg(C, 64));
1169
+ }, Fg = new WeakSet(), dI = function() {
1170
+ const g = I(this, Vg);
1171
+ "clientWidth" in g && g.clientWidth > 0 ? (o(this, D, (typeof window < "u" && window.devicePixelRatio || 1) * I(this, _g)), o(this, K, g.width = Math.round(g.clientWidth * I(this, D))), o(this, H, g.height = Math.round(g.clientHeight * I(this, D)))) : (o(this, K, g.width), o(this, H, g.height)), !(I(this, K) === 0 || I(this, H) === 0) && (o(this, P, Math.max(1, Math.round(I(this, K) * I(this, Ag)))), o(this, _, Math.max(1, Math.round(I(this, H) * I(this, Ag)))), h(this, nI, TI).call(this));
1172
+ }, nI = new WeakSet(), TI = function() {
1173
+ if (h(this, rI, JI).call(this), I(this, F)) {
1174
+ const { device: g } = I(this, F), C = "rgba16float", i = I(this, P), s = I(this, _);
1175
+ o(this, x, DI(g, C, i, s)), o(this, b, DI(g, C, i, s)), o(this, sg, DI(g, C, i, s)), o(this, Gg, KI(g, C, i, s)), o(this, pg, KI(g, C, i, s));
1327
1176
  } else {
1328
1177
  const g = I(this, j), C = I(this, mI), i = I(this, P), s = I(this, _);
1329
- o(this, k, MI(g, C, i, s)), o(this, H, MI(g, C, i, s)), o(this, Cg, MI(g, C, i, s)), o(this, Ig, hI(g, C, i, s)), o(this, ig, hI(g, C, i, s));
1178
+ o(this, M, FI(g, C, i, s)), o(this, X, FI(g, C, i, s)), o(this, Cg, FI(g, C, i, s)), o(this, Ig, VI(g, C, i, s)), o(this, ig, VI(g, C, i, s));
1330
1179
  }
1331
- }, wg = new WeakSet(), Ng = function() {
1332
- if (!(!I(this, U) || I(this, V) === 0 || I(this, X) === 0)) {
1333
- if (L(this, GI, JI).call(this), I(this, D)) {
1334
- const { device: g } = I(this, D);
1335
- I(this, U).type === "text" ? o(this, E, GC(
1180
+ }, wg = new WeakSet(), Qg = function() {
1181
+ if (!(!I(this, U) || I(this, K) === 0 || I(this, H) === 0)) {
1182
+ if (h(this, GI, zI).call(this), I(this, F)) {
1183
+ const { device: g } = I(this, F);
1184
+ I(this, U).type === "text" ? o(this, E, pC(
1336
1185
  g,
1337
- I(this, V),
1338
- I(this, X),
1186
+ I(this, K),
1187
+ I(this, H),
1339
1188
  I(this, U).opts,
1340
1189
  I(this, N),
1341
- I(this, bg)
1342
- )) : o(this, E, rC(
1190
+ I(this, Lg)
1191
+ )) : o(this, E, LC(
1343
1192
  g,
1344
1193
  I(this, U).bitmap,
1345
- I(this, V),
1346
- I(this, X),
1194
+ I(this, K),
1195
+ I(this, H),
1347
1196
  I(this, U).effect,
1348
1197
  I(this, U).size,
1349
1198
  I(this, N),
1350
- I(this, bg)
1199
+ I(this, Lg)
1351
1200
  ));
1352
1201
  } else {
1353
1202
  const g = I(this, j);
1354
1203
  if (I(this, U).type === "text") {
1355
- const { backgroundTex: C, obstacleTex: i, coverageTex: s } = ZC(
1204
+ const { backgroundTex: C, obstacleTex: i, coverageTex: s } = rC(
1356
1205
  g,
1357
- I(this, V),
1358
- I(this, X),
1206
+ I(this, K),
1207
+ I(this, H),
1359
1208
  I(this, U).opts,
1360
1209
  I(this, N),
1361
- I(this, bg)
1210
+ I(this, Lg)
1362
1211
  );
1363
- o(this, og, C), o(this, z, i), o(this, eg, s);
1212
+ o(this, og, C), o(this, Q, i), o(this, eg, s);
1364
1213
  } else {
1365
- const { backgroundTex: C, obstacleTex: i, coverageTex: s } = BC(
1214
+ const { backgroundTex: C, obstacleTex: i, coverageTex: s } = GC(
1366
1215
  g,
1367
1216
  I(this, U).bitmap,
1368
- I(this, V),
1369
- I(this, X),
1217
+ I(this, K),
1218
+ I(this, H),
1370
1219
  I(this, U).effect,
1371
1220
  I(this, U).size,
1372
1221
  I(this, N),
1373
- I(this, bg)
1222
+ I(this, Lg)
1374
1223
  );
1375
- o(this, og, C), o(this, z, i), o(this, eg, s);
1224
+ o(this, og, C), o(this, Q, i), o(this, eg, s);
1376
1225
  }
1377
1226
  }
1378
- o(this, Mg, !0);
1227
+ o(this, xg, !0);
1379
1228
  }
1380
- }, Fg = new WeakSet(), dI = function() {
1381
- I(this, Mg) && !this.isRunning && this.start();
1382
- }, BI = new WeakSet(), FI = function() {
1383
- var g, C, i, s, l, t, S, u;
1384
- if (I(this, D))
1385
- (g = I(this, M)) == null || g.dispose(), (C = I(this, h)) == null || C.dispose(), (i = I(this, sg)) == null || i.dispose(), (s = I(this, rg)) == null || s.tex.destroy(), (l = I(this, ng)) == null || l.tex.destroy(), o(this, M, o(this, h, o(this, sg, null))), o(this, rg, o(this, ng, null));
1229
+ }, Dg = new WeakSet(), AI = function() {
1230
+ I(this, xg) && !this.isRunning && this.start();
1231
+ }, rI = new WeakSet(), JI = function() {
1232
+ var g, C, i, s, t, l, u, Z;
1233
+ if (I(this, F))
1234
+ (g = I(this, x)) == null || g.dispose(), (C = I(this, b)) == null || C.dispose(), (i = I(this, sg)) == null || i.dispose(), (s = I(this, Gg)) == null || s.tex.destroy(), (t = I(this, pg)) == null || t.tex.destroy(), o(this, x, o(this, b, o(this, sg, null))), o(this, Gg, o(this, pg, null));
1386
1235
  else {
1387
- const c = I(this, j);
1388
- (t = I(this, k)) == null || t.dispose(), (S = I(this, H)) == null || S.dispose(), (u = I(this, Cg)) == null || u.dispose(), I(this, Ig) && (c.deleteTexture(I(this, Ig).tex), c.deleteFramebuffer(I(this, Ig).fbo)), I(this, ig) && (c.deleteTexture(I(this, ig).tex), c.deleteFramebuffer(I(this, ig).fbo)), o(this, k, o(this, H, o(this, Cg, o(this, Ig, o(this, ig, null)))));
1236
+ const d = I(this, j);
1237
+ (l = I(this, M)) == null || l.dispose(), (u = I(this, X)) == null || u.dispose(), (Z = I(this, Cg)) == null || Z.dispose(), I(this, Ig) && (d.deleteTexture(I(this, Ig).tex), d.deleteFramebuffer(I(this, Ig).fbo)), I(this, ig) && (d.deleteTexture(I(this, ig).tex), d.deleteFramebuffer(I(this, ig).fbo)), o(this, M, o(this, X, o(this, Cg, o(this, Ig, o(this, ig, null)))));
1389
1238
  }
1390
- }, GI = new WeakSet(), JI = function() {
1391
- if (I(this, D))
1239
+ }, GI = new WeakSet(), zI = function() {
1240
+ if (I(this, F))
1392
1241
  I(this, E) && (I(this, E).backgroundTex.destroy(), I(this, E).obstacleTex.destroy(), I(this, E).sharedCoverage || I(this, E).coverageTex.destroy(), o(this, E, null));
1393
1242
  else {
1394
1243
  const g = I(this, j);
1395
- I(this, og) && g.deleteTexture(I(this, og)), I(this, z) && g.deleteTexture(I(this, z)), I(this, eg) && I(this, eg) !== I(this, z) && g.deleteTexture(I(this, eg)), o(this, og, o(this, z, o(this, eg, null)));
1244
+ I(this, og) && g.deleteTexture(I(this, og)), I(this, Q) && g.deleteTexture(I(this, Q)), I(this, eg) && I(this, eg) !== I(this, Q) && g.deleteTexture(I(this, eg)), o(this, og, o(this, Q, o(this, eg, null)));
1396
1245
  }
1397
- }, HI = new WeakSet(), sC = function() {
1398
- !I(this, Mg) || I(this, V) === 0 || (I(this, D) ? L(this, XI, lC).call(this) : L(this, WI, AC).call(this));
1399
- }, XI = new WeakSet(), lC = function() {
1400
- const g = I(this, D), C = g.device, i = I(this, jg), s = I(this, Hg), l = I(this, Pg), t = I(this, Sg), S = I(this, E);
1401
- if (!I(this, M) || !I(this, h))
1246
+ }, vI = new WeakSet(), lC = function() {
1247
+ !I(this, xg) || I(this, K) === 0 || (I(this, F) ? h(this, WI, oC).call(this) : h(this, YI, AC).call(this));
1248
+ }, WI = new WeakSet(), oC = function() {
1249
+ const g = I(this, F), C = g.device, i = I(this, jg), s = I(this, Xg), t = I(this, Pg), l = I(this, ug), u = I(this, E);
1250
+ if (!I(this, x) || !I(this, b))
1402
1251
  return;
1403
- I(this, w).x += (I(this, w).targetX - I(this, w).x) * 0.15, I(this, w).y += (I(this, w).targetY - I(this, w).y) * 0.15;
1404
- const u = I(this, P), c = I(this, _), p = I(this, V), a = I(this, X), A = 1 / u, m = 1 / c;
1405
- jI(C, I(this, Xg), A, m, AI, t.velocityDissipation), wI(C, I(this, Rg), A, m), wI(C, I(this, Wg), A, m), wI(C, I(this, Yg), A, m), wI(C, I(this, Ug), A, m), QC(C, I(this, xg), A, m, t.curl, AI), EC(
1252
+ I(this, L).x += (I(this, L).targetX - I(this, L).x) * 0.15, I(this, L).y += (I(this, L).targetY - I(this, L).y) * 0.15;
1253
+ const Z = I(this, P), d = I(this, _), S = I(this, K), a = I(this, H), c = 1 / Z, m = 1 / d;
1254
+ _I(C, I(this, Hg), c, m, cI, l.velocityDissipation), hI(C, I(this, Wg), c, m), hI(C, I(this, Rg), c, m), hI(C, I(this, Ug), c, m), hI(C, I(this, Yg), c, m), OC(C, I(this, kg), c, m, l.curl, cI), jC(
1406
1255
  C,
1407
- I(this, kg),
1408
- 1 / p,
1256
+ I(this, Mg),
1257
+ 1 / S,
1409
1258
  1 / a,
1410
- t.refraction,
1411
- t.specularExp,
1412
- bI(t.waterColor),
1413
- bI(t.glowColor),
1414
- t.shine,
1415
- t.warpStrength ?? 0.015,
1416
- _I[t.algorithm] ?? 0,
1259
+ l.refraction,
1260
+ l.specularExp,
1261
+ wI(l.waterColor),
1262
+ wI(l.glowColor),
1263
+ l.shine,
1264
+ l.warpStrength ?? 0.015,
1265
+ $I[l.algorithm] ?? 0,
1417
1266
  I(this, fg)
1418
1267
  );
1419
- const Z = C.createCommandEncoder(), r = (B, K) => C.createBindGroup({ layout: B.getBindGroupLayout(0), entries: K }), b = { binding: 1, resource: l };
1268
+ const B = C.createCommandEncoder(), r = (n, y) => C.createBindGroup({ layout: n.getBindGroupLayout(0), entries: y }), w = { binding: 1, resource: t };
1420
1269
  {
1421
- const B = r(i.advection, [
1422
- { binding: 0, resource: { buffer: I(this, Xg) } },
1423
- b,
1424
- { binding: 2, resource: I(this, h).read.view },
1425
- { binding: 3, resource: I(this, h).read.view },
1426
- { binding: 4, resource: S.obstacleView }
1270
+ const n = r(i.advection, [
1271
+ { binding: 0, resource: { buffer: I(this, Hg) } },
1272
+ w,
1273
+ { binding: 2, resource: I(this, b).read.view },
1274
+ { binding: 3, resource: I(this, b).read.view },
1275
+ { binding: 4, resource: u.obstacleView }
1427
1276
  ]);
1428
- O(Z, i.advection, B, s, I(this, h).write.view);
1277
+ O(B, i.advection, n, s, I(this, b).write.view);
1429
1278
  }
1430
- I(this, h).swap();
1279
+ I(this, b).swap();
1431
1280
  {
1432
- jI(C, I(this, vg), A, m, AI, t.densityDissipation);
1433
- const B = r(i.advection, [
1281
+ _I(C, I(this, vg), c, m, cI, l.densityDissipation);
1282
+ const n = r(i.advection, [
1434
1283
  { binding: 0, resource: { buffer: I(this, vg) } },
1435
- b,
1436
- { binding: 2, resource: I(this, h).read.view },
1437
- { binding: 3, resource: I(this, M).read.view },
1438
- { binding: 4, resource: S.obstacleView }
1284
+ w,
1285
+ { binding: 2, resource: I(this, b).read.view },
1286
+ { binding: 3, resource: I(this, x).read.view },
1287
+ { binding: 4, resource: u.obstacleView }
1439
1288
  ]);
1440
- O(Z, i.advection, B, s, I(this, M).write.view);
1289
+ O(B, i.advection, n, s, I(this, x).write.view);
1441
1290
  }
1442
- I(this, M).swap();
1291
+ I(this, x).swap();
1443
1292
  {
1444
- const B = r(i.curl, [
1445
- { binding: 0, resource: { buffer: I(this, Ug) } },
1446
- b,
1447
- { binding: 2, resource: I(this, h).read.view }
1293
+ const n = r(i.curl, [
1294
+ { binding: 0, resource: { buffer: I(this, Yg) } },
1295
+ w,
1296
+ { binding: 2, resource: I(this, b).read.view }
1448
1297
  ]);
1449
- O(Z, i.curl, B, s, I(this, ng).view);
1298
+ O(B, i.curl, n, s, I(this, pg).view);
1450
1299
  }
1451
1300
  {
1452
- const B = r(i.vorticity, [
1453
- { binding: 0, resource: { buffer: I(this, xg) } },
1454
- b,
1455
- { binding: 2, resource: I(this, h).read.view },
1456
- { binding: 3, resource: I(this, ng).view }
1301
+ const n = r(i.vorticity, [
1302
+ { binding: 0, resource: { buffer: I(this, kg) } },
1303
+ w,
1304
+ { binding: 2, resource: I(this, b).read.view },
1305
+ { binding: 3, resource: I(this, pg).view }
1457
1306
  ]);
1458
- O(Z, i.vorticity, B, s, I(this, h).write.view);
1307
+ O(B, i.vorticity, n, s, I(this, b).write.view);
1459
1308
  }
1460
- if (I(this, h).swap(), I(this, w).moved) {
1461
- const B = I(this, w).x * I(this, F) / p, K = I(this, w).y * I(this, F) / a;
1462
- LI(
1309
+ if (I(this, b).swap(), I(this, L).moved) {
1310
+ const n = I(this, L).x * I(this, D) / S, y = I(this, L).y * I(this, D) / a;
1311
+ bI(
1463
1312
  C,
1464
- I(this, Ag),
1465
- A,
1313
+ I(this, cg),
1314
+ c,
1466
1315
  m,
1467
- p / a,
1468
- t.splatRadius,
1469
- I(this, w).dx * t.splatForce,
1470
- I(this, w).dy * t.splatForce,
1316
+ S / a,
1317
+ l.splatRadius,
1318
+ I(this, L).dx * l.splatForce,
1319
+ I(this, L).dy * l.splatForce,
1471
1320
  0,
1472
- B,
1473
- K
1321
+ n,
1322
+ y
1474
1323
  );
1475
1324
  {
1476
- const W = r(i.splat, [
1477
- { binding: 0, resource: { buffer: I(this, Ag) } },
1478
- b,
1479
- { binding: 2, resource: I(this, h).read.view }
1325
+ const v = r(i.splat, [
1326
+ { binding: 0, resource: { buffer: I(this, cg) } },
1327
+ w,
1328
+ { binding: 2, resource: I(this, b).read.view }
1480
1329
  ]);
1481
- O(Z, i.splat, W, s, I(this, h).write.view);
1330
+ O(B, i.splat, v, s, I(this, b).write.view);
1482
1331
  }
1483
- I(this, h).swap(), LI(
1332
+ I(this, b).swap(), bI(
1484
1333
  C,
1485
- I(this, cg),
1486
- A,
1334
+ I(this, dg),
1335
+ c,
1487
1336
  m,
1488
- p / a,
1489
- t.splatRadius,
1337
+ S / a,
1338
+ l.splatRadius,
1490
1339
  1,
1491
1340
  1,
1492
1341
  1,
1493
- B,
1494
- K
1342
+ n,
1343
+ y
1495
1344
  );
1496
1345
  {
1497
- const W = r(i.splat, [
1498
- { binding: 0, resource: { buffer: I(this, cg) } },
1499
- b,
1500
- { binding: 2, resource: I(this, M).read.view }
1346
+ const v = r(i.splat, [
1347
+ { binding: 0, resource: { buffer: I(this, dg) } },
1348
+ w,
1349
+ { binding: 2, resource: I(this, x).read.view }
1501
1350
  ]);
1502
- O(Z, i.splat, W, s, I(this, M).write.view);
1351
+ O(B, i.splat, v, s, I(this, x).write.view);
1503
1352
  }
1504
- I(this, M).swap(), I(this, w).moved = !1;
1353
+ I(this, x).swap(), I(this, L).moved = !1;
1505
1354
  }
1506
1355
  {
1507
- const B = r(i.divergence, [
1508
- { binding: 0, resource: { buffer: I(this, Rg) } },
1509
- b,
1510
- { binding: 2, resource: I(this, h).read.view },
1511
- { binding: 3, resource: S.obstacleView }
1356
+ const n = r(i.divergence, [
1357
+ { binding: 0, resource: { buffer: I(this, Wg) } },
1358
+ w,
1359
+ { binding: 2, resource: I(this, b).read.view },
1360
+ { binding: 3, resource: u.obstacleView }
1512
1361
  ]);
1513
- O(Z, i.divergence, B, s, I(this, rg).view);
1362
+ O(B, i.divergence, n, s, I(this, Gg).view);
1514
1363
  }
1515
- for (let B = 0; B < t.pressureIterations; B++) {
1516
- const K = r(i.pressure, [
1517
- { binding: 0, resource: { buffer: I(this, Wg) } },
1518
- b,
1364
+ for (let n = 0; n < l.pressureIterations; n++) {
1365
+ const y = r(i.pressure, [
1366
+ { binding: 0, resource: { buffer: I(this, Rg) } },
1367
+ w,
1519
1368
  { binding: 2, resource: I(this, sg).read.view },
1520
- { binding: 3, resource: I(this, rg).view },
1521
- { binding: 4, resource: S.obstacleView }
1369
+ { binding: 3, resource: I(this, Gg).view },
1370
+ { binding: 4, resource: u.obstacleView }
1522
1371
  ]);
1523
- O(Z, i.pressure, K, s, I(this, sg).write.view), I(this, sg).swap();
1372
+ O(B, i.pressure, y, s, I(this, sg).write.view), I(this, sg).swap();
1524
1373
  }
1525
1374
  {
1526
- const B = r(i.gradientSubtract, [
1527
- { binding: 0, resource: { buffer: I(this, Yg) } },
1528
- b,
1375
+ const n = r(i.gradientSubtract, [
1376
+ { binding: 0, resource: { buffer: I(this, Ug) } },
1377
+ w,
1529
1378
  { binding: 2, resource: I(this, sg).read.view },
1530
- { binding: 3, resource: I(this, h).read.view },
1531
- { binding: 4, resource: S.obstacleView }
1379
+ { binding: 3, resource: I(this, b).read.view },
1380
+ { binding: 4, resource: u.obstacleView }
1532
1381
  ]);
1533
- O(Z, i.gradientSubtract, B, s, I(this, h).write.view);
1382
+ O(B, i.gradientSubtract, n, s, I(this, b).write.view);
1534
1383
  }
1535
- I(this, h).swap();
1384
+ I(this, b).swap();
1536
1385
  {
1537
- const B = g.context.getCurrentTexture().createView(), K = r(i.display, [
1538
- { binding: 0, resource: { buffer: I(this, kg) } },
1539
- b,
1540
- { binding: 2, resource: I(this, M).read.view },
1541
- { binding: 3, resource: S.obstacleView },
1542
- { binding: 4, resource: S.backgroundView },
1543
- { binding: 5, resource: S.coverageView },
1544
- { binding: 6, resource: I(this, h).read.view }
1386
+ const n = g.context.getCurrentTexture().createView(), y = r(i.display, [
1387
+ { binding: 0, resource: { buffer: I(this, Mg) } },
1388
+ w,
1389
+ { binding: 2, resource: I(this, x).read.view },
1390
+ { binding: 3, resource: u.obstacleView },
1391
+ { binding: 4, resource: u.backgroundView },
1392
+ { binding: 5, resource: u.coverageView },
1393
+ { binding: 6, resource: I(this, b).read.view }
1545
1394
  ]);
1546
- OC(Z, i.display, K, s, B);
1395
+ PC(B, i.display, y, s, n);
1547
1396
  }
1548
- C.queue.submit([Z.finish()]);
1549
- }, vI = new WeakSet(), tC = function(g, C, i, s, l) {
1550
- const S = I(this, D).device, u = I(this, jg).splat, c = I(this, Hg), p = I(this, Pg), a = I(this, Sg), A = I(this, P), m = I(this, _), Z = 1 / A, r = 1 / m, b = S.createCommandEncoder(), B = { binding: 1, resource: p }, K = (Q) => S.createBindGroup({ layout: u.getBindGroupLayout(0), entries: Q }), W = g * I(this, F) / I(this, V), x = C * I(this, F) / I(this, X);
1551
- LI(
1552
- S,
1553
- I(this, Ag),
1554
- Z,
1397
+ C.queue.submit([B.finish()]);
1398
+ }, RI = new WeakSet(), cC = function(g, C, i, s, t) {
1399
+ const u = I(this, F).device, Z = I(this, jg).splat, d = I(this, Xg), S = I(this, Pg), a = I(this, ug), c = I(this, P), m = I(this, _), B = 1 / c, r = 1 / m, w = u.createCommandEncoder(), n = { binding: 1, resource: S }, y = (T) => u.createBindGroup({ layout: Z.getBindGroupLayout(0), entries: T }), v = g * I(this, D) / I(this, K), Y = C * I(this, D) / I(this, H);
1400
+ bI(
1401
+ u,
1402
+ I(this, cg),
1403
+ B,
1555
1404
  r,
1556
- I(this, V) / I(this, X),
1405
+ I(this, K) / I(this, H),
1557
1406
  a.splatRadius,
1558
- i * a.splatForce * l,
1559
- s * a.splatForce * l,
1407
+ i * a.splatForce * t,
1408
+ s * a.splatForce * t,
1560
1409
  0,
1561
- W,
1562
- x
1410
+ v,
1411
+ Y
1563
1412
  );
1564
1413
  {
1565
- const Q = K([
1566
- { binding: 0, resource: { buffer: I(this, Ag) } },
1567
- B,
1568
- { binding: 2, resource: I(this, h).read.view }
1414
+ const T = y([
1415
+ { binding: 0, resource: { buffer: I(this, cg) } },
1416
+ n,
1417
+ { binding: 2, resource: I(this, b).read.view }
1569
1418
  ]);
1570
- O(b, u, Q, c, I(this, h).write.view);
1419
+ O(w, Z, T, d, I(this, b).write.view);
1571
1420
  }
1572
- I(this, h).swap(), LI(
1573
- S,
1574
- I(this, cg),
1575
- Z,
1421
+ I(this, b).swap(), bI(
1422
+ u,
1423
+ I(this, dg),
1424
+ B,
1576
1425
  r,
1577
- I(this, V) / I(this, X),
1426
+ I(this, K) / I(this, H),
1578
1427
  a.splatRadius,
1579
- l,
1580
- l,
1581
- l,
1582
- W,
1583
- x
1428
+ t,
1429
+ t,
1430
+ t,
1431
+ v,
1432
+ Y
1584
1433
  );
1585
1434
  {
1586
- const Q = K([
1587
- { binding: 0, resource: { buffer: I(this, cg) } },
1588
- B,
1589
- { binding: 2, resource: I(this, M).read.view }
1435
+ const T = y([
1436
+ { binding: 0, resource: { buffer: I(this, dg) } },
1437
+ n,
1438
+ { binding: 2, resource: I(this, x).read.view }
1590
1439
  ]);
1591
- O(b, u, Q, c, I(this, M).write.view);
1440
+ O(w, Z, T, d, I(this, x).write.view);
1592
1441
  }
1593
- I(this, M).swap(), S.queue.submit([b.finish()]);
1594
- }, RI = new WeakSet(), oC = function(g, C, i, s, l) {
1595
- const t = I(this, j), S = I(this, Sg), u = I(this, Vg).splat, c = I(this, Og);
1596
- t.viewport(0, 0, I(this, P), I(this, _)), u.bind(), t.uniform1f(u.uniforms.aspectRatio, I(this, V) / I(this, X)), t.uniform2f(u.uniforms.point, g * I(this, F) / I(this, V), 1 - C * I(this, F) / I(this, X)), t.uniform1f(u.uniforms.radius, S.splatRadius), t.uniform1i(u.uniforms.uTarget, 0), t.activeTexture(t.TEXTURE0), t.bindTexture(t.TEXTURE_2D, I(this, H).read.tex), t.uniform3f(u.uniforms.color, i * S.splatForce * l, -s * S.splatForce * l, 0), c(I(this, H).write.fbo), I(this, H).swap(), t.activeTexture(t.TEXTURE0), t.bindTexture(t.TEXTURE_2D, I(this, k).read.tex), t.uniform3f(u.uniforms.color, l, l, l), c(I(this, k).write.fbo), I(this, k).swap();
1597
- }, WI = new WeakSet(), AC = function() {
1598
- if (!I(this, k) || !I(this, H))
1442
+ I(this, x).swap(), u.queue.submit([w.finish()]);
1443
+ }, UI = new WeakSet(), dC = function(g, C, i, s, t) {
1444
+ const l = I(this, j), u = I(this, ug), Z = I(this, Kg).splat, d = I(this, Og);
1445
+ l.viewport(0, 0, I(this, P), I(this, _)), Z.bind(), l.uniform1f(Z.uniforms.aspectRatio, I(this, K) / I(this, H)), l.uniform2f(Z.uniforms.point, g * I(this, D) / I(this, K), 1 - C * I(this, D) / I(this, H)), l.uniform1f(Z.uniforms.radius, u.splatRadius), l.uniform1i(Z.uniforms.uTarget, 0), l.activeTexture(l.TEXTURE0), l.bindTexture(l.TEXTURE_2D, I(this, X).read.tex), l.uniform3f(Z.uniforms.color, i * u.splatForce * t, -s * u.splatForce * t, 0), d(I(this, X).write.fbo), I(this, X).swap(), l.activeTexture(l.TEXTURE0), l.bindTexture(l.TEXTURE_2D, I(this, M).read.tex), l.uniform3f(Z.uniforms.color, t, t, t), d(I(this, M).write.fbo), I(this, M).swap();
1446
+ }, YI = new WeakSet(), AC = function() {
1447
+ if (!I(this, M) || !I(this, X))
1599
1448
  return;
1600
- const g = I(this, j), C = I(this, Sg), { advection: i, divergence: s, pressure: l, gradientSubtract: t, splat: S, curl: u, vorticity: c, display: p } = I(this, Vg);
1601
- I(this, w).x += (I(this, w).targetX - I(this, w).x) * 0.15, I(this, w).y += (I(this, w).targetY - I(this, w).y) * 0.15;
1602
- const a = I(this, P), A = I(this, _), m = I(this, Og);
1603
- g.viewport(0, 0, a, A), i.bind(), g.uniform2f(i.uniforms.texelSize, 1 / a, 1 / A), g.uniform1f(i.uniforms.dt, AI), g.uniform1i(i.uniforms.uObstacle, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, z)), g.uniform1f(i.uniforms.dissipation, C.velocityDissipation), g.uniform1i(i.uniforms.uVelocity, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, H).read.tex), g.uniform1i(i.uniforms.uSource, 1), m(I(this, H).write.fbo), I(this, H).swap(), g.uniform1f(i.uniforms.dissipation, C.densityDissipation), g.uniform1i(i.uniforms.uSource, 2), g.activeTexture(g.TEXTURE2), g.bindTexture(g.TEXTURE_2D, I(this, k).read.tex), m(I(this, k).write.fbo), I(this, k).swap(), u.bind(), g.uniform2f(u.uniforms.texelSize, 1 / a, 1 / A), g.uniform1i(u.uniforms.uVelocity, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, H).read.tex), m(I(this, ig).fbo), c.bind(), g.uniform2f(c.uniforms.texelSize, 1 / a, 1 / A), g.uniform1f(c.uniforms.curl, C.curl), g.uniform1f(c.uniforms.dt, AI), g.uniform1i(c.uniforms.uVelocity, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, H).read.tex), g.uniform1i(c.uniforms.uCurl, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, ig).tex), m(I(this, H).write.fbo), I(this, H).swap(), I(this, w).moved && (S.bind(), g.uniform1f(S.uniforms.aspectRatio, I(this, V) / I(this, X)), g.uniform2f(S.uniforms.point, I(this, w).x * I(this, F) / I(this, V), 1 - I(this, w).y * I(this, F) / I(this, X)), g.uniform1f(S.uniforms.radius, C.splatRadius), g.uniform1i(S.uniforms.uTarget, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, H).read.tex), g.uniform3f(S.uniforms.color, I(this, w).dx * C.splatForce, -I(this, w).dy * C.splatForce, 0), m(I(this, H).write.fbo), I(this, H).swap(), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, k).read.tex), g.uniform3f(S.uniforms.color, 1, 1, 1), m(I(this, k).write.fbo), I(this, k).swap(), I(this, w).moved = !1), s.bind(), g.uniform2f(s.uniforms.texelSize, 1 / a, 1 / A), g.uniform1i(s.uniforms.uVelocity, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, H).read.tex), g.uniform1i(s.uniforms.uObstacle, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, z)), m(I(this, Ig).fbo), l.bind(), g.uniform2f(l.uniforms.texelSize, 1 / a, 1 / A), g.uniform1i(l.uniforms.uDivergence, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, Ig).tex), g.uniform1i(l.uniforms.uObstacle, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, z));
1604
- for (let Z = 0; Z < C.pressureIterations; Z++)
1605
- g.uniform1i(l.uniforms.uPressure, 2), g.activeTexture(g.TEXTURE2), g.bindTexture(g.TEXTURE_2D, I(this, Cg).read.tex), m(I(this, Cg).write.fbo), I(this, Cg).swap();
1606
- t.bind(), g.uniform2f(t.uniforms.texelSize, 1 / a, 1 / A), g.uniform1i(t.uniforms.uPressure, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, Cg).read.tex), g.uniform1i(t.uniforms.uVelocity, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, H).read.tex), g.uniform1i(t.uniforms.uObstacle, 2), g.activeTexture(g.TEXTURE2), g.bindTexture(g.TEXTURE_2D, I(this, z)), m(I(this, H).write.fbo), I(this, H).swap(), g.viewport(0, 0, I(this, V), I(this, X)), g.bindFramebuffer(g.FRAMEBUFFER, null), g.clear(g.COLOR_BUFFER_BIT), p.bind(), g.uniform2f(p.uniforms.texelSize, 1 / I(this, V), 1 / I(this, X)), g.uniform3fv(p.uniforms.uWaterColor, bI(C.waterColor)), g.uniform3fv(p.uniforms.uGlowColor, bI(C.glowColor)), g.uniform1f(p.uniforms.uRefraction, C.refraction), g.uniform1f(p.uniforms.uSpecularExp, C.specularExp), g.uniform1f(p.uniforms.uShine, C.shine), g.uniform1f(p.uniforms.uWarpStrength, C.warpStrength ?? 0.015), g.uniform1i(p.uniforms.uAlgorithm, _I[C.algorithm] ?? 0), g.uniform1i(p.uniforms.uEnableAlpha, I(this, fg) ? 1 : 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, k).read.tex), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, z)), g.activeTexture(g.TEXTURE2), g.bindTexture(g.TEXTURE_2D, I(this, og)), g.activeTexture(g.TEXTURE3), g.bindTexture(g.TEXTURE_2D, I(this, eg)), g.activeTexture(g.TEXTURE4), g.bindTexture(g.TEXTURE_2D, I(this, H).read.tex), g.uniform1i(p.uniforms.uTexture, 0), g.uniform1i(p.uniforms.uObstacle, 1), g.uniform1i(p.uniforms.uBackground, 2), g.uniform1i(p.uniforms.uCoverage, 3), g.uniform1i(p.uniforms.uVelocity, 4), m(null);
1449
+ const g = I(this, j), C = I(this, ug), { advection: i, divergence: s, pressure: t, gradientSubtract: l, splat: u, curl: Z, vorticity: d, display: S } = I(this, Kg);
1450
+ I(this, L).x += (I(this, L).targetX - I(this, L).x) * 0.15, I(this, L).y += (I(this, L).targetY - I(this, L).y) * 0.15;
1451
+ const a = I(this, P), c = I(this, _), m = I(this, Og);
1452
+ g.viewport(0, 0, a, c), i.bind(), g.uniform2f(i.uniforms.texelSize, 1 / a, 1 / c), g.uniform1f(i.uniforms.dt, cI), g.uniform1i(i.uniforms.uObstacle, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, Q)), g.uniform1f(i.uniforms.dissipation, C.velocityDissipation), g.uniform1i(i.uniforms.uVelocity, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, X).read.tex), g.uniform1i(i.uniforms.uSource, 1), m(I(this, X).write.fbo), I(this, X).swap(), g.uniform1f(i.uniforms.dissipation, C.densityDissipation), g.uniform1i(i.uniforms.uSource, 2), g.activeTexture(g.TEXTURE2), g.bindTexture(g.TEXTURE_2D, I(this, M).read.tex), m(I(this, M).write.fbo), I(this, M).swap(), Z.bind(), g.uniform2f(Z.uniforms.texelSize, 1 / a, 1 / c), g.uniform1i(Z.uniforms.uVelocity, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, X).read.tex), m(I(this, ig).fbo), d.bind(), g.uniform2f(d.uniforms.texelSize, 1 / a, 1 / c), g.uniform1f(d.uniforms.curl, C.curl), g.uniform1f(d.uniforms.dt, cI), g.uniform1i(d.uniforms.uVelocity, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, X).read.tex), g.uniform1i(d.uniforms.uCurl, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, ig).tex), m(I(this, X).write.fbo), I(this, X).swap(), I(this, L).moved && (u.bind(), g.uniform1f(u.uniforms.aspectRatio, I(this, K) / I(this, H)), g.uniform2f(u.uniforms.point, I(this, L).x * I(this, D) / I(this, K), 1 - I(this, L).y * I(this, D) / I(this, H)), g.uniform1f(u.uniforms.radius, C.splatRadius), g.uniform1i(u.uniforms.uTarget, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, X).read.tex), g.uniform3f(u.uniforms.color, I(this, L).dx * C.splatForce, -I(this, L).dy * C.splatForce, 0), m(I(this, X).write.fbo), I(this, X).swap(), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, M).read.tex), g.uniform3f(u.uniforms.color, 1, 1, 1), m(I(this, M).write.fbo), I(this, M).swap(), I(this, L).moved = !1), s.bind(), g.uniform2f(s.uniforms.texelSize, 1 / a, 1 / c), g.uniform1i(s.uniforms.uVelocity, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, X).read.tex), g.uniform1i(s.uniforms.uObstacle, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, Q)), m(I(this, Ig).fbo), t.bind(), g.uniform2f(t.uniforms.texelSize, 1 / a, 1 / c), g.uniform1i(t.uniforms.uDivergence, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, Ig).tex), g.uniform1i(t.uniforms.uObstacle, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, Q));
1453
+ for (let B = 0; B < C.pressureIterations; B++)
1454
+ g.uniform1i(t.uniforms.uPressure, 2), g.activeTexture(g.TEXTURE2), g.bindTexture(g.TEXTURE_2D, I(this, Cg).read.tex), m(I(this, Cg).write.fbo), I(this, Cg).swap();
1455
+ l.bind(), g.uniform2f(l.uniforms.texelSize, 1 / a, 1 / c), g.uniform1i(l.uniforms.uPressure, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, Cg).read.tex), g.uniform1i(l.uniforms.uVelocity, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, X).read.tex), g.uniform1i(l.uniforms.uObstacle, 2), g.activeTexture(g.TEXTURE2), g.bindTexture(g.TEXTURE_2D, I(this, Q)), m(I(this, X).write.fbo), I(this, X).swap(), g.viewport(0, 0, I(this, K), I(this, H)), g.bindFramebuffer(g.FRAMEBUFFER, null), g.clear(g.COLOR_BUFFER_BIT), S.bind(), g.uniform2f(S.uniforms.texelSize, 1 / I(this, K), 1 / I(this, H)), g.uniform3fv(S.uniforms.uWaterColor, wI(C.waterColor)), g.uniform3fv(S.uniforms.uGlowColor, wI(C.glowColor)), g.uniform1f(S.uniforms.uRefraction, C.refraction), g.uniform1f(S.uniforms.uSpecularExp, C.specularExp), g.uniform1f(S.uniforms.uShine, C.shine), g.uniform1f(S.uniforms.uWarpStrength, C.warpStrength ?? 0.015), g.uniform1i(S.uniforms.uAlgorithm, $I[C.algorithm] ?? 0), g.uniform1i(S.uniforms.uEnableAlpha, I(this, fg) ? 1 : 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, M).read.tex), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, Q)), g.activeTexture(g.TEXTURE2), g.bindTexture(g.TEXTURE_2D, I(this, og)), g.activeTexture(g.TEXTURE3), g.bindTexture(g.TEXTURE_2D, I(this, eg)), g.activeTexture(g.TEXTURE4), g.bindTexture(g.TEXTURE_2D, I(this, X).read.tex), g.uniform1i(S.uniforms.uTexture, 0), g.uniform1i(S.uniforms.uObstacle, 1), g.uniform1i(S.uniforms.uBackground, 2), g.uniform1i(S.uniforms.uCoverage, 3), g.uniform1i(S.uniforms.uVelocity, 4), m(null);
1607
1456
  };
1608
- let yI = NI;
1609
- const cC = "dmFyIFR0ID0gT2JqZWN0LmRlZmluZVByb3BlcnR5Owp2YXIgeXQgPSAoaSwgZSwgcikgPT4gZSBpbiBpID8gVHQoaSwgZSwgeyBlbnVtZXJhYmxlOiAhMCwgY29uZmlndXJhYmxlOiAhMCwgd3JpdGFibGU6ICEwLCB2YWx1ZTogciB9KSA6IGlbZV0gPSByOwp2YXIga2UgPSAoaSwgZSwgcikgPT4gKHl0KGksIHR5cGVvZiBlICE9ICJzeW1ib2wiID8gZSArICIiIDogZSwgciksIHIpLCBldCA9IChpLCBlLCByKSA9PiB7CiAgaWYgKCFlLmhhcyhpKSkKICAgIHRocm93IFR5cGVFcnJvcigiQ2Fubm90ICIgKyByKTsKfTsKdmFyIHQgPSAoaSwgZSwgcikgPT4gKGV0KGksIGUsICJyZWFkIGZyb20gcHJpdmF0ZSBmaWVsZCIpLCByID8gci5jYWxsKGkpIDogZS5nZXQoaSkpLCBmID0gKGksIGUsIHIpID0+IHsKICBpZiAoZS5oYXMoaSkpCiAgICB0aHJvdyBUeXBlRXJyb3IoIkNhbm5vdCBhZGQgdGhlIHNhbWUgcHJpdmF0ZSBtZW1iZXIgbW9yZSB0aGFuIG9uY2UiKTsKICBlIGluc3RhbmNlb2YgV2Vha1NldCA/IGUuYWRkKGkpIDogZS5zZXQoaSwgcik7Cn0sIGwgPSAoaSwgZSwgciwgcykgPT4gKGV0KGksIGUsICJ3cml0ZSB0byBwcml2YXRlIGZpZWxkIiksIHMgPyBzLmNhbGwoaSwgcikgOiBlLnNldChpLCByKSwgcik7CnZhciBTID0gKGksIGUsIHIpID0+IChldChpLCBlLCAiYWNjZXNzIHByaXZhdGUgbWV0aG9kIiksIHIpOwpjb25zdCB2dCA9IHsKICBkZW5zaXR5RGlzc2lwYXRpb246IDAuODMsCiAgdmVsb2NpdHlEaXNzaXBhdGlvbjogMC45MSwKICBwcmVzc3VyZUl0ZXJhdGlvbnM6IDEsCiAgY3VybDogMCwKICBzcGxhdFJhZGl1czogMC4xLAogIHNwbGF0Rm9yY2U6IDAuMDgsCiAgcmVmcmFjdGlvbjogMSwKICBzcGVjdWxhckV4cDogMCwKICBzaGluZTogMCwKICB3YXRlckNvbG9yOiAiIzAwMDAwMCIsCiAgZ2xvd0NvbG9yOiAiI2IzZDlmZiIsCiAgYWxnb3JpdGhtOiAiYXVyb3JhIiwKICB3YXJwU3RyZW5ndGg6IDAuMDQKfTsKKHsKICAuLi52dAp9KTsKY29uc3QgU3QgPSB7CiAgY2FsbTogewogICAgZGVuc2l0eURpc3NpcGF0aW9uOiAwLjk4LAogICAgdmVsb2NpdHlEaXNzaXBhdGlvbjogMC44MSwKICAgIGN1cmw6IDFlLTQsCiAgICBzcGxhdFJhZGl1czogMC4wNSwKICAgIHNwbGF0Rm9yY2U6IDAuMDgsCiAgICByZWZyYWN0aW9uOiAwLjE1LAogICAgc2hpbmU6IDAuMDMsCiAgICBnbG93Q29sb3I6ICIjOTlkOWZmIiwKICAgIHdhdGVyQ29sb3I6ICIjMDAwNTBkIgogIH0sCiAgc2FuZDogewogICAgZGVuc2l0eURpc3NpcGF0aW9uOiAwLjk1LAogICAgdmVsb2NpdHlEaXNzaXBhdGlvbjogMC44MSwKICAgIGN1cmw6IDEsCiAgICBzcGxhdFJhZGl1czogMC4yMywKICAgIHNwbGF0Rm9yY2U6IDAuMTYsCiAgICByZWZyYWN0aW9uOiAwLjgsCiAgICBzcGVjdWxhckV4cDogMCwKICAgIHNoaW5lOiAwLjMzLAogICAgZ2xvd0NvbG9yOiAiIzA3MDcwNyIsCiAgICB3YXRlckNvbG9yOiAiIzczNTQyMCIKICB9LAogIHdhdmU6IHsKICAgIGRlbnNpdHlEaXNzaXBhdGlvbjogMC45LAogICAgdmVsb2NpdHlEaXNzaXBhdGlvbjogMC4yLAogICAgY3VybDogMC4yLAogICAgc3BsYXRSYWRpdXM6IDAuMSwKICAgIHNwbGF0Rm9yY2U6IDAuMjIsCiAgICByZWZyYWN0aW9uOiAwLjM1LAogICAgc2hpbmU6IDAuMiwKICAgIGdsb3dDb2xvcjogIiM4MGNjZmYiLAogICAgd2F0ZXJDb2xvcjogIiMwMDAzMDgiCiAgfSwKICBuZW9uOiB7CiAgICBkZW5zaXR5RGlzc2lwYXRpb246IDAuNzUsCiAgICB2ZWxvY2l0eURpc3NpcGF0aW9uOiAwLjMsCiAgICBjdXJsOiAwLjA1LAogICAgc3BsYXRSYWRpdXM6IDAuMTgsCiAgICBzcGxhdEZvcmNlOiAwLjI5LAogICAgcmVmcmFjdGlvbjogMC4yNSwKICAgIHNwZWN1bGFyRXhwOiAwLjA0LAogICAgc2hpbmU6IDAuOTMsCiAgICBnbG93Q29sb3I6ICIjZmYzM2NjIiwKICAgIHdhdGVyQ29sb3I6ICIjMGQwMDE0IgogIH0sCiAgc21va2U6IHsKICAgIGRlbnNpdHlEaXNzaXBhdGlvbjogMC45MywKICAgIHZlbG9jaXR5RGlzc2lwYXRpb246IDAuNzEsCiAgICBjdXJsOiAwLjA0LAogICAgc3BsYXRSYWRpdXM6IDAuMjEsCiAgICBzcGxhdEZvcmNlOiAwLjE0LAogICAgcmVmcmFjdGlvbjogMC4wOCwKICAgIHNoaW5lOiAwLAogICAgZ2xvd0NvbG9yOiAiIzgwODA4MCIsCiAgICB3YXRlckNvbG9yOiAiIzBmMGYwZiIKICB9Cn07CmZ1bmN0aW9uIFdlKGkpIHsKICBpZiAoQXJyYXkuaXNBcnJheShpKSkKICAgIHJldHVybiBpOwogIGNvbnN0IGUgPSBpLnNsaWNlKDEsIDcpOwogIHJldHVybiBlLmxlbmd0aCA9PT0gMyA/IFsKICAgIHBhcnNlSW50KGVbMF0gKyBlWzBdLCAxNikgLyAyNTUsCiAgICBwYXJzZUludChlWzFdICsgZVsxXSwgMTYpIC8gMjU1LAogICAgcGFyc2VJbnQoZVsyXSArIGVbMl0sIDE2KSAvIDI1NQogIF0gOiBbCiAgICBwYXJzZUludChlLnNsaWNlKDAsIDIpLCAxNikgLyAyNTUsCiAgICBwYXJzZUludChlLnNsaWNlKDIsIDQpLCAxNikgLyAyNTUsCiAgICBwYXJzZUludChlLnNsaWNlKDQsIDYpLCAxNikgLyAyNTUKICBdOwp9CmZ1bmN0aW9uIHd0KGkgPSB7fSwgZSwgciA9IHZ0KSB7CiAgcmV0dXJuIHsgLi4uZSA/IHsgLi4uciwgLi4uU3RbZV0gfSA6IHIsIC4uLmkgfTsKfQpjb25zdCByZSA9ICgKICAvKiBnbHNsICovCiAgYAogIHByZWNpc2lvbiBoaWdocCBmbG9hdDsKICBhdHRyaWJ1dGUgdmVjMiBhUG9zaXRpb247CiAgdmFyeWluZyB2ZWMyIHZVdjsKICB2YXJ5aW5nIHZlYzIgdkw7IHZhcnlpbmcgdmVjMiB2UjsgdmFyeWluZyB2ZWMyIHZUOyB2YXJ5aW5nIHZlYzIgdkI7CiAgdW5pZm9ybSB2ZWMyIHRleGVsU2l6ZTsKICB2b2lkIG1haW4gKCkgewogICAgdlV2ID0gYVBvc2l0aW9uICogMC41ICsgMC41OwogICAgdkwgPSB2VXYgLSB2ZWMyKHRleGVsU2l6ZS54LCAwLjApOwogICAgdlIgPSB2VXYgKyB2ZWMyKHRleGVsU2l6ZS54LCAwLjApOwogICAgdlQgPSB2VXYgKyB2ZWMyKDAuMCwgdGV4ZWxTaXplLnkpOwogICAgdkIgPSB2VXYgLSB2ZWMyKDAuMCwgdGV4ZWxTaXplLnkpOwogICAgZ2xfUG9zaXRpb24gPSB2ZWM0KGFQb3NpdGlvbiwgMC4wLCAxLjApOwogIH0KYAopLCBSdCA9ICgKICAvKiBnbHNsICovCiAgYAogIHByZWNpc2lvbiBoaWdocCBmbG9hdDsKICB2YXJ5aW5nIHZlYzIgdlV2OwogIHVuaWZvcm0gc2FtcGxlcjJEIHVWZWxvY2l0eTsKICB1bmlmb3JtIHNhbXBsZXIyRCB1U291cmNlOwogIHVuaWZvcm0gc2FtcGxlcjJEIHVPYnN0YWNsZTsKICB1bmlmb3JtIHZlYzIgdGV4ZWxTaXplOwogIHVuaWZvcm0gZmxvYXQgZHQ7CiAgdW5pZm9ybSBmbG9hdCBkaXNzaXBhdGlvbjsKICB2b2lkIG1haW4gKCkgewogICAgZmxvYXQgb2JzICA9IHRleHR1cmUyRCh1T2JzdGFjbGUsIHZVdikucjsKICAgIHZlYzIgY29vcmQgPSB2VXYgLSBkdCAqIHRleHR1cmUyRCh1VmVsb2NpdHksIHZVdikueHkgKiB0ZXhlbFNpemU7CiAgICAvLyBTbW9vdGggZGFtcGluZzogb2JzPTAgb3V0c2lkZSAoZnVsbCBmbG93KSwgb2JzPTEgaW5zaWRlIChmdWxsIHN0b3ApLCBibHVycmVkCiAgICAvLyBib3VuZGFyeSBpbiBiZXR3ZWVuLiAgTm8gYnJhbmNoaW5nIOKAlCBtdWx0aXBseWluZyBieSAoMS1vYnMpIGlzIGVxdWl2YWxlbnQgdG8gdGhlCiAgICAvLyBoYXJkIHplcm8taW5zaWRlIGNoZWNrIGJ1dCB3aXRoIGEgY29udGludW91cyBncmFkaWVudCB0aGF0IGF2b2lkcyBncmlkIGFydGVmYWN0cy4KICAgIGdsX0ZyYWdDb2xvciA9IGRpc3NpcGF0aW9uICogdGV4dHVyZTJEKHVTb3VyY2UsIGNvb3JkKSAqICgxLjAgLSBvYnMpOwogIH0KYAopLCBFdCA9ICgKICAvKiBnbHNsICovCiAgYAogIHByZWNpc2lvbiBoaWdocCBmbG9hdDsKICB2YXJ5aW5nIHZlYzIgdkw7IHZhcnlpbmcgdmVjMiB2UjsgdmFyeWluZyB2ZWMyIHZUOyB2YXJ5aW5nIHZlYzIgdkI7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdVZlbG9jaXR5OwogIHVuaWZvcm0gc2FtcGxlcjJEIHVPYnN0YWNsZTsKICB2b2lkIG1haW4gKCkgewogICAgZmxvYXQgTCA9IHRleHR1cmUyRCh1VmVsb2NpdHksIHZMKS54ICogKDEuMCAtIHRleHR1cmUyRCh1T2JzdGFjbGUsIHZMKS5yKTsKICAgIGZsb2F0IFIgPSB0ZXh0dXJlMkQodVZlbG9jaXR5LCB2UikueCAqICgxLjAgLSB0ZXh0dXJlMkQodU9ic3RhY2xlLCB2Uikucik7CiAgICBmbG9hdCBUID0gdGV4dHVyZTJEKHVWZWxvY2l0eSwgdlQpLnkgKiAoMS4wIC0gdGV4dHVyZTJEKHVPYnN0YWNsZSwgdlQpLnIpOwogICAgZmxvYXQgQiA9IHRleHR1cmUyRCh1VmVsb2NpdHksIHZCKS55ICogKDEuMCAtIHRleHR1cmUyRCh1T2JzdGFjbGUsIHZCKS5yKTsKICAgIGdsX0ZyYWdDb2xvciA9IHZlYzQoMC41ICogKFIgLSBMICsgVCAtIEIpLCAwLjAsIDAuMCwgMS4wKTsKICB9CmAKKSwgVXQgPSAoCiAgLyogZ2xzbCAqLwogIGAKICBwcmVjaXNpb24gaGlnaHAgZmxvYXQ7CiAgdmFyeWluZyB2ZWMyIHZVdjsgdmFyeWluZyB2ZWMyIHZMOyB2YXJ5aW5nIHZlYzIgdlI7IHZhcnlpbmcgdmVjMiB2VDsgdmFyeWluZyB2ZWMyIHZCOwogIHVuaWZvcm0gc2FtcGxlcjJEIHVQcmVzc3VyZTsKICB1bmlmb3JtIHNhbXBsZXIyRCB1RGl2ZXJnZW5jZTsKICB1bmlmb3JtIHNhbXBsZXIyRCB1T2JzdGFjbGU7CiAgdm9pZCBtYWluICgpIHsKICAgIGZsb2F0IEMgPSB0ZXh0dXJlMkQodVByZXNzdXJlLCB2VXYpLng7CiAgICBmbG9hdCBMID0gbWl4KHRleHR1cmUyRCh1UHJlc3N1cmUsIHZMKS54LCBDLCB0ZXh0dXJlMkQodU9ic3RhY2xlLCB2TCkucik7CiAgICBmbG9hdCBSID0gbWl4KHRleHR1cmUyRCh1UHJlc3N1cmUsIHZSKS54LCBDLCB0ZXh0dXJlMkQodU9ic3RhY2xlLCB2Uikucik7CiAgICBmbG9hdCBUID0gbWl4KHRleHR1cmUyRCh1UHJlc3N1cmUsIHZUKS54LCBDLCB0ZXh0dXJlMkQodU9ic3RhY2xlLCB2VCkucik7CiAgICBmbG9hdCBCID0gbWl4KHRleHR1cmUyRCh1UHJlc3N1cmUsIHZCKS54LCBDLCB0ZXh0dXJlMkQodU9ic3RhY2xlLCB2Qikucik7CiAgICBmbG9hdCBkaXYgPSB0ZXh0dXJlMkQodURpdmVyZ2VuY2UsIHZVdikueDsKICAgIGdsX0ZyYWdDb2xvciA9IHZlYzQoKEwgKyBSICsgQiArIFQgLSBkaXYpICogMC4yNSwgMC4wLCAwLjAsIDEuMCk7CiAgfQpgCiksIER0ID0gKAogIC8qIGdsc2wgKi8KICBgCiAgcHJlY2lzaW9uIGhpZ2hwIGZsb2F0OwogIHZhcnlpbmcgdmVjMiB2VXY7IHZhcnlpbmcgdmVjMiB2TDsgdmFyeWluZyB2ZWMyIHZSOyB2YXJ5aW5nIHZlYzIgdlQ7IHZhcnlpbmcgdmVjMiB2QjsKICB1bmlmb3JtIHNhbXBsZXIyRCB1UHJlc3N1cmU7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdVZlbG9jaXR5OwogIHVuaWZvcm0gc2FtcGxlcjJEIHVPYnN0YWNsZTsKICB2b2lkIG1haW4gKCkgewogICAgZmxvYXQgb2JzID0gdGV4dHVyZTJEKHVPYnN0YWNsZSwgdlV2KS5yOwogICAgZmxvYXQgQyAgID0gdGV4dHVyZTJEKHVQcmVzc3VyZSwgdlV2KS54OwogICAgZmxvYXQgTCAgID0gbWl4KHRleHR1cmUyRCh1UHJlc3N1cmUsIHZMKS54LCBDLCB0ZXh0dXJlMkQodU9ic3RhY2xlLCB2TCkucik7CiAgICBmbG9hdCBSICAgPSBtaXgodGV4dHVyZTJEKHVQcmVzc3VyZSwgdlIpLngsIEMsIHRleHR1cmUyRCh1T2JzdGFjbGUsIHZSKS5yKTsKICAgIGZsb2F0IFQgICA9IG1peCh0ZXh0dXJlMkQodVByZXNzdXJlLCB2VCkueCwgQywgdGV4dHVyZTJEKHVPYnN0YWNsZSwgdlQpLnIpOwogICAgZmxvYXQgQiAgID0gbWl4KHRleHR1cmUyRCh1UHJlc3N1cmUsIHZCKS54LCBDLCB0ZXh0dXJlMkQodU9ic3RhY2xlLCB2Qikucik7CiAgICB2ZWMyIHZlbCAgPSAodGV4dHVyZTJEKHVWZWxvY2l0eSwgdlV2KS54eSAtIHZlYzIoUiAtIEwsIFQgLSBCKSkgKiAoMS4wIC0gb2JzKTsKICAgIGdsX0ZyYWdDb2xvciA9IHZlYzQodmVsLCAwLjAsIDEuMCk7CiAgfQpgCiksIF90ID0gKAogIC8qIGdsc2wgKi8KICBgCiAgcHJlY2lzaW9uIGhpZ2hwIGZsb2F0OwogIHZhcnlpbmcgdmVjMiB2VXY7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdVRhcmdldDsKICB1bmlmb3JtIGZsb2F0IGFzcGVjdFJhdGlvOwogIHVuaWZvcm0gdmVjMyBjb2xvcjsKICB1bmlmb3JtIHZlYzIgcG9pbnQ7CiAgdW5pZm9ybSBmbG9hdCByYWRpdXM7CiAgdm9pZCBtYWluICgpIHsKICAgIHZlYzIgcCA9IHZVdiAtIHBvaW50Lnh5OwogICAgcC54ICo9IGFzcGVjdFJhdGlvOwogICAgdmVjMyBzcGxhdCA9IGV4cCgtZG90KHAsIHApIC8gcmFkaXVzKSAqIGNvbG9yOwogICAgZ2xfRnJhZ0NvbG9yID0gdmVjNCh0ZXh0dXJlMkQodVRhcmdldCwgdlV2KS54eXogKyBzcGxhdCwgMS4wKTsKICB9CmAKKSwgQ3QgPSAoCiAgLyogZ2xzbCAqLwogIGAKICBwcmVjaXNpb24gaGlnaHAgZmxvYXQ7CiAgdmFyeWluZyB2ZWMyIHZMOyB2YXJ5aW5nIHZlYzIgdlI7IHZhcnlpbmcgdmVjMiB2VDsgdmFyeWluZyB2ZWMyIHZCOwogIHVuaWZvcm0gc2FtcGxlcjJEIHVWZWxvY2l0eTsKICB2b2lkIG1haW4gKCkgewogICAgZmxvYXQgTCA9IHRleHR1cmUyRCh1VmVsb2NpdHksIHZMKS55OwogICAgZmxvYXQgUiA9IHRleHR1cmUyRCh1VmVsb2NpdHksIHZSKS55OwogICAgZmxvYXQgVCA9IHRleHR1cmUyRCh1VmVsb2NpdHksIHZUKS54OwogICAgZmxvYXQgQiA9IHRleHR1cmUyRCh1VmVsb2NpdHksIHZCKS54OwogICAgZ2xfRnJhZ0NvbG9yID0gdmVjNCgwLjUgKiAoUiAtIEwgLSBUICsgQiksIDAuMCwgMC4wLCAxLjApOwogIH0KYAopLCBCdCA9ICgKICAvKiBnbHNsICovCiAgYAogIHByZWNpc2lvbiBoaWdocCBmbG9hdDsKICB2YXJ5aW5nIHZlYzIgdlV2OyB2YXJ5aW5nIHZlYzIgdkw7IHZhcnlpbmcgdmVjMiB2UjsgdmFyeWluZyB2ZWMyIHZUOyB2YXJ5aW5nIHZlYzIgdkI7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdVZlbG9jaXR5OwogIHVuaWZvcm0gc2FtcGxlcjJEIHVDdXJsOwogIHVuaWZvcm0gZmxvYXQgY3VybDsKICB1bmlmb3JtIGZsb2F0IGR0OwogIHZvaWQgbWFpbiAoKSB7CiAgICBmbG9hdCBMID0gdGV4dHVyZTJEKHVDdXJsLCB2TCkueDsKICAgIGZsb2F0IFIgPSB0ZXh0dXJlMkQodUN1cmwsIHZSKS54OwogICAgZmxvYXQgVCA9IHRleHR1cmUyRCh1Q3VybCwgdlQpLng7CiAgICBmbG9hdCBCID0gdGV4dHVyZTJEKHVDdXJsLCB2QikueDsKICAgIGZsb2F0IEMgPSB0ZXh0dXJlMkQodUN1cmwsIHZVdikueDsKICAgIHZlYzIgZm9yY2UgPSAwLjUgKiB2ZWMyKGFicyhUKSAtIGFicyhCKSwgYWJzKFIpIC0gYWJzKEwpKTsKICAgIGZvcmNlIC89IGxlbmd0aChmb3JjZSkgKyAwLjAwMDE7CiAgICBmb3JjZSAqPSBjdXJsICogMzAuMCAqIEM7CiAgICBnbF9GcmFnQ29sb3IgPSB2ZWM0KHRleHR1cmUyRCh1VmVsb2NpdHksIHZVdikueHkgKyBmb3JjZSAqIGR0LCAwLjAsIDEuMCk7CiAgfQpgCiksIE90ID0gKAogIC8qIGdsc2wgKi8KICBgCiAgcHJlY2lzaW9uIGhpZ2hwIGZsb2F0OwogIHZhcnlpbmcgdmVjMiB2VXY7CgogIHVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlOwogIHVuaWZvcm0gc2FtcGxlcjJEIHVPYnN0YWNsZTsKICB1bmlmb3JtIHNhbXBsZXIyRCB1QmFja2dyb3VuZDsKICB1bmlmb3JtIHNhbXBsZXIyRCB1Q292ZXJhZ2U7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdVZlbG9jaXR5OwoKICB1bmlmb3JtIHZlYzIgIHRleGVsU2l6ZTsKICB1bmlmb3JtIHZlYzMgIHVXYXRlckNvbG9yOwogIHVuaWZvcm0gdmVjMyAgdUdsb3dDb2xvcjsKICB1bmlmb3JtIGZsb2F0IHVSZWZyYWN0aW9uOwogIHVuaWZvcm0gZmxvYXQgdVNwZWN1bGFyRXhwOwogIHVuaWZvcm0gZmxvYXQgdVNoaW5lOwogIHVuaWZvcm0gZmxvYXQgdVdhcnBTdHJlbmd0aDsKICB1bmlmb3JtIGludCAgIHVBbGdvcml0aG07CiAgdW5pZm9ybSBpbnQgICB1RW5hYmxlQWxwaGE7CgogIHZvaWQgbWFpbiAoKSB7CiAgICBmbG9hdCBvYnMgICAgICA9IHRleHR1cmUyRCh1T2JzdGFjbGUsICB2VXYpLnI7CiAgICAvLyBTbW9vdGggZmFkZTogZGVuc2l0eSBmYWxscyBvZmYgb3ZlciB0aGUgYmx1cnJlZCBvYnN0YWNsZSBib3VuZGFyeSB6b25lCiAgICAvLyByYXRoZXIgdGhhbiBjdXR0aW5nIG9mZiBhdCBhIGhhcmQgc3RlcCwgZWxpbWluYXRpbmcgdGhlIGphZ2dlZCBmcmluZ2UuCiAgICBmbG9hdCBkZW5zaXR5ICA9IG1heCh0ZXh0dXJlMkQodVRleHR1cmUsIHZVdikuciwgMC4wKSAqICgxLjAgLSBvYnMpOwogICAgZmxvYXQgY292ZXJhZ2UgPSB0ZXh0dXJlMkQodUNvdmVyYWdlLCAgdlV2KS5yOwoKICAgIC8vIDgtdGFwIFNvYmVsIG5vcm1hbCDigJQgY29tcHV0ZXMgZ3JhZGllbnQgdmlhIDPDlzMga2VybmVsIChubyBjZW50cmUgc2FtcGxlIG5lZWRlZCkuCiAgICAvLyB0ZXhlbFNpemUgPSAxL2Rpc3BsYXlSZXM7IGRlbnNpdHkgRkJPIGlzIGF0IHNpbVNjYWxlICgwLjXDlyksIHNvIHM9NiBkaXNwbGF5IHB4CiAgICAvLyDiiYggMyBzaW0gdGV4ZWxzIHBlciBheGlzLiAgVGhlIFNvYmVsIGtlcm5lbCBwcm9wZXJseSBhdmVyYWdlcyB0aGUgZ3JhZGllbnQgaW4KICAgIC8vIGV2ZXJ5IGRpcmVjdGlvbiDigJQgbm8gNC10YXAgY3Jvc3MgYmlhcyB0aGF0IGNyZWF0ZXMgNDXCsCBjaXJjdWl0LWJvYXJkIGFydGVmYWN0cy4KICAgIGZsb2F0IHN4ID0gdGV4ZWxTaXplLnggKiA2LjAsIHN5ID0gdGV4ZWxTaXplLnkgKiA2LjA7CiAgICBmbG9hdCBkMDAgPSBtYXgodGV4dHVyZTJEKHVUZXh0dXJlLCB2VXYgKyB2ZWMyKC1zeCwgLXN5KSkuciwgMC4wKTsKICAgIGZsb2F0IGQxMCA9IG1heCh0ZXh0dXJlMkQodVRleHR1cmUsIHZVdiArIHZlYzIoMC4wLCAtc3kpKS5yLCAwLjApOwogICAgZmxvYXQgZDIwID0gbWF4KHRleHR1cmUyRCh1VGV4dHVyZSwgdlV2ICsgdmVjMiggc3gsIC1zeSkpLnIsIDAuMCk7CiAgICBmbG9hdCBkMDEgPSBtYXgodGV4dHVyZTJEKHVUZXh0dXJlLCB2VXYgKyB2ZWMyKC1zeCwgMC4wKSkuciwgMC4wKTsKICAgIGZsb2F0IGQyMSA9IG1heCh0ZXh0dXJlMkQodVRleHR1cmUsIHZVdiArIHZlYzIoIHN4LCAwLjApKS5yLCAwLjApOwogICAgZmxvYXQgZDAyID0gbWF4KHRleHR1cmUyRCh1VGV4dHVyZSwgdlV2ICsgdmVjMigtc3gsICBzeSkpLnIsIDAuMCk7CiAgICBmbG9hdCBkMTIgPSBtYXgodGV4dHVyZTJEKHVUZXh0dXJlLCB2VXYgKyB2ZWMyKDAuMCwgIHN5KSkuciwgMC4wKTsKICAgIGZsb2F0IGQyMiA9IG1heCh0ZXh0dXJlMkQodVRleHR1cmUsIHZVdiArIHZlYzIoIHN4LCAgc3kpKS5yLCAwLjApOwogICAgZmxvYXQgZ3ggID0gKGQyMCArIDIuMCpkMjEgKyBkMjIpIC0gKGQwMCArIDIuMCpkMDEgKyBkMDIpOwogICAgZmxvYXQgZ3kgID0gKGQwMiArIDIuMCpkMTIgKyBkMjIpIC0gKGQwMCArIDIuMCpkMTAgKyBkMjApOwoKICAgIHZlYzMgIG5vcm1hbCAgID0gbm9ybWFsaXplKHZlYzMoZ3gsIGd5LCAxLjIpKTsKICAgIHZlYzMgIGxpZ2h0RGlyID0gbm9ybWFsaXplKHZlYzMoMC41LCAxLjAsIDAuNSkpOwogICAgdmVjMyAgaGFsZlYgICAgPSBub3JtYWxpemUobGlnaHREaXIgKyB2ZWMzKDAuMCwgMC4wLCAxLjApKTsKICAgIC8vIFN1cHByZXNzIHNwZWN1bGFyIGF0IGxvdyAvIGZhZGluZyBkZW5zaXR5IOKAlCBwcmV2ZW50cyBoaWdobGlnaHQgcmluZ3MgZnJvbQogICAgLy8gYXBwZWFyaW5nIGF0IHRoZSBkaXNzaXBhdGluZyBlZGdlIG9mIGEgc3Ryb2tlIGFzIGl0cyBkZW5zaXR5IGFwcHJvYWNoZXMgemVyby4KICAgIGZsb2F0IHNwZWNEZW4gID0gZGVuc2l0eSAqIG1pbihkZW5zaXR5ICogNS4wLCAxLjApOwogICAgZmxvYXQgc3BlYyAgICAgPSBwb3cobWF4KGRvdChub3JtYWwsIGhhbGZWKSwgMC4wKSwgdVNwZWN1bGFyRXhwKSAqIHVTaGluZSAqIHNwZWNEZW47CgogICAgLy8gSW4gdHJhbnNwYXJlbnQgKG5vbi1jb3ZlcmFnZSkgYXJlYXMgdGhlIGJhY2tncm91bmQgdGV4dHVyZSBpcyBlbXB0eSBibGFjayBjYW52YXMuCiAgICAvLyBSZXBsYWNlIGl0IHdpdGggdVdhdGVyQ29sb3Igc28gZmx1aWQgY29sb3VyIGlzIG5vdCBjb250YW1pbmF0ZWQgYnkgdGhhdCBibGFjaywKICAgIC8vIGFsbG93aW5nIHRoZSBDU1MgYmFja2dyb3VuZENvbG9yIHRvIHNob3cgdGhyb3VnaCBjb3JyZWN0bHkgdmlhIHByZW11bHRpcGxpZWQgYWxwaGEuCiAgICB2ZWMzIGJnUmF3ID0gdGV4dHVyZTJEKHVCYWNrZ3JvdW5kLCB2VXYpLnJnYjsKICAgIHZlYzMgYmcgICAgPSBtaXgodVdhdGVyQ29sb3IsIGJnUmF3LCBjb3ZlcmFnZSk7CiAgICB2ZWMzIGNvbG9yID0gYmc7CgogICAgaWYgKHVBbGdvcml0aG0gPT0gMSkgewogICAgICAvLyDilIDilIAgZ2xhc3Mg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiAgICAgIC8vIFN0cm9uZyBVViBkaXN0b3J0aW9uIG9ubHkuIEltYWdlIGJlbmRzIGJ1dCBubyBjb2xvdXIgb3ZlcmxheS4KICAgICAgdmVjMiByZWZyVXYgPSBjbGFtcCh2VXYgKyBub3JtYWwueHkgKiB1UmVmcmFjdGlvbiAqIGRlbnNpdHkgKiAzLjAsIDAuMCwgMS4wKTsKICAgICAgdmVjMyByZWZyQmcgPSBtaXgodVdhdGVyQ29sb3IsIHRleHR1cmUyRCh1QmFja2dyb3VuZCwgbWl4KHZVdiwgcmVmclV2LCAxLjAgLSBvYnMpKS5yZ2IsIGNvdmVyYWdlKTsKICAgICAgY29sb3IgPSByZWZyQmcgKyBzcGVjICogdUdsb3dDb2xvciAqIDIuNTsKICAgICAgY29sb3IgPSBtaXgoY29sb3IsIGJnICogMC42LCBvYnMgKiAwLjMpOwoKICAgIH0gZWxzZSBpZiAodUFsZ29yaXRobSA9PSAyKSB7CiAgICAgIC8vIOKUgOKUgCBpbmsg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiAgICAgIC8vIERlbnNlIG9wYXF1ZSBwaWdtZW50IHRoYXQgc3RhaW5zLiBTdWJ0bGUgcmVmcmFjdGlvbiB1bmRlcm5lYXRoLgogICAgICBmbG9hdCBpbmtEICA9IG1pbihkZW5zaXR5ICogNC4wLCAxLjApOwogICAgICB2ZWMyIHJlZnJVdiA9IGNsYW1wKHZVdiArIG5vcm1hbC54eSAqIHVSZWZyYWN0aW9uICogZGVuc2l0eSAqIDAuNCwgMC4wLCAxLjApOwogICAgICB2ZWMzIHJlZnJCZyA9IG1peCh1V2F0ZXJDb2xvciwgdGV4dHVyZTJEKHVCYWNrZ3JvdW5kLCBtaXgodlV2LCByZWZyVXYsIDEuMCAtIG9icykpLnJnYiwgY292ZXJhZ2UpOwogICAgICBjb2xvciA9IG1peChyZWZyQmcsIHVXYXRlckNvbG9yICsgc3BlYyAqIHVHbG93Q29sb3IsIGlua0QpOwogICAgICBjb2xvciA9IG1peChjb2xvciwgYmcgKiAwLjUsIG9icyAqIDAuMTUpOwoKICAgIH0gZWxzZSBpZiAodUFsZ29yaXRobSA9PSAzKSB7CiAgICAgIC8vIOKUgOKUgCBhdXJvcmEg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiAgICAgIC8vIFZlbG9jaXR5IGZpZWxkIHdhcnBzIGJhY2tncm91bmQgVVZzIOKAlCBsaXF1aWQgbWV0YWwgLyBsYXZhLWxhbXAgZmVlbC4KICAgICAgdmVjMiAgdmVsICAgID0gdGV4dHVyZTJEKHVWZWxvY2l0eSwgdlV2KS54eTsKICAgICAgZmxvYXQgdmVsTWFnID0gY2xhbXAobGVuZ3RoKHZlbCkgKiAyMC4wLCAwLjAsIDEuMCk7CiAgICAgIHZlYzIgIHdhcnBVdiA9IGNsYW1wKHZVdiArIHZlbCAqIHVXYXJwU3RyZW5ndGgsIDAuMCwgMS4wKTsKICAgICAgdmVjMyAgd2FycEJnID0gbWl4KHVXYXRlckNvbG9yLCB0ZXh0dXJlMkQodUJhY2tncm91bmQsIHdhcnBVdikucmdiLCBjb3ZlcmFnZSk7CiAgICAgIGNvbG9yICA9IG1peChiZywgd2FycEJnLCB2ZWxNYWcgKiAoMS4wIC0gb2JzKSk7CiAgICAgIGNvbG9yICs9IHNwZWMgKiB1R2xvd0NvbG9yICogdmVsTWFnICogMS41OwogICAgICBjb2xvciArPSB1V2F0ZXJDb2xvciAqIGRlbnNpdHkgKiAwLjM7CiAgICAgIGNvbG9yICA9IG1peChjb2xvciwgYmcgKiAwLjUsIG9icyAqIDAuMik7CgogICAgfSBlbHNlIGlmICh1QWxnb3JpdGhtID09IDQpIHsKICAgICAgLy8g4pSA4pSAIHJpcHBsZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKICAgICAgLy8gRXhhZ2dlcmF0ZWQgbm9ybWFsIHBlcnR1cmJhdGlvbiArIEZyZXNuZWwgcmltIOKAlCBjYWxtIHdhdGVyIHN1cmZhY2UuCiAgICAgIHZlYzIgIHJpcHBsZVV2ID0gY2xhbXAodlV2ICsgbm9ybWFsLnh5ICogdVJlZnJhY3Rpb24gKiBkZW5zaXR5ICogNi4wLCAwLjAsIDEuMCk7CiAgICAgIHZlYzMgIHJlZnJCZyAgID0gbWl4KHVXYXRlckNvbG9yLCB0ZXh0dXJlMkQodUJhY2tncm91bmQsIG1peCh2VXYsIHJpcHBsZVV2LCAxLjAgLSBvYnMpKS5yZ2IsIGNvdmVyYWdlKTsKICAgICAgZmxvYXQgZnJlc25lbCAgPSBwb3coY2xhbXAoMS4wIC0gZG90KG5vcm1hbCwgdmVjMygwLjAsIDAuMCwgMS4wKSksIDAuMCwgMS4wKSwgMy4wKSAqIGRlbnNpdHk7CiAgICAgIGNvbG9yICA9IHJlZnJCZzsKICAgICAgY29sb3IgKz0gZnJlc25lbCAqIHVHbG93Q29sb3IgKiAyLjA7CiAgICAgIGNvbG9yICs9IHNwZWMgKiB1R2xvd0NvbG9yICogZGVuc2l0eSAqIDIuMDsKICAgICAgY29sb3IgID0gbWl4KGNvbG9yLCBiZyAqIDAuNSwgb2JzICogMC4yKTsKCiAgICB9IGVsc2UgewogICAgICAvLyDilIDilIAgc3RhbmRhcmQgKDApIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAogICAgICAvLyBPcmlnaW5hbDogY29sb3VyIG92ZXJsYXkgYmxlbmRlZCBvdmVyIHJlZnJhY3RlZCBiYWNrZ3JvdW5kLgogICAgICB2ZWMyIHJlZnJVdiA9IHZVdiArIG5vcm1hbC54eSAqIHVSZWZyYWN0aW9uICogZGVuc2l0eTsKICAgICAgdmVjMyByZWZyQmcgPSBtaXgodVdhdGVyQ29sb3IsIHRleHR1cmUyRCh1QmFja2dyb3VuZCwgbWl4KHZVdiwgcmVmclV2LCAxLjAgLSBvYnMpKS5yZ2IsIGNvdmVyYWdlKTsKICAgICAgY29sb3IgID0gbWl4KHJlZnJCZywgdVdhdGVyQ29sb3IsIG1pbihkZW5zaXR5ICogMS41LCAwLjgpKTsKICAgICAgY29sb3IgKz0gc3BlYyAqIHVHbG93Q29sb3I7CiAgICAgIGNvbG9yICA9IG1peChjb2xvciwgYmcgKiAwLjUsIG9icyAqIDAuMik7CiAgICB9CgogICAgLy8gT3V0cHV0OiBwcmVtdWx0aXBsaWVkIGFscGhhIHdoZW4gdHJhbnNwYXJlbmN5IGlzIGVuYWJsZWQgKGxldHMgQ1NTIGJhY2tncm91bmRDb2xvcgogICAgLy8gc2hvdyB0aHJvdWdoKSwgb3Igc3RyYWlnaHQgb3BhcXVlIGNvbG91ciB3aGVuIGVuYWJsZUFscGhhIGlzIG9mZiAocGVyZiBtb2RlKS4KICAgIGZsb2F0IGFscGhhID0gY2xhbXAobWF4KGRlbnNpdHkgKiAxLjUsIGNvdmVyYWdlKSwgMC4wLCAxLjApOwogICAgaWYgKHVFbmFibGVBbHBoYSA9PSAxKSB7CiAgICAgIGdsX0ZyYWdDb2xvciA9IHZlYzQoY29sb3IgKiBhbHBoYSwgYWxwaGEpOwogICAgfSBlbHNlIHsKICAgICAgZ2xfRnJhZ0NvbG9yID0gdmVjNChjb2xvciwgMS4wKTsKICAgIH0KICB9CmAKKTsKZnVuY3Rpb24gVnQoaSwgZSA9ICEwKSB7CiAgY29uc3QgciA9IHsgYWxwaGE6IGUsIGRlcHRoOiAhMSwgc3RlbmNpbDogITEsIGFudGlhbGlhczogITAsIHByZXNlcnZlRHJhd2luZ0J1ZmZlcjogITEgfTsKICBsZXQgcyA9IGkuZ2V0Q29udGV4dCgid2ViZ2wyIiwgcik7CiAgY29uc3QgbyA9ICEhczsKICBvIHx8IChzID0gaS5nZXRDb250ZXh0KCJ3ZWJnbCIsIHIpLCBzLmdldEV4dGVuc2lvbigiRVhUX2NvbG9yX2J1ZmZlcl9oYWxmX2Zsb2F0IikpOwogIGNvbnN0IGEgPSBvID8gbnVsbCA6IHMuZ2V0RXh0ZW5zaW9uKCJPRVNfdGV4dHVyZV9oYWxmX2Zsb2F0IiksIHUgPSBvID8gcy5IQUxGX0ZMT0FUIDogYS5IQUxGX0ZMT0FUX09FUzsKICByZXR1cm4gcy5nZXRFeHRlbnNpb24oIkVYVF9jb2xvcl9idWZmZXJfZmxvYXQiKSwgcy5nZXRFeHRlbnNpb24oIk9FU190ZXh0dXJlX2hhbGZfZmxvYXRfbGluZWFyIiksIHsKICAgIHR5cGU6IG8gPyAid2ViZ2wyIiA6ICJ3ZWJnbDEiLAogICAgZ2w6IHMsCiAgICBpc1dlYkdMMjogbywKICAgIGV4dDogewogICAgICBpbnRlcm5hbEZvcm1hdDogbyA/IHMuUkdCQTE2RiA6IHMuUkdCQSwKICAgICAgZm9ybWF0OiBzLlJHQkEsCiAgICAgIHR5cGU6IHUKICAgIH0KICB9Owp9CmFzeW5jIGZ1bmN0aW9uIFB0KGksIGUgPSAhMCkgewogIGlmICh0eXBlb2YgbmF2aWdhdG9yID4gInUiIHx8ICFuYXZpZ2F0b3IuZ3B1KQogICAgcmV0dXJuIG51bGw7CiAgdHJ5IHsKICAgIGNvbnN0IHIgPSBhd2FpdCBuYXZpZ2F0b3IuZ3B1LnJlcXVlc3RBZGFwdGVyKCk7CiAgICBpZiAoIXIpCiAgICAgIHJldHVybiBudWxsOwogICAgY29uc3QgcyA9IGF3YWl0IHIucmVxdWVzdERldmljZSgpLCBvID0gaS5nZXRDb250ZXh0KCJ3ZWJncHUiKTsKICAgIGlmICghbykKICAgICAgcmV0dXJuIG51bGw7CiAgICBjb25zdCBhID0gbmF2aWdhdG9yLmdwdS5nZXRQcmVmZXJyZWRDYW52YXNGb3JtYXQoKTsKICAgIHJldHVybiBvLmNvbmZpZ3VyZSh7IGRldmljZTogcywgZm9ybWF0OiBhLCBhbHBoYU1vZGU6IGUgPyAicHJlbXVsdGlwbGllZCIgOiAib3BhcXVlIiB9KSwgeyB0eXBlOiAid2ViZ3B1IiwgYWRhcHRlcjogciwgZGV2aWNlOiBzLCBjb250ZXh0OiBvLCBmb3JtYXQ6IGEgfTsKICB9IGNhdGNoIHsKICAgIHJldHVybiBudWxsOwogIH0KfQpjbGFzcyBpZSB7CiAgY29uc3RydWN0b3IoZSwgciwgcykgewogICAga2UodGhpcywgInByb2dyYW0iKTsKICAgIGtlKHRoaXMsICJ1bmlmb3JtcyIsIHt9KTsKICAgIGtlKHRoaXMsICJfZ2wiKTsKICAgIHRoaXMuX2dsID0gZSwgdGhpcy5wcm9ncmFtID0gZS5jcmVhdGVQcm9ncmFtKCksIGUuYXR0YWNoU2hhZGVyKHRoaXMucHJvZ3JhbSwgdGhpcy5fY29tcGlsZShlLlZFUlRFWF9TSEFERVIsIHIpKSwgZS5hdHRhY2hTaGFkZXIodGhpcy5wcm9ncmFtLCB0aGlzLl9jb21waWxlKGUuRlJBR01FTlRfU0hBREVSLCBzKSksIGUubGlua1Byb2dyYW0odGhpcy5wcm9ncmFtKTsKICAgIGNvbnN0IG8gPSBlLmdldFByb2dyYW1QYXJhbWV0ZXIodGhpcy5wcm9ncmFtLCBlLkFDVElWRV9VTklGT1JNUyk7CiAgICBmb3IgKGxldCBhID0gMDsgYSA8IG87IGErKykgewogICAgICBjb25zdCB1ID0gZS5nZXRBY3RpdmVVbmlmb3JtKHRoaXMucHJvZ3JhbSwgYSkubmFtZTsKICAgICAgdGhpcy51bmlmb3Jtc1t1XSA9IGUuZ2V0VW5pZm9ybUxvY2F0aW9uKHRoaXMucHJvZ3JhbSwgdSk7CiAgICB9CiAgfQogIF9jb21waWxlKGUsIHIpIHsKICAgIGNvbnN0IHMgPSB0aGlzLl9nbCwgbyA9IHMuY3JlYXRlU2hhZGVyKGUpOwogICAgcmV0dXJuIHMuc2hhZGVyU291cmNlKG8sIHIpLCBzLmNvbXBpbGVTaGFkZXIobyksIG87CiAgfQogIGJpbmQoKSB7CiAgICB0aGlzLl9nbC51c2VQcm9ncmFtKHRoaXMucHJvZ3JhbSk7CiAgfQogIGRpc3Bvc2UoKSB7CiAgICB0aGlzLl9nbC5kZWxldGVQcm9ncmFtKHRoaXMucHJvZ3JhbSk7CiAgfQp9CmZ1bmN0aW9uIEZ0KGkpIHsKICByZXR1cm4gewogICAgYWR2ZWN0aW9uOiBuZXcgaWUoaSwgcmUsIFJ0KSwKICAgIGRpdmVyZ2VuY2U6IG5ldyBpZShpLCByZSwgRXQpLAogICAgcHJlc3N1cmU6IG5ldyBpZShpLCByZSwgVXQpLAogICAgZ3JhZGllbnRTdWJ0cmFjdDogbmV3IGllKGksIHJlLCBEdCksCiAgICBzcGxhdDogbmV3IGllKGksIHJlLCBfdCksCiAgICBjdXJsOiBuZXcgaWUoaSwgcmUsIEN0KSwKICAgIHZvcnRpY2l0eTogbmV3IGllKGksIHJlLCBCdCksCiAgICBkaXNwbGF5OiBuZXcgaWUoaSwgcmUsIE90KQogIH07Cn0KZnVuY3Rpb24gcWUoaSwgZSwgciwgcykgewogIGkuYWN0aXZlVGV4dHVyZShpLlRFWFRVUkUwKTsKICBjb25zdCBvID0gaS5jcmVhdGVUZXh0dXJlKCk7CiAgaS5iaW5kVGV4dHVyZShpLlRFWFRVUkVfMkQsIG8pLCBpLnRleFBhcmFtZXRlcmkoaS5URVhUVVJFXzJELCBpLlRFWFRVUkVfTUlOX0ZJTFRFUiwgaS5MSU5FQVIpLCBpLnRleFBhcmFtZXRlcmkoaS5URVhUVVJFXzJELCBpLlRFWFRVUkVfTUFHX0ZJTFRFUiwgaS5MSU5FQVIpLCBpLnRleFBhcmFtZXRlcmkoaS5URVhUVVJFXzJELCBpLlRFWFRVUkVfV1JBUF9TLCBpLkNMQU1QX1RPX0VER0UpLCBpLnRleFBhcmFtZXRlcmkoaS5URVhUVVJFXzJELCBpLlRFWFRVUkVfV1JBUF9ULCBpLkNMQU1QX1RPX0VER0UpLCBpLnRleEltYWdlMkQoaS5URVhUVVJFXzJELCAwLCBlLmludGVybmFsRm9ybWF0LCByLCBzLCAwLCBlLmZvcm1hdCwgZS50eXBlLCBudWxsKTsKICBjb25zdCBhID0gaS5jcmVhdGVGcmFtZWJ1ZmZlcigpOwogIHJldHVybiBpLmJpbmRGcmFtZWJ1ZmZlcihpLkZSQU1FQlVGRkVSLCBhKSwgaS5mcmFtZWJ1ZmZlclRleHR1cmUyRChpLkZSQU1FQlVGRkVSLCBpLkNPTE9SX0FUVEFDSE1FTlQwLCBpLlRFWFRVUkVfMkQsIG8sIDApLCB7IHRleDogbywgZmJvOiBhLCB3aWR0aDogciwgaGVpZ2h0OiBzIH07Cn0KZnVuY3Rpb24gdHQoaSwgZSwgciwgcykgewogIGxldCBvID0gcWUoaSwgZSwgciwgcyksIGEgPSBxZShpLCBlLCByLCBzKTsKICByZXR1cm4gewogICAgZ2V0IHJlYWQoKSB7CiAgICAgIHJldHVybiBvOwogICAgfSwKICAgIGdldCB3cml0ZSgpIHsKICAgICAgcmV0dXJuIGE7CiAgICB9LAogICAgc3dhcCgpIHsKICAgICAgW28sIGFdID0gW2EsIG9dOwogICAgfSwKICAgIGRpc3Bvc2UoKSB7CiAgICAgIGkuZGVsZXRlVGV4dHVyZShvLnRleCksIGkuZGVsZXRlRnJhbWVidWZmZXIoby5mYm8pLCBpLmRlbGV0ZVRleHR1cmUoYS50ZXgpLCBpLmRlbGV0ZUZyYW1lYnVmZmVyKGEuZmJvKTsKICAgIH0KICB9Owp9CmZ1bmN0aW9uIEx0KGkpIHsKICBjb25zdCBlID0gaS5jcmVhdGVCdWZmZXIoKTsKICByZXR1cm4gaS5iaW5kQnVmZmVyKGkuQVJSQVlfQlVGRkVSLCBlKSwgaS5idWZmZXJEYXRhKGkuQVJSQVlfQlVGRkVSLCBuZXcgRmxvYXQzMkFycmF5KFstMSwgLTEsIC0xLCAxLCAxLCAxLCAxLCAtMV0pLCBpLlNUQVRJQ19EUkFXKSwgaS52ZXJ0ZXhBdHRyaWJQb2ludGVyKDAsIDIsIGkuRkxPQVQsICExLCAwLCAwKSwgaS5lbmFibGVWZXJ0ZXhBdHRyaWJBcnJheSgwKSwgZnVuY3Rpb24ocykgewogICAgaS5iaW5kRnJhbWVidWZmZXIoaS5GUkFNRUJVRkZFUiwgcyksIGkuZHJhd0FycmF5cyhpLlRSSUFOR0xFX0ZBTiwgMCwgNCk7CiAgfTsKfQpjb25zdCBsZSA9ICgKICAvKiB3Z3NsICovCiAgYApzdHJ1Y3QgVlNPdXQgewogIEBidWlsdGluKHBvc2l0aW9uKSBwb3MgOiB2ZWM0ZiwKICBAbG9jYXRpb24oMCkgICAgICAgdXYgIDogdmVjMmYsCiAgQGxvY2F0aW9uKDEpICAgICAgIHZMICA6IHZlYzJmLAogIEBsb2NhdGlvbigyKSAgICAgICB2UiAgOiB2ZWMyZiwKICBAbG9jYXRpb24oMykgICAgICAgdlQgIDogdmVjMmYsCiAgQGxvY2F0aW9uKDQpICAgICAgIHZCICA6IHZlYzJmLAp9YAopLCBBdCA9ICgKICAvKiB3Z3NsICovCiAgYAoke2xlfQoKc3RydWN0IFUgewogIHRleGVsU2l6ZSAgOiB2ZWMyZiwKICBkdCAgICAgICAgIDogZjMyLAogIGRpc3NpcGF0aW9uOiBmMzIsCn0KQGdyb3VwKDApIEBiaW5kaW5nKDApIHZhcjx1bmlmb3JtPiB1ICAgICA6IFU7CkBncm91cCgwKSBAYmluZGluZygxKSB2YXIgICAgICAgICAgc2FtcCAgOiBzYW1wbGVyOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMikgdmFyICAgICAgICAgIHVWZWwgIDogdGV4dHVyZV8yZDxmMzI+OwpAZ3JvdXAoMCkgQGJpbmRpbmcoMykgdmFyICAgICAgICAgIHVTcmMgIDogdGV4dHVyZV8yZDxmMzI+OwpAZ3JvdXAoMCkgQGJpbmRpbmcoNCkgdmFyICAgICAgICAgIHVPYnMgIDogdGV4dHVyZV8yZDxmMzI+OwoKQHZlcnRleCBmbiB2cyhAbG9jYXRpb24oMCkgYTogdmVjMmYpIC0+IFZTT3V0IHsKICB2YXIgbzogVlNPdXQ7CiAgby51diA9IHZlYzJmKGEueCAqIDAuNSArIDAuNSwgMC41IC0gYS55ICogMC41KTsKICBvLnZMID0gby51diAtIHZlYzJmKHUudGV4ZWxTaXplLngsIDAuMCk7CiAgby52UiA9IG8udXYgKyB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlQgPSBvLnV2ICsgdmVjMmYoMC4wLCB1LnRleGVsU2l6ZS55KTsKICBvLnZCID0gby51diAtIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby5wb3MgPSB2ZWM0ZihhLCAwLjAsIDEuMCk7CiAgcmV0dXJuIG87Cn0KCkBmcmFnbWVudCBmbiBmcyhpOiBWU091dCkgLT4gQGxvY2F0aW9uKDApIHZlYzRmIHsKICBsZXQgb2JzICAgPSB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudXYpLnI7CiAgbGV0IHZlbCAgID0gdGV4dHVyZVNhbXBsZSh1VmVsLCBzYW1wLCBpLnV2KS54eTsKICBsZXQgY29vcmQgPSBpLnV2IC0gdS5kdCAqIHZlbCAqIHUudGV4ZWxTaXplOwogIGxldCBzcmMgICA9IHRleHR1cmVTYW1wbGUodVNyYywgc2FtcCwgY29vcmQpOwogIHJldHVybiB1LmRpc3NpcGF0aW9uICogc3JjICogKDEuMCAtIG9icyk7Cn0KYAopLCB6dCA9ICgKICAvKiB3Z3NsICovCiAgYAoke2xlfQoKc3RydWN0IFUgeyB0ZXhlbFNpemU6IHZlYzJmLCBfcGFkOiB2ZWMyZiB9CkBncm91cCgwKSBAYmluZGluZygwKSB2YXI8dW5pZm9ybT4gdSAgICA6IFU7CkBncm91cCgwKSBAYmluZGluZygxKSB2YXIgICAgICAgICAgc2FtcCA6IHNhbXBsZXI7CkBncm91cCgwKSBAYmluZGluZygyKSB2YXIgICAgICAgICAgdVZlbCA6IHRleHR1cmVfMmQ8ZjMyPjsKQGdyb3VwKDApIEBiaW5kaW5nKDMpIHZhciAgICAgICAgICB1T2JzIDogdGV4dHVyZV8yZDxmMzI+OwoKQHZlcnRleCBmbiB2cyhAbG9jYXRpb24oMCkgYTogdmVjMmYpIC0+IFZTT3V0IHsKICB2YXIgbzogVlNPdXQ7CiAgby51diA9IHZlYzJmKGEueCAqIDAuNSArIDAuNSwgMC41IC0gYS55ICogMC41KTsKICBvLnZMID0gby51diAtIHZlYzJmKHUudGV4ZWxTaXplLngsIDAuMCk7CiAgby52UiA9IG8udXYgKyB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlQgPSBvLnV2ICsgdmVjMmYoMC4wLCB1LnRleGVsU2l6ZS55KTsKICBvLnZCID0gby51diAtIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby5wb3MgPSB2ZWM0ZihhLCAwLjAsIDEuMCk7CiAgcmV0dXJuIG87Cn0KCkBmcmFnbWVudCBmbiBmcyhpOiBWU091dCkgLT4gQGxvY2F0aW9uKDApIHZlYzRmIHsKICBsZXQgTCA9IHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS52TCkueCAqICgxLjAgLSB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudkwpLnIpOwogIGxldCBSID0gdGV4dHVyZVNhbXBsZSh1VmVsLCBzYW1wLCBpLnZSKS54ICogKDEuMCAtIHRleHR1cmVTYW1wbGUodU9icywgc2FtcCwgaS52Uikucik7CiAgbGV0IFQgPSB0ZXh0dXJlU2FtcGxlKHVWZWwsIHNhbXAsIGkudlQpLnkgKiAoMS4wIC0gdGV4dHVyZVNhbXBsZSh1T2JzLCBzYW1wLCBpLnZUKS5yKTsKICBsZXQgQiA9IHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS52QikueSAqICgxLjAgLSB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudkIpLnIpOwogIHJldHVybiB2ZWM0ZigwLjUgKiAoUiAtIEwgKyBUIC0gQiksIDAuMCwgMC4wLCAxLjApOwp9CmAKKSwgWHQgPSAoCiAgLyogd2dzbCAqLwogIGAKJHtsZX0KCnN0cnVjdCBVIHsgdGV4ZWxTaXplOiB2ZWMyZiwgX3BhZDogdmVjMmYgfQpAZ3JvdXAoMCkgQGJpbmRpbmcoMCkgdmFyPHVuaWZvcm0+IHUgICAgOiBVOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMSkgdmFyICAgICAgICAgIHNhbXAgOiBzYW1wbGVyOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMikgdmFyICAgICAgICAgIHVQcmVzOiB0ZXh0dXJlXzJkPGYzMj47CkBncm91cCgwKSBAYmluZGluZygzKSB2YXIgICAgICAgICAgdURpdiA6IHRleHR1cmVfMmQ8ZjMyPjsKQGdyb3VwKDApIEBiaW5kaW5nKDQpIHZhciAgICAgICAgICB1T2JzIDogdGV4dHVyZV8yZDxmMzI+OwoKQHZlcnRleCBmbiB2cyhAbG9jYXRpb24oMCkgYTogdmVjMmYpIC0+IFZTT3V0IHsKICB2YXIgbzogVlNPdXQ7CiAgby51diA9IHZlYzJmKGEueCAqIDAuNSArIDAuNSwgMC41IC0gYS55ICogMC41KTsKICBvLnZMID0gby51diAtIHZlYzJmKHUudGV4ZWxTaXplLngsIDAuMCk7CiAgby52UiA9IG8udXYgKyB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlQgPSBvLnV2ICsgdmVjMmYoMC4wLCB1LnRleGVsU2l6ZS55KTsKICBvLnZCID0gby51diAtIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby5wb3MgPSB2ZWM0ZihhLCAwLjAsIDEuMCk7CiAgcmV0dXJuIG87Cn0KCkBmcmFnbWVudCBmbiBmcyhpOiBWU091dCkgLT4gQGxvY2F0aW9uKDApIHZlYzRmIHsKICBsZXQgQyAgPSB0ZXh0dXJlU2FtcGxlKHVQcmVzLCBzYW1wLCBpLnV2KS54OwogIGxldCBMICA9IG1peCh0ZXh0dXJlU2FtcGxlKHVQcmVzLCBzYW1wLCBpLnZMKS54LCBDLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudkwpLnIpOwogIGxldCBSICA9IG1peCh0ZXh0dXJlU2FtcGxlKHVQcmVzLCBzYW1wLCBpLnZSKS54LCBDLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudlIpLnIpOwogIGxldCBUICA9IG1peCh0ZXh0dXJlU2FtcGxlKHVQcmVzLCBzYW1wLCBpLnZUKS54LCBDLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudlQpLnIpOwogIGxldCBCICA9IG1peCh0ZXh0dXJlU2FtcGxlKHVQcmVzLCBzYW1wLCBpLnZCKS54LCBDLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudkIpLnIpOwogIGxldCBkdiA9IHRleHR1cmVTYW1wbGUodURpdiwgc2FtcCwgaS51dikueDsKICByZXR1cm4gdmVjNGYoKEwgKyBSICsgQiArIFQgLSBkdikgKiAwLjI1LCAwLjAsIDAuMCwgMS4wKTsKfQpgCiksIEd0ID0gKAogIC8qIHdnc2wgKi8KICBgCiR7bGV9CgpzdHJ1Y3QgVSB7IHRleGVsU2l6ZTogdmVjMmYsIF9wYWQ6IHZlYzJmIH0KQGdyb3VwKDApIEBiaW5kaW5nKDApIHZhcjx1bmlmb3JtPiB1ICAgIDogVTsKQGdyb3VwKDApIEBiaW5kaW5nKDEpIHZhciAgICAgICAgICBzYW1wIDogc2FtcGxlcjsKQGdyb3VwKDApIEBiaW5kaW5nKDIpIHZhciAgICAgICAgICB1UHJlczogdGV4dHVyZV8yZDxmMzI+OwpAZ3JvdXAoMCkgQGJpbmRpbmcoMykgdmFyICAgICAgICAgIHVWZWwgOiB0ZXh0dXJlXzJkPGYzMj47CkBncm91cCgwKSBAYmluZGluZyg0KSB2YXIgICAgICAgICAgdU9icyA6IHRleHR1cmVfMmQ8ZjMyPjsKCkB2ZXJ0ZXggZm4gdnMoQGxvY2F0aW9uKDApIGE6IHZlYzJmKSAtPiBWU091dCB7CiAgdmFyIG86IFZTT3V0OwogIG8udXYgPSB2ZWMyZihhLnggKiAwLjUgKyAwLjUsIDAuNSAtIGEueSAqIDAuNSk7CiAgby52TCA9IG8udXYgLSB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlIgPSBvLnV2ICsgdmVjMmYodS50ZXhlbFNpemUueCwgMC4wKTsKICBvLnZUID0gby51diArIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby52QiA9IG8udXYgLSB2ZWMyZigwLjAsIHUudGV4ZWxTaXplLnkpOwogIG8ucG9zID0gdmVjNGYoYSwgMC4wLCAxLjApOwogIHJldHVybiBvOwp9CgpAZnJhZ21lbnQgZm4gZnMoaTogVlNPdXQpIC0+IEBsb2NhdGlvbigwKSB2ZWM0ZiB7CiAgbGV0IG9icyA9IHRleHR1cmVTYW1wbGUodU9icywgc2FtcCwgaS51dikucjsKICBsZXQgQyAgID0gdGV4dHVyZVNhbXBsZSh1UHJlcywgc2FtcCwgaS51dikueDsKICBsZXQgTCAgID0gbWl4KHRleHR1cmVTYW1wbGUodVByZXMsIHNhbXAsIGkudkwpLngsIEMsIHRleHR1cmVTYW1wbGUodU9icywgc2FtcCwgaS52TCkucik7CiAgbGV0IFIgICA9IG1peCh0ZXh0dXJlU2FtcGxlKHVQcmVzLCBzYW1wLCBpLnZSKS54LCBDLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudlIpLnIpOwogIGxldCBUICAgPSBtaXgodGV4dHVyZVNhbXBsZSh1UHJlcywgc2FtcCwgaS52VCkueCwgQywgdGV4dHVyZVNhbXBsZSh1T2JzLCBzYW1wLCBpLnZUKS5yKTsKICBsZXQgQiAgID0gbWl4KHRleHR1cmVTYW1wbGUodVByZXMsIHNhbXAsIGkudkIpLngsIEMsIHRleHR1cmVTYW1wbGUodU9icywgc2FtcCwgaS52Qikucik7CiAgbGV0IHZlbCA9ICh0ZXh0dXJlU2FtcGxlKHVWZWwsIHNhbXAsIGkudXYpLnh5IC0gdmVjMmYoUiAtIEwsIFQgLSBCKSkgKiAoMS4wIC0gb2JzKTsKICByZXR1cm4gdmVjNGYodmVsLCAwLjAsIDEuMCk7Cn0KYAopLCBNdCA9ICgKICAvKiB3Z3NsICovCiAgYAoke2xlfQoKLy8gdGV4ZWxTaXplIG9jY3VwaWVzIGJ5dGVzIDAtNyBmb3IgdGhlIHNoYXJlZCB2ZXJ0ZXggc3RhZ2U7IGFzcGVjdFJhdGlvL3JhZGl1cyBmaWxsIHRoZSByZXN0LgpzdHJ1Y3QgVSB7CiAgdGV4ZWxTaXplICA6IHZlYzJmLAogIGFzcGVjdFJhdGlvOiBmMzIsCiAgcmFkaXVzICAgICA6IGYzMiwKICBjb2xvciAgICAgIDogdmVjNGYsICAvLyB4eXogPSBjb2xvdXIsIHcgdW51c2VkCiAgcG9pbnQgICAgICA6IHZlYzJmLAogIF9wYWQgICAgICAgOiB2ZWMyZiwKfQpAZ3JvdXAoMCkgQGJpbmRpbmcoMCkgdmFyPHVuaWZvcm0+IHUgICAgOiBVOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMSkgdmFyICAgICAgICAgIHNhbXAgOiBzYW1wbGVyOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMikgdmFyICAgICAgICAgIHVUZ3QgOiB0ZXh0dXJlXzJkPGYzMj47CgpAdmVydGV4IGZuIHZzKEBsb2NhdGlvbigwKSBhOiB2ZWMyZikgLT4gVlNPdXQgewogIHZhciBvOiBWU091dDsKICBvLnV2ID0gdmVjMmYoYS54ICogMC41ICsgMC41LCAwLjUgLSBhLnkgKiAwLjUpOwogIG8udkwgPSBvLnV2IC0gdmVjMmYodS50ZXhlbFNpemUueCwgMC4wKTsKICBvLnZSID0gby51diArIHZlYzJmKHUudGV4ZWxTaXplLngsIDAuMCk7CiAgby52VCA9IG8udXYgKyB2ZWMyZigwLjAsIHUudGV4ZWxTaXplLnkpOwogIG8udkIgPSBvLnV2IC0gdmVjMmYoMC4wLCB1LnRleGVsU2l6ZS55KTsKICBvLnBvcyA9IHZlYzRmKGEsIDAuMCwgMS4wKTsKICByZXR1cm4gbzsKfQoKQGZyYWdtZW50IGZuIGZzKGk6IFZTT3V0KSAtPiBAbG9jYXRpb24oMCkgdmVjNGYgewogIHZhciBwICA9IGkudXYgLSB1LnBvaW50OwogIHAueCAgICo9IHUuYXNwZWN0UmF0aW87CiAgbGV0IHNwID0gZXhwKC1kb3QocCwgcCkgLyB1LnJhZGl1cykgKiB1LmNvbG9yLnh5ejsKICByZXR1cm4gdmVjNGYodGV4dHVyZVNhbXBsZSh1VGd0LCBzYW1wLCBpLnV2KS54eXogKyBzcCwgMS4wKTsKfQpgCiksIEl0ID0gKAogIC8qIHdnc2wgKi8KICBgCiR7bGV9CgpzdHJ1Y3QgVSB7IHRleGVsU2l6ZTogdmVjMmYsIF9wYWQ6IHZlYzJmIH0KQGdyb3VwKDApIEBiaW5kaW5nKDApIHZhcjx1bmlmb3JtPiB1ICAgIDogVTsKQGdyb3VwKDApIEBiaW5kaW5nKDEpIHZhciAgICAgICAgICBzYW1wIDogc2FtcGxlcjsKQGdyb3VwKDApIEBiaW5kaW5nKDIpIHZhciAgICAgICAgICB1VmVsIDogdGV4dHVyZV8yZDxmMzI+OwoKQHZlcnRleCBmbiB2cyhAbG9jYXRpb24oMCkgYTogdmVjMmYpIC0+IFZTT3V0IHsKICB2YXIgbzogVlNPdXQ7CiAgby51diA9IHZlYzJmKGEueCAqIDAuNSArIDAuNSwgMC41IC0gYS55ICogMC41KTsKICBvLnZMID0gby51diAtIHZlYzJmKHUudGV4ZWxTaXplLngsIDAuMCk7CiAgby52UiA9IG8udXYgKyB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlQgPSBvLnV2ICsgdmVjMmYoMC4wLCB1LnRleGVsU2l6ZS55KTsKICBvLnZCID0gby51diAtIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby5wb3MgPSB2ZWM0ZihhLCAwLjAsIDEuMCk7CiAgcmV0dXJuIG87Cn0KCkBmcmFnbWVudCBmbiBmcyhpOiBWU091dCkgLT4gQGxvY2F0aW9uKDApIHZlYzRmIHsKICBsZXQgTCA9IHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS52TCkueTsKICBsZXQgUiA9IHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS52UikueTsKICBsZXQgVCA9IHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS52VCkueDsKICBsZXQgQiA9IHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS52QikueDsKICByZXR1cm4gdmVjNGYoMC41ICogKFIgLSBMIC0gVCArIEIpLCAwLjAsIDAuMCwgMS4wKTsKfQpgCiksIGt0ID0gKAogIC8qIHdnc2wgKi8KICBgCiR7bGV9CgpzdHJ1Y3QgVSB7CiAgdGV4ZWxTaXplOiB2ZWMyZiwKICBjdXJsICAgICA6IGYzMiwKICBkdCAgICAgICA6IGYzMiwKfQpAZ3JvdXAoMCkgQGJpbmRpbmcoMCkgdmFyPHVuaWZvcm0+IHUgICAgOiBVOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMSkgdmFyICAgICAgICAgIHNhbXAgOiBzYW1wbGVyOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMikgdmFyICAgICAgICAgIHVWZWwgOiB0ZXh0dXJlXzJkPGYzMj47CkBncm91cCgwKSBAYmluZGluZygzKSB2YXIgICAgICAgICAgdUNybCA6IHRleHR1cmVfMmQ8ZjMyPjsKCkB2ZXJ0ZXggZm4gdnMoQGxvY2F0aW9uKDApIGE6IHZlYzJmKSAtPiBWU091dCB7CiAgdmFyIG86IFZTT3V0OwogIG8udXYgPSB2ZWMyZihhLnggKiAwLjUgKyAwLjUsIDAuNSAtIGEueSAqIDAuNSk7CiAgby52TCA9IG8udXYgLSB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlIgPSBvLnV2ICsgdmVjMmYodS50ZXhlbFNpemUueCwgMC4wKTsKICBvLnZUID0gby51diArIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby52QiA9IG8udXYgLSB2ZWMyZigwLjAsIHUudGV4ZWxTaXplLnkpOwogIG8ucG9zID0gdmVjNGYoYSwgMC4wLCAxLjApOwogIHJldHVybiBvOwp9CgpAZnJhZ21lbnQgZm4gZnMoaTogVlNPdXQpIC0+IEBsb2NhdGlvbigwKSB2ZWM0ZiB7CiAgbGV0IEwgICAgID0gdGV4dHVyZVNhbXBsZSh1Q3JsLCBzYW1wLCBpLnZMKS54OwogIGxldCBSICAgICA9IHRleHR1cmVTYW1wbGUodUNybCwgc2FtcCwgaS52UikueDsKICBsZXQgVCAgICAgPSB0ZXh0dXJlU2FtcGxlKHVDcmwsIHNhbXAsIGkudlQpLng7CiAgbGV0IEIgICAgID0gdGV4dHVyZVNhbXBsZSh1Q3JsLCBzYW1wLCBpLnZCKS54OwogIGxldCBDICAgICA9IHRleHR1cmVTYW1wbGUodUNybCwgc2FtcCwgaS51dikueDsKICB2YXIgZm9yY2UgPSAwLjUgKiB2ZWMyZihhYnMoVCkgLSBhYnMoQiksIGFicyhSKSAtIGFicyhMKSk7CiAgZm9yY2UgICAgLz0gbGVuZ3RoKGZvcmNlKSArIDAuMDAwMTsKICBmb3JjZSAgICAqPSB1LmN1cmwgKiAzMC4wICogQzsKICBsZXQgdmVsICAgPSB0ZXh0dXJlU2FtcGxlKHVWZWwsIHNhbXAsIGkudXYpLnh5ICsgZm9yY2UgKiB1LmR0OwogIHJldHVybiB2ZWM0Zih2ZWwsIDAuMCwgMS4wKTsKfQpgCiksIFd0ID0gKAogIC8qIHdnc2wgKi8KICBgCiR7bGV9CgpzdHJ1Y3QgVSB7CiAgdGV4ZWxTaXplICAgOiB2ZWMyZiwKICByZWZyYWN0aW9uICA6IGYzMiwKICBzcGVjdWxhckV4cCA6IGYzMiwKICB3YXRlckNvbG9yICA6IHZlYzRmLAogIGdsb3dDb2xvciAgIDogdmVjNGYsCiAgc2hpbmUgICAgICAgOiBmMzIsCiAgd2FycFN0cmVuZ3RoOiBmMzIsCiAgYWxnb3JpdGhtICAgOiBpMzIsCiAgZW5hYmxlQWxwaGEgOiBpMzIsCn0KQGdyb3VwKDApIEBiaW5kaW5nKDApIHZhcjx1bmlmb3JtPiB1ICAgIDogVTsKQGdyb3VwKDApIEBiaW5kaW5nKDEpIHZhciAgICAgICAgICBzYW1wIDogc2FtcGxlcjsKQGdyb3VwKDApIEBiaW5kaW5nKDIpIHZhciAgICAgICAgICB1VGV4IDogdGV4dHVyZV8yZDxmMzI+OwpAZ3JvdXAoMCkgQGJpbmRpbmcoMykgdmFyICAgICAgICAgIHVPYnMgOiB0ZXh0dXJlXzJkPGYzMj47CkBncm91cCgwKSBAYmluZGluZyg0KSB2YXIgICAgICAgICAgdUJnICA6IHRleHR1cmVfMmQ8ZjMyPjsKQGdyb3VwKDApIEBiaW5kaW5nKDUpIHZhciAgICAgICAgICB1Q292IDogdGV4dHVyZV8yZDxmMzI+OwpAZ3JvdXAoMCkgQGJpbmRpbmcoNikgdmFyICAgICAgICAgIHVWZWwgOiB0ZXh0dXJlXzJkPGYzMj47CgpAdmVydGV4IGZuIHZzKEBsb2NhdGlvbigwKSBhOiB2ZWMyZikgLT4gVlNPdXQgewogIHZhciBvOiBWU091dDsKICBvLnV2ID0gdmVjMmYoYS54ICogMC41ICsgMC41LCAwLjUgLSBhLnkgKiAwLjUpOwogIG8udkwgPSBvLnV2IC0gdmVjMmYodS50ZXhlbFNpemUueCwgMC4wKTsKICBvLnZSID0gby51diArIHZlYzJmKHUudGV4ZWxTaXplLngsIDAuMCk7CiAgby52VCA9IG8udXYgKyB2ZWMyZigwLjAsIHUudGV4ZWxTaXplLnkpOwogIG8udkIgPSBvLnV2IC0gdmVjMmYoMC4wLCB1LnRleGVsU2l6ZS55KTsKICBvLnBvcyA9IHZlYzRmKGEsIDAuMCwgMS4wKTsKICByZXR1cm4gbzsKfQoKQGZyYWdtZW50IGZuIGZzKGk6IFZTT3V0KSAtPiBAbG9jYXRpb24oMCkgdmVjNGYgewogIGxldCBvYnMgICAgID0gdGV4dHVyZVNhbXBsZSh1T2JzLCBzYW1wLCBpLnV2KS5yOwogIGxldCBkZW5zaXR5ID0gbWF4KHRleHR1cmVTYW1wbGUodVRleCwgc2FtcCwgaS51dikuciwgMC4wKSAqICgxLjAgLSBvYnMpOwogIGxldCBjb3YgICAgID0gdGV4dHVyZVNhbXBsZSh1Q292LCBzYW1wLCBpLnV2KS5yOwoKICBsZXQgc3ggID0gdS50ZXhlbFNpemUueCAqIDYuMDsKICBsZXQgc3kgID0gdS50ZXhlbFNpemUueSAqIDYuMDsKICBsZXQgZDAwID0gbWF4KHRleHR1cmVTYW1wbGUodVRleCwgc2FtcCwgaS51diArIHZlYzJmKC1zeCwgLXN5KSkuciwgMC4wKTsKICBsZXQgZDEwID0gbWF4KHRleHR1cmVTYW1wbGUodVRleCwgc2FtcCwgaS51diArIHZlYzJmKDAuMCwgLXN5KSkuciwgMC4wKTsKICBsZXQgZDIwID0gbWF4KHRleHR1cmVTYW1wbGUodVRleCwgc2FtcCwgaS51diArIHZlYzJmKCBzeCwgLXN5KSkuciwgMC4wKTsKICBsZXQgZDAxID0gbWF4KHRleHR1cmVTYW1wbGUodVRleCwgc2FtcCwgaS51diArIHZlYzJmKC1zeCwgMC4wKSkuciwgMC4wKTsKICBsZXQgZDIxID0gbWF4KHRleHR1cmVTYW1wbGUodVRleCwgc2FtcCwgaS51diArIHZlYzJmKCBzeCwgMC4wKSkuciwgMC4wKTsKICBsZXQgZDAyID0gbWF4KHRleHR1cmVTYW1wbGUodVRleCwgc2FtcCwgaS51diArIHZlYzJmKC1zeCwgIHN5KSkuciwgMC4wKTsKICBsZXQgZDEyID0gbWF4KHRleHR1cmVTYW1wbGUodVRleCwgc2FtcCwgaS51diArIHZlYzJmKDAuMCwgIHN5KSkuciwgMC4wKTsKICBsZXQgZDIyID0gbWF4KHRleHR1cmVTYW1wbGUodVRleCwgc2FtcCwgaS51diArIHZlYzJmKCBzeCwgIHN5KSkuciwgMC4wKTsKICBsZXQgZ3ggID0gKGQyMCArIDIuMCpkMjEgKyBkMjIpIC0gKGQwMCArIDIuMCpkMDEgKyBkMDIpOwogIGxldCBneSAgPSAoZDAyICsgMi4wKmQxMiArIGQyMikgLSAoZDAwICsgMi4wKmQxMCArIGQyMCk7CgogIGxldCBub3JtICAgID0gbm9ybWFsaXplKHZlYzNmKGd4LCBneSwgMS4yKSk7CiAgbGV0IGxkaXIgICAgPSBub3JtYWxpemUodmVjM2YoMC41LCAxLjAsIDAuNSkpOwogIGxldCBoYWxmViAgID0gbm9ybWFsaXplKGxkaXIgKyB2ZWMzZigwLjAsIDAuMCwgMS4wKSk7CiAgbGV0IHNwZWNEZW4gPSBkZW5zaXR5ICogbWluKGRlbnNpdHkgKiA1LjAsIDEuMCk7CiAgbGV0IHNwZWMgICAgPSBwb3cobWF4KGRvdChub3JtLCBoYWxmViksIDAuMCksIHUuc3BlY3VsYXJFeHApICogdS5zaGluZSAqIHNwZWNEZW47CgogIGxldCBiZ1JhdyA9IHRleHR1cmVTYW1wbGUodUJnLCBzYW1wLCBpLnV2KS5yZ2I7CiAgbGV0IHdjICAgID0gdS53YXRlckNvbG9yLnJnYjsKICBsZXQgZ2MgICAgPSB1Lmdsb3dDb2xvci5yZ2I7CiAgbGV0IGJnICAgID0gbWl4KHdjLCBiZ1JhdywgY292KTsKICB2YXIgY29sb3IgPSBiZzsKCiAgaWYgKHUuYWxnb3JpdGhtID09IDEpIHsKICAgIGxldCBydXYgPSBjbGFtcChpLnV2ICsgbm9ybS54eSAqIHUucmVmcmFjdGlvbiAqIGRlbnNpdHkgKiAzLjAsIHZlYzJmKDAuMCksIHZlYzJmKDEuMCkpOwogICAgbGV0IHJiZyA9IG1peCh3YywgdGV4dHVyZVNhbXBsZSh1QmcsIHNhbXAsIG1peChpLnV2LCBydXYsIDEuMCAtIG9icykpLnJnYiwgY292KTsKICAgIGNvbG9yICAgPSByYmcgKyBzcGVjICogZ2MgKiAyLjU7CiAgICBjb2xvciAgID0gbWl4KGNvbG9yLCBiZyAqIDAuNiwgb2JzICogMC4zKTsKICB9IGVsc2UgaWYgKHUuYWxnb3JpdGhtID09IDIpIHsKICAgIGxldCBpbmtEID0gbWluKGRlbnNpdHkgKiA0LjAsIDEuMCk7CiAgICBsZXQgcnV2ICA9IGNsYW1wKGkudXYgKyBub3JtLnh5ICogdS5yZWZyYWN0aW9uICogZGVuc2l0eSAqIDAuNCwgdmVjMmYoMC4wKSwgdmVjMmYoMS4wKSk7CiAgICBsZXQgcmJnICA9IG1peCh3YywgdGV4dHVyZVNhbXBsZSh1QmcsIHNhbXAsIG1peChpLnV2LCBydXYsIDEuMCAtIG9icykpLnJnYiwgY292KTsKICAgIGNvbG9yICAgID0gbWl4KHJiZywgd2MgKyBzcGVjICogZ2MsIGlua0QpOwogICAgY29sb3IgICAgPSBtaXgoY29sb3IsIGJnICogMC41LCBvYnMgKiAwLjE1KTsKICB9IGVsc2UgaWYgKHUuYWxnb3JpdGhtID09IDMpIHsKICAgIGxldCB2ZWwgICAgPSB0ZXh0dXJlU2FtcGxlKHVWZWwsIHNhbXAsIGkudXYpLnh5OwogICAgbGV0IHZlbE1hZyA9IGNsYW1wKGxlbmd0aCh2ZWwpICogMjAuMCwgMC4wLCAxLjApOwogICAgbGV0IHd1diAgICA9IGNsYW1wKGkudXYgKyB2ZWwgKiB1LndhcnBTdHJlbmd0aCwgdmVjMmYoMC4wKSwgdmVjMmYoMS4wKSk7CiAgICBsZXQgd2JnICAgID0gbWl4KHdjLCB0ZXh0dXJlU2FtcGxlKHVCZywgc2FtcCwgd3V2KS5yZ2IsIGNvdik7CiAgICBjb2xvciAgICAgID0gbWl4KGJnLCB3YmcsIHZlbE1hZyAqICgxLjAgLSBvYnMpKTsKICAgIGNvbG9yICAgICArPSBzcGVjICogZ2MgKiB2ZWxNYWcgKiAxLjU7CiAgICBjb2xvciAgICAgKz0gd2MgKiBkZW5zaXR5ICogMC4zOwogICAgY29sb3IgICAgICA9IG1peChjb2xvciwgYmcgKiAwLjUsIG9icyAqIDAuMik7CiAgfSBlbHNlIGlmICh1LmFsZ29yaXRobSA9PSA0KSB7CiAgICBsZXQgcnV2ICAgPSBjbGFtcChpLnV2ICsgbm9ybS54eSAqIHUucmVmcmFjdGlvbiAqIGRlbnNpdHkgKiA2LjAsIHZlYzJmKDAuMCksIHZlYzJmKDEuMCkpOwogICAgbGV0IHJiZyAgID0gbWl4KHdjLCB0ZXh0dXJlU2FtcGxlKHVCZywgc2FtcCwgbWl4KGkudXYsIHJ1diwgMS4wIC0gb2JzKSkucmdiLCBjb3YpOwogICAgbGV0IGZyZXMgID0gcG93KGNsYW1wKDEuMCAtIGRvdChub3JtLCB2ZWMzZigwLjAsIDAuMCwgMS4wKSksIDAuMCwgMS4wKSwgMy4wKSAqIGRlbnNpdHk7CiAgICBjb2xvciAgICAgPSByYmc7CiAgICBjb2xvciAgICArPSBmcmVzICogZ2MgKiAyLjA7CiAgICBjb2xvciAgICArPSBzcGVjICogZ2MgKiBkZW5zaXR5ICogMi4wOwogICAgY29sb3IgICAgID0gbWl4KGNvbG9yLCBiZyAqIDAuNSwgb2JzICogMC4yKTsKICB9IGVsc2UgewogICAgbGV0IHJ1diA9IGkudXYgKyBub3JtLnh5ICogdS5yZWZyYWN0aW9uICogZGVuc2l0eTsKICAgIGxldCByYmcgPSBtaXgod2MsIHRleHR1cmVTYW1wbGUodUJnLCBzYW1wLCBtaXgoaS51diwgcnV2LCAxLjAgLSBvYnMpKS5yZ2IsIGNvdik7CiAgICBjb2xvciAgID0gbWl4KHJiZywgd2MsIG1pbihkZW5zaXR5ICogMS41LCAwLjgpKTsKICAgIGNvbG9yICArPSBzcGVjICogZ2M7CiAgICBjb2xvciAgID0gbWl4KGNvbG9yLCBiZyAqIDAuNSwgb2JzICogMC4yKTsKICB9CgogIGxldCBhbHBoYSA9IGNsYW1wKG1heChkZW5zaXR5ICogMS41LCBjb3YpLCAwLjAsIDEuMCk7CiAgaWYgKHUuZW5hYmxlQWxwaGEgPT0gMSkgewogICAgcmV0dXJuIHZlYzRmKGNvbG9yICogYWxwaGEsIGFscGhhKTsKICB9CiAgcmV0dXJuIHZlYzRmKGNvbG9yLCAxLjApOwp9CmAKKSwgTnQgPSB7CiAgYXJyYXlTdHJpZGU6IDgsCiAgYXR0cmlidXRlczogW3sgc2hhZGVyTG9jYXRpb246IDAsIG9mZnNldDogMCwgZm9ybWF0OiAiZmxvYXQzMngyIiB9XQp9LCBudCA9IG5ldyBGbG9hdDMyQXJyYXkoWwogIC0xLAogIC0xLAogIC0xLAogIDEsCiAgMSwKICAtMSwKICAxLAogIC0xLAogIC0xLAogIDEsCiAgMSwKICAxCl0pOwpmdW5jdGlvbiAkdChpKSB7CiAgY29uc3QgZSA9IGkuY3JlYXRlQnVmZmVyKHsgc2l6ZTogbnQuYnl0ZUxlbmd0aCwgdXNhZ2U6IEdQVUJ1ZmZlclVzYWdlLlZFUlRFWCB8IEdQVUJ1ZmZlclVzYWdlLkNPUFlfRFNUIH0pOwogIHJldHVybiBpLnF1ZXVlLndyaXRlQnVmZmVyKGUsIDAsIG50KSwgZTsKfQpmdW5jdGlvbiBIZShpLCBlLCByLCBzKSB7CiAgY29uc3QgbyA9IGkuY3JlYXRlVGV4dHVyZSh7CiAgICBzaXplOiBbciwgc10sCiAgICBmb3JtYXQ6IGUsCiAgICB1c2FnZTogR1BVVGV4dHVyZVVzYWdlLlRFWFRVUkVfQklORElORyB8IEdQVVRleHR1cmVVc2FnZS5SRU5ERVJfQVRUQUNITUVOVCB8IEdQVVRleHR1cmVVc2FnZS5DT1BZX1NSQwogIH0pOwogIHJldHVybiB7IHRleDogbywgdmlldzogby5jcmVhdGVWaWV3KCksIHdpZHRoOiByLCBoZWlnaHQ6IHMgfTsKfQpmdW5jdGlvbiBydChpLCBlLCByLCBzKSB7CiAgbGV0IG8gPSBIZShpLCBlLCByLCBzKSwgYSA9IEhlKGksIGUsIHIsIHMpOwogIHJldHVybiB7CiAgICBnZXQgcmVhZCgpIHsKICAgICAgcmV0dXJuIG87CiAgICB9LAogICAgZ2V0IHdyaXRlKCkgewogICAgICByZXR1cm4gYTsKICAgIH0sCiAgICBzd2FwKCkgewogICAgICBbbywgYV0gPSBbYSwgb107CiAgICB9LAogICAgZGlzcG9zZSgpIHsKICAgICAgby50ZXguZGVzdHJveSgpLCBhLnRleC5kZXN0cm95KCk7CiAgICB9CiAgfTsKfQpmdW5jdGlvbiBzZShpLCBlLCByLCBzKSB7CiAgY29uc3QgbyA9IGkuY3JlYXRlU2hhZGVyTW9kdWxlKHsgY29kZTogZSB9KTsKICByZXR1cm4gaS5jcmVhdGVSZW5kZXJQaXBlbGluZSh7CiAgICBsYXlvdXQ6ICJhdXRvIiwKICAgIHZlcnRleDogeyBtb2R1bGU6IG8sIGVudHJ5UG9pbnQ6ICJ2cyIsIGJ1ZmZlcnM6IFtOdF0gfSwKICAgIGZyYWdtZW50OiB7IG1vZHVsZTogbywgZW50cnlQb2ludDogImZzIiwgdGFyZ2V0czogW3sgZm9ybWF0OiByLCAuLi5zID8geyBibGVuZDogcyB9IDoge30gfV0gfSwKICAgIHByaW1pdGl2ZTogeyB0b3BvbG9neTogInRyaWFuZ2xlLWxpc3QiIH0KICB9KTsKfQpjb25zdCBxdCA9IHsKICBjb2xvcjogeyBvcGVyYXRpb246ICJhZGQiLCBzcmNGYWN0b3I6ICJvbmUiLCBkc3RGYWN0b3I6ICJ6ZXJvIiB9LAogIGFscGhhOiB7IG9wZXJhdGlvbjogImFkZCIsIHNyY0ZhY3RvcjogIm9uZSIsIGRzdEZhY3RvcjogInplcm8iIH0KfTsKZnVuY3Rpb24gSHQoaSwgZSwgciA9ICEwKSB7CiAgY29uc3QgcyA9ICJyZ2JhMTZmbG9hdCI7CiAgcmV0dXJuIHsKICAgIGFkdmVjdGlvbjogc2UoaSwgQXQsIHMpLAogICAgZGl2ZXJnZW5jZTogc2UoaSwgenQsIHMpLAogICAgcHJlc3N1cmU6IHNlKGksIFh0LCBzKSwKICAgIGdyYWRpZW50U3VidHJhY3Q6IHNlKGksIEd0LCBzKSwKICAgIHNwbGF0OiBzZShpLCBNdCwgcyksCiAgICBjdXJsOiBzZShpLCBJdCwgcyksCiAgICB2b3J0aWNpdHk6IHNlKGksIGt0LCBzKSwKICAgIGRpc3BsYXk6IHNlKGksIFd0LCBlLCByID8gdm9pZCAwIDogcXQpCiAgfTsKfQpmdW5jdGlvbiBZdChpKSB7CiAgcmV0dXJuIGkuY3JlYXRlU2FtcGxlcih7IG1hZ0ZpbHRlcjogImxpbmVhciIsIG1pbkZpbHRlcjogImxpbmVhciIsIGFkZHJlc3NNb2RlVTogImNsYW1wLXRvLWVkZ2UiLCBhZGRyZXNzTW9kZVY6ICJjbGFtcC10by1lZGdlIiB9KTsKfQpmdW5jdGlvbiBXKGksIGUpIHsKICByZXR1cm4gaS5jcmVhdGVCdWZmZXIoeyBzaXplOiBlLCB1c2FnZTogR1BVQnVmZmVyVXNhZ2UuVU5JRk9STSB8IEdQVUJ1ZmZlclVzYWdlLkNPUFlfRFNUIH0pOwp9CmZ1bmN0aW9uIGx0KGksIGUsIHIsIHMsIG8sIGEpIHsKICBjb25zdCB1ID0gbmV3IEZsb2F0MzJBcnJheShbciwgcywgbywgYV0pOwogIGkucXVldWUud3JpdGVCdWZmZXIoZSwgMCwgdSk7Cn0KZnVuY3Rpb24gTmUoaSwgZSwgciwgcykgewogIGNvbnN0IG8gPSBuZXcgRmxvYXQzMkFycmF5KFtyLCBzLCAwLCAwXSk7CiAgaS5xdWV1ZS53cml0ZUJ1ZmZlcihlLCAwLCBvKTsKfQpmdW5jdGlvbiBRdChpLCBlLCByLCBzLCBvLCBhKSB7CiAgY29uc3QgdSA9IG5ldyBGbG9hdDMyQXJyYXkoW3IsIHMsIG8sIGFdKTsKICBpLnF1ZXVlLndyaXRlQnVmZmVyKGUsIDAsIHUpOwp9CmZ1bmN0aW9uICRlKGksIGUsIHIsIHMsIG8sIGEsIHUsIHYsIG0sIGMsIHApIHsKICBjb25zdCB4ID0gbmV3IEZsb2F0MzJBcnJheSgxMik7CiAgeFswXSA9IHIsIHhbMV0gPSBzLCB4WzJdID0gbywgeFszXSA9IGEsIHhbNF0gPSB1LCB4WzVdID0gdiwgeFs2XSA9IG0sIHhbN10gPSAwLCB4WzhdID0gYywgeFs5XSA9IHAsIHhbMTBdID0gMCwgeFsxMV0gPSAwLCBpLnF1ZXVlLndyaXRlQnVmZmVyKGUsIDAsIHgpOwp9CmZ1bmN0aW9uIGp0KGksIGUsIHIsIHMsIG8sIGEsIHUsIHYsIG0sIGMsIHAsIHgpIHsKICBjb25zdCBuID0gbmV3IEZsb2F0MzJBcnJheSgxNiksIGQgPSBuZXcgSW50MzJBcnJheShuLmJ1ZmZlcik7CiAgblswXSA9IHIsIG5bMV0gPSBzLCBuWzJdID0gbywgblszXSA9IGEsIG5bNF0gPSB1WzBdLCBuWzVdID0gdVsxXSwgbls2XSA9IHVbMl0sIG5bN10gPSAwLCBuWzhdID0gdlswXSwgbls5XSA9IHZbMV0sIG5bMTBdID0gdlsyXSwgblsxMV0gPSAwLCBuWzEyXSA9IG0sIG5bMTNdID0gYywgZFsxNF0gPSBwLCBkWzE1XSA9IHggPyAxIDogMCwgaS5xdWV1ZS53cml0ZUJ1ZmZlcihlLCAwLCBuKTsKfQpmdW5jdGlvbiBYKGksIGUsIHIsIHMsIG8pIHsKICBjb25zdCBhID0gaS5iZWdpblJlbmRlclBhc3MoewogICAgY29sb3JBdHRhY2htZW50czogW3sKICAgICAgdmlldzogbywKICAgICAgY2xlYXJWYWx1ZTogWzAsIDAsIDAsIDBdLAogICAgICBsb2FkT3A6ICJjbGVhciIsCiAgICAgIHN0b3JlT3A6ICJzdG9yZSIKICAgIH1dCiAgfSk7CiAgYS5zZXRQaXBlbGluZShlKSwgYS5zZXRCaW5kR3JvdXAoMCwgciksIGEuc2V0VmVydGV4QnVmZmVyKDAsIHMpLCBhLmRyYXcoNiksIGEuZW5kKCk7Cn0KZnVuY3Rpb24gS3QoaSwgZSwgciwgcywgbykgewogIGNvbnN0IGEgPSBpLmJlZ2luUmVuZGVyUGFzcyh7CiAgICBjb2xvckF0dGFjaG1lbnRzOiBbewogICAgICB2aWV3OiBvLAogICAgICBjbGVhclZhbHVlOiBbMCwgMCwgMCwgMF0sCiAgICAgIGxvYWRPcDogImNsZWFyIiwKICAgICAgc3RvcmVPcDogInN0b3JlIgogICAgfV0KICB9KTsKICBhLnNldFBpcGVsaW5lKGUpLCBhLnNldEJpbmRHcm91cCgwLCByKSwgYS5zZXRWZXJ0ZXhCdWZmZXIoMCwgcyksIGEuZHJhdyg2KSwgYS5lbmQoKTsKfQpmdW5jdGlvbiBCZShpLCBlLCByLCBzLCBvID0gImNvdmVyIikgewogIGxldCBhOwogIG8gPT09ICJjb3ZlciIgPyBhID0gTWF0aC5tYXgociAvIGksIHMgLyBlKSA6IG8gPT09ICJjb250YWluIiA/IGEgPSBNYXRoLm1pbihyIC8gaSwgcyAvIGUpIDogdHlwZW9mIG8gPT0gInN0cmluZyIgJiYgby5lbmRzV2l0aCgiJSIpID8gYSA9IE1hdGgubWluKHIgLyBpLCBzIC8gZSkgKiAocGFyc2VGbG9hdChvKSAvIDEwMCkgOiB0eXBlb2YgbyA9PSAic3RyaW5nIiAmJiBvLmVuZHNXaXRoKCJweCIpID8gYSA9IHBhcnNlRmxvYXQobykgLyBNYXRoLm1heChpLCBlKSA6IHR5cGVvZiBvID09ICJudW1iZXIiID8gYSA9IG8gOiBhID0gTWF0aC5tYXgociAvIGksIHMgLyBlKTsKICBjb25zdCB1ID0gaSAqIGEsIHYgPSBlICogYTsKICByZXR1cm4geyB4OiAociAtIHUpIC8gMiwgeTogKHMgLSB2KSAvIDIsIGRyYXdXOiB1LCBkcmF3SDogdiB9Owp9CmZ1bmN0aW9uIEp0KGksIGUsIHIsIHMsIG8gPSBudWxsLCBhID0gImNvdmVyIikgewogIGNvbnN0IHsgdGV4dDogdSwgZm9udFNpemU6IHYsIGNvbG9yOiBtLCBmb250RmFtaWx5OiBjID0gInNhbnMtc2VyaWYiLCBmb250V2VpZ2h0OiBwID0gOTAwIH0gPSBzLCB4ID0gbmV3IE9mZnNjcmVlbkNhbnZhcyhlLCByKSwgbiA9IHguZ2V0Q29udGV4dCgiMmQiKTsKICAoKEQpID0+IHsKICAgIGlmIChvKSB7CiAgICAgIG4uY2xlYXJSZWN0KDAsIDAsIGUsIHIpLCBuLmZpbGxTdHlsZSA9ICJibGFjayIsIG4uZmlsbFJlY3QoMCwgMCwgZSwgcik7CiAgICAgIGNvbnN0IHsgeDogZywgeTogXywgZHJhd1c6IEYsIGRyYXdIOiBrIH0gPSBCZSgKICAgICAgICBvLndpZHRoLAogICAgICAgIG8uaGVpZ2h0LAogICAgICAgIGUsCiAgICAgICAgciwKICAgICAgICBhCiAgICAgICk7CiAgICAgIG4uZHJhd0ltYWdlKG8sIGcsIF8sIEYsIGspOwogICAgfSBlbHNlCiAgICAgIG4uZmlsbFN0eWxlID0gImJsYWNrIiwgbi5maWxsUmVjdCgwLCAwLCBlLCByKTsKICAgIG4uZmlsbFN0eWxlID0gRCwgbi5mb250ID0gYCR7cH0gJHt2fXB4ICR7Y31gLCBuLnRleHRBbGlnbiA9ICJjZW50ZXIiLCBuLnRleHRCYXNlbGluZSA9ICJtaWRkbGUiLCBuLmZpbGxUZXh0KHUsIGUgLyAyLCByIC8gMik7CiAgfSkobSk7CiAgY29uc3QgYiA9IExlKGksIHgpOwogIG4uZmlsbFN0eWxlID0gImJsYWNrIiwgbi5maWxsUmVjdCgwLCAwLCBlLCByKSwgbi5maWxsU3R5bGUgPSAid2hpdGUiLCBuLmZvbnQgPSBgJHtwfSAke3Z9cHggJHtjfWAsIG4udGV4dEFsaWduID0gImNlbnRlciIsIG4udGV4dEJhc2VsaW5lID0gIm1pZGRsZSIsIG4uZmlsbFRleHQodSwgZSAvIDIsIHIgLyAyKTsKICBjb25zdCB5ID0gTGUoaSwgeCk7CiAgcmV0dXJuIHsgYmFja2dyb3VuZFRleDogYiwgb2JzdGFjbGVUZXg6IHksIGNvdmVyYWdlVGV4OiB5IH07Cn0KZnVuY3Rpb24gWnQoaSwgZSwgciwgcywgbyA9IDAsIGEgPSAiY292ZXIiLCB1ID0gbnVsbCwgdiA9ICJjb3ZlciIpIHsKICBjb25zdCBtID0gbmV3IE9mZnNjcmVlbkNhbnZhcyhyLCBzKSwgYyA9IG0uZ2V0Q29udGV4dCgiMmQiKSwgeyB4OiBwLCB5OiB4LCBkcmF3VzogbiwgZHJhd0g6IGQgfSA9IEJlKGUud2lkdGgsIGUuaGVpZ2h0LCByLCBzLCBhKTsKICBpZiAoYy5jbGVhclJlY3QoMCwgMCwgciwgcyksIGMuZmlsbFN0eWxlID0gImJsYWNrIiwgYy5maWxsUmVjdCgwLCAwLCByLCBzKSwgdSkgewogICAgY29uc3QgewogICAgICB4OiBnLAogICAgICB5OiBfLAogICAgICBkcmF3VzogRiwKICAgICAgZHJhd0g6IGsKICAgIH0gPSBCZSh1LndpZHRoLCB1LmhlaWdodCwgciwgcywgdik7CiAgICBjLmZpbHRlciA9IGBicmlnaHRuZXNzKCR7b30pIGJsdXIoOHB4KWAsIGMuZHJhd0ltYWdlKHUsIGcsIF8sIEYsIGspLCBjLmZpbHRlciA9ICJub25lIjsKICB9CiAgYy5kcmF3SW1hZ2UoZSwgcCwgeCwgbiwgZCk7CiAgY29uc3QgYiA9IExlKGksIG0pOwogIGMuY2xlYXJSZWN0KDAsIDAsIHIsIHMpLCBjLmZpbGxTdHlsZSA9ICJibGFjayIsIGMuZmlsbFJlY3QoMCwgMCwgciwgcyksIGMuZmlsdGVyID0gYGJyaWdodG5lc3MoJHtvfSkgYmx1cig4cHgpYCwgYy5kcmF3SW1hZ2UoZSwgcCwgeCwgbiwgZCksIGMuZmlsdGVyID0gIm5vbmUiOwogIGNvbnN0IHkgPSBMZShpLCBtKTsKICBjLmNsZWFyUmVjdCgwLCAwLCByLCBzKSwgYy5maWxsU3R5bGUgPSAiYmxhY2siLCBjLmZpbGxSZWN0KDAsIDAsIHIsIHMpLCBjLmZpbGxTdHlsZSA9ICJ3aGl0ZSIsIGMuZmlsbFJlY3QoCiAgICBNYXRoLm1heCgwLCBwKSwKICAgIE1hdGgubWF4KDAsIHgpLAogICAgTWF0aC5taW4obiwgciAtIE1hdGgubWF4KDAsIHApKSwKICAgIE1hdGgubWluKGQsIHMgLSBNYXRoLm1heCgwLCB4KSkKICApOwogIGNvbnN0IEQgPSBMZShpLCBtKTsKICByZXR1cm4geyBiYWNrZ3JvdW5kVGV4OiBiLCBvYnN0YWNsZVRleDogeSwgY292ZXJhZ2VUZXg6IEQgfTsKfQpmdW5jdGlvbiBMZShpLCBlKSB7CiAgY29uc3QgciA9IGkuY3JlYXRlVGV4dHVyZSgpOwogIHJldHVybiBpLmJpbmRUZXh0dXJlKGkuVEVYVFVSRV8yRCwgciksIGkucGl4ZWxTdG9yZWkoaS5VTlBBQ0tfRkxJUF9ZX1dFQkdMLCAhMCksIGkudGV4SW1hZ2UyRChpLlRFWFRVUkVfMkQsIDAsIGkuUkdCQSwgaS5SR0JBLCBpLlVOU0lHTkVEX0JZVEUsIGUpLCBpLnRleFBhcmFtZXRlcmkoaS5URVhUVVJFXzJELCBpLlRFWFRVUkVfTUlOX0ZJTFRFUiwgaS5MSU5FQVIpLCBpLnRleFBhcmFtZXRlcmkoaS5URVhUVVJFXzJELCBpLlRFWFRVUkVfTUFHX0ZJTFRFUiwgaS5MSU5FQVIpLCBpLnRleFBhcmFtZXRlcmkoaS5URVhUVVJFXzJELCBpLlRFWFRVUkVfV1JBUF9TLCBpLkNMQU1QX1RPX0VER0UpLCBpLnRleFBhcmFtZXRlcmkoaS5URVhUVVJFXzJELCBpLlRFWFRVUkVfV1JBUF9ULCBpLkNMQU1QX1RPX0VER0UpLCByOwp9CmZ1bmN0aW9uIGVyKGksIGUsIHIsIHMsIG8gPSBudWxsLCBhID0gImNvdmVyIikgewogIGNvbnN0IHsgdGV4dDogdSwgZm9udFNpemU6IHYsIGNvbG9yOiBtLCBmb250RmFtaWx5OiBjID0gInNhbnMtc2VyaWYiLCBmb250V2VpZ2h0OiBwID0gOTAwIH0gPSBzLCB4ID0gbmV3IE9mZnNjcmVlbkNhbnZhcyhlLCByKSwgbiA9IHguZ2V0Q29udGV4dCgiMmQiKTsKICAoKEQpID0+IHsKICAgIGlmIChvKSB7CiAgICAgIG4uY2xlYXJSZWN0KDAsIDAsIGUsIHIpLCBuLmZpbGxTdHlsZSA9ICJibGFjayIsIG4uZmlsbFJlY3QoMCwgMCwgZSwgcik7CiAgICAgIGNvbnN0IHsgeDogZywgeTogXywgZHJhd1c6IEYsIGRyYXdIOiBrIH0gPSBCZSgKICAgICAgICBvLndpZHRoLAogICAgICAgIG8uaGVpZ2h0LAogICAgICAgIGUsCiAgICAgICAgciwKICAgICAgICBhCiAgICAgICk7CiAgICAgIG4uZHJhd0ltYWdlKG8sIGcsIF8sIEYsIGspOwogICAgfSBlbHNlCiAgICAgIG4uZmlsbFN0eWxlID0gImJsYWNrIiwgbi5maWxsUmVjdCgwLCAwLCBlLCByKTsKICAgIG4uZmlsbFN0eWxlID0gRCwgbi5mb250ID0gYCR7cH0gJHt2fXB4ICR7Y31gLCBuLnRleHRBbGlnbiA9ICJjZW50ZXIiLCBuLnRleHRCYXNlbGluZSA9ICJtaWRkbGUiLCBuLmZpbGxUZXh0KHUsIGUgLyAyLCByIC8gMik7CiAgfSkobSk7CiAgY29uc3QgYiA9IEFlKGksIHgsIGUsIHIpOwogIG4uZmlsbFN0eWxlID0gImJsYWNrIiwgbi5maWxsUmVjdCgwLCAwLCBlLCByKSwgbi5maWxsU3R5bGUgPSAid2hpdGUiLCBuLmZvbnQgPSBgJHtwfSAke3Z9cHggJHtjfWAsIG4udGV4dEFsaWduID0gImNlbnRlciIsIG4udGV4dEJhc2VsaW5lID0gIm1pZGRsZSIsIG4uZmlsbFRleHQodSwgZSAvIDIsIHIgLyAyKTsKICBjb25zdCB5ID0gQWUoaSwgeCwgZSwgcik7CiAgcmV0dXJuIHsKICAgIGJhY2tncm91bmRUZXg6IGIsCiAgICBiYWNrZ3JvdW5kVmlldzogYi5jcmVhdGVWaWV3KCksCiAgICBvYnN0YWNsZVRleDogeSwKICAgIG9ic3RhY2xlVmlldzogeS5jcmVhdGVWaWV3KCksCiAgICBjb3ZlcmFnZVRleDogeSwKICAgIGNvdmVyYWdlVmlldzogeS5jcmVhdGVWaWV3KCksCiAgICBzaGFyZWRDb3ZlcmFnZTogITAKICB9Owp9CmZ1bmN0aW9uIHRyKGksIGUsIHIsIHMsIG8gPSAwLCBhID0gImNvdmVyIiwgdSA9IG51bGwsIHYgPSAiY292ZXIiKSB7CiAgY29uc3QgbSA9IG5ldyBPZmZzY3JlZW5DYW52YXMociwgcyksIGMgPSBtLmdldENvbnRleHQoIjJkIiksIHsgeDogcCwgeTogeCwgZHJhd1c6IG4sIGRyYXdIOiBkIH0gPSBCZShlLndpZHRoLCBlLmhlaWdodCwgciwgcywgYSk7CiAgaWYgKGMuY2xlYXJSZWN0KDAsIDAsIHIsIHMpLCBjLmZpbGxTdHlsZSA9ICJibGFjayIsIGMuZmlsbFJlY3QoMCwgMCwgciwgcyksIHUpIHsKICAgIGNvbnN0IHsgeDogZywgeTogXywgZHJhd1c6IEYsIGRyYXdIOiBrIH0gPSBCZSgKICAgICAgdS53aWR0aCwKICAgICAgdS5oZWlnaHQsCiAgICAgIHIsCiAgICAgIHMsCiAgICAgIHYKICAgICk7CiAgICBjLmZpbHRlciA9IGBicmlnaHRuZXNzKCR7b30pIGJsdXIoOHB4KWAsIGMuZHJhd0ltYWdlKHUsIGcsIF8sIEYsIGspLCBjLmZpbHRlciA9ICJub25lIjsKICB9CiAgYy5kcmF3SW1hZ2UoZSwgcCwgeCwgbiwgZCk7CiAgY29uc3QgYiA9IEFlKGksIG0sIHIsIHMpOwogIGMuY2xlYXJSZWN0KDAsIDAsIHIsIHMpLCBjLmZpbGxTdHlsZSA9ICJibGFjayIsIGMuZmlsbFJlY3QoMCwgMCwgciwgcyksIGMuZmlsdGVyID0gYGJyaWdodG5lc3MoJHtvfSkgYmx1cig4cHgpYCwgYy5kcmF3SW1hZ2UoZSwgcCwgeCwgbiwgZCksIGMuZmlsdGVyID0gIm5vbmUiOwogIGNvbnN0IHkgPSBBZShpLCBtLCByLCBzKTsKICBjLmNsZWFyUmVjdCgwLCAwLCByLCBzKSwgYy5maWxsU3R5bGUgPSAiYmxhY2siLCBjLmZpbGxSZWN0KDAsIDAsIHIsIHMpLCBjLmZpbGxTdHlsZSA9ICJ3aGl0ZSIsIGMuZmlsbFJlY3QoTWF0aC5tYXgoMCwgcCksIE1hdGgubWF4KDAsIHgpLCBNYXRoLm1pbihuLCByIC0gTWF0aC5tYXgoMCwgcCkpLCBNYXRoLm1pbihkLCBzIC0gTWF0aC5tYXgoMCwgeCkpKTsKICBjb25zdCBEID0gQWUoaSwgbSwgciwgcyk7CiAgcmV0dXJuIHsKICAgIGJhY2tncm91bmRUZXg6IGIsCiAgICBiYWNrZ3JvdW5kVmlldzogYi5jcmVhdGVWaWV3KCksCiAgICBvYnN0YWNsZVRleDogeSwKICAgIG9ic3RhY2xlVmlldzogeS5jcmVhdGVWaWV3KCksCiAgICBjb3ZlcmFnZVRleDogRCwKICAgIGNvdmVyYWdlVmlldzogRC5jcmVhdGVWaWV3KCksCiAgICBzaGFyZWRDb3ZlcmFnZTogITEKICB9Owp9CmZ1bmN0aW9uIEFlKGksIGUsIHIsIHMpIHsKICBjb25zdCBvID0gaS5jcmVhdGVUZXh0dXJlKHsKICAgIHNpemU6IFtyLCBzXSwKICAgIGZvcm1hdDogInJnYmE4dW5vcm0iLAogICAgdXNhZ2U6IEdQVVRleHR1cmVVc2FnZS5URVhUVVJFX0JJTkRJTkcgfCBHUFVUZXh0dXJlVXNhZ2UuQ09QWV9EU1QgfCBHUFVUZXh0dXJlVXNhZ2UuUkVOREVSX0FUVEFDSE1FTlQKICB9KTsKICByZXR1cm4gaS5xdWV1ZS5jb3B5RXh0ZXJuYWxJbWFnZVRvVGV4dHVyZSgKICAgIHsgc291cmNlOiBlIH0sCiAgICB7IHRleHR1cmU6IG8gfSwKICAgIFtyLCBzXQogICksIG87Cn0KYXN5bmMgZnVuY3Rpb24gcnIoaSkgewogIGNvbnN0IGUgPSBhd2FpdCBmZXRjaChpKTsKICBpZiAoIWUub2spCiAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBmZXRjaCBpbWFnZTogJHtpfSAoJHtlLnN0YXR1c30pYCk7CiAgY29uc3QgciA9IGF3YWl0IGUuYmxvYigpOwogIHJldHVybiBjcmVhdGVJbWFnZUJpdG1hcChyKTsKfQpjb25zdCBjdCA9IHR5cGVvZiByZXF1ZXN0QW5pbWF0aW9uRnJhbWUgPCAidSIgPyByZXF1ZXN0QW5pbWF0aW9uRnJhbWUuYmluZChnbG9iYWxUaGlzKSA6IChpKSA9PiBzZXRUaW1lb3V0KGksIDFlMyAvIDYwKSwgaXIgPSB0eXBlb2YgY2FuY2VsQW5pbWF0aW9uRnJhbWUgPCAidSIgPyBjYW5jZWxBbmltYXRpb25GcmFtZS5iaW5kKGdsb2JhbFRoaXMpIDogY2xlYXJUaW1lb3V0LCBWZSA9IDAuMDE2LCBmdCA9IHsgc3RhbmRhcmQ6IDAsIGdsYXNzOiAxLCBpbms6IDIsIGF1cm9yYTogMywgcmlwcGxlOiA0IH07CnZhciBjZSwgRywgemUsIGZlLCBVZSwgQiwgUiwgJCwgcSwgSCwgSywgTCwgWSwgViwgRGUsIHZlLCBfZSwgTywgVCwgb2UsIFEsIGFlLCB6LCB4ZSwgcGUsIG1lLCBkZSwgaGUsIEosIFosIGdlLCBiZSwgVGUsIHcsIFUsIE0sIEksIFAsIENlLCBlZSwgQSwgdWUsIHRlLCBoLCBDLCBqLCB5ZSwgWGUsIFNlLCBZZSwgeHQsIHdlLCBQZSwgR2UsIHN0LCBuZSwgRWUsIFJlLCBGZSwgTWUsIG90LCBJZSwgYXQsIFFlLCBwdCwgamUsIG10LCBLZSwgZHQsIEplLCBodCwgWmUsIGd0Owpjb25zdCB1dCA9IGNsYXNzIHV0IHsKICAvLyDilIDilIAgQ29uc3RydWN0b3Ig4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiAgY29uc3RydWN0b3IoZSwgciA9IHt9LCBzID0ge30sIG8sIGEgPSAhMCkgewogICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAvLyBQcml2YXRlIOKAlCBHUFUgaW5pdGlhbGlzYXRpb24KICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgZih0aGlzLCBZZSk7CiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8vIFByaXZhdGUg4oCUIHNoYXJlZCBoZWxwZXJzCiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIGYodGhpcywgd2UpOwogICAgZih0aGlzLCBHZSk7CiAgICBmKHRoaXMsIG5lKTsKICAgIGYodGhpcywgUmUpOwogICAgZih0aGlzLCBNZSk7CiAgICBmKHRoaXMsIEllKTsKICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLy8gUHJpdmF0ZSDigJQgZnJhbWUgZGlzcGF0Y2gKICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgZih0aGlzLCBRZSk7CiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8vIFByaXZhdGUg4oCUIFdlYkdQVSBzaW11bGF0aW9uIHN0ZXAKICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgZih0aGlzLCBqZSk7CiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8vIFByaXZhdGUg4oCUIFdlYkdQVSBkaXJlY3Qgc3BsYXQKICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgZih0aGlzLCBLZSk7CiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8vIFByaXZhdGUg4oCUIFdlYkdMIHNwbGF0CiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIGYodGhpcywgSmUpOwogICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAvLyBQcml2YXRlIOKAlCBXZWJHTCBzaW11bGF0aW9uIHN0ZXAgKHVuY2hhbmdlZCBmcm9tIG9yaWdpbmFsKQogICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBmKHRoaXMsIFplKTsKICAgIGYodGhpcywgY2UsIHZvaWQgMCk7CiAgICAvLyDilIDilIAgV2ViR0wgcGF0aCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKICAgIGYodGhpcywgRywgbnVsbCk7CiAgICBmKHRoaXMsIHplLCBudWxsKTsKICAgIGYodGhpcywgZmUsIG51bGwpOwogICAgZih0aGlzLCBVZSwgbnVsbCk7CiAgICBmKHRoaXMsIEIsIG51bGwpOwogICAgZih0aGlzLCBSLCBudWxsKTsKICAgIGYodGhpcywgJCwgbnVsbCk7CiAgICBmKHRoaXMsIHEsIG51bGwpOwogICAgZih0aGlzLCBILCBudWxsKTsKICAgIGYodGhpcywgSywgbnVsbCk7CiAgICBmKHRoaXMsIEwsIG51bGwpOwogICAgZih0aGlzLCBZLCBudWxsKTsKICAgIC8vIOKUgOKUgCBXZWJHUFUgcGF0aCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKICAgIGYodGhpcywgViwgbnVsbCk7CiAgICBmKHRoaXMsIERlLCBudWxsKTsKICAgIGYodGhpcywgdmUsIG51bGwpOwogICAgZih0aGlzLCBfZSwgbnVsbCk7CiAgICBmKHRoaXMsIE8sIG51bGwpOwogICAgZih0aGlzLCBULCBudWxsKTsKICAgIGYodGhpcywgb2UsIG51bGwpOwogICAgZih0aGlzLCBRLCBudWxsKTsKICAgIGYodGhpcywgYWUsIG51bGwpOwogICAgZih0aGlzLCB6LCBudWxsKTsKICAgIC8vIFByZS1hbGxvY2F0ZWQgdW5pZm9ybSBidWZmZXJzIChzaXplczogc2VlIGdwdS11dGlscyB3cml0ZVh4eCBkb2NzKQogICAgLy8gVmVsb2NpdHkvZGVuc2l0eSBhZHZlY3Rpb24gdXNlIHNlcGFyYXRlIGJ1ZmZlcnMg4oCUIHdyaXRlQnVmZmVyIGlzIGEgcXVldWUgb3A7CiAgICAvLyBhIHNlY29uZCB3cml0ZSB0byB0aGUgc2FtZSBidWZmZXIgYmVmb3JlIHF1ZXVlLnN1Ym1pdCgpIGFsaWFzZXMgYm90aCBwYXNzZXMuCiAgICBmKHRoaXMsIHhlLCBudWxsKTsKICAgIC8vIDE2IGJ5dGVzIOKAlCB2ZWxvY2l0eSBhZHZlY3Rpb24KICAgIGYodGhpcywgcGUsIG51bGwpOwogICAgLy8gMTYgYnl0ZXMg4oCUIGRlbnNpdHkgYWR2ZWN0aW9uCiAgICBmKHRoaXMsIG1lLCBudWxsKTsKICAgIC8vIDE2IGJ5dGVzCiAgICBmKHRoaXMsIGRlLCBudWxsKTsKICAgIC8vIDE2IGJ5dGVzCiAgICBmKHRoaXMsIGhlLCBudWxsKTsKICAgIC8vIDE2IGJ5dGVzCiAgICBmKHRoaXMsIEosIG51bGwpOwogICAgLy8gNDggYnl0ZXMg4oCUIHZlbG9jaXR5IHNwbGF0CiAgICBmKHRoaXMsIFosIG51bGwpOwogICAgLy8gNDggYnl0ZXMg4oCUIGRlbnNpdHkgc3BsYXQKICAgIGYodGhpcywgZ2UsIG51bGwpOwogICAgLy8gMTYgYnl0ZXMKICAgIGYodGhpcywgYmUsIG51bGwpOwogICAgLy8gMTYgYnl0ZXMKICAgIGYodGhpcywgVGUsIG51bGwpOwogICAgLy8gNjQgYnl0ZXMKICAgIC8vIOKUgOKUgCBTaGFyZWQgc3RhdGUg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiAgICBmKHRoaXMsIHcsIDApOwogICAgZih0aGlzLCBVLCAwKTsKICAgIGYodGhpcywgTSwgMCk7CiAgICBmKHRoaXMsIEksIDApOwogICAgZih0aGlzLCBQLCAxKTsKICAgIGYodGhpcywgQ2UsIDEpOwogICAgZih0aGlzLCBlZSwgMC41KTsKICAgIGYodGhpcywgQSwgbnVsbCk7CiAgICBmKHRoaXMsIHVlLCAiY292ZXIiKTsKICAgIGYodGhpcywgdGUsIHZvaWQgMCk7CiAgICBmKHRoaXMsIGgsIHsgeDogMCwgeTogMCwgZHg6IDAsIGR5OiAwLCB0YXJnZXRYOiAwLCB0YXJnZXRZOiAwLCBtb3ZlZDogITEgfSk7CiAgICBmKHRoaXMsIEMsIG51bGwpOwogICAgZih0aGlzLCBqLCBudWxsKTsKICAgIGYodGhpcywgeWUsICExKTsKICAgIGYodGhpcywgWGUsICExKTsKICAgIGYodGhpcywgU2UsICEwKTsKICAgIGlmIChsKHRoaXMsIGNlLCBlKSwgbCh0aGlzLCBDZSwgTWF0aC5tYXgoMC4xLCBNYXRoLm1pbigxLCBzLmRwciA/PyAxKSkpLCBsKHRoaXMsIGVlLCBNYXRoLm1heCgwLjEsIE1hdGgubWluKDEsIHMuc2ltID8/IDAuNSkpKSwgbCh0aGlzLCB0ZSwgd3QocikpLCBsKHRoaXMsIFNlLCBhKSwgbykKICAgICAgbCh0aGlzLCBWLCBvKSwgUyh0aGlzLCBZZSwgeHQpLmNhbGwodGhpcywgbyk7CiAgICBlbHNlIHsKICAgICAgY29uc3QgeyBnbDogdSwgZXh0OiB2IH0gPSBWdChlLCBhKTsKICAgICAgbCh0aGlzLCBHLCB1KSwgbCh0aGlzLCB6ZSwgdiksIGwodGhpcywgZmUsIEZ0KHUpKSwgbCh0aGlzLCBVZSwgTHQodSkpLCB1LmNsZWFyQ29sb3IoMCwgMCwgMCwgYSA/IDAgOiAxKTsKICAgIH0KICB9CiAgLyoqCiAgICogV2ViR1BVLWZpcnN0IGZhY3RvcnkuIFRyaWVzIFdlYkdQVSwgZmFsbHMgYmFjayB0byBXZWJHTDIg4oaSIFdlYkdMMS4KICAgKiBUaGlzIGlzIHRoZSByZWNvbW1lbmRlZCBlbnRyeSBwb2ludCB3aGVuIFdlYkdQVSBzdXBwb3J0IGlzIGRlc2lyZWQuCiAgICovCiAgc3RhdGljIGFzeW5jIGNyZWF0ZShlLCByID0ge30sIHMgPSB7fSwgbyA9ICEwLCBhID0gITApIHsKICAgIGNvbnN0IHUgPSBvID8gYXdhaXQgUHQoZSwgYSkgOiBudWxsOwogICAgcmV0dXJuIG5ldyB1dChlLCByLCBzLCB1ID8/IHZvaWQgMCwgYSk7CiAgfQogIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIC8vIFB1YmxpYyBBUEkKICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICBzZXRUZXh0U291cmNlKGUpIHsKICAgIGwodGhpcywgQywgeyB0eXBlOiAidGV4dCIsIG9wdHM6IGUgfSksIFModGhpcywgd2UsIFBlKS5jYWxsKHRoaXMpLCBTKHRoaXMsIG5lLCBFZSkuY2FsbCh0aGlzKSwgUyh0aGlzLCBSZSwgRmUpLmNhbGwodGhpcyk7CiAgfQogIGFzeW5jIHNldEltYWdlU291cmNlKGUsIHIgPSAwLCBzID0gImNvdmVyIikgewogICAgY29uc3QgbyA9IGF3YWl0IHJyKGUpOwogICAgaWYgKHQodGhpcywgWGUpKSB7CiAgICAgIG8uY2xvc2UoKTsKICAgICAgcmV0dXJuOwogICAgfQogICAgbCh0aGlzLCBDLCB7IHR5cGU6ICJpbWFnZSIsIGJpdG1hcDogbywgZWZmZWN0OiByLCBzaXplOiBzIH0pLCBTKHRoaXMsIHdlLCBQZSkuY2FsbCh0aGlzKSwgUyh0aGlzLCBuZSwgRWUpLmNhbGwodGhpcyksIFModGhpcywgUmUsIEZlKS5jYWxsKHRoaXMpOwogIH0KICBzZXRJbWFnZUJpdG1hcChlLCByID0gMCwgcyA9ICJjb3ZlciIpIHsKICAgIGwodGhpcywgQywgeyB0eXBlOiAiaW1hZ2UiLCBiaXRtYXA6IGUsIGVmZmVjdDogciwgc2l6ZTogcyB9KSwgUyh0aGlzLCB3ZSwgUGUpLmNhbGwodGhpcyksIFModGhpcywgbmUsIEVlKS5jYWxsKHRoaXMpLCBTKHRoaXMsIFJlLCBGZSkuY2FsbCh0aGlzKTsKICB9CiAgc2V0QmFja2dyb3VuZChlLCByID0gImNvdmVyIikgewogICAgdCh0aGlzLCBBKSAmJiB0KHRoaXMsIEEpICE9PSBlICYmIHQodGhpcywgQSkuY2xvc2UoKSwgbCh0aGlzLCBBLCBlKSwgbCh0aGlzLCB1ZSwgciA/PyAiY292ZXIiKSwgdCh0aGlzLCBDKSAmJiB0KHRoaXMsIHcpID4gMCAmJiB0KHRoaXMsIFUpID4gMCAmJiBTKHRoaXMsIG5lLCBFZSkuY2FsbCh0aGlzKTsKICB9CiAgaGFuZGxlTW92ZShlLCByLCBzID0gMSkgewogICAgdCh0aGlzLCBoKS5tb3ZlZCA9ICEwLCB0KHRoaXMsIGgpLmR4ID0gKGUgLSB0KHRoaXMsIGgpLnRhcmdldFgpICogcywgdCh0aGlzLCBoKS5keSA9IChyIC0gdCh0aGlzLCBoKS50YXJnZXRZKSAqIHMsIHQodGhpcywgaCkudGFyZ2V0WCA9IGUsIHQodGhpcywgaCkudGFyZ2V0WSA9IHI7CiAgfQogIC8qKgogICAqIEltbWVkaWF0ZWx5IGFwcGxpZXMgb25lIGZsdWlkIHNwbGF0IGF0ICh4LCB5KSB3aXRoIGV4cGxpY2l0IHZlbG9jaXR5ICh2eCwgdnkpLgogICAqIFNhZmUgdG8gY2FsbCBtdWx0aXBsZSB0aW1lcyBwZXIgZnJhbWUg4oCUIGVhY2ggY2FsbCB3cml0ZXMgZGlyZWN0bHkgdG8gdGhlIEZCT3MuCiAgICogRGVzaWduZWQgZm9yIHByb2dyYW1tYXRpYyB1c2UgY2FzZXMgKGUuZy4gcGFydGljbGUgc3lzdGVtcywgYXR0cmFjdG9yIHBhdGhzKQogICAqIHdoZXJlIHlvdSB3YW50IE4gaW5kZXBlbmRlbnQgaW5qZWN0aW9uIHBvaW50cyBwZXIgZnJhbWUgd2l0aG91dCBmbG9vZGluZyB0aGUKICAgKiBtb3VzZS1zdGF0ZSBtYWNoaW5lIG9yIHRoZSB3b3JrZXIgbWVzc2FnZSBxdWV1ZS4KICAgKi8KICBzcGxhdChlLCByLCBzLCBvLCBhID0gMSkgewogICAgIXQodGhpcywgeWUpIHx8IHQodGhpcywgdykgPT09IDAgfHwgKHQodGhpcywgVikgPyBTKHRoaXMsIEtlLCBkdCkuY2FsbCh0aGlzLCBlLCByLCBzLCBvLCBhKSA6IFModGhpcywgSmUsIGh0KS5jYWxsKHRoaXMsIGUsIHIsIHMsIG8sIGEpKTsKICB9CiAgdXBkYXRlUXVhbGl0eShlKSB7CiAgICBlLmRwciAhPT0gdm9pZCAwICYmIGwodGhpcywgQ2UsIE1hdGgubWF4KDAuMSwgTWF0aC5taW4oMSwgZS5kcHIpKSksIGUuc2ltICE9PSB2b2lkIDAgJiYgbCh0aGlzLCBlZSwgTWF0aC5tYXgoMC4xLCBNYXRoLm1pbigxLCBlLnNpbSkpKTsKICB9CiAgcmVzaXplKGUsIHIsIHMpIHsKICAgIGlmIChzICE9PSB2b2lkIDAgPyBsKHRoaXMsIFAsIHMpIDogdHlwZW9mIHdpbmRvdyA8ICJ1IiAmJiB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyAmJiBsKHRoaXMsIFAsIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvKSwgZSAhPT0gdm9pZCAwICYmIGUgPiAwKSB7CiAgICAgIGlmIChyID09PSB2b2lkIDAgfHwgciA8PSAwKQogICAgICAgIHJldHVybjsKICAgICAgbCh0aGlzLCB3LCB0KHRoaXMsIGNlKS53aWR0aCA9IGUpLCBsKHRoaXMsIFUsIHQodGhpcywgY2UpLmhlaWdodCA9IHIpLCBsKHRoaXMsIE0sIE1hdGgubWF4KDEsIE1hdGgucm91bmQoZSAqIHQodGhpcywgZWUpKSkpLCBsKHRoaXMsIEksIE1hdGgubWF4KDEsIE1hdGgucm91bmQociAqIHQodGhpcywgZWUpKSkpLCBTKHRoaXMsIEdlLCBzdCkuY2FsbCh0aGlzKTsKICAgIH0gZWxzZQogICAgICBTKHRoaXMsIHdlLCBQZSkuY2FsbCh0aGlzKTsKICAgIHQodGhpcywgQykgJiYgUyh0aGlzLCBuZSwgRWUpLmNhbGwodGhpcyksIFModGhpcywgUmUsIEZlKS5jYWxsKHRoaXMpOwogIH0KICB1cGRhdGVDb25maWcoZSkgewogICAgT2JqZWN0LmFzc2lnbih0KHRoaXMsIHRlKSwgZSk7CiAgfQogIGRlc3Ryb3koKSB7CiAgICB2YXIgZSwgciwgcywgbywgYSwgdSwgdiwgbSwgYywgcCwgeDsKICAgIGlmIChsKHRoaXMsIFhlLCAhMCksIHRoaXMuc3RvcCgpLCBTKHRoaXMsIE1lLCBvdCkuY2FsbCh0aGlzKSwgUyh0aGlzLCBJZSwgYXQpLmNhbGwodGhpcyksIHQodGhpcywgQSkgJiYgKHQodGhpcywgQSkuY2xvc2UoKSwgbCh0aGlzLCBBLCBudWxsKSksIHQodGhpcywgVikpCiAgICAgIChlID0gdCh0aGlzLCB4ZSkpID09IG51bGwgfHwgZS5kZXN0cm95KCksIChyID0gdCh0aGlzLCBwZSkpID09IG51bGwgfHwgci5kZXN0cm95KCksIChzID0gdCh0aGlzLCBtZSkpID09IG51bGwgfHwgcy5kZXN0cm95KCksIChvID0gdCh0aGlzLCBkZSkpID09IG51bGwgfHwgby5kZXN0cm95KCksIChhID0gdCh0aGlzLCBoZSkpID09IG51bGwgfHwgYS5kZXN0cm95KCksICh1ID0gdCh0aGlzLCBKKSkgPT0gbnVsbCB8fCB1LmRlc3Ryb3koKSwgKHYgPSB0KHRoaXMsIFopKSA9PSBudWxsIHx8IHYuZGVzdHJveSgpLCAobSA9IHQodGhpcywgZ2UpKSA9PSBudWxsIHx8IG0uZGVzdHJveSgpLCAoYyA9IHQodGhpcywgYmUpKSA9PSBudWxsIHx8IGMuZGVzdHJveSgpLCAocCA9IHQodGhpcywgVGUpKSA9PSBudWxsIHx8IHAuZGVzdHJveSgpLCAoeCA9IHQodGhpcywgdmUpKSA9PSBudWxsIHx8IHguZGVzdHJveSgpLCB0KHRoaXMsIFYpLmRldmljZS5kZXN0cm95KCk7CiAgICBlbHNlIHsKICAgICAgY29uc3QgbiA9IHQodGhpcywgRyk7CiAgICAgIGZvciAoY29uc3QgYiBvZiBPYmplY3QudmFsdWVzKHQodGhpcywgZmUpKSkKICAgICAgICBiLmRpc3Bvc2UoKTsKICAgICAgY29uc3QgZCA9IG4uZ2V0RXh0ZW5zaW9uKCJXRUJHTF9sb3NlX2NvbnRleHQiKTsKICAgICAgZCA9PSBudWxsIHx8IGQubG9zZUNvbnRleHQoKTsKICAgIH0KICB9CiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgLy8gTG9vcCBjb250cm9sCiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgc3RhcnQoKSB7CiAgICBpZiAodCh0aGlzLCBqKSAhPT0gbnVsbCkKICAgICAgcmV0dXJuOwogICAgY29uc3QgZSA9ICgpID0+IHsKICAgICAgUyh0aGlzLCBRZSwgcHQpLmNhbGwodGhpcyksIGwodGhpcywgaiwgY3QoZSkpOwogICAgfTsKICAgIGwodGhpcywgaiwgY3QoZSkpOwogIH0KICBzdG9wKCkgewogICAgdCh0aGlzLCBqKSAhPT0gbnVsbCAmJiAoaXIodCh0aGlzLCBqKSksIGwodGhpcywgaiwgbnVsbCkpOwogIH0KICBnZXQgaXNSdW5uaW5nKCkgewogICAgcmV0dXJuIHQodGhpcywgaikgIT09IG51bGw7CiAgfQp9OwpjZSA9IG5ldyBXZWFrTWFwKCksIEcgPSBuZXcgV2Vha01hcCgpLCB6ZSA9IG5ldyBXZWFrTWFwKCksIGZlID0gbmV3IFdlYWtNYXAoKSwgVWUgPSBuZXcgV2Vha01hcCgpLCBCID0gbmV3IFdlYWtNYXAoKSwgUiA9IG5ldyBXZWFrTWFwKCksICQgPSBuZXcgV2Vha01hcCgpLCBxID0gbmV3IFdlYWtNYXAoKSwgSCA9IG5ldyBXZWFrTWFwKCksIEsgPSBuZXcgV2Vha01hcCgpLCBMID0gbmV3IFdlYWtNYXAoKSwgWSA9IG5ldyBXZWFrTWFwKCksIFYgPSBuZXcgV2Vha01hcCgpLCBEZSA9IG5ldyBXZWFrTWFwKCksIHZlID0gbmV3IFdlYWtNYXAoKSwgX2UgPSBuZXcgV2Vha01hcCgpLCBPID0gbmV3IFdlYWtNYXAoKSwgVCA9IG5ldyBXZWFrTWFwKCksIG9lID0gbmV3IFdlYWtNYXAoKSwgUSA9IG5ldyBXZWFrTWFwKCksIGFlID0gbmV3IFdlYWtNYXAoKSwgeiA9IG5ldyBXZWFrTWFwKCksIHhlID0gbmV3IFdlYWtNYXAoKSwgcGUgPSBuZXcgV2Vha01hcCgpLCBtZSA9IG5ldyBXZWFrTWFwKCksIGRlID0gbmV3IFdlYWtNYXAoKSwgaGUgPSBuZXcgV2Vha01hcCgpLCBKID0gbmV3IFdlYWtNYXAoKSwgWiA9IG5ldyBXZWFrTWFwKCksIGdlID0gbmV3IFdlYWtNYXAoKSwgYmUgPSBuZXcgV2Vha01hcCgpLCBUZSA9IG5ldyBXZWFrTWFwKCksIHcgPSBuZXcgV2Vha01hcCgpLCBVID0gbmV3IFdlYWtNYXAoKSwgTSA9IG5ldyBXZWFrTWFwKCksIEkgPSBuZXcgV2Vha01hcCgpLCBQID0gbmV3IFdlYWtNYXAoKSwgQ2UgPSBuZXcgV2Vha01hcCgpLCBlZSA9IG5ldyBXZWFrTWFwKCksIEEgPSBuZXcgV2Vha01hcCgpLCB1ZSA9IG5ldyBXZWFrTWFwKCksIHRlID0gbmV3IFdlYWtNYXAoKSwgaCA9IG5ldyBXZWFrTWFwKCksIEMgPSBuZXcgV2Vha01hcCgpLCBqID0gbmV3IFdlYWtNYXAoKSwgeWUgPSBuZXcgV2Vha01hcCgpLCBYZSA9IG5ldyBXZWFrTWFwKCksIFNlID0gbmV3IFdlYWtNYXAoKSwgWWUgPSBuZXcgV2Vha1NldCgpLCB4dCA9IGZ1bmN0aW9uKGUpIHsKICBjb25zdCB7IGRldmljZTogciwgZm9ybWF0OiBzIH0gPSBlOwogIGwodGhpcywgRGUsIEh0KHIsIHMsIHQodGhpcywgU2UpKSksIGwodGhpcywgdmUsICR0KHIpKSwgbCh0aGlzLCBfZSwgWXQocikpLCBsKHRoaXMsIHhlLCBXKHIsIDE2KSksIGwodGhpcywgcGUsIFcociwgMTYpKSwgbCh0aGlzLCBtZSwgVyhyLCAxNikpLCBsKHRoaXMsIGRlLCBXKHIsIDE2KSksIGwodGhpcywgaGUsIFcociwgMTYpKSwgbCh0aGlzLCBKLCBXKHIsIDQ4KSksIGwodGhpcywgWiwgVyhyLCA0OCkpLCBsKHRoaXMsIGdlLCBXKHIsIDE2KSksIGwodGhpcywgYmUsIFcociwgMTYpKSwgbCh0aGlzLCBUZSwgVyhyLCA2NCkpOwp9LCB3ZSA9IG5ldyBXZWFrU2V0KCksIFBlID0gZnVuY3Rpb24oKSB7CiAgY29uc3QgZSA9IHQodGhpcywgY2UpOwogICJjbGllbnRXaWR0aCIgaW4gZSAmJiBlLmNsaWVudFdpZHRoID4gMCA/IChsKHRoaXMsIFAsICh0eXBlb2Ygd2luZG93IDwgInUiICYmIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvIHx8IDEpICogdCh0aGlzLCBDZSkpLCBsKHRoaXMsIHcsIGUud2lkdGggPSBNYXRoLnJvdW5kKGUuY2xpZW50V2lkdGggKiB0KHRoaXMsIFApKSksIGwodGhpcywgVSwgZS5oZWlnaHQgPSBNYXRoLnJvdW5kKGUuY2xpZW50SGVpZ2h0ICogdCh0aGlzLCBQKSkpKSA6IChsKHRoaXMsIHcsIGUud2lkdGgpLCBsKHRoaXMsIFUsIGUuaGVpZ2h0KSksICEodCh0aGlzLCB3KSA9PT0gMCB8fCB0KHRoaXMsIFUpID09PSAwKSAmJiAobCh0aGlzLCBNLCBNYXRoLm1heCgxLCBNYXRoLnJvdW5kKHQodGhpcywgdykgKiB0KHRoaXMsIGVlKSkpKSwgbCh0aGlzLCBJLCBNYXRoLm1heCgxLCBNYXRoLnJvdW5kKHQodGhpcywgVSkgKiB0KHRoaXMsIGVlKSkpKSwgUyh0aGlzLCBHZSwgc3QpLmNhbGwodGhpcykpOwp9LCBHZSA9IG5ldyBXZWFrU2V0KCksIHN0ID0gZnVuY3Rpb24oKSB7CiAgaWYgKFModGhpcywgTWUsIG90KS5jYWxsKHRoaXMpLCB0KHRoaXMsIFYpKSB7CiAgICBjb25zdCB7IGRldmljZTogZSB9ID0gdCh0aGlzLCBWKSwgciA9ICJyZ2JhMTZmbG9hdCIsIHMgPSB0KHRoaXMsIE0pLCBvID0gdCh0aGlzLCBJKTsKICAgIGwodGhpcywgTywgcnQoZSwgciwgcywgbykpLCBsKHRoaXMsIFQsIHJ0KGUsIHIsIHMsIG8pKSwgbCh0aGlzLCBRLCBydChlLCByLCBzLCBvKSksIGwodGhpcywgb2UsIEhlKGUsIHIsIHMsIG8pKSwgbCh0aGlzLCBhZSwgSGUoZSwgciwgcywgbykpOwogIH0gZWxzZSB7CiAgICBjb25zdCBlID0gdCh0aGlzLCBHKSwgciA9IHQodGhpcywgemUpLCBzID0gdCh0aGlzLCBNKSwgbyA9IHQodGhpcywgSSk7CiAgICBsKHRoaXMsIEIsIHR0KGUsIHIsIHMsIG8pKSwgbCh0aGlzLCBSLCB0dChlLCByLCBzLCBvKSksIGwodGhpcywgcSwgdHQoZSwgciwgcywgbykpLCBsKHRoaXMsICQsIHFlKGUsIHIsIHMsIG8pKSwgbCh0aGlzLCBILCBxZShlLCByLCBzLCBvKSk7CiAgfQp9LCBuZSA9IG5ldyBXZWFrU2V0KCksIEVlID0gZnVuY3Rpb24oKSB7CiAgaWYgKCEoIXQodGhpcywgQykgfHwgdCh0aGlzLCB3KSA9PT0gMCB8fCB0KHRoaXMsIFUpID09PSAwKSkgewogICAgaWYgKFModGhpcywgSWUsIGF0KS5jYWxsKHRoaXMpLCB0KHRoaXMsIFYpKSB7CiAgICAgIGNvbnN0IHsgZGV2aWNlOiBlIH0gPSB0KHRoaXMsIFYpOwogICAgICB0KHRoaXMsIEMpLnR5cGUgPT09ICJ0ZXh0IiA/IGwodGhpcywgeiwgZXIoCiAgICAgICAgZSwKICAgICAgICB0KHRoaXMsIHcpLAogICAgICAgIHQodGhpcywgVSksCiAgICAgICAgdCh0aGlzLCBDKS5vcHRzLAogICAgICAgIHQodGhpcywgQSksCiAgICAgICAgdCh0aGlzLCB1ZSkKICAgICAgKSkgOiBsKHRoaXMsIHosIHRyKAogICAgICAgIGUsCiAgICAgICAgdCh0aGlzLCBDKS5iaXRtYXAsCiAgICAgICAgdCh0aGlzLCB3KSwKICAgICAgICB0KHRoaXMsIFUpLAogICAgICAgIHQodGhpcywgQykuZWZmZWN0LAogICAgICAgIHQodGhpcywgQykuc2l6ZSwKICAgICAgICB0KHRoaXMsIEEpLAogICAgICAgIHQodGhpcywgdWUpCiAgICAgICkpOwogICAgfSBlbHNlIHsKICAgICAgY29uc3QgZSA9IHQodGhpcywgRyk7CiAgICAgIGlmICh0KHRoaXMsIEMpLnR5cGUgPT09ICJ0ZXh0IikgewogICAgICAgIGNvbnN0IHsgYmFja2dyb3VuZFRleDogciwgb2JzdGFjbGVUZXg6IHMsIGNvdmVyYWdlVGV4OiBvIH0gPSBKdCgKICAgICAgICAgIGUsCiAgICAgICAgICB0KHRoaXMsIHcpLAogICAgICAgICAgdCh0aGlzLCBVKSwKICAgICAgICAgIHQodGhpcywgQykub3B0cywKICAgICAgICAgIHQodGhpcywgQSksCiAgICAgICAgICB0KHRoaXMsIHVlKQogICAgICAgICk7CiAgICAgICAgbCh0aGlzLCBLLCByKSwgbCh0aGlzLCBMLCBzKSwgbCh0aGlzLCBZLCBvKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb25zdCB7IGJhY2tncm91bmRUZXg6IHIsIG9ic3RhY2xlVGV4OiBzLCBjb3ZlcmFnZVRleDogbyB9ID0gWnQoCiAgICAgICAgICBlLAogICAgICAgICAgdCh0aGlzLCBDKS5iaXRtYXAsCiAgICAgICAgICB0KHRoaXMsIHcpLAogICAgICAgICAgdCh0aGlzLCBVKSwKICAgICAgICAgIHQodGhpcywgQykuZWZmZWN0LAogICAgICAgICAgdCh0aGlzLCBDKS5zaXplLAogICAgICAgICAgdCh0aGlzLCBBKSwKICAgICAgICAgIHQodGhpcywgdWUpCiAgICAgICAgKTsKICAgICAgICBsKHRoaXMsIEssIHIpLCBsKHRoaXMsIEwsIHMpLCBsKHRoaXMsIFksIG8pOwogICAgICB9CiAgICB9CiAgICBsKHRoaXMsIHllLCAhMCk7CiAgfQp9LCBSZSA9IG5ldyBXZWFrU2V0KCksIEZlID0gZnVuY3Rpb24oKSB7CiAgdCh0aGlzLCB5ZSkgJiYgIXRoaXMuaXNSdW5uaW5nICYmIHRoaXMuc3RhcnQoKTsKfSwgTWUgPSBuZXcgV2Vha1NldCgpLCBvdCA9IGZ1bmN0aW9uKCkgewogIHZhciBlLCByLCBzLCBvLCBhLCB1LCB2LCBtOwogIGlmICh0KHRoaXMsIFYpKQogICAgKGUgPSB0KHRoaXMsIE8pKSA9PSBudWxsIHx8IGUuZGlzcG9zZSgpLCAociA9IHQodGhpcywgVCkpID09IG51bGwgfHwgci5kaXNwb3NlKCksIChzID0gdCh0aGlzLCBRKSkgPT0gbnVsbCB8fCBzLmRpc3Bvc2UoKSwgKG8gPSB0KHRoaXMsIG9lKSkgPT0gbnVsbCB8fCBvLnRleC5kZXN0cm95KCksIChhID0gdCh0aGlzLCBhZSkpID09IG51bGwgfHwgYS50ZXguZGVzdHJveSgpLCBsKHRoaXMsIE8sIGwodGhpcywgVCwgbCh0aGlzLCBRLCBudWxsKSkpLCBsKHRoaXMsIG9lLCBsKHRoaXMsIGFlLCBudWxsKSk7CiAgZWxzZSB7CiAgICBjb25zdCBjID0gdCh0aGlzLCBHKTsKICAgICh1ID0gdCh0aGlzLCBCKSkgPT0gbnVsbCB8fCB1LmRpc3Bvc2UoKSwgKHYgPSB0KHRoaXMsIFIpKSA9PSBudWxsIHx8IHYuZGlzcG9zZSgpLCAobSA9IHQodGhpcywgcSkpID09IG51bGwgfHwgbS5kaXNwb3NlKCksIHQodGhpcywgJCkgJiYgKGMuZGVsZXRlVGV4dHVyZSh0KHRoaXMsICQpLnRleCksIGMuZGVsZXRlRnJhbWVidWZmZXIodCh0aGlzLCAkKS5mYm8pKSwgdCh0aGlzLCBIKSAmJiAoYy5kZWxldGVUZXh0dXJlKHQodGhpcywgSCkudGV4KSwgYy5kZWxldGVGcmFtZWJ1ZmZlcih0KHRoaXMsIEgpLmZibykpLCBsKHRoaXMsIEIsIGwodGhpcywgUiwgbCh0aGlzLCBxLCBsKHRoaXMsICQsIGwodGhpcywgSCwgbnVsbCkpKSkpOwogIH0KfSwgSWUgPSBuZXcgV2Vha1NldCgpLCBhdCA9IGZ1bmN0aW9uKCkgewogIGlmICh0KHRoaXMsIFYpKQogICAgdCh0aGlzLCB6KSAmJiAodCh0aGlzLCB6KS5iYWNrZ3JvdW5kVGV4LmRlc3Ryb3koKSwgdCh0aGlzLCB6KS5vYnN0YWNsZVRleC5kZXN0cm95KCksIHQodGhpcywgeikuc2hhcmVkQ292ZXJhZ2UgfHwgdCh0aGlzLCB6KS5jb3ZlcmFnZVRleC5kZXN0cm95KCksIGwodGhpcywgeiwgbnVsbCkpOwogIGVsc2UgewogICAgY29uc3QgZSA9IHQodGhpcywgRyk7CiAgICB0KHRoaXMsIEspICYmIGUuZGVsZXRlVGV4dHVyZSh0KHRoaXMsIEspKSwgdCh0aGlzLCBMKSAmJiBlLmRlbGV0ZVRleHR1cmUodCh0aGlzLCBMKSksIHQodGhpcywgWSkgJiYgdCh0aGlzLCBZKSAhPT0gdCh0aGlzLCBMKSAmJiBlLmRlbGV0ZVRleHR1cmUodCh0aGlzLCBZKSksIGwodGhpcywgSywgbCh0aGlzLCBMLCBsKHRoaXMsIFksIG51bGwpKSk7CiAgfQp9LCBRZSA9IG5ldyBXZWFrU2V0KCksIHB0ID0gZnVuY3Rpb24oKSB7CiAgIXQodGhpcywgeWUpIHx8IHQodGhpcywgdykgPT09IDAgfHwgKHQodGhpcywgVikgPyBTKHRoaXMsIGplLCBtdCkuY2FsbCh0aGlzKSA6IFModGhpcywgWmUsIGd0KS5jYWxsKHRoaXMpKTsKfSwgamUgPSBuZXcgV2Vha1NldCgpLCBtdCA9IGZ1bmN0aW9uKCkgewogIGNvbnN0IGUgPSB0KHRoaXMsIFYpLCByID0gZS5kZXZpY2UsIHMgPSB0KHRoaXMsIERlKSwgbyA9IHQodGhpcywgdmUpLCBhID0gdCh0aGlzLCBfZSksIHUgPSB0KHRoaXMsIHRlKSwgdiA9IHQodGhpcywgeik7CiAgaWYgKCF0KHRoaXMsIE8pIHx8ICF0KHRoaXMsIFQpKQogICAgcmV0dXJuOwogIHQodGhpcywgaCkueCArPSAodCh0aGlzLCBoKS50YXJnZXRYIC0gdCh0aGlzLCBoKS54KSAqIDAuMTUsIHQodGhpcywgaCkueSArPSAodCh0aGlzLCBoKS50YXJnZXRZIC0gdCh0aGlzLCBoKS55KSAqIDAuMTU7CiAgY29uc3QgbSA9IHQodGhpcywgTSksIGMgPSB0KHRoaXMsIEkpLCBwID0gdCh0aGlzLCB3KSwgeCA9IHQodGhpcywgVSksIG4gPSAxIC8gbSwgZCA9IDEgLyBjOwogIGx0KHIsIHQodGhpcywgeGUpLCBuLCBkLCBWZSwgdS52ZWxvY2l0eURpc3NpcGF0aW9uKSwgTmUociwgdCh0aGlzLCBtZSksIG4sIGQpLCBOZShyLCB0KHRoaXMsIGRlKSwgbiwgZCksIE5lKHIsIHQodGhpcywgaGUpLCBuLCBkKSwgTmUociwgdCh0aGlzLCBnZSksIG4sIGQpLCBRdChyLCB0KHRoaXMsIGJlKSwgbiwgZCwgdS5jdXJsLCBWZSksIGp0KAogICAgciwKICAgIHQodGhpcywgVGUpLAogICAgMSAvIHAsCiAgICAxIC8geCwKICAgIHUucmVmcmFjdGlvbiwKICAgIHUuc3BlY3VsYXJFeHAsCiAgICBXZSh1LndhdGVyQ29sb3IpLAogICAgV2UodS5nbG93Q29sb3IpLAogICAgdS5zaGluZSwKICAgIHUud2FycFN0cmVuZ3RoID8/IDAuMDE1LAogICAgZnRbdS5hbGdvcml0aG1dID8/IDAsCiAgICB0KHRoaXMsIFNlKQogICk7CiAgY29uc3QgYiA9IHIuY3JlYXRlQ29tbWFuZEVuY29kZXIoKSwgeSA9IChnLCBfKSA9PiByLmNyZWF0ZUJpbmRHcm91cCh7IGxheW91dDogZy5nZXRCaW5kR3JvdXBMYXlvdXQoMCksIGVudHJpZXM6IF8gfSksIEQgPSB7IGJpbmRpbmc6IDEsIHJlc291cmNlOiBhIH07CiAgewogICAgY29uc3QgZyA9IHkocy5hZHZlY3Rpb24sIFsKICAgICAgeyBiaW5kaW5nOiAwLCByZXNvdXJjZTogeyBidWZmZXI6IHQodGhpcywgeGUpIH0gfSwKICAgICAgRCwKICAgICAgeyBiaW5kaW5nOiAyLCByZXNvdXJjZTogdCh0aGlzLCBUKS5yZWFkLnZpZXcgfSwKICAgICAgeyBiaW5kaW5nOiAzLCByZXNvdXJjZTogdCh0aGlzLCBUKS5yZWFkLnZpZXcgfSwKICAgICAgeyBiaW5kaW5nOiA0LCByZXNvdXJjZTogdi5vYnN0YWNsZVZpZXcgfQogICAgXSk7CiAgICBYKGIsIHMuYWR2ZWN0aW9uLCBnLCBvLCB0KHRoaXMsIFQpLndyaXRlLnZpZXcpOwogIH0KICB0KHRoaXMsIFQpLnN3YXAoKTsKICB7CiAgICBsdChyLCB0KHRoaXMsIHBlKSwgbiwgZCwgVmUsIHUuZGVuc2l0eURpc3NpcGF0aW9uKTsKICAgIGNvbnN0IGcgPSB5KHMuYWR2ZWN0aW9uLCBbCiAgICAgIHsgYmluZGluZzogMCwgcmVzb3VyY2U6IHsgYnVmZmVyOiB0KHRoaXMsIHBlKSB9IH0sCiAgICAgIEQsCiAgICAgIHsgYmluZGluZzogMiwgcmVzb3VyY2U6IHQodGhpcywgVCkucmVhZC52aWV3IH0sCiAgICAgIHsgYmluZGluZzogMywgcmVzb3VyY2U6IHQodGhpcywgTykucmVhZC52aWV3IH0sCiAgICAgIHsgYmluZGluZzogNCwgcmVzb3VyY2U6IHYub2JzdGFjbGVWaWV3IH0KICAgIF0pOwogICAgWChiLCBzLmFkdmVjdGlvbiwgZywgbywgdCh0aGlzLCBPKS53cml0ZS52aWV3KTsKICB9CiAgdCh0aGlzLCBPKS5zd2FwKCk7CiAgewogICAgY29uc3QgZyA9IHkocy5jdXJsLCBbCiAgICAgIHsgYmluZGluZzogMCwgcmVzb3VyY2U6IHsgYnVmZmVyOiB0KHRoaXMsIGdlKSB9IH0sCiAgICAgIEQsCiAgICAgIHsgYmluZGluZzogMiwgcmVzb3VyY2U6IHQodGhpcywgVCkucmVhZC52aWV3IH0KICAgIF0pOwogICAgWChiLCBzLmN1cmwsIGcsIG8sIHQodGhpcywgYWUpLnZpZXcpOwogIH0KICB7CiAgICBjb25zdCBnID0geShzLnZvcnRpY2l0eSwgWwogICAgICB7IGJpbmRpbmc6IDAsIHJlc291cmNlOiB7IGJ1ZmZlcjogdCh0aGlzLCBiZSkgfSB9LAogICAgICBELAogICAgICB7IGJpbmRpbmc6IDIsIHJlc291cmNlOiB0KHRoaXMsIFQpLnJlYWQudmlldyB9LAogICAgICB7IGJpbmRpbmc6IDMsIHJlc291cmNlOiB0KHRoaXMsIGFlKS52aWV3IH0KICAgIF0pOwogICAgWChiLCBzLnZvcnRpY2l0eSwgZywgbywgdCh0aGlzLCBUKS53cml0ZS52aWV3KTsKICB9CiAgaWYgKHQodGhpcywgVCkuc3dhcCgpLCB0KHRoaXMsIGgpLm1vdmVkKSB7CiAgICBjb25zdCBnID0gdCh0aGlzLCBoKS54ICogdCh0aGlzLCBQKSAvIHAsIF8gPSB0KHRoaXMsIGgpLnkgKiB0KHRoaXMsIFApIC8geDsKICAgICRlKAogICAgICByLAogICAgICB0KHRoaXMsIEopLAogICAgICBuLAogICAgICBkLAogICAgICBwIC8geCwKICAgICAgdS5zcGxhdFJhZGl1cywKICAgICAgdCh0aGlzLCBoKS5keCAqIHUuc3BsYXRGb3JjZSwKICAgICAgdCh0aGlzLCBoKS5keSAqIHUuc3BsYXRGb3JjZSwKICAgICAgMCwKICAgICAgZywKICAgICAgXwogICAgKTsKICAgIHsKICAgICAgY29uc3QgRiA9IHkocy5zcGxhdCwgWwogICAgICAgIHsgYmluZGluZzogMCwgcmVzb3VyY2U6IHsgYnVmZmVyOiB0KHRoaXMsIEopIH0gfSwKICAgICAgICBELAogICAgICAgIHsgYmluZGluZzogMiwgcmVzb3VyY2U6IHQodGhpcywgVCkucmVhZC52aWV3IH0KICAgICAgXSk7CiAgICAgIFgoYiwgcy5zcGxhdCwgRiwgbywgdCh0aGlzLCBUKS53cml0ZS52aWV3KTsKICAgIH0KICAgIHQodGhpcywgVCkuc3dhcCgpLCAkZSgKICAgICAgciwKICAgICAgdCh0aGlzLCBaKSwKICAgICAgbiwKICAgICAgZCwKICAgICAgcCAvIHgsCiAgICAgIHUuc3BsYXRSYWRpdXMsCiAgICAgIDEsCiAgICAgIDEsCiAgICAgIDEsCiAgICAgIGcsCiAgICAgIF8KICAgICk7CiAgICB7CiAgICAgIGNvbnN0IEYgPSB5KHMuc3BsYXQsIFsKICAgICAgICB7IGJpbmRpbmc6IDAsIHJlc291cmNlOiB7IGJ1ZmZlcjogdCh0aGlzLCBaKSB9IH0sCiAgICAgICAgRCwKICAgICAgICB7IGJpbmRpbmc6IDIsIHJlc291cmNlOiB0KHRoaXMsIE8pLnJlYWQudmlldyB9CiAgICAgIF0pOwogICAgICBYKGIsIHMuc3BsYXQsIEYsIG8sIHQodGhpcywgTykud3JpdGUudmlldyk7CiAgICB9CiAgICB0KHRoaXMsIE8pLnN3YXAoKSwgdCh0aGlzLCBoKS5tb3ZlZCA9ICExOwogIH0KICB7CiAgICBjb25zdCBnID0geShzLmRpdmVyZ2VuY2UsIFsKICAgICAgeyBiaW5kaW5nOiAwLCByZXNvdXJjZTogeyBidWZmZXI6IHQodGhpcywgbWUpIH0gfSwKICAgICAgRCwKICAgICAgeyBiaW5kaW5nOiAyLCByZXNvdXJjZTogdCh0aGlzLCBUKS5yZWFkLnZpZXcgfSwKICAgICAgeyBiaW5kaW5nOiAzLCByZXNvdXJjZTogdi5vYnN0YWNsZVZpZXcgfQogICAgXSk7CiAgICBYKGIsIHMuZGl2ZXJnZW5jZSwgZywgbywgdCh0aGlzLCBvZSkudmlldyk7CiAgfQogIGZvciAobGV0IGcgPSAwOyBnIDwgdS5wcmVzc3VyZUl0ZXJhdGlvbnM7IGcrKykgewogICAgY29uc3QgXyA9IHkocy5wcmVzc3VyZSwgWwogICAgICB7IGJpbmRpbmc6IDAsIHJlc291cmNlOiB7IGJ1ZmZlcjogdCh0aGlzLCBkZSkgfSB9LAogICAgICBELAogICAgICB7IGJpbmRpbmc6IDIsIHJlc291cmNlOiB0KHRoaXMsIFEpLnJlYWQudmlldyB9LAogICAgICB7IGJpbmRpbmc6IDMsIHJlc291cmNlOiB0KHRoaXMsIG9lKS52aWV3IH0sCiAgICAgIHsgYmluZGluZzogNCwgcmVzb3VyY2U6IHYub2JzdGFjbGVWaWV3IH0KICAgIF0pOwogICAgWChiLCBzLnByZXNzdXJlLCBfLCBvLCB0KHRoaXMsIFEpLndyaXRlLnZpZXcpLCB0KHRoaXMsIFEpLnN3YXAoKTsKICB9CiAgewogICAgY29uc3QgZyA9IHkocy5ncmFkaWVudFN1YnRyYWN0LCBbCiAgICAgIHsgYmluZGluZzogMCwgcmVzb3VyY2U6IHsgYnVmZmVyOiB0KHRoaXMsIGhlKSB9IH0sCiAgICAgIEQsCiAgICAgIHsgYmluZGluZzogMiwgcmVzb3VyY2U6IHQodGhpcywgUSkucmVhZC52aWV3IH0sCiAgICAgIHsgYmluZGluZzogMywgcmVzb3VyY2U6IHQodGhpcywgVCkucmVhZC52aWV3IH0sCiAgICAgIHsgYmluZGluZzogNCwgcmVzb3VyY2U6IHYub2JzdGFjbGVWaWV3IH0KICAgIF0pOwogICAgWChiLCBzLmdyYWRpZW50U3VidHJhY3QsIGcsIG8sIHQodGhpcywgVCkud3JpdGUudmlldyk7CiAgfQogIHQodGhpcywgVCkuc3dhcCgpOwogIHsKICAgIGNvbnN0IGcgPSBlLmNvbnRleHQuZ2V0Q3VycmVudFRleHR1cmUoKS5jcmVhdGVWaWV3KCksIF8gPSB5KHMuZGlzcGxheSwgWwogICAgICB7IGJpbmRpbmc6IDAsIHJlc291cmNlOiB7IGJ1ZmZlcjogdCh0aGlzLCBUZSkgfSB9LAogICAgICBELAogICAgICB7IGJpbmRpbmc6IDIsIHJlc291cmNlOiB0KHRoaXMsIE8pLnJlYWQudmlldyB9LAogICAgICB7IGJpbmRpbmc6IDMsIHJlc291cmNlOiB2Lm9ic3RhY2xlVmlldyB9LAogICAgICB7IGJpbmRpbmc6IDQsIHJlc291cmNlOiB2LmJhY2tncm91bmRWaWV3IH0sCiAgICAgIHsgYmluZGluZzogNSwgcmVzb3VyY2U6IHYuY292ZXJhZ2VWaWV3IH0sCiAgICAgIHsgYmluZGluZzogNiwgcmVzb3VyY2U6IHQodGhpcywgVCkucmVhZC52aWV3IH0KICAgIF0pOwogICAgS3QoYiwgcy5kaXNwbGF5LCBfLCBvLCBnKTsKICB9CiAgci5xdWV1ZS5zdWJtaXQoW2IuZmluaXNoKCldKTsKfSwgS2UgPSBuZXcgV2Vha1NldCgpLCBkdCA9IGZ1bmN0aW9uKGUsIHIsIHMsIG8sIGEpIHsKICBjb25zdCB2ID0gdCh0aGlzLCBWKS5kZXZpY2UsIG0gPSB0KHRoaXMsIERlKS5zcGxhdCwgYyA9IHQodGhpcywgdmUpLCBwID0gdCh0aGlzLCBfZSksIHggPSB0KHRoaXMsIHRlKSwgbiA9IHQodGhpcywgTSksIGQgPSB0KHRoaXMsIEkpLCBiID0gMSAvIG4sIHkgPSAxIC8gZCwgRCA9IHYuY3JlYXRlQ29tbWFuZEVuY29kZXIoKSwgZyA9IHsgYmluZGluZzogMSwgcmVzb3VyY2U6IHAgfSwgXyA9IChPZSkgPT4gdi5jcmVhdGVCaW5kR3JvdXAoeyBsYXlvdXQ6IG0uZ2V0QmluZEdyb3VwTGF5b3V0KDApLCBlbnRyaWVzOiBPZSB9KSwgRiA9IGUgKiB0KHRoaXMsIFApIC8gdCh0aGlzLCB3KSwgayA9IHIgKiB0KHRoaXMsIFApIC8gdCh0aGlzLCBVKTsKICAkZSgKICAgIHYsCiAgICB0KHRoaXMsIEopLAogICAgYiwKICAgIHksCiAgICB0KHRoaXMsIHcpIC8gdCh0aGlzLCBVKSwKICAgIHguc3BsYXRSYWRpdXMsCiAgICBzICogeC5zcGxhdEZvcmNlICogYSwKICAgIG8gKiB4LnNwbGF0Rm9yY2UgKiBhLAogICAgMCwKICAgIEYsCiAgICBrCiAgKTsKICB7CiAgICBjb25zdCBPZSA9IF8oWwogICAgICB7IGJpbmRpbmc6IDAsIHJlc291cmNlOiB7IGJ1ZmZlcjogdCh0aGlzLCBKKSB9IH0sCiAgICAgIGcsCiAgICAgIHsgYmluZGluZzogMiwgcmVzb3VyY2U6IHQodGhpcywgVCkucmVhZC52aWV3IH0KICAgIF0pOwogICAgWChELCBtLCBPZSwgYywgdCh0aGlzLCBUKS53cml0ZS52aWV3KTsKICB9CiAgdCh0aGlzLCBUKS5zd2FwKCksICRlKAogICAgdiwKICAgIHQodGhpcywgWiksCiAgICBiLAogICAgeSwKICAgIHQodGhpcywgdykgLyB0KHRoaXMsIFUpLAogICAgeC5zcGxhdFJhZGl1cywKICAgIGEsCiAgICBhLAogICAgYSwKICAgIEYsCiAgICBrCiAgKTsKICB7CiAgICBjb25zdCBPZSA9IF8oWwogICAgICB7IGJpbmRpbmc6IDAsIHJlc291cmNlOiB7IGJ1ZmZlcjogdCh0aGlzLCBaKSB9IH0sCiAgICAgIGcsCiAgICAgIHsgYmluZGluZzogMiwgcmVzb3VyY2U6IHQodGhpcywgTykucmVhZC52aWV3IH0KICAgIF0pOwogICAgWChELCBtLCBPZSwgYywgdCh0aGlzLCBPKS53cml0ZS52aWV3KTsKICB9CiAgdCh0aGlzLCBPKS5zd2FwKCksIHYucXVldWUuc3VibWl0KFtELmZpbmlzaCgpXSk7Cn0sIEplID0gbmV3IFdlYWtTZXQoKSwgaHQgPSBmdW5jdGlvbihlLCByLCBzLCBvLCBhKSB7CiAgY29uc3QgdSA9IHQodGhpcywgRyksIHYgPSB0KHRoaXMsIHRlKSwgbSA9IHQodGhpcywgZmUpLnNwbGF0LCBjID0gdCh0aGlzLCBVZSk7CiAgdS52aWV3cG9ydCgwLCAwLCB0KHRoaXMsIE0pLCB0KHRoaXMsIEkpKSwgbS5iaW5kKCksIHUudW5pZm9ybTFmKG0udW5pZm9ybXMuYXNwZWN0UmF0aW8sIHQodGhpcywgdykgLyB0KHRoaXMsIFUpKSwgdS51bmlmb3JtMmYobS51bmlmb3Jtcy5wb2ludCwgZSAqIHQodGhpcywgUCkgLyB0KHRoaXMsIHcpLCAxIC0gciAqIHQodGhpcywgUCkgLyB0KHRoaXMsIFUpKSwgdS51bmlmb3JtMWYobS51bmlmb3Jtcy5yYWRpdXMsIHYuc3BsYXRSYWRpdXMpLCB1LnVuaWZvcm0xaShtLnVuaWZvcm1zLnVUYXJnZXQsIDApLCB1LmFjdGl2ZVRleHR1cmUodS5URVhUVVJFMCksIHUuYmluZFRleHR1cmUodS5URVhUVVJFXzJELCB0KHRoaXMsIFIpLnJlYWQudGV4KSwgdS51bmlmb3JtM2YobS51bmlmb3Jtcy5jb2xvciwgcyAqIHYuc3BsYXRGb3JjZSAqIGEsIC1vICogdi5zcGxhdEZvcmNlICogYSwgMCksIGModCh0aGlzLCBSKS53cml0ZS5mYm8pLCB0KHRoaXMsIFIpLnN3YXAoKSwgdS5hY3RpdmVUZXh0dXJlKHUuVEVYVFVSRTApLCB1LmJpbmRUZXh0dXJlKHUuVEVYVFVSRV8yRCwgdCh0aGlzLCBCKS5yZWFkLnRleCksIHUudW5pZm9ybTNmKG0udW5pZm9ybXMuY29sb3IsIGEsIGEsIGEpLCBjKHQodGhpcywgQikud3JpdGUuZmJvKSwgdCh0aGlzLCBCKS5zd2FwKCk7Cn0sIFplID0gbmV3IFdlYWtTZXQoKSwgZ3QgPSBmdW5jdGlvbigpIHsKICBpZiAoIXQodGhpcywgQikgfHwgIXQodGhpcywgUikpCiAgICByZXR1cm47CiAgY29uc3QgZSA9IHQodGhpcywgRyksIHIgPSB0KHRoaXMsIHRlKSwgeyBhZHZlY3Rpb246IHMsIGRpdmVyZ2VuY2U6IG8sIHByZXNzdXJlOiBhLCBncmFkaWVudFN1YnRyYWN0OiB1LCBzcGxhdDogdiwgY3VybDogbSwgdm9ydGljaXR5OiBjLCBkaXNwbGF5OiBwIH0gPSB0KHRoaXMsIGZlKTsKICB0KHRoaXMsIGgpLnggKz0gKHQodGhpcywgaCkudGFyZ2V0WCAtIHQodGhpcywgaCkueCkgKiAwLjE1LCB0KHRoaXMsIGgpLnkgKz0gKHQodGhpcywgaCkudGFyZ2V0WSAtIHQodGhpcywgaCkueSkgKiAwLjE1OwogIGNvbnN0IHggPSB0KHRoaXMsIE0pLCBuID0gdCh0aGlzLCBJKSwgZCA9IHQodGhpcywgVWUpOwogIGUudmlld3BvcnQoMCwgMCwgeCwgbiksIHMuYmluZCgpLCBlLnVuaWZvcm0yZihzLnVuaWZvcm1zLnRleGVsU2l6ZSwgMSAvIHgsIDEgLyBuKSwgZS51bmlmb3JtMWYocy51bmlmb3Jtcy5kdCwgVmUpLCBlLnVuaWZvcm0xaShzLnVuaWZvcm1zLnVPYnN0YWNsZSwgMCksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUwKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgTCkpLCBlLnVuaWZvcm0xZihzLnVuaWZvcm1zLmRpc3NpcGF0aW9uLCByLnZlbG9jaXR5RGlzc2lwYXRpb24pLCBlLnVuaWZvcm0xaShzLnVuaWZvcm1zLnVWZWxvY2l0eSwgMSksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUxKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgUikucmVhZC50ZXgpLCBlLnVuaWZvcm0xaShzLnVuaWZvcm1zLnVTb3VyY2UsIDEpLCBkKHQodGhpcywgUikud3JpdGUuZmJvKSwgdCh0aGlzLCBSKS5zd2FwKCksIGUudW5pZm9ybTFmKHMudW5pZm9ybXMuZGlzc2lwYXRpb24sIHIuZGVuc2l0eURpc3NpcGF0aW9uKSwgZS51bmlmb3JtMWkocy51bmlmb3Jtcy51U291cmNlLCAyKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTIpLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBCKS5yZWFkLnRleCksIGQodCh0aGlzLCBCKS53cml0ZS5mYm8pLCB0KHRoaXMsIEIpLnN3YXAoKSwgbS5iaW5kKCksIGUudW5pZm9ybTJmKG0udW5pZm9ybXMudGV4ZWxTaXplLCAxIC8geCwgMSAvIG4pLCBlLnVuaWZvcm0xaShtLnVuaWZvcm1zLnVWZWxvY2l0eSwgMCksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUwKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgUikucmVhZC50ZXgpLCBkKHQodGhpcywgSCkuZmJvKSwgYy5iaW5kKCksIGUudW5pZm9ybTJmKGMudW5pZm9ybXMudGV4ZWxTaXplLCAxIC8geCwgMSAvIG4pLCBlLnVuaWZvcm0xZihjLnVuaWZvcm1zLmN1cmwsIHIuY3VybCksIGUudW5pZm9ybTFmKGMudW5pZm9ybXMuZHQsIFZlKSwgZS51bmlmb3JtMWkoYy51bmlmb3Jtcy51VmVsb2NpdHksIDApLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMCksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIFIpLnJlYWQudGV4KSwgZS51bmlmb3JtMWkoYy51bmlmb3Jtcy51Q3VybCwgMSksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUxKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgSCkudGV4KSwgZCh0KHRoaXMsIFIpLndyaXRlLmZibyksIHQodGhpcywgUikuc3dhcCgpLCB0KHRoaXMsIGgpLm1vdmVkICYmICh2LmJpbmQoKSwgZS51bmlmb3JtMWYodi51bmlmb3Jtcy5hc3BlY3RSYXRpbywgdCh0aGlzLCB3KSAvIHQodGhpcywgVSkpLCBlLnVuaWZvcm0yZih2LnVuaWZvcm1zLnBvaW50LCB0KHRoaXMsIGgpLnggKiB0KHRoaXMsIFApIC8gdCh0aGlzLCB3KSwgMSAtIHQodGhpcywgaCkueSAqIHQodGhpcywgUCkgLyB0KHRoaXMsIFUpKSwgZS51bmlmb3JtMWYodi51bmlmb3Jtcy5yYWRpdXMsIHIuc3BsYXRSYWRpdXMpLCBlLnVuaWZvcm0xaSh2LnVuaWZvcm1zLnVUYXJnZXQsIDApLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMCksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIFIpLnJlYWQudGV4KSwgZS51bmlmb3JtM2Yodi51bmlmb3Jtcy5jb2xvciwgdCh0aGlzLCBoKS5keCAqIHIuc3BsYXRGb3JjZSwgLXQodGhpcywgaCkuZHkgKiByLnNwbGF0Rm9yY2UsIDApLCBkKHQodGhpcywgUikud3JpdGUuZmJvKSwgdCh0aGlzLCBSKS5zd2FwKCksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUwKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgQikucmVhZC50ZXgpLCBlLnVuaWZvcm0zZih2LnVuaWZvcm1zLmNvbG9yLCAxLCAxLCAxKSwgZCh0KHRoaXMsIEIpLndyaXRlLmZibyksIHQodGhpcywgQikuc3dhcCgpLCB0KHRoaXMsIGgpLm1vdmVkID0gITEpLCBvLmJpbmQoKSwgZS51bmlmb3JtMmYoby51bmlmb3Jtcy50ZXhlbFNpemUsIDEgLyB4LCAxIC8gbiksIGUudW5pZm9ybTFpKG8udW5pZm9ybXMudVZlbG9jaXR5LCAwKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTApLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBSKS5yZWFkLnRleCksIGUudW5pZm9ybTFpKG8udW5pZm9ybXMudU9ic3RhY2xlLCAxKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTEpLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBMKSksIGQodCh0aGlzLCAkKS5mYm8pLCBhLmJpbmQoKSwgZS51bmlmb3JtMmYoYS51bmlmb3Jtcy50ZXhlbFNpemUsIDEgLyB4LCAxIC8gbiksIGUudW5pZm9ybTFpKGEudW5pZm9ybXMudURpdmVyZ2VuY2UsIDApLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMCksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsICQpLnRleCksIGUudW5pZm9ybTFpKGEudW5pZm9ybXMudU9ic3RhY2xlLCAxKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTEpLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBMKSk7CiAgZm9yIChsZXQgYiA9IDA7IGIgPCByLnByZXNzdXJlSXRlcmF0aW9uczsgYisrKQogICAgZS51bmlmb3JtMWkoYS51bmlmb3Jtcy51UHJlc3N1cmUsIDIpLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMiksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIHEpLnJlYWQudGV4KSwgZCh0KHRoaXMsIHEpLndyaXRlLmZibyksIHQodGhpcywgcSkuc3dhcCgpOwogIHUuYmluZCgpLCBlLnVuaWZvcm0yZih1LnVuaWZvcm1zLnRleGVsU2l6ZSwgMSAvIHgsIDEgLyBuKSwgZS51bmlmb3JtMWkodS51bmlmb3Jtcy51UHJlc3N1cmUsIDApLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMCksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIHEpLnJlYWQudGV4KSwgZS51bmlmb3JtMWkodS51bmlmb3Jtcy51VmVsb2NpdHksIDEpLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMSksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIFIpLnJlYWQudGV4KSwgZS51bmlmb3JtMWkodS51bmlmb3Jtcy51T2JzdGFjbGUsIDIpLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMiksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIEwpKSwgZCh0KHRoaXMsIFIpLndyaXRlLmZibyksIHQodGhpcywgUikuc3dhcCgpLCBlLnZpZXdwb3J0KDAsIDAsIHQodGhpcywgdyksIHQodGhpcywgVSkpLCBlLmJpbmRGcmFtZWJ1ZmZlcihlLkZSQU1FQlVGRkVSLCBudWxsKSwgZS5jbGVhcihlLkNPTE9SX0JVRkZFUl9CSVQpLCBwLmJpbmQoKSwgZS51bmlmb3JtMmYocC51bmlmb3Jtcy50ZXhlbFNpemUsIDEgLyB0KHRoaXMsIHcpLCAxIC8gdCh0aGlzLCBVKSksIGUudW5pZm9ybTNmdihwLnVuaWZvcm1zLnVXYXRlckNvbG9yLCBXZShyLndhdGVyQ29sb3IpKSwgZS51bmlmb3JtM2Z2KHAudW5pZm9ybXMudUdsb3dDb2xvciwgV2Uoci5nbG93Q29sb3IpKSwgZS51bmlmb3JtMWYocC51bmlmb3Jtcy51UmVmcmFjdGlvbiwgci5yZWZyYWN0aW9uKSwgZS51bmlmb3JtMWYocC51bmlmb3Jtcy51U3BlY3VsYXJFeHAsIHIuc3BlY3VsYXJFeHApLCBlLnVuaWZvcm0xZihwLnVuaWZvcm1zLnVTaGluZSwgci5zaGluZSksIGUudW5pZm9ybTFmKHAudW5pZm9ybXMudVdhcnBTdHJlbmd0aCwgci53YXJwU3RyZW5ndGggPz8gMC4wMTUpLCBlLnVuaWZvcm0xaShwLnVuaWZvcm1zLnVBbGdvcml0aG0sIGZ0W3IuYWxnb3JpdGhtXSA/PyAwKSwgZS51bmlmb3JtMWkocC51bmlmb3Jtcy51RW5hYmxlQWxwaGEsIHQodGhpcywgU2UpID8gMSA6IDApLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMCksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIEIpLnJlYWQudGV4KSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTEpLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBMKSksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUyKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgSykpLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMyksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIFkpKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTQpLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBSKS5yZWFkLnRleCksIGUudW5pZm9ybTFpKHAudW5pZm9ybXMudVRleHR1cmUsIDApLCBlLnVuaWZvcm0xaShwLnVuaWZvcm1zLnVPYnN0YWNsZSwgMSksIGUudW5pZm9ybTFpKHAudW5pZm9ybXMudUJhY2tncm91bmQsIDIpLCBlLnVuaWZvcm0xaShwLnVuaWZvcm1zLnVDb3ZlcmFnZSwgMyksIGUudW5pZm9ybTFpKHAudW5pZm9ybXMudVZlbG9jaXR5LCA0KSwgZChudWxsKTsKfTsKbGV0IGl0ID0gdXQsIEUgPSBudWxsLCBidDsKY29uc3QgTiA9IG5ldyBQcm9taXNlKChpKSA9PiB7CiAgYnQgPSBpOwp9KTsKc2VsZi5vbm1lc3NhZ2UgPSBhc3luYyAoaSkgPT4gewogIGNvbnN0IHsgdHlwZTogZSwgLi4uciB9ID0gaS5kYXRhOwogIHRyeSB7CiAgICBzd2l0Y2ggKGUpIHsKICAgICAgY2FzZSAiaW5pdCI6IHsKICAgICAgICBjb25zdCB7IGNhbnZhczogcywgd2lkdGg6IG8sIGhlaWdodDogYSwgY29uZmlnOiB1LCBkcHI6IHYsIHF1YWxpdHk6IG0sIHVzZVdlYkdQVTogYywgZW5hYmxlQWxwaGE6IHAgfSA9IHI7CiAgICAgICAgcy53aWR0aCA9IG8sIHMuaGVpZ2h0ID0gYSwgRSA9IGF3YWl0IGl0LmNyZWF0ZShzLCB1LCBtID8/IHt9LCBjID8/ICEwLCBwID8/ICEwKSwgRS5yZXNpemUobywgYSwgdiB8fCAxKSwgYnQoKSwgc2VsZi5wb3N0TWVzc2FnZSh7IHR5cGU6ICJyZWFkeSIgfSk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY2FzZSAic2V0VGV4dFNvdXJjZSI6IHsKICAgICAgICBpZiAoYXdhaXQgTiwgIUUpCiAgICAgICAgICByZXR1cm47CiAgICAgICAgRS5zZXRUZXh0U291cmNlKHIub3B0cyk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY2FzZSAic2V0SW1hZ2VTb3VyY2UiOiB7CiAgICAgICAgaWYgKGF3YWl0IE4sICFFKQogICAgICAgICAgcmV0dXJuOwogICAgICAgIGF3YWl0IEUuc2V0SW1hZ2VTb3VyY2UoCiAgICAgICAgICByLnNyYywKICAgICAgICAgIHIuZWZmZWN0LAogICAgICAgICAgci5zaXplCiAgICAgICAgKTsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBjYXNlICJzZXRJbWFnZUJpdG1hcCI6IHsKICAgICAgICBpZiAoYXdhaXQgTiwgIUUpCiAgICAgICAgICByZXR1cm47CiAgICAgICAgRS5zZXRJbWFnZUJpdG1hcCgKICAgICAgICAgIHIuYml0bWFwLAogICAgICAgICAgci5lZmZlY3QsCiAgICAgICAgICByLnNpemUKICAgICAgICApOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGNhc2UgInNldEJhY2tncm91bmQiOiB7CiAgICAgICAgaWYgKGF3YWl0IE4sICFFKQogICAgICAgICAgcmV0dXJuOwogICAgICAgIEUuc2V0QmFja2dyb3VuZChyLmJpdG1hcCwgci5zaXplKTsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBjYXNlICJzcGxhdCI6IHsKICAgICAgICBpZiAoYXdhaXQgTiwgIUUpCiAgICAgICAgICByZXR1cm47CiAgICAgICAgRS5zcGxhdCgKICAgICAgICAgIHIueCwKICAgICAgICAgIHIueSwKICAgICAgICAgIHIudngsCiAgICAgICAgICByLnZ5LAogICAgICAgICAgci5zdHJlbmd0aCA/PyAxCiAgICAgICAgKTsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBjYXNlICJtb3ZlIjogewogICAgICAgIGlmIChhd2FpdCBOLCAhRSkKICAgICAgICAgIHJldHVybjsKICAgICAgICBFLmhhbmRsZU1vdmUoci54LCByLnksIHIuc3RyZW5ndGggPz8gMSk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY2FzZSAicmVzaXplIjogewogICAgICAgIGlmIChhd2FpdCBOLCAhRSkKICAgICAgICAgIHJldHVybjsKICAgICAgICBFLnJlc2l6ZShyLndpZHRoLCByLmhlaWdodCwgci5kcHIpOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGNhc2UgInVwZGF0ZVF1YWxpdHkiOiB7CiAgICAgICAgaWYgKGF3YWl0IE4sICFFKQogICAgICAgICAgcmV0dXJuOwogICAgICAgIEUudXBkYXRlUXVhbGl0eShyLnF1YWxpdHkpOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGNhc2UgInVwZGF0ZUNvbmZpZyI6IHsKICAgICAgICBpZiAoYXdhaXQgTiwgIUUpCiAgICAgICAgICByZXR1cm47CiAgICAgICAgRS51cGRhdGVDb25maWcoci5jb25maWcpOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGNhc2UgImRlc3Ryb3kiOiB7CiAgICAgICAgYXdhaXQgTiwgRSA9PSBudWxsIHx8IEUuZGVzdHJveSgpLCBFID0gbnVsbDsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBkZWZhdWx0OgogICAgICAgIGNvbnNvbGUud2FybigiW2ZsdWlkaXR5LWpzIHdvcmtlcl0gVW5rbm93biBtZXNzYWdlIHR5cGU6IiwgZSk7CiAgICB9CiAgfSBjYXRjaCAocykgewogICAgc2VsZi5wb3N0TWVzc2FnZSh7IHR5cGU6ICJlcnJvciIsIG1lc3NhZ2U6IChzID09IG51bGwgPyB2b2lkIDAgOiBzLm1lc3NhZ2UpID8/IFN0cmluZyhzKSB9KTsKICB9Cn07Cg==", qI = typeof window < "u" && window.Blob && new Blob([atob(cC)], { type: "text/javascript;charset=utf-8" });
1610
- function PC() {
1457
+ let XI = EI;
1458
+ const uC="var yt = Object.defineProperty;\nvar St = (i, e, r) => e in i ? yt(i, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : i[e] = r;\nvar ke = (i, e, r) => (St(i, typeof e != \"symbol\" ? e + \"\" : e, r), r), tt = (i, e, r) => {\n if (!e.has(i))\n throw TypeError(\"Cannot \" + r);\n};\nvar t = (i, e, r) => (tt(i, e, \"read from private field\"), r ? r.call(i) : e.get(i)), f = (i, e, r) => {\n if (e.has(i))\n throw TypeError(\"Cannot add the same private member more than once\");\n e instanceof WeakSet ? e.add(i) : e.set(i, r);\n}, l = (i, e, r, s) => (tt(i, e, \"write to private field\"), s ? s.call(i, r) : e.set(i, r), r);\nvar S = (i, e, r) => (tt(i, e, \"access private method\"), r);\nconst xt = {\n densityDissipation: 0.83,\n velocityDissipation: 0.91,\n pressureIterations: 1,\n curl: 0,\n splatRadius: 0.1,\n splatForce: 0.08,\n refraction: 1,\n specularExp: 0,\n shine: 0,\n waterColor: \"#000000\",\n glowColor: \"#b3d9ff\",\n algorithm: \"aurora\",\n warpStrength: 0.04\n};\n({\n ...xt\n});\nconst Rt = {\n calm: {\n densityDissipation: 0.98,\n velocityDissipation: 0.81,\n curl: 1e-4,\n splatRadius: 0.05,\n splatForce: 0.08,\n refraction: 0.15,\n shine: 0.03,\n glowColor: \"#99d9ff\",\n waterColor: \"#00050d\"\n },\n sand: {\n densityDissipation: 0.95,\n velocityDissipation: 0.81,\n curl: 1,\n splatRadius: 0.23,\n splatForce: 0.16,\n refraction: 0.8,\n specularExp: 0,\n shine: 0.33,\n glowColor: \"#070707\",\n waterColor: \"#735420\"\n },\n wave: {\n densityDissipation: 0.9,\n velocityDissipation: 0.2,\n curl: 0.2,\n splatRadius: 0.1,\n splatForce: 0.22,\n refraction: 0.35,\n shine: 0.2,\n glowColor: \"#80ccff\",\n waterColor: \"#000308\"\n },\n neon: {\n densityDissipation: 0.75,\n velocityDissipation: 0.3,\n curl: 0.05,\n splatRadius: 0.18,\n splatForce: 0.29,\n refraction: 0.25,\n specularExp: 0.04,\n shine: 0.93,\n glowColor: \"#ff33cc\",\n waterColor: \"#0d0014\"\n },\n smoke: {\n densityDissipation: 0.93,\n velocityDissipation: 0.71,\n curl: 0.04,\n splatRadius: 0.21,\n splatForce: 0.14,\n refraction: 0.08,\n shine: 0,\n glowColor: \"#808080\",\n waterColor: \"#0f0f0f\"\n }\n};\nfunction Ne(i) {\n if (Array.isArray(i))\n return i;\n const e = i.slice(1, 7);\n return e.length === 3 ? [\n parseInt(e[0] + e[0], 16) / 255,\n parseInt(e[1] + e[1], 16) / 255,\n parseInt(e[2] + e[2], 16) / 255\n ] : [\n parseInt(e.slice(0, 2), 16) / 255,\n parseInt(e.slice(2, 4), 16) / 255,\n parseInt(e.slice(4, 6), 16) / 255\n ];\n}\nfunction wt(i = {}, e, r = xt) {\n return { ...e ? { ...r, ...Rt[e] } : r, ...i };\n}\nconst re = `precision highp float;\nattribute vec2 aPosition;\nvarying vec2 vUv;\nvarying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;\nuniform vec2 texelSize;\nvoid main () {\nvUv = aPosition * 0.5 + 0.5;\nvL = vUv - vec2(texelSize.x, 0.0);\nvR = vUv + vec2(texelSize.x, 0.0);\nvT = vUv + vec2(0.0, texelSize.y);\nvB = vUv - vec2(0.0, texelSize.y);\ngl_Position = vec4(aPosition, 0.0, 1.0);\n}`, Et = `precision highp float;\nvarying vec2 vUv;\nuniform sampler2D uVelocity;\nuniform sampler2D uSource;\nuniform sampler2D uObstacle;\nuniform vec2 texelSize;\nuniform float dt;\nuniform float dissipation;\nvoid main () {\nfloat obs = texture2D(uObstacle, vUv).r;\nvec2 coord = vUv - dt * texture2D(uVelocity, vUv).xy * texelSize;\ngl_FragColor = dissipation * texture2D(uSource, coord) * (1.0 - obs);\n}`, Ut = `precision highp float;\nvarying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;\nuniform sampler2D uVelocity;\nuniform sampler2D uObstacle;\nvoid main () {\nfloat L = texture2D(uVelocity, vL).x * (1.0 - texture2D(uObstacle, vL).r);\nfloat R = texture2D(uVelocity, vR).x * (1.0 - texture2D(uObstacle, vR).r);\nfloat T = texture2D(uVelocity, vT).y * (1.0 - texture2D(uObstacle, vT).r);\nfloat B = texture2D(uVelocity, vB).y * (1.0 - texture2D(uObstacle, vB).r);\ngl_FragColor = vec4(0.5 * (R - L + T - B), 0.0, 0.0, 1.0);\n}`, Dt = `precision highp float;\nvarying vec2 vUv; varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;\nuniform sampler2D uPressure;\nuniform sampler2D uDivergence;\nuniform sampler2D uObstacle;\nvoid main () {\nfloat C = texture2D(uPressure, vUv).x;\nfloat L = mix(texture2D(uPressure, vL).x, C, texture2D(uObstacle, vL).r);\nfloat R = mix(texture2D(uPressure, vR).x, C, texture2D(uObstacle, vR).r);\nfloat T = mix(texture2D(uPressure, vT).x, C, texture2D(uObstacle, vT).r);\nfloat B = mix(texture2D(uPressure, vB).x, C, texture2D(uObstacle, vB).r);\nfloat div = texture2D(uDivergence, vUv).x;\ngl_FragColor = vec4((L + R + B + T - div) * 0.25, 0.0, 0.0, 1.0);\n}`, _t = `precision highp float;\nvarying vec2 vUv; varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;\nuniform sampler2D uPressure;\nuniform sampler2D uVelocity;\nuniform sampler2D uObstacle;\nvoid main () {\nfloat obs = texture2D(uObstacle, vUv).r;\nfloat C = texture2D(uPressure, vUv).x;\nfloat L = mix(texture2D(uPressure, vL).x, C, texture2D(uObstacle, vL).r);\nfloat R = mix(texture2D(uPressure, vR).x, C, texture2D(uObstacle, vR).r);\nfloat T = mix(texture2D(uPressure, vT).x, C, texture2D(uObstacle, vT).r);\nfloat B = mix(texture2D(uPressure, vB).x, C, texture2D(uObstacle, vB).r);\nvec2 vel = (texture2D(uVelocity, vUv).xy - vec2(R - L, T - B)) * (1.0 - obs);\ngl_FragColor = vec4(vel, 0.0, 1.0);\n}`, Ct = `precision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTarget;\nuniform float aspectRatio;\nuniform vec3 color;\nuniform vec2 point;\nuniform float radius;\nvoid main () {\nvec2 p = vUv - point.xy;\np.x *= aspectRatio;\nvec3 splat = exp(-dot(p, p) / radius) * color;\ngl_FragColor = vec4(texture2D(uTarget, vUv).xyz + splat, 1.0);\n}`, Bt = `precision highp float;\nvarying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;\nuniform sampler2D uVelocity;\nvoid main () {\nfloat L = texture2D(uVelocity, vL).y;\nfloat R = texture2D(uVelocity, vR).y;\nfloat T = texture2D(uVelocity, vT).x;\nfloat B = texture2D(uVelocity, vB).x;\ngl_FragColor = vec4(0.5 * (R - L - T + B), 0.0, 0.0, 1.0);\n}`, Ot = `precision highp float;\nvarying vec2 vUv; varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;\nuniform sampler2D uVelocity;\nuniform sampler2D uCurl;\nuniform float curl;\nuniform float dt;\nvoid main () {\nfloat L = texture2D(uCurl, vL).x;\nfloat R = texture2D(uCurl, vR).x;\nfloat T = texture2D(uCurl, vT).x;\nfloat B = texture2D(uCurl, vB).x;\nfloat C = texture2D(uCurl, vUv).x;\nvec2 force = 0.5 * vec2(abs(T) - abs(B), abs(R) - abs(L));\nforce /= length(force) + 0.0001;\nforce *= curl * 30.0 * C;\ngl_FragColor = vec4(texture2D(uVelocity, vUv).xy + force * dt, 0.0, 1.0);\n}`, Vt = `precision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform sampler2D uObstacle;\nuniform sampler2D uBackground;\nuniform sampler2D uCoverage;\nuniform sampler2D uVelocity;\nuniform vec2 texelSize;\nuniform vec3 uWaterColor;\nuniform vec3 uGlowColor;\nuniform float uRefraction;\nuniform float uSpecularExp;\nuniform float uShine;\nuniform float uWarpStrength;\nuniform int uAlgorithm;\nuniform int uEnableAlpha;\nvoid main () {\nfloat obs = texture2D(uObstacle, vUv).r;\nfloat density = max(texture2D(uTexture, vUv).r, 0.0) * (1.0 - obs);\nfloat coverage = texture2D(uCoverage, vUv).r;\nfloat sx = texelSize.x * 6.0, sy = texelSize.y * 6.0;\nfloat d00 = max(texture2D(uTexture, vUv + vec2(-sx, -sy)).r, 0.0);\nfloat d10 = max(texture2D(uTexture, vUv + vec2(0.0, -sy)).r, 0.0);\nfloat d20 = max(texture2D(uTexture, vUv + vec2( sx, -sy)).r, 0.0);\nfloat d01 = max(texture2D(uTexture, vUv + vec2(-sx, 0.0)).r, 0.0);\nfloat d21 = max(texture2D(uTexture, vUv + vec2( sx, 0.0)).r, 0.0);\nfloat d02 = max(texture2D(uTexture, vUv + vec2(-sx, sy)).r, 0.0);\nfloat d12 = max(texture2D(uTexture, vUv + vec2(0.0, sy)).r, 0.0);\nfloat d22 = max(texture2D(uTexture, vUv + vec2( sx, sy)).r, 0.0);\nfloat gx = (d20 + 2.0*d21 + d22) - (d00 + 2.0*d01 + d02);\nfloat gy = (d02 + 2.0*d12 + d22) - (d00 + 2.0*d10 + d20);\nvec3 normal = normalize(vec3(gx, gy, 1.2));\nvec3 lightDir = normalize(vec3(0.5, 1.0, 0.5));\nvec3 halfV = normalize(lightDir + vec3(0.0, 0.0, 1.0));\nfloat specDen = density * min(density * 5.0, 1.0);\nfloat spec = pow(max(dot(normal, halfV), 0.0), uSpecularExp) * uShine * specDen;\nvec3 bgRaw = texture2D(uBackground, vUv).rgb;\nvec3 bg = mix(uWaterColor, bgRaw, coverage);\nvec3 color = bg;\nif (uAlgorithm == 1) {\nvec2 refrUv = clamp(vUv + normal.xy * uRefraction * density * 3.0, 0.0, 1.0);\nvec3 refrBg = mix(uWaterColor, texture2D(uBackground, mix(vUv, refrUv, 1.0 - obs)).rgb, coverage);\ncolor = refrBg + spec * uGlowColor * 2.5;\ncolor = mix(color, bg * 0.6, obs * 0.3);\n} else if (uAlgorithm == 2) {\nfloat inkD = min(density * 4.0, 1.0);\nvec2 refrUv = clamp(vUv + normal.xy * uRefraction * density * 0.4, 0.0, 1.0);\nvec3 refrBg = mix(uWaterColor, texture2D(uBackground, mix(vUv, refrUv, 1.0 - obs)).rgb, coverage);\ncolor = mix(refrBg, uWaterColor + spec * uGlowColor, inkD);\ncolor = mix(color, bg * 0.5, obs * 0.15);\n} else if (uAlgorithm == 3) {\nvec2 vel = texture2D(uVelocity, vUv).xy;\nfloat velMag = clamp(length(vel) * 20.0, 0.0, 1.0);\nvec2 warpUv = clamp(vUv + vel * uWarpStrength, 0.0, 1.0);\nvec3 warpBg = mix(uWaterColor, texture2D(uBackground, warpUv).rgb, coverage);\ncolor = mix(bg, warpBg, velMag * (1.0 - obs));\ncolor += spec * uGlowColor * velMag * 1.5;\ncolor += uWaterColor * density * 0.3;\ncolor = mix(color, bg * 0.5, obs * 0.2);\n} else if (uAlgorithm == 4) {\nvec2 rippleUv = clamp(vUv + normal.xy * uRefraction * density * 6.0, 0.0, 1.0);\nvec3 refrBg = mix(uWaterColor, texture2D(uBackground, mix(vUv, rippleUv, 1.0 - obs)).rgb, coverage);\nfloat fresnel = pow(clamp(1.0 - dot(normal, vec3(0.0, 0.0, 1.0)), 0.0, 1.0), 3.0) * density;\ncolor = refrBg;\ncolor += fresnel * uGlowColor * 2.0;\ncolor += spec * uGlowColor * density * 2.0;\ncolor = mix(color, bg * 0.5, obs * 0.2);\n} else {\nvec2 refrUv = vUv + normal.xy * uRefraction * density;\nvec3 refrBg = mix(uWaterColor, texture2D(uBackground, mix(vUv, refrUv, 1.0 - obs)).rgb, coverage);\ncolor = mix(refrBg, uWaterColor, min(density * 1.5, 0.8));\ncolor += spec * uGlowColor;\ncolor = mix(color, bg * 0.5, obs * 0.2);\n}\nfloat alpha = clamp(max(density * 1.5, coverage), 0.0, 1.0);\nif (uEnableAlpha == 1) {\ngl_FragColor = vec4(color * alpha, alpha);\n} else {\ngl_FragColor = vec4(color, 1.0);\n}\n}`;\nfunction Pt(i, e = !0) {\n const r = { alpha: e, depth: !1, stencil: !1, antialias: !0, preserveDrawingBuffer: !1 };\n let s = i.getContext(\"webgl2\", r);\n const o = !!s;\n o || (s = i.getContext(\"webgl\", r), s.getExtension(\"EXT_color_buffer_half_float\"));\n const a = o ? null : s.getExtension(\"OES_texture_half_float\"), u = o ? s.HALF_FLOAT : a.HALF_FLOAT_OES;\n return s.getExtension(\"EXT_color_buffer_float\"), s.getExtension(\"OES_texture_half_float_linear\"), {\n type: o ? \"webgl2\" : \"webgl1\",\n gl: s,\n isWebGL2: o,\n ext: {\n internalFormat: o ? s.RGBA16F : s.RGBA,\n format: s.RGBA,\n type: u\n }\n };\n}\nasync function Ft(i, e = !0) {\n if (typeof navigator > \"u\" || !navigator.gpu)\n return null;\n try {\n const r = await navigator.gpu.requestAdapter();\n if (!r)\n return null;\n const s = await r.requestDevice(), o = i.getContext(\"webgpu\");\n if (!o)\n return null;\n const a = navigator.gpu.getPreferredCanvasFormat();\n return o.configure({ device: s, format: a, alphaMode: e ? \"premultiplied\" : \"opaque\" }), { type: \"webgpu\", adapter: r, device: s, context: o, format: a };\n } catch {\n return null;\n }\n}\nclass ie {\n constructor(e, r, s) {\n ke(this, \"program\");\n ke(this, \"uniforms\", {});\n ke(this, \"_gl\");\n this._gl = e, this.program = e.createProgram(), e.attachShader(this.program, this._compile(e.VERTEX_SHADER, r)), e.attachShader(this.program, this._compile(e.FRAGMENT_SHADER, s)), e.linkProgram(this.program);\n const o = e.getProgramParameter(this.program, e.ACTIVE_UNIFORMS);\n for (let a = 0; a < o; a++) {\n const u = e.getActiveUniform(this.program, a).name;\n this.uniforms[u] = e.getUniformLocation(this.program, u);\n }\n }\n _compile(e, r) {\n const s = this._gl, o = s.createShader(e);\n return s.shaderSource(o, r), s.compileShader(o), o;\n }\n bind() {\n this._gl.useProgram(this.program);\n }\n dispose() {\n this._gl.deleteProgram(this.program);\n }\n}\nfunction Lt(i) {\n return {\n advection: new ie(i, re, Et),\n divergence: new ie(i, re, Ut),\n pressure: new ie(i, re, Dt),\n gradientSubtract: new ie(i, re, _t),\n splat: new ie(i, re, Ct),\n curl: new ie(i, re, Bt),\n vorticity: new ie(i, re, Ot),\n display: new ie(i, re, Vt)\n };\n}\nfunction He(i, e, r, s) {\n i.activeTexture(i.TEXTURE0);\n const o = i.createTexture();\n i.bindTexture(i.TEXTURE_2D, o), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MIN_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MAG_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_S, i.CLAMP_TO_EDGE), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_T, i.CLAMP_TO_EDGE), i.texImage2D(i.TEXTURE_2D, 0, e.internalFormat, r, s, 0, e.format, e.type, null);\n const a = i.createFramebuffer();\n return i.bindFramebuffer(i.FRAMEBUFFER, a), i.framebufferTexture2D(i.FRAMEBUFFER, i.COLOR_ATTACHMENT0, i.TEXTURE_2D, o, 0), { tex: o, fbo: a, width: r, height: s };\n}\nfunction rt(i, e, r, s) {\n let o = He(i, e, r, s), a = He(i, e, r, s);\n return {\n get read() {\n return o;\n },\n get write() {\n return a;\n },\n swap() {\n [o, a] = [a, o];\n },\n dispose() {\n i.deleteTexture(o.tex), i.deleteFramebuffer(o.fbo), i.deleteTexture(a.tex), i.deleteFramebuffer(a.fbo);\n }\n };\n}\nfunction At(i) {\n const e = i.createBuffer();\n return i.bindBuffer(i.ARRAY_BUFFER, e), i.bufferData(i.ARRAY_BUFFER, new Float32Array([-1, -1, -1, 1, 1, 1, 1, -1]), i.STATIC_DRAW), i.vertexAttribPointer(0, 2, i.FLOAT, !1, 0, 0), i.enableVertexAttribArray(0), function(s) {\n i.bindFramebuffer(i.FRAMEBUFFER, s), i.drawArrays(i.TRIANGLE_FAN, 0, 4);\n };\n}\nconst le = `struct VSOut {\n@builtin(position) pos : vec4f,\n@location(0) uv : vec2f,\n@location(1) vL : vec2f,\n@location(2) vR : vec2f,\n@location(3) vT : vec2f,\n@location(4) vB : vec2f,\n}`, Xt = `${le}\nstruct U {\ntexelSize : vec2f,\ndt : f32,\ndissipation: f32,\n}\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uVel : texture_2d<f32>;\n@group(0) @binding(3) var uSrc : texture_2d<f32>;\n@group(0) @binding(4) var uObs : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\nvar o: VSOut;\no.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\no.vL = o.uv - vec2f(u.texelSize.x, 0.0);\no.vR = o.uv + vec2f(u.texelSize.x, 0.0);\no.vT = o.uv + vec2f(0.0, u.texelSize.y);\no.vB = o.uv - vec2f(0.0, u.texelSize.y);\no.pos = vec4f(a, 0.0, 1.0);\nreturn o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\nlet obs = textureSample(uObs, samp, i.uv).r;\nlet vel = textureSample(uVel, samp, i.uv).xy;\nlet coord = i.uv - u.dt * vel * u.texelSize;\nlet src = textureSample(uSrc, samp, coord);\nreturn u.dissipation * src * (1.0 - obs);\n}`, zt = `${le}\nstruct U { texelSize: vec2f, _pad: vec2f }\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uVel : texture_2d<f32>;\n@group(0) @binding(3) var uObs : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\nvar o: VSOut;\no.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\no.vL = o.uv - vec2f(u.texelSize.x, 0.0);\no.vR = o.uv + vec2f(u.texelSize.x, 0.0);\no.vT = o.uv + vec2f(0.0, u.texelSize.y);\no.vB = o.uv - vec2f(0.0, u.texelSize.y);\no.pos = vec4f(a, 0.0, 1.0);\nreturn o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\nlet L = textureSample(uVel, samp, i.vL).x * (1.0 - textureSample(uObs, samp, i.vL).r);\nlet R = textureSample(uVel, samp, i.vR).x * (1.0 - textureSample(uObs, samp, i.vR).r);\nlet T = textureSample(uVel, samp, i.vT).y * (1.0 - textureSample(uObs, samp, i.vT).r);\nlet B = textureSample(uVel, samp, i.vB).y * (1.0 - textureSample(uObs, samp, i.vB).r);\nreturn vec4f(0.5 * (R - L + T - B), 0.0, 0.0, 1.0);\n}`, Gt = `${le}\nstruct U { texelSize: vec2f, _pad: vec2f }\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uPres: texture_2d<f32>;\n@group(0) @binding(3) var uDiv : texture_2d<f32>;\n@group(0) @binding(4) var uObs : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\nvar o: VSOut;\no.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\no.vL = o.uv - vec2f(u.texelSize.x, 0.0);\no.vR = o.uv + vec2f(u.texelSize.x, 0.0);\no.vT = o.uv + vec2f(0.0, u.texelSize.y);\no.vB = o.uv - vec2f(0.0, u.texelSize.y);\no.pos = vec4f(a, 0.0, 1.0);\nreturn o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\nlet C = textureSample(uPres, samp, i.uv).x;\nlet L = mix(textureSample(uPres, samp, i.vL).x, C, textureSample(uObs, samp, i.vL).r);\nlet R = mix(textureSample(uPres, samp, i.vR).x, C, textureSample(uObs, samp, i.vR).r);\nlet T = mix(textureSample(uPres, samp, i.vT).x, C, textureSample(uObs, samp, i.vT).r);\nlet B = mix(textureSample(uPres, samp, i.vB).x, C, textureSample(uObs, samp, i.vB).r);\nlet dv = textureSample(uDiv, samp, i.uv).x;\nreturn vec4f((L + R + B + T - dv) * 0.25, 0.0, 0.0, 1.0);\n}`, Mt = `${le}\nstruct U { texelSize: vec2f, _pad: vec2f }\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uPres: texture_2d<f32>;\n@group(0) @binding(3) var uVel : texture_2d<f32>;\n@group(0) @binding(4) var uObs : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\nvar o: VSOut;\no.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\no.vL = o.uv - vec2f(u.texelSize.x, 0.0);\no.vR = o.uv + vec2f(u.texelSize.x, 0.0);\no.vT = o.uv + vec2f(0.0, u.texelSize.y);\no.vB = o.uv - vec2f(0.0, u.texelSize.y);\no.pos = vec4f(a, 0.0, 1.0);\nreturn o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\nlet obs = textureSample(uObs, samp, i.uv).r;\nlet C = textureSample(uPres, samp, i.uv).x;\nlet L = mix(textureSample(uPres, samp, i.vL).x, C, textureSample(uObs, samp, i.vL).r);\nlet R = mix(textureSample(uPres, samp, i.vR).x, C, textureSample(uObs, samp, i.vR).r);\nlet T = mix(textureSample(uPres, samp, i.vT).x, C, textureSample(uObs, samp, i.vT).r);\nlet B = mix(textureSample(uPres, samp, i.vB).x, C, textureSample(uObs, samp, i.vB).r);\nlet vel = (textureSample(uVel, samp, i.uv).xy - vec2f(R - L, T - B)) * (1.0 - obs);\nreturn vec4f(vel, 0.0, 1.0);\n}`, It = `${le}\nstruct U {\ntexelSize : vec2f,\naspectRatio: f32,\nradius : f32,\ncolor : vec4f, \npoint : vec2f,\n_pad : vec2f,\n}\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uTgt : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\nvar o: VSOut;\no.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\no.vL = o.uv - vec2f(u.texelSize.x, 0.0);\no.vR = o.uv + vec2f(u.texelSize.x, 0.0);\no.vT = o.uv + vec2f(0.0, u.texelSize.y);\no.vB = o.uv - vec2f(0.0, u.texelSize.y);\no.pos = vec4f(a, 0.0, 1.0);\nreturn o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\nvar p = i.uv - u.point;\np.x *= u.aspectRatio;\nlet sp = exp(-dot(p, p) / u.radius) * u.color.xyz;\nreturn vec4f(textureSample(uTgt, samp, i.uv).xyz + sp, 1.0);\n}`, Wt = `${le}\nstruct U { texelSize: vec2f, _pad: vec2f }\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uVel : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\nvar o: VSOut;\no.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\no.vL = o.uv - vec2f(u.texelSize.x, 0.0);\no.vR = o.uv + vec2f(u.texelSize.x, 0.0);\no.vT = o.uv + vec2f(0.0, u.texelSize.y);\no.vB = o.uv - vec2f(0.0, u.texelSize.y);\no.pos = vec4f(a, 0.0, 1.0);\nreturn o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\nlet L = textureSample(uVel, samp, i.vL).y;\nlet R = textureSample(uVel, samp, i.vR).y;\nlet T = textureSample(uVel, samp, i.vT).x;\nlet B = textureSample(uVel, samp, i.vB).x;\nreturn vec4f(0.5 * (R - L - T + B), 0.0, 0.0, 1.0);\n}`, kt = `${le}\nstruct U {\ntexelSize: vec2f,\ncurl : f32,\ndt : f32,\n}\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uVel : texture_2d<f32>;\n@group(0) @binding(3) var uCrl : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\nvar o: VSOut;\no.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\no.vL = o.uv - vec2f(u.texelSize.x, 0.0);\no.vR = o.uv + vec2f(u.texelSize.x, 0.0);\no.vT = o.uv + vec2f(0.0, u.texelSize.y);\no.vB = o.uv - vec2f(0.0, u.texelSize.y);\no.pos = vec4f(a, 0.0, 1.0);\nreturn o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\nlet L = textureSample(uCrl, samp, i.vL).x;\nlet R = textureSample(uCrl, samp, i.vR).x;\nlet T = textureSample(uCrl, samp, i.vT).x;\nlet B = textureSample(uCrl, samp, i.vB).x;\nlet C = textureSample(uCrl, samp, i.uv).x;\nvar force = 0.5 * vec2f(abs(T) - abs(B), abs(R) - abs(L));\nforce /= length(force) + 0.0001;\nforce *= u.curl * 30.0 * C;\nlet vel = textureSample(uVel, samp, i.uv).xy + force * u.dt;\nreturn vec4f(vel, 0.0, 1.0);\n}`, Nt = `${le}\nstruct U {\ntexelSize : vec2f,\nrefraction : f32,\nspecularExp : f32,\nwaterColor : vec4f,\nglowColor : vec4f,\nshine : f32,\nwarpStrength: f32,\nalgorithm : i32,\nenableAlpha : i32,\n}\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uTex : texture_2d<f32>;\n@group(0) @binding(3) var uObs : texture_2d<f32>;\n@group(0) @binding(4) var uBg : texture_2d<f32>;\n@group(0) @binding(5) var uCov : texture_2d<f32>;\n@group(0) @binding(6) var uVel : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\nvar o: VSOut;\no.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\no.vL = o.uv - vec2f(u.texelSize.x, 0.0);\no.vR = o.uv + vec2f(u.texelSize.x, 0.0);\no.vT = o.uv + vec2f(0.0, u.texelSize.y);\no.vB = o.uv - vec2f(0.0, u.texelSize.y);\no.pos = vec4f(a, 0.0, 1.0);\nreturn o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\nlet obs = textureSample(uObs, samp, i.uv).r;\nlet density = max(textureSample(uTex, samp, i.uv).r, 0.0) * (1.0 - obs);\nlet cov = textureSample(uCov, samp, i.uv).r;\nlet sx = u.texelSize.x * 6.0;\nlet sy = u.texelSize.y * 6.0;\nlet d00 = max(textureSample(uTex, samp, i.uv + vec2f(-sx, -sy)).r, 0.0);\nlet d10 = max(textureSample(uTex, samp, i.uv + vec2f(0.0, -sy)).r, 0.0);\nlet d20 = max(textureSample(uTex, samp, i.uv + vec2f( sx, -sy)).r, 0.0);\nlet d01 = max(textureSample(uTex, samp, i.uv + vec2f(-sx, 0.0)).r, 0.0);\nlet d21 = max(textureSample(uTex, samp, i.uv + vec2f( sx, 0.0)).r, 0.0);\nlet d02 = max(textureSample(uTex, samp, i.uv + vec2f(-sx, sy)).r, 0.0);\nlet d12 = max(textureSample(uTex, samp, i.uv + vec2f(0.0, sy)).r, 0.0);\nlet d22 = max(textureSample(uTex, samp, i.uv + vec2f( sx, sy)).r, 0.0);\nlet gx = (d20 + 2.0*d21 + d22) - (d00 + 2.0*d01 + d02);\nlet gy = (d02 + 2.0*d12 + d22) - (d00 + 2.0*d10 + d20);\nlet norm = normalize(vec3f(gx, gy, 1.2));\nlet ldir = normalize(vec3f(0.5, 1.0, 0.5));\nlet halfV = normalize(ldir + vec3f(0.0, 0.0, 1.0));\nlet specDen = density * min(density * 5.0, 1.0);\nlet spec = pow(max(dot(norm, halfV), 0.0), u.specularExp) * u.shine * specDen;\nlet bgRaw = textureSample(uBg, samp, i.uv).rgb;\nlet wc = u.waterColor.rgb;\nlet gc = u.glowColor.rgb;\nlet bg = mix(wc, bgRaw, cov);\nvar color = bg;\nif (u.algorithm == 1) {\nlet ruv = clamp(i.uv + norm.xy * u.refraction * density * 3.0, vec2f(0.0), vec2f(1.0));\nlet rbg = mix(wc, textureSample(uBg, samp, mix(i.uv, ruv, 1.0 - obs)).rgb, cov);\ncolor = rbg + spec * gc * 2.5;\ncolor = mix(color, bg * 0.6, obs * 0.3);\n} else if (u.algorithm == 2) {\nlet inkD = min(density * 4.0, 1.0);\nlet ruv = clamp(i.uv + norm.xy * u.refraction * density * 0.4, vec2f(0.0), vec2f(1.0));\nlet rbg = mix(wc, textureSample(uBg, samp, mix(i.uv, ruv, 1.0 - obs)).rgb, cov);\ncolor = mix(rbg, wc + spec * gc, inkD);\ncolor = mix(color, bg * 0.5, obs * 0.15);\n} else if (u.algorithm == 3) {\nlet vel = textureSample(uVel, samp, i.uv).xy;\nlet velMag = clamp(length(vel) * 20.0, 0.0, 1.0);\nlet wuv = clamp(i.uv + vel * u.warpStrength, vec2f(0.0), vec2f(1.0));\nlet wbg = mix(wc, textureSample(uBg, samp, wuv).rgb, cov);\ncolor = mix(bg, wbg, velMag * (1.0 - obs));\ncolor += spec * gc * velMag * 1.5;\ncolor += wc * density * 0.3;\ncolor = mix(color, bg * 0.5, obs * 0.2);\n} else if (u.algorithm == 4) {\nlet ruv = clamp(i.uv + norm.xy * u.refraction * density * 6.0, vec2f(0.0), vec2f(1.0));\nlet rbg = mix(wc, textureSample(uBg, samp, mix(i.uv, ruv, 1.0 - obs)).rgb, cov);\nlet fres = pow(clamp(1.0 - dot(norm, vec3f(0.0, 0.0, 1.0)), 0.0, 1.0), 3.0) * density;\ncolor = rbg;\ncolor += fres * gc * 2.0;\ncolor += spec * gc * density * 2.0;\ncolor = mix(color, bg * 0.5, obs * 0.2);\n} else {\nlet ruv = i.uv + norm.xy * u.refraction * density;\nlet rbg = mix(wc, textureSample(uBg, samp, mix(i.uv, ruv, 1.0 - obs)).rgb, cov);\ncolor = mix(rbg, wc, min(density * 1.5, 0.8));\ncolor += spec * gc;\ncolor = mix(color, bg * 0.5, obs * 0.2);\n}\nlet alpha = clamp(max(density * 1.5, cov), 0.0, 1.0);\nif (u.enableAlpha == 1) {\nreturn vec4f(color * alpha, alpha);\n}\nreturn vec4f(color, 1.0);\n}`, $t = {\n arrayStride: 8,\n attributes: [{ shaderLocation: 0, offset: 0, format: \"float32x2\" }]\n}, lt = new Float32Array([\n -1,\n -1,\n -1,\n 1,\n 1,\n -1,\n 1,\n -1,\n -1,\n 1,\n 1,\n 1\n]);\nfunction qt(i) {\n const e = i.createBuffer({ size: lt.byteLength, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST });\n return i.queue.writeBuffer(e, 0, lt), e;\n}\nfunction Ye(i, e, r, s) {\n const o = i.createTexture({\n size: [r, s],\n format: e,\n usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC\n });\n return { tex: o, view: o.createView(), width: r, height: s };\n}\nfunction it(i, e, r, s) {\n let o = Ye(i, e, r, s), a = Ye(i, e, r, s);\n return {\n get read() {\n return o;\n },\n get write() {\n return a;\n },\n swap() {\n [o, a] = [a, o];\n },\n dispose() {\n o.tex.destroy(), a.tex.destroy();\n }\n };\n}\nfunction se(i, e, r, s) {\n const o = i.createShaderModule({ code: e });\n return i.createRenderPipeline({\n layout: \"auto\",\n vertex: { module: o, entryPoint: \"vs\", buffers: [$t] },\n fragment: { module: o, entryPoint: \"fs\", targets: [{ format: r, ...s ? { blend: s } : {} }] },\n primitive: { topology: \"triangle-list\" }\n });\n}\nconst Ht = {\n color: { operation: \"add\", srcFactor: \"one\", dstFactor: \"zero\" },\n alpha: { operation: \"add\", srcFactor: \"one\", dstFactor: \"zero\" }\n};\nfunction Yt(i, e, r = !0) {\n const s = \"rgba16float\";\n return {\n advection: se(i, Xt, s),\n divergence: se(i, zt, s),\n pressure: se(i, Gt, s),\n gradientSubtract: se(i, Mt, s),\n splat: se(i, It, s),\n curl: se(i, Wt, s),\n vorticity: se(i, kt, s),\n display: se(i, Nt, e, r ? void 0 : Ht)\n };\n}\nfunction Qt(i) {\n return i.createSampler({ magFilter: \"linear\", minFilter: \"linear\", addressModeU: \"clamp-to-edge\", addressModeV: \"clamp-to-edge\" });\n}\nfunction k(i, e) {\n return i.createBuffer({ size: e, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST });\n}\nfunction ct(i, e, r, s, o, a) {\n const u = new Float32Array([r, s, o, a]);\n i.queue.writeBuffer(e, 0, u);\n}\nfunction $e(i, e, r, s) {\n const o = new Float32Array([r, s, 0, 0]);\n i.queue.writeBuffer(e, 0, o);\n}\nfunction jt(i, e, r, s, o, a) {\n const u = new Float32Array([r, s, o, a]);\n i.queue.writeBuffer(e, 0, u);\n}\nfunction qe(i, e, r, s, o, a, u, v, p, c, m) {\n const x = new Float32Array(12);\n x[0] = r, x[1] = s, x[2] = o, x[3] = a, x[4] = u, x[5] = v, x[6] = p, x[7] = 0, x[8] = c, x[9] = m, x[10] = 0, x[11] = 0, i.queue.writeBuffer(e, 0, x);\n}\nfunction Kt(i, e, r, s, o, a, u, v, p, c, m, x) {\n const n = new Float32Array(16), d = new Int32Array(n.buffer);\n n[0] = r, n[1] = s, n[2] = o, n[3] = a, n[4] = u[0], n[5] = u[1], n[6] = u[2], n[7] = 0, n[8] = v[0], n[9] = v[1], n[10] = v[2], n[11] = 0, n[12] = p, n[13] = c, d[14] = m, d[15] = x ? 1 : 0, i.queue.writeBuffer(e, 0, n);\n}\nfunction z(i, e, r, s, o) {\n const a = i.beginRenderPass({\n colorAttachments: [{\n view: o,\n clearValue: [0, 0, 0, 0],\n loadOp: \"clear\",\n storeOp: \"store\"\n }]\n });\n a.setPipeline(e), a.setBindGroup(0, r), a.setVertexBuffer(0, s), a.draw(6), a.end();\n}\nfunction Jt(i, e, r, s, o) {\n const a = i.beginRenderPass({\n colorAttachments: [{\n view: o,\n clearValue: [0, 0, 0, 0],\n loadOp: \"clear\",\n storeOp: \"store\"\n }]\n });\n a.setPipeline(e), a.setBindGroup(0, r), a.setVertexBuffer(0, s), a.draw(6), a.end();\n}\nfunction Be(i, e, r, s, o = \"cover\") {\n let a;\n o === \"cover\" ? a = Math.max(r / i, s / e) : o === \"contain\" ? a = Math.min(r / i, s / e) : typeof o == \"string\" && o.endsWith(\"%\") ? a = Math.min(r / i, s / e) * (parseFloat(o) / 100) : typeof o == \"string\" && o.endsWith(\"px\") ? a = parseFloat(o) / Math.max(i, e) : typeof o == \"number\" ? a = o : a = Math.max(r / i, s / e);\n const u = i * a, v = e * a;\n return { x: (r - u) / 2, y: (s - v) / 2, drawW: u, drawH: v };\n}\nfunction Zt(i, e, r, s, o = null, a = \"cover\") {\n const { text: u, fontSize: v, color: p, fontFamily: c = \"sans-serif\", fontWeight: m = 900 } = s, x = new OffscreenCanvas(e, r), n = x.getContext(\"2d\");\n ((D) => {\n if (o) {\n n.clearRect(0, 0, e, r), n.fillStyle = \"black\", n.fillRect(0, 0, e, r);\n const { x: g, y: _, drawW: F, drawH: W } = Be(\n o.width,\n o.height,\n e,\n r,\n a\n );\n n.drawImage(o, g, _, F, W);\n } else\n n.fillStyle = \"black\", n.fillRect(0, 0, e, r);\n n.fillStyle = D, n.font = `${m} ${v}px ${c}`, n.textAlign = \"center\", n.textBaseline = \"middle\", n.fillText(u, e / 2, r / 2);\n })(p);\n const b = Le(i, x);\n n.fillStyle = \"black\", n.fillRect(0, 0, e, r), n.fillStyle = \"white\", n.font = `${m} ${v}px ${c}`, n.textAlign = \"center\", n.textBaseline = \"middle\", n.fillText(u, e / 2, r / 2);\n const y = Le(i, x);\n return { backgroundTex: b, obstacleTex: y, coverageTex: y };\n}\nfunction er(i, e, r, s, o = 0, a = \"cover\", u = null, v = \"cover\") {\n const p = new OffscreenCanvas(r, s), c = p.getContext(\"2d\"), { x: m, y: x, drawW: n, drawH: d } = Be(e.width, e.height, r, s, a);\n if (c.clearRect(0, 0, r, s), c.fillStyle = \"black\", c.fillRect(0, 0, r, s), u) {\n const {\n x: g,\n y: _,\n drawW: F,\n drawH: W\n } = Be(u.width, u.height, r, s, v);\n c.filter = `brightness(${o}) blur(8px)`, c.drawImage(u, g, _, F, W), c.filter = \"none\";\n }\n c.drawImage(e, m, x, n, d);\n const b = Le(i, p);\n c.clearRect(0, 0, r, s), c.fillStyle = \"black\", c.fillRect(0, 0, r, s), c.filter = `brightness(${o}) blur(8px)`, c.drawImage(e, m, x, n, d), c.filter = \"none\";\n const y = Le(i, p);\n c.clearRect(0, 0, r, s), c.fillStyle = \"black\", c.fillRect(0, 0, r, s), c.fillStyle = \"white\", c.fillRect(\n Math.max(0, m),\n Math.max(0, x),\n Math.min(n, r - Math.max(0, m)),\n Math.min(d, s - Math.max(0, x))\n );\n const D = Le(i, p);\n return { backgroundTex: b, obstacleTex: y, coverageTex: D };\n}\nfunction Le(i, e) {\n const r = i.createTexture();\n return i.bindTexture(i.TEXTURE_2D, r), i.pixelStorei(i.UNPACK_FLIP_Y_WEBGL, !0), i.texImage2D(i.TEXTURE_2D, 0, i.RGBA, i.RGBA, i.UNSIGNED_BYTE, e), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MIN_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MAG_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_S, i.CLAMP_TO_EDGE), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_T, i.CLAMP_TO_EDGE), r;\n}\nfunction tr(i, e, r, s, o = null, a = \"cover\") {\n const { text: u, fontSize: v, color: p, fontFamily: c = \"sans-serif\", fontWeight: m = 900 } = s, x = new OffscreenCanvas(e, r), n = x.getContext(\"2d\");\n ((D) => {\n if (o) {\n n.clearRect(0, 0, e, r), n.fillStyle = \"black\", n.fillRect(0, 0, e, r);\n const { x: g, y: _, drawW: F, drawH: W } = Be(\n o.width,\n o.height,\n e,\n r,\n a\n );\n n.drawImage(o, g, _, F, W);\n } else\n n.fillStyle = \"black\", n.fillRect(0, 0, e, r);\n n.fillStyle = D, n.font = `${m} ${v}px ${c}`, n.textAlign = \"center\", n.textBaseline = \"middle\", n.fillText(u, e / 2, r / 2);\n })(p);\n const b = Ae(i, x, e, r);\n n.fillStyle = \"black\", n.fillRect(0, 0, e, r), n.fillStyle = \"white\", n.font = `${m} ${v}px ${c}`, n.textAlign = \"center\", n.textBaseline = \"middle\", n.fillText(u, e / 2, r / 2);\n const y = Ae(i, x, e, r);\n return {\n backgroundTex: b,\n backgroundView: b.createView(),\n obstacleTex: y,\n obstacleView: y.createView(),\n coverageTex: y,\n coverageView: y.createView(),\n sharedCoverage: !0\n };\n}\nfunction rr(i, e, r, s, o = 0, a = \"cover\", u = null, v = \"cover\") {\n const p = new OffscreenCanvas(r, s), c = p.getContext(\"2d\"), { x: m, y: x, drawW: n, drawH: d } = Be(e.width, e.height, r, s, a);\n if (c.clearRect(0, 0, r, s), c.fillStyle = \"black\", c.fillRect(0, 0, r, s), u) {\n const { x: g, y: _, drawW: F, drawH: W } = Be(\n u.width,\n u.height,\n r,\n s,\n v\n );\n c.filter = `brightness(${o}) blur(8px)`, c.drawImage(u, g, _, F, W), c.filter = \"none\";\n }\n c.drawImage(e, m, x, n, d);\n const b = Ae(i, p, r, s);\n c.clearRect(0, 0, r, s), c.fillStyle = \"black\", c.fillRect(0, 0, r, s), c.filter = `brightness(${o}) blur(8px)`, c.drawImage(e, m, x, n, d), c.filter = \"none\";\n const y = Ae(i, p, r, s);\n c.clearRect(0, 0, r, s), c.fillStyle = \"black\", c.fillRect(0, 0, r, s), c.fillStyle = \"white\", c.fillRect(Math.max(0, m), Math.max(0, x), Math.min(n, r - Math.max(0, m)), Math.min(d, s - Math.max(0, x)));\n const D = Ae(i, p, r, s);\n return {\n backgroundTex: b,\n backgroundView: b.createView(),\n obstacleTex: y,\n obstacleView: y.createView(),\n coverageTex: D,\n coverageView: D.createView(),\n sharedCoverage: !1\n };\n}\nfunction Ae(i, e, r, s) {\n const o = i.createTexture({\n size: [r, s],\n format: \"rgba8unorm\",\n usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT\n });\n return i.queue.copyExternalImageToTexture(\n { source: e },\n { texture: o },\n [r, s]\n ), o;\n}\nasync function ir(i) {\n const e = await fetch(i);\n if (!e.ok)\n throw new Error(`Failed to fetch image: ${i} (${e.status})`);\n const r = await e.blob();\n return createImageBitmap(r);\n}\nconst ft = typeof requestAnimationFrame < \"u\" ? requestAnimationFrame.bind(globalThis) : (i) => setTimeout(i, 1e3 / 60), sr = typeof cancelAnimationFrame < \"u\" ? cancelAnimationFrame.bind(globalThis) : clearTimeout, Ve = 0.016, vt = { standard: 0, glass: 1, ink: 2, aurora: 3, ripple: 4 };\nvar ce, G, Xe, fe, Ue, B, w, $, q, H, K, L, Y, V, De, ve, _e, O, T, oe, Q, ae, X, xe, me, pe, de, he, J, Z, ge, be, Te, R, U, M, I, P, Ce, ee, A, ue, te, h, ze, C, j, ye, Ge, Se, Qe, mt, Re, Pe, Me, ot, ne, Ee, we, Fe, Ie, at, We, ut, je, pt, Ke, dt, Je, ht, Ze, gt, et, bt;\nconst nt = class nt {\n // ── Constructor ─────────────────────────────────────────────────────────────\n constructor(e, r = {}, s = {}, o, a = !0) {\n // ---------------------------------------------------------------------------\n // Private — GPU initialisation\n // ---------------------------------------------------------------------------\n f(this, Qe);\n // ---------------------------------------------------------------------------\n // Private — shared helpers\n // ---------------------------------------------------------------------------\n f(this, Re);\n f(this, Me);\n f(this, ne);\n f(this, we);\n f(this, Ie);\n f(this, We);\n // ---------------------------------------------------------------------------\n // Private — frame dispatch\n // ---------------------------------------------------------------------------\n f(this, je);\n // ---------------------------------------------------------------------------\n // Private — WebGPU simulation step\n // ---------------------------------------------------------------------------\n f(this, Ke);\n // ---------------------------------------------------------------------------\n // Private — WebGPU direct splat\n // ---------------------------------------------------------------------------\n f(this, Je);\n // ---------------------------------------------------------------------------\n // Private — WebGL splat\n // ---------------------------------------------------------------------------\n f(this, Ze);\n // ---------------------------------------------------------------------------\n // Private — WebGL simulation step (unchanged from original)\n // ---------------------------------------------------------------------------\n f(this, et);\n f(this, ce, void 0);\n // ── WebGL path ──────────────────────────────────────────────────────────────\n f(this, G, null);\n f(this, Xe, null);\n f(this, fe, null);\n f(this, Ue, null);\n f(this, B, null);\n f(this, w, null);\n f(this, $, null);\n f(this, q, null);\n f(this, H, null);\n f(this, K, null);\n f(this, L, null);\n f(this, Y, null);\n // ── WebGPU path ─────────────────────────────────────────────────────────────\n f(this, V, null);\n f(this, De, null);\n f(this, ve, null);\n f(this, _e, null);\n f(this, O, null);\n f(this, T, null);\n f(this, oe, null);\n f(this, Q, null);\n f(this, ae, null);\n f(this, X, null);\n // Pre-allocated uniform buffers (sizes: see gpu-utils writeXxx docs)\n // Velocity/density advection use separate buffers — writeBuffer is a queue op;\n // a second write to the same buffer before queue.submit() aliases both passes.\n f(this, xe, null);\n // 16 bytes — velocity advection\n f(this, me, null);\n // 16 bytes — density advection\n f(this, pe, null);\n // 16 bytes\n f(this, de, null);\n // 16 bytes\n f(this, he, null);\n // 16 bytes\n f(this, J, null);\n // 48 bytes — velocity splat\n f(this, Z, null);\n // 48 bytes — density splat\n f(this, ge, null);\n // 16 bytes\n f(this, be, null);\n // 16 bytes\n f(this, Te, null);\n // 64 bytes\n // ── Shared state ────────────────────────────────────────────────────────────\n f(this, R, 0);\n f(this, U, 0);\n f(this, M, 0);\n f(this, I, 0);\n f(this, P, 1);\n f(this, Ce, 1);\n f(this, ee, 0.5);\n f(this, A, null);\n f(this, ue, \"cover\");\n f(this, te, void 0);\n f(this, h, { x: 0, y: 0, dx: 0, dy: 0, targetX: 0, targetY: 0, moved: !1 });\n f(this, ze, !1);\n f(this, C, null);\n f(this, j, null);\n f(this, ye, !1);\n f(this, Ge, !1);\n f(this, Se, !0);\n if (l(this, ce, e), l(this, Ce, Math.max(0.1, Math.min(1, s.dpr ?? 1))), l(this, ee, Math.max(0.1, Math.min(1, s.sim ?? 0.5))), l(this, te, wt(r)), l(this, Se, a), o)\n l(this, V, o), S(this, Qe, mt).call(this, o);\n else {\n const { gl: u, ext: v } = Pt(e, a);\n l(this, G, u), l(this, Xe, v), l(this, fe, Lt(u)), l(this, Ue, At(u)), u.clearColor(0, 0, 0, a ? 0 : 1);\n }\n }\n /**\n * WebGPU-first factory. Tries WebGPU, falls back to WebGL2 → WebGL1.\n * This is the recommended entry point when WebGPU support is desired.\n */\n static async create(e, r = {}, s = {}, o = !0, a = !0) {\n const u = o ? await Ft(e, a) : null;\n return new nt(e, r, s, u ?? void 0, a);\n }\n // ---------------------------------------------------------------------------\n // Public API\n // ---------------------------------------------------------------------------\n setTextSource(e) {\n l(this, C, { type: \"text\", opts: e }), S(this, Re, Pe).call(this), S(this, ne, Ee).call(this), S(this, we, Fe).call(this);\n }\n async setImageSource(e, r = 0, s = \"cover\") {\n const o = await ir(e);\n if (t(this, Ge)) {\n o.close();\n return;\n }\n l(this, C, { type: \"image\", bitmap: o, effect: r, size: s }), S(this, Re, Pe).call(this), S(this, ne, Ee).call(this), S(this, we, Fe).call(this);\n }\n setImageBitmap(e, r = 0, s = \"cover\") {\n l(this, C, { type: \"image\", bitmap: e, effect: r, size: s }), S(this, Re, Pe).call(this), S(this, ne, Ee).call(this), S(this, we, Fe).call(this);\n }\n setBackground(e, r = \"cover\") {\n t(this, A) && t(this, A) !== e && t(this, A).close(), l(this, A, e), l(this, ue, r ?? \"cover\"), t(this, C) && t(this, R) > 0 && t(this, U) > 0 && S(this, ne, Ee).call(this);\n }\n handleMove(e, r, s = 1) {\n if (!t(this, ze)) {\n t(this, h).x = t(this, h).targetX = e, t(this, h).y = t(this, h).targetY = r, l(this, ze, !0);\n return;\n }\n t(this, h).moved = !0, t(this, h).dx = (e - t(this, h).targetX) * s, t(this, h).dy = (r - t(this, h).targetY) * s, t(this, h).targetX = e, t(this, h).targetY = r;\n }\n /**\n * Immediately applies one fluid splat at (x, y) with explicit velocity (vx, vy).\n * Safe to call multiple times per frame — each call writes directly to the FBOs.\n * Designed for programmatic use cases (e.g. particle systems, attractor paths)\n * where you want N independent injection points per frame without flooding the\n * mouse-state machine or the worker message queue.\n */\n splat(e, r, s, o, a = 1) {\n !t(this, ye) || t(this, R) === 0 || (t(this, V) ? S(this, Je, ht).call(this, e, r, s, o, a) : S(this, Ze, gt).call(this, e, r, s, o, a));\n }\n updateQuality(e) {\n e.dpr !== void 0 && l(this, Ce, Math.max(0.1, Math.min(1, e.dpr))), e.sim !== void 0 && l(this, ee, Math.max(0.1, Math.min(1, e.sim)));\n }\n resize(e, r, s) {\n if (s !== void 0 ? l(this, P, s) : typeof window < \"u\" && window.devicePixelRatio && l(this, P, window.devicePixelRatio), e !== void 0 && e > 0) {\n if (r === void 0 || r <= 0)\n return;\n l(this, R, t(this, ce).width = e), l(this, U, t(this, ce).height = r), l(this, M, Math.max(1, Math.round(e * t(this, ee)))), l(this, I, Math.max(1, Math.round(r * t(this, ee)))), S(this, Me, ot).call(this);\n } else\n S(this, Re, Pe).call(this);\n t(this, C) && S(this, ne, Ee).call(this), S(this, we, Fe).call(this);\n }\n updateConfig(e) {\n Object.assign(t(this, te), e);\n }\n destroy() {\n var e, r, s, o, a, u, v, p, c, m, x;\n if (l(this, Ge, !0), this.stop(), S(this, Ie, at).call(this), S(this, We, ut).call(this), t(this, A) && (t(this, A).close(), l(this, A, null)), t(this, V))\n (e = t(this, xe)) == null || e.destroy(), (r = t(this, me)) == null || r.destroy(), (s = t(this, pe)) == null || s.destroy(), (o = t(this, de)) == null || o.destroy(), (a = t(this, he)) == null || a.destroy(), (u = t(this, J)) == null || u.destroy(), (v = t(this, Z)) == null || v.destroy(), (p = t(this, ge)) == null || p.destroy(), (c = t(this, be)) == null || c.destroy(), (m = t(this, Te)) == null || m.destroy(), (x = t(this, ve)) == null || x.destroy(), t(this, V).device.destroy();\n else {\n const n = t(this, G);\n for (const b of Object.values(t(this, fe)))\n b.dispose();\n const d = n.getExtension(\"WEBGL_lose_context\");\n d == null || d.loseContext();\n }\n }\n // ---------------------------------------------------------------------------\n // Loop control\n // ---------------------------------------------------------------------------\n start() {\n if (t(this, j) !== null)\n return;\n const e = () => {\n S(this, je, pt).call(this), l(this, j, ft(e));\n };\n l(this, j, ft(e));\n }\n stop() {\n t(this, j) !== null && (sr(t(this, j)), l(this, j, null));\n }\n get isRunning() {\n return t(this, j) !== null;\n }\n};\nce = new WeakMap(), G = new WeakMap(), Xe = new WeakMap(), fe = new WeakMap(), Ue = new WeakMap(), B = new WeakMap(), w = new WeakMap(), $ = new WeakMap(), q = new WeakMap(), H = new WeakMap(), K = new WeakMap(), L = new WeakMap(), Y = new WeakMap(), V = new WeakMap(), De = new WeakMap(), ve = new WeakMap(), _e = new WeakMap(), O = new WeakMap(), T = new WeakMap(), oe = new WeakMap(), Q = new WeakMap(), ae = new WeakMap(), X = new WeakMap(), xe = new WeakMap(), me = new WeakMap(), pe = new WeakMap(), de = new WeakMap(), he = new WeakMap(), J = new WeakMap(), Z = new WeakMap(), ge = new WeakMap(), be = new WeakMap(), Te = new WeakMap(), R = new WeakMap(), U = new WeakMap(), M = new WeakMap(), I = new WeakMap(), P = new WeakMap(), Ce = new WeakMap(), ee = new WeakMap(), A = new WeakMap(), ue = new WeakMap(), te = new WeakMap(), h = new WeakMap(), ze = new WeakMap(), C = new WeakMap(), j = new WeakMap(), ye = new WeakMap(), Ge = new WeakMap(), Se = new WeakMap(), Qe = new WeakSet(), mt = function(e) {\n const { device: r, format: s } = e;\n l(this, De, Yt(r, s, t(this, Se))), l(this, ve, qt(r)), l(this, _e, Qt(r)), l(this, xe, k(r, 16)), l(this, me, k(r, 16)), l(this, pe, k(r, 16)), l(this, de, k(r, 16)), l(this, he, k(r, 16)), l(this, J, k(r, 48)), l(this, Z, k(r, 48)), l(this, ge, k(r, 16)), l(this, be, k(r, 16)), l(this, Te, k(r, 64));\n}, Re = new WeakSet(), Pe = function() {\n const e = t(this, ce);\n \"clientWidth\" in e && e.clientWidth > 0 ? (l(this, P, (typeof window < \"u\" && window.devicePixelRatio || 1) * t(this, Ce)), l(this, R, e.width = Math.round(e.clientWidth * t(this, P))), l(this, U, e.height = Math.round(e.clientHeight * t(this, P)))) : (l(this, R, e.width), l(this, U, e.height)), !(t(this, R) === 0 || t(this, U) === 0) && (l(this, M, Math.max(1, Math.round(t(this, R) * t(this, ee)))), l(this, I, Math.max(1, Math.round(t(this, U) * t(this, ee)))), S(this, Me, ot).call(this));\n}, Me = new WeakSet(), ot = function() {\n if (S(this, Ie, at).call(this), t(this, V)) {\n const { device: e } = t(this, V), r = \"rgba16float\", s = t(this, M), o = t(this, I);\n l(this, O, it(e, r, s, o)), l(this, T, it(e, r, s, o)), l(this, Q, it(e, r, s, o)), l(this, oe, Ye(e, r, s, o)), l(this, ae, Ye(e, r, s, o));\n } else {\n const e = t(this, G), r = t(this, Xe), s = t(this, M), o = t(this, I);\n l(this, B, rt(e, r, s, o)), l(this, w, rt(e, r, s, o)), l(this, q, rt(e, r, s, o)), l(this, $, He(e, r, s, o)), l(this, H, He(e, r, s, o));\n }\n}, ne = new WeakSet(), Ee = function() {\n if (!(!t(this, C) || t(this, R) === 0 || t(this, U) === 0)) {\n if (S(this, We, ut).call(this), t(this, V)) {\n const { device: e } = t(this, V);\n t(this, C).type === \"text\" ? l(this, X, tr(\n e,\n t(this, R),\n t(this, U),\n t(this, C).opts,\n t(this, A),\n t(this, ue)\n )) : l(this, X, rr(\n e,\n t(this, C).bitmap,\n t(this, R),\n t(this, U),\n t(this, C).effect,\n t(this, C).size,\n t(this, A),\n t(this, ue)\n ));\n } else {\n const e = t(this, G);\n if (t(this, C).type === \"text\") {\n const { backgroundTex: r, obstacleTex: s, coverageTex: o } = Zt(\n e,\n t(this, R),\n t(this, U),\n t(this, C).opts,\n t(this, A),\n t(this, ue)\n );\n l(this, K, r), l(this, L, s), l(this, Y, o);\n } else {\n const { backgroundTex: r, obstacleTex: s, coverageTex: o } = er(\n e,\n t(this, C).bitmap,\n t(this, R),\n t(this, U),\n t(this, C).effect,\n t(this, C).size,\n t(this, A),\n t(this, ue)\n );\n l(this, K, r), l(this, L, s), l(this, Y, o);\n }\n }\n l(this, ye, !0);\n }\n}, we = new WeakSet(), Fe = function() {\n t(this, ye) && !this.isRunning && this.start();\n}, Ie = new WeakSet(), at = function() {\n var e, r, s, o, a, u, v, p;\n if (t(this, V))\n (e = t(this, O)) == null || e.dispose(), (r = t(this, T)) == null || r.dispose(), (s = t(this, Q)) == null || s.dispose(), (o = t(this, oe)) == null || o.tex.destroy(), (a = t(this, ae)) == null || a.tex.destroy(), l(this, O, l(this, T, l(this, Q, null))), l(this, oe, l(this, ae, null));\n else {\n const c = t(this, G);\n (u = t(this, B)) == null || u.dispose(), (v = t(this, w)) == null || v.dispose(), (p = t(this, q)) == null || p.dispose(), t(this, $) && (c.deleteTexture(t(this, $).tex), c.deleteFramebuffer(t(this, $).fbo)), t(this, H) && (c.deleteTexture(t(this, H).tex), c.deleteFramebuffer(t(this, H).fbo)), l(this, B, l(this, w, l(this, q, l(this, $, l(this, H, null)))));\n }\n}, We = new WeakSet(), ut = function() {\n if (t(this, V))\n t(this, X) && (t(this, X).backgroundTex.destroy(), t(this, X).obstacleTex.destroy(), t(this, X).sharedCoverage || t(this, X).coverageTex.destroy(), l(this, X, null));\n else {\n const e = t(this, G);\n t(this, K) && e.deleteTexture(t(this, K)), t(this, L) && e.deleteTexture(t(this, L)), t(this, Y) && t(this, Y) !== t(this, L) && e.deleteTexture(t(this, Y)), l(this, K, l(this, L, l(this, Y, null)));\n }\n}, je = new WeakSet(), pt = function() {\n !t(this, ye) || t(this, R) === 0 || (t(this, V) ? S(this, Ke, dt).call(this) : S(this, et, bt).call(this));\n}, Ke = new WeakSet(), dt = function() {\n const e = t(this, V), r = e.device, s = t(this, De), o = t(this, ve), a = t(this, _e), u = t(this, te), v = t(this, X);\n if (!t(this, O) || !t(this, T))\n return;\n t(this, h).x += (t(this, h).targetX - t(this, h).x) * 0.15, t(this, h).y += (t(this, h).targetY - t(this, h).y) * 0.15;\n const p = t(this, M), c = t(this, I), m = t(this, R), x = t(this, U), n = 1 / p, d = 1 / c;\n ct(r, t(this, xe), n, d, Ve, u.velocityDissipation), $e(r, t(this, pe), n, d), $e(r, t(this, de), n, d), $e(r, t(this, he), n, d), $e(r, t(this, ge), n, d), jt(r, t(this, be), n, d, u.curl, Ve), Kt(\n r,\n t(this, Te),\n 1 / m,\n 1 / x,\n u.refraction,\n u.specularExp,\n Ne(u.waterColor),\n Ne(u.glowColor),\n u.shine,\n u.warpStrength ?? 0.015,\n vt[u.algorithm] ?? 0,\n t(this, Se)\n );\n const b = r.createCommandEncoder(), y = (g, _) => r.createBindGroup({ layout: g.getBindGroupLayout(0), entries: _ }), D = { binding: 1, resource: a };\n {\n const g = y(s.advection, [\n { binding: 0, resource: { buffer: t(this, xe) } },\n D,\n { binding: 2, resource: t(this, T).read.view },\n { binding: 3, resource: t(this, T).read.view },\n { binding: 4, resource: v.obstacleView }\n ]);\n z(b, s.advection, g, o, t(this, T).write.view);\n }\n t(this, T).swap();\n {\n ct(r, t(this, me), n, d, Ve, u.densityDissipation);\n const g = y(s.advection, [\n { binding: 0, resource: { buffer: t(this, me) } },\n D,\n { binding: 2, resource: t(this, T).read.view },\n { binding: 3, resource: t(this, O).read.view },\n { binding: 4, resource: v.obstacleView }\n ]);\n z(b, s.advection, g, o, t(this, O).write.view);\n }\n t(this, O).swap();\n {\n const g = y(s.curl, [\n { binding: 0, resource: { buffer: t(this, ge) } },\n D,\n { binding: 2, resource: t(this, T).read.view }\n ]);\n z(b, s.curl, g, o, t(this, ae).view);\n }\n {\n const g = y(s.vorticity, [\n { binding: 0, resource: { buffer: t(this, be) } },\n D,\n { binding: 2, resource: t(this, T).read.view },\n { binding: 3, resource: t(this, ae).view }\n ]);\n z(b, s.vorticity, g, o, t(this, T).write.view);\n }\n if (t(this, T).swap(), t(this, h).moved) {\n const g = t(this, h).x * t(this, P) / m, _ = t(this, h).y * t(this, P) / x;\n qe(\n r,\n t(this, J),\n n,\n d,\n m / x,\n u.splatRadius,\n t(this, h).dx * u.splatForce,\n t(this, h).dy * u.splatForce,\n 0,\n g,\n _\n );\n {\n const F = y(s.splat, [\n { binding: 0, resource: { buffer: t(this, J) } },\n D,\n { binding: 2, resource: t(this, T).read.view }\n ]);\n z(b, s.splat, F, o, t(this, T).write.view);\n }\n t(this, T).swap(), qe(\n r,\n t(this, Z),\n n,\n d,\n m / x,\n u.splatRadius,\n 1,\n 1,\n 1,\n g,\n _\n );\n {\n const F = y(s.splat, [\n { binding: 0, resource: { buffer: t(this, Z) } },\n D,\n { binding: 2, resource: t(this, O).read.view }\n ]);\n z(b, s.splat, F, o, t(this, O).write.view);\n }\n t(this, O).swap(), t(this, h).moved = !1;\n }\n {\n const g = y(s.divergence, [\n { binding: 0, resource: { buffer: t(this, pe) } },\n D,\n { binding: 2, resource: t(this, T).read.view },\n { binding: 3, resource: v.obstacleView }\n ]);\n z(b, s.divergence, g, o, t(this, oe).view);\n }\n for (let g = 0; g < u.pressureIterations; g++) {\n const _ = y(s.pressure, [\n { binding: 0, resource: { buffer: t(this, de) } },\n D,\n { binding: 2, resource: t(this, Q).read.view },\n { binding: 3, resource: t(this, oe).view },\n { binding: 4, resource: v.obstacleView }\n ]);\n z(b, s.pressure, _, o, t(this, Q).write.view), t(this, Q).swap();\n }\n {\n const g = y(s.gradientSubtract, [\n { binding: 0, resource: { buffer: t(this, he) } },\n D,\n { binding: 2, resource: t(this, Q).read.view },\n { binding: 3, resource: t(this, T).read.view },\n { binding: 4, resource: v.obstacleView }\n ]);\n z(b, s.gradientSubtract, g, o, t(this, T).write.view);\n }\n t(this, T).swap();\n {\n const g = e.context.getCurrentTexture().createView(), _ = y(s.display, [\n { binding: 0, resource: { buffer: t(this, Te) } },\n D,\n { binding: 2, resource: t(this, O).read.view },\n { binding: 3, resource: v.obstacleView },\n { binding: 4, resource: v.backgroundView },\n { binding: 5, resource: v.coverageView },\n { binding: 6, resource: t(this, T).read.view }\n ]);\n Jt(b, s.display, _, o, g);\n }\n r.queue.submit([b.finish()]);\n}, Je = new WeakSet(), ht = function(e, r, s, o, a) {\n const v = t(this, V).device, p = t(this, De).splat, c = t(this, ve), m = t(this, _e), x = t(this, te), n = t(this, M), d = t(this, I), b = 1 / n, y = 1 / d, D = v.createCommandEncoder(), g = { binding: 1, resource: m }, _ = (Oe) => v.createBindGroup({ layout: p.getBindGroupLayout(0), entries: Oe }), F = e * t(this, P) / t(this, R), W = r * t(this, P) / t(this, U);\n qe(\n v,\n t(this, J),\n b,\n y,\n t(this, R) / t(this, U),\n x.splatRadius,\n s * x.splatForce * a,\n o * x.splatForce * a,\n 0,\n F,\n W\n );\n {\n const Oe = _([\n { binding: 0, resource: { buffer: t(this, J) } },\n g,\n { binding: 2, resource: t(this, T).read.view }\n ]);\n z(D, p, Oe, c, t(this, T).write.view);\n }\n t(this, T).swap(), qe(\n v,\n t(this, Z),\n b,\n y,\n t(this, R) / t(this, U),\n x.splatRadius,\n a,\n a,\n a,\n F,\n W\n );\n {\n const Oe = _([\n { binding: 0, resource: { buffer: t(this, Z) } },\n g,\n { binding: 2, resource: t(this, O).read.view }\n ]);\n z(D, p, Oe, c, t(this, O).write.view);\n }\n t(this, O).swap(), v.queue.submit([D.finish()]);\n}, Ze = new WeakSet(), gt = function(e, r, s, o, a) {\n const u = t(this, G), v = t(this, te), p = t(this, fe).splat, c = t(this, Ue);\n u.viewport(0, 0, t(this, M), t(this, I)), p.bind(), u.uniform1f(p.uniforms.aspectRatio, t(this, R) / t(this, U)), u.uniform2f(p.uniforms.point, e * t(this, P) / t(this, R), 1 - r * t(this, P) / t(this, U)), u.uniform1f(p.uniforms.radius, v.splatRadius), u.uniform1i(p.uniforms.uTarget, 0), u.activeTexture(u.TEXTURE0), u.bindTexture(u.TEXTURE_2D, t(this, w).read.tex), u.uniform3f(p.uniforms.color, s * v.splatForce * a, -o * v.splatForce * a, 0), c(t(this, w).write.fbo), t(this, w).swap(), u.activeTexture(u.TEXTURE0), u.bindTexture(u.TEXTURE_2D, t(this, B).read.tex), u.uniform3f(p.uniforms.color, a, a, a), c(t(this, B).write.fbo), t(this, B).swap();\n}, et = new WeakSet(), bt = function() {\n if (!t(this, B) || !t(this, w))\n return;\n const e = t(this, G), r = t(this, te), { advection: s, divergence: o, pressure: a, gradientSubtract: u, splat: v, curl: p, vorticity: c, display: m } = t(this, fe);\n t(this, h).x += (t(this, h).targetX - t(this, h).x) * 0.15, t(this, h).y += (t(this, h).targetY - t(this, h).y) * 0.15;\n const x = t(this, M), n = t(this, I), d = t(this, Ue);\n e.viewport(0, 0, x, n), s.bind(), e.uniform2f(s.uniforms.texelSize, 1 / x, 1 / n), e.uniform1f(s.uniforms.dt, Ve), e.uniform1i(s.uniforms.uObstacle, 0), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, t(this, L)), e.uniform1f(s.uniforms.dissipation, r.velocityDissipation), e.uniform1i(s.uniforms.uVelocity, 1), e.activeTexture(e.TEXTURE1), e.bindTexture(e.TEXTURE_2D, t(this, w).read.tex), e.uniform1i(s.uniforms.uSource, 1), d(t(this, w).write.fbo), t(this, w).swap(), e.uniform1f(s.uniforms.dissipation, r.densityDissipation), e.uniform1i(s.uniforms.uSource, 2), e.activeTexture(e.TEXTURE2), e.bindTexture(e.TEXTURE_2D, t(this, B).read.tex), d(t(this, B).write.fbo), t(this, B).swap(), p.bind(), e.uniform2f(p.uniforms.texelSize, 1 / x, 1 / n), e.uniform1i(p.uniforms.uVelocity, 0), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, t(this, w).read.tex), d(t(this, H).fbo), c.bind(), e.uniform2f(c.uniforms.texelSize, 1 / x, 1 / n), e.uniform1f(c.uniforms.curl, r.curl), e.uniform1f(c.uniforms.dt, Ve), e.uniform1i(c.uniforms.uVelocity, 0), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, t(this, w).read.tex), e.uniform1i(c.uniforms.uCurl, 1), e.activeTexture(e.TEXTURE1), e.bindTexture(e.TEXTURE_2D, t(this, H).tex), d(t(this, w).write.fbo), t(this, w).swap(), t(this, h).moved && (v.bind(), e.uniform1f(v.uniforms.aspectRatio, t(this, R) / t(this, U)), e.uniform2f(v.uniforms.point, t(this, h).x * t(this, P) / t(this, R), 1 - t(this, h).y * t(this, P) / t(this, U)), e.uniform1f(v.uniforms.radius, r.splatRadius), e.uniform1i(v.uniforms.uTarget, 0), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, t(this, w).read.tex), e.uniform3f(v.uniforms.color, t(this, h).dx * r.splatForce, -t(this, h).dy * r.splatForce, 0), d(t(this, w).write.fbo), t(this, w).swap(), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, t(this, B).read.tex), e.uniform3f(v.uniforms.color, 1, 1, 1), d(t(this, B).write.fbo), t(this, B).swap(), t(this, h).moved = !1), o.bind(), e.uniform2f(o.uniforms.texelSize, 1 / x, 1 / n), e.uniform1i(o.uniforms.uVelocity, 0), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, t(this, w).read.tex), e.uniform1i(o.uniforms.uObstacle, 1), e.activeTexture(e.TEXTURE1), e.bindTexture(e.TEXTURE_2D, t(this, L)), d(t(this, $).fbo), a.bind(), e.uniform2f(a.uniforms.texelSize, 1 / x, 1 / n), e.uniform1i(a.uniforms.uDivergence, 0), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, t(this, $).tex), e.uniform1i(a.uniforms.uObstacle, 1), e.activeTexture(e.TEXTURE1), e.bindTexture(e.TEXTURE_2D, t(this, L));\n for (let b = 0; b < r.pressureIterations; b++)\n e.uniform1i(a.uniforms.uPressure, 2), e.activeTexture(e.TEXTURE2), e.bindTexture(e.TEXTURE_2D, t(this, q).read.tex), d(t(this, q).write.fbo), t(this, q).swap();\n u.bind(), e.uniform2f(u.uniforms.texelSize, 1 / x, 1 / n), e.uniform1i(u.uniforms.uPressure, 0), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, t(this, q).read.tex), e.uniform1i(u.uniforms.uVelocity, 1), e.activeTexture(e.TEXTURE1), e.bindTexture(e.TEXTURE_2D, t(this, w).read.tex), e.uniform1i(u.uniforms.uObstacle, 2), e.activeTexture(e.TEXTURE2), e.bindTexture(e.TEXTURE_2D, t(this, L)), d(t(this, w).write.fbo), t(this, w).swap(), e.viewport(0, 0, t(this, R), t(this, U)), e.bindFramebuffer(e.FRAMEBUFFER, null), e.clear(e.COLOR_BUFFER_BIT), m.bind(), e.uniform2f(m.uniforms.texelSize, 1 / t(this, R), 1 / t(this, U)), e.uniform3fv(m.uniforms.uWaterColor, Ne(r.waterColor)), e.uniform3fv(m.uniforms.uGlowColor, Ne(r.glowColor)), e.uniform1f(m.uniforms.uRefraction, r.refraction), e.uniform1f(m.uniforms.uSpecularExp, r.specularExp), e.uniform1f(m.uniforms.uShine, r.shine), e.uniform1f(m.uniforms.uWarpStrength, r.warpStrength ?? 0.015), e.uniform1i(m.uniforms.uAlgorithm, vt[r.algorithm] ?? 0), e.uniform1i(m.uniforms.uEnableAlpha, t(this, Se) ? 1 : 0), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, t(this, B).read.tex), e.activeTexture(e.TEXTURE1), e.bindTexture(e.TEXTURE_2D, t(this, L)), e.activeTexture(e.TEXTURE2), e.bindTexture(e.TEXTURE_2D, t(this, K)), e.activeTexture(e.TEXTURE3), e.bindTexture(e.TEXTURE_2D, t(this, Y)), e.activeTexture(e.TEXTURE4), e.bindTexture(e.TEXTURE_2D, t(this, w).read.tex), e.uniform1i(m.uniforms.uTexture, 0), e.uniform1i(m.uniforms.uObstacle, 1), e.uniform1i(m.uniforms.uBackground, 2), e.uniform1i(m.uniforms.uCoverage, 3), e.uniform1i(m.uniforms.uVelocity, 4), d(null);\n};\nlet st = nt;\nconst or = () => {\n};\nlet E = null, Tt;\nconst N = new Promise((i) => {\n Tt = i;\n});\nself.onmessage = async (i) => {\n const { type: e, ...r } = i.data;\n try {\n switch (e) {\n case \"init\": {\n const { canvas: s, width: o, height: a, config: u, dpr: v, quality: p, useWebGPU: c, enableAlpha: m } = r;\n s.width = o, s.height = a, E = await st.create(s, u, p ?? {}, c ?? !0, m ?? !0), E.resize(o, a, v || 1), Tt(), self.postMessage({ type: \"ready\" });\n break;\n }\n case \"setTextSource\": {\n if (await N, !E)\n return;\n E.setTextSource(r.opts);\n break;\n }\n case \"setImageSource\": {\n if (await N, !E)\n return;\n await E.setImageSource(\n r.src,\n r.effect,\n r.size\n );\n break;\n }\n case \"setImageBitmap\": {\n if (await N, !E)\n return;\n E.setImageBitmap(\n r.bitmap,\n r.effect,\n r.size\n );\n break;\n }\n case \"setBackground\": {\n if (await N, !E)\n return;\n E.setBackground(r.bitmap, r.size);\n break;\n }\n case \"splat\": {\n if (await N, !E)\n return;\n E.splat(\n r.x,\n r.y,\n r.vx,\n r.vy,\n r.strength ?? 1\n );\n break;\n }\n case \"move\": {\n if (await N, !E)\n return;\n E.handleMove(r.x, r.y, r.strength ?? 1);\n break;\n }\n case \"resize\": {\n if (await N, !E)\n return;\n E.resize(r.width, r.height, r.dpr);\n break;\n }\n case \"updateQuality\": {\n if (await N, !E)\n return;\n E.updateQuality(r.quality);\n break;\n }\n case \"updateConfig\": {\n if (await N, !E)\n return;\n E.updateConfig(r.config);\n break;\n }\n case \"destroy\": {\n await N, E == null || E.destroy(), E = null;\n break;\n }\n default:\n or(\"Unknown message type:\", e);\n }\n } catch (s) {\n self.postMessage({ type: \"error\", message: (s == null ? void 0 : s.message) ?? String(s) });\n }\n};\n", gC = typeof window < "u" && window.Blob && new Blob([uC], { type: "text/javascript;charset=utf-8" });
1459
+ function qC() {
1611
1460
  let e;
1612
1461
  try {
1613
- if (e = qI && (window.URL || window.webkitURL).createObjectURL(qI), !e)
1462
+ if (e = gC && (window.URL || window.webkitURL).createObjectURL(gC), !e)
1614
1463
  throw "";
1615
1464
  return new Worker(e);
1616
1465
  } catch {
1617
- return new Worker("data:application/javascript;base64," + cC, { type: "module" });
1466
+ return new Worker("data:application/javascript;base64," + uC, { type: "module" });
1618
1467
  } finally {
1619
1468
  e && (window.URL || window.webkitURL).revokeObjectURL(e);
1620
1469
  }
1621
1470
  }
1622
- const _C = typeof Worker < "u" && typeof OffscreenCanvas < "u";
1623
- var v, f, qg, $g, Jg, q, ag, Lg, hg, rI, TI, YI, dC;
1624
- class qC {
1471
+ const $C = typeof Worker < "u" && typeof OffscreenCanvas < "u";
1472
+ var W, f, qg, $g, Tg, q, ag, hg, bg, pI, QI, kI, aC;
1473
+ class gi {
1625
1474
  constructor(g, {
1626
1475
  workerEnabled: C = !0,
1627
1476
  webGPUEnabled: i = !0,
1628
1477
  alphaEnabled: s = !0,
1629
- quality: l = {},
1630
- config: t = {}
1478
+ quality: t = {},
1479
+ config: l = {}
1631
1480
  } = {}) {
1632
1481
  // ---------------------------------------------------------------------------
1633
1482
  // Private
@@ -1642,38 +1491,38 @@ class qC {
1642
1491
  * this is the common path in jsdom/test environments and keeps the
1643
1492
  * constructor behaviour synchronous where possible.
1644
1493
  */
1645
- d(this, rI);
1646
- d(this, YI);
1647
- d(this, v, null);
1648
- d(this, f, null);
1649
- d(this, qg, void 0);
1650
- d(this, $g, void 0);
1651
- d(this, Jg, void 0);
1652
- d(this, q, void 0);
1653
- d(this, ag, void 0);
1494
+ A(this, pI);
1495
+ A(this, kI);
1496
+ A(this, W, null);
1497
+ A(this, f, null);
1498
+ A(this, qg, void 0);
1499
+ A(this, $g, void 0);
1500
+ A(this, Tg, void 0);
1501
+ A(this, q, void 0);
1502
+ A(this, ag, void 0);
1654
1503
  // Pending source calls queued while WebGPU async init is in progress (main-thread only)
1655
- d(this, Lg, null);
1656
- d(this, hg, null);
1657
- o(this, q, Math.max(0.1, Math.min(1, l.dpr ?? 1))), o(this, ag, Math.max(0.1, Math.min(1, l.sim ?? 0.5))), o(this, $g, i), o(this, Jg, s), o(this, qg, C && _C), I(this, qg) ? L(this, YI, dC).call(this, g, t) : L(this, rI, TI).call(this, g, t);
1504
+ A(this, hg, null);
1505
+ A(this, bg, null);
1506
+ o(this, q, Math.max(0.1, Math.min(1, t.dpr ?? 1))), o(this, ag, Math.max(0.1, Math.min(1, t.sim ?? 0.5))), o(this, $g, i), o(this, Tg, s), o(this, qg, C && $C), I(this, qg) ? h(this, kI, aC).call(this, g, l) : h(this, pI, QI).call(this, g, l);
1658
1507
  }
1659
1508
  // ---------------------------------------------------------------------------
1660
1509
  // Source setters
1661
1510
  // ---------------------------------------------------------------------------
1662
1511
  setTextSource(g) {
1663
- I(this, v) ? I(this, v).postMessage({ type: "setTextSource", opts: g }) : I(this, f) ? I(this, f).setTextSource(g) : (o(this, Lg, g), o(this, hg, null));
1512
+ I(this, W) ? I(this, W).postMessage({ type: "setTextSource", opts: g }) : I(this, f) ? I(this, f).setTextSource(g) : (o(this, hg, g), o(this, bg, null));
1664
1513
  }
1665
- setImageSource(g, C = Gg.effect, i = Gg.imageSize) {
1666
- if (I(this, v)) {
1514
+ setImageSource(g, C = rg.effect, i = rg.imageSize) {
1515
+ if (I(this, W)) {
1667
1516
  const s = new URL(g, location.href).href;
1668
- I(this, v).postMessage({ type: "setImageSource", src: s, effect: C, size: i });
1517
+ I(this, W).postMessage({ type: "setImageSource", src: s, effect: C, size: i });
1669
1518
  } else
1670
- I(this, f) ? I(this, f).setImageSource(g, C, i) : (o(this, hg, { src: g, effect: C, size: i }), o(this, Lg, null));
1519
+ I(this, f) ? I(this, f).setImageSource(g, C, i) : (o(this, bg, { src: g, effect: C, size: i }), o(this, hg, null));
1671
1520
  }
1672
1521
  setBackground(g, C = "cover") {
1673
1522
  var i;
1674
- if (I(this, v)) {
1523
+ if (I(this, W)) {
1675
1524
  const s = g ? [g] : [];
1676
- I(this, v).postMessage({ type: "setBackground", bitmap: g ?? null, size: C }, s);
1525
+ I(this, W).postMessage({ type: "setBackground", bitmap: g ?? null, size: C }, s);
1677
1526
  } else
1678
1527
  (i = I(this, f)) == null || i.setBackground(g ?? null, C);
1679
1528
  }
@@ -1684,383 +1533,413 @@ class qC {
1684
1533
  * Immediately injects one splat at (x, y) with explicit velocity (vx, vy).
1685
1534
  * Safe to call multiple times per frame. See FluidSimulation.splat for details.
1686
1535
  */
1687
- splat(g, C, i, s, l = 1) {
1688
- I(this, v) ? I(this, v).postMessage({ type: "splat", x: g, y: C, vx: i, vy: s, strength: l }) : I(this, f).splat(g, C, i, s, l);
1536
+ splat(g, C, i, s, t = 1) {
1537
+ I(this, W) ? I(this, W).postMessage({ type: "splat", x: g, y: C, vx: i, vy: s, strength: t }) : I(this, f).splat(g, C, i, s, t);
1689
1538
  }
1690
1539
  handleMove(g, C, i = 1) {
1691
- I(this, v) ? I(this, v).postMessage({ type: "move", x: g, y: C, strength: i }) : I(this, f).handleMove(g, C, i);
1540
+ I(this, W) ? I(this, W).postMessage({ type: "move", x: g, y: C, strength: i }) : I(this, f).handleMove(g, C, i);
1692
1541
  }
1693
1542
  // ---------------------------------------------------------------------------
1694
1543
  // Config + control
1695
1544
  // ---------------------------------------------------------------------------
1696
1545
  updateQuality(g) {
1697
- o(this, q, Math.max(0.1, Math.min(1, g.dpr ?? I(this, q)))), o(this, ag, Math.max(0.1, Math.min(1, g.sim ?? I(this, ag)))), I(this, v) ? I(this, v).postMessage({ type: "updateQuality", quality: { dpr: I(this, q), sim: I(this, ag) } }) : I(this, f).updateQuality(g);
1546
+ o(this, q, Math.max(0.1, Math.min(1, g.dpr ?? I(this, q)))), o(this, ag, Math.max(0.1, Math.min(1, g.sim ?? I(this, ag)))), I(this, W) ? I(this, W).postMessage({ type: "updateQuality", quality: { dpr: I(this, q), sim: I(this, ag) } }) : I(this, f).updateQuality(g);
1698
1547
  }
1699
1548
  updateConfig(g) {
1700
- I(this, v) ? I(this, v).postMessage({ type: "updateConfig", config: g }) : I(this, f).updateConfig(g);
1549
+ I(this, W) ? I(this, W).postMessage({ type: "updateConfig", config: g }) : I(this, f).updateConfig(g);
1701
1550
  }
1702
1551
  resize(g, C) {
1552
+ var s;
1703
1553
  const i = (typeof window < "u" && window.devicePixelRatio || 1) * I(this, q);
1704
- I(this, v) ? I(this, v).postMessage({ type: "resize", width: g, height: C, dpr: i }) : I(this, f).resize(g, C, i);
1554
+ I(this, W) ? I(this, W).postMessage({ type: "resize", width: g, height: C, dpr: i }) : (s = I(this, f)) == null || s.resize(g, C, i);
1705
1555
  }
1706
1556
  destroy() {
1707
1557
  var g;
1708
- if (I(this, v)) {
1709
- const C = I(this, v);
1710
- o(this, v, null), C.postMessage({ type: "destroy" }), setTimeout(() => C.terminate(), 50);
1558
+ if (I(this, W)) {
1559
+ const C = I(this, W);
1560
+ o(this, W, null), C.postMessage({ type: "destroy" }), setTimeout(() => C.terminate(), 50);
1711
1561
  } else
1712
1562
  (g = I(this, f)) == null || g.destroy(), o(this, f, null);
1713
1563
  }
1714
1564
  }
1715
- v = new WeakMap(), f = new WeakMap(), qg = new WeakMap(), $g = new WeakMap(), Jg = new WeakMap(), q = new WeakMap(), ag = new WeakMap(), Lg = new WeakMap(), hg = new WeakMap(), rI = new WeakSet(), TI = function(g, C) {
1565
+ W = new WeakMap(), f = new WeakMap(), qg = new WeakMap(), $g = new WeakMap(), Tg = new WeakMap(), q = new WeakMap(), ag = new WeakMap(), hg = new WeakMap(), bg = new WeakMap(), pI = new WeakSet(), QI = function(g, C) {
1716
1566
  const i = { dpr: I(this, q), sim: I(this, ag) };
1717
- I(this, $g) && typeof navigator < "u" && !!navigator.gpu ? yI.create(g, C, i, !0, I(this, Jg)).then((l) => {
1718
- if (o(this, f, l), I(this, Lg))
1719
- l.setTextSource(I(this, Lg)), o(this, Lg, null);
1720
- else if (I(this, hg)) {
1721
- const { src: t, effect: S, size: u } = I(this, hg);
1722
- l.setImageSource(t, S, u), o(this, hg, null);
1567
+ I(this, $g) && typeof navigator < "u" && !!navigator.gpu ? XI.create(g, C, i, !0, I(this, Tg)).then((t) => {
1568
+ if (o(this, f, t), I(this, hg))
1569
+ t.setTextSource(I(this, hg)), o(this, hg, null);
1570
+ else if (I(this, bg)) {
1571
+ const { src: l, effect: u, size: Z } = I(this, bg);
1572
+ t.setImageSource(l, u, Z), o(this, bg, null);
1723
1573
  }
1724
- }).catch((l) => {
1725
- console.error("[fluidity-js] Renderer init failed:", l);
1726
- }) : o(this, f, new yI(g, C, i, void 0, I(this, Jg)));
1727
- }, YI = new WeakSet(), dC = function(g, C) {
1728
- const i = (typeof window < "u" && window.devicePixelRatio || 1) * I(this, q), s = Math.round(g.clientWidth * i), l = Math.round(g.clientHeight * i);
1729
- g.width = s, g.height = l;
1730
- let t;
1574
+ }).catch((t) => {
1575
+ }) : o(this, f, new XI(g, C, i, void 0, I(this, Tg)));
1576
+ }, kI = new WeakSet(), aC = function(g, C) {
1577
+ const i = (typeof window < "u" && window.devicePixelRatio || 1) * I(this, q), s = Math.round(g.clientWidth * i), t = Math.round(g.clientHeight * i);
1578
+ g.width = s, g.height = t;
1579
+ let l;
1731
1580
  try {
1732
- t = g.transferControlToOffscreen();
1581
+ l = g.transferControlToOffscreen();
1733
1582
  } catch {
1734
- console.warn(
1735
- "[fluidity-js] OffscreenCanvas transfer failed — falling back to main-thread mode. This is expected in React StrictMode development."
1736
- ), o(this, qg, !1), L(this, rI, TI).call(this, g, C);
1583
+ o(this, qg, !1), h(this, pI, QI).call(this, g, C);
1737
1584
  return;
1738
1585
  }
1739
- const S = o(this, v, new PC());
1740
- S.onerror = (u) => {
1741
- console.error("[fluidity-js] Worker error:", u.message);
1742
- }, S.onmessage = (u) => {
1743
- u.data.type === "error" && console.error("[fluidity-js] Simulation error:", u.data.message);
1744
- }, S.postMessage(
1745
- { type: "init", canvas: t, width: s, height: l, config: C, dpr: i, quality: { dpr: I(this, q), sim: I(this, ag) }, useWebGPU: I(this, $g), enableAlpha: I(this, Jg) },
1746
- [t]
1586
+ const u = o(this, W, new qC());
1587
+ u.onerror = (Z) => yI("Worker error:", Z.message), u.onmessage = (Z) => {
1588
+ Z.data.type === "error" && yI("Simulation error:", Z.data.message);
1589
+ }, u.postMessage(
1590
+ {
1591
+ type: "init",
1592
+ canvas: l,
1593
+ width: s,
1594
+ height: t,
1595
+ config: C,
1596
+ dpr: i,
1597
+ quality: { dpr: I(this, q), sim: I(this, ag) },
1598
+ useWebGPU: I(this, $g),
1599
+ enableAlpha: I(this, Tg)
1600
+ },
1601
+ [l]
1747
1602
  );
1748
1603
  };
1749
- function SC(e, {
1604
+ function ZC(e, {
1750
1605
  workerEnabled: g = !0,
1751
1606
  webGPUEnabled: C = !0,
1752
1607
  alphaEnabled: i = !0,
1753
1608
  pixelRatio: s,
1754
- simResolution: l,
1755
- config: t = {}
1609
+ simResolution: t,
1610
+ config: l = {}
1756
1611
  } = {}) {
1757
- const S = { dpr: s, sim: l }, u = Qg(null), c = Qg({ workerEnabled: g, quality: S, config: t }), p = Qg(Math.max(0.1, Math.min(1, s ?? gI.dpr ?? 1))), a = Qg({
1612
+ const u = { dpr: s, sim: t }, Z = Ng(null), d = Ng({ workerEnabled: g, quality: u, config: l }), S = Ng(Math.max(0.1, Math.min(1, s ?? gI.dpr ?? 1))), a = Ng({
1758
1613
  pixelRatio: s,
1759
- simResolution: l
1614
+ simResolution: t
1760
1615
  });
1761
- return tg(() => {
1762
- const A = e.current;
1763
- if (!A)
1616
+ return lg(() => {
1617
+ const c = e.current;
1618
+ if (!c)
1764
1619
  return;
1765
1620
  const m = document.createElement("canvas");
1766
- m.id = `fluid_canvas_${Date.now()}`, m.style.cssText = "position:absolute;inset:0;width:100%;height:100%;display:block;", A.appendChild(m);
1767
- const { workerEnabled: Z, quality: r, config: b } = c.current, B = (window.devicePixelRatio || 1) * p.current, K = A.getBoundingClientRect(), W = Math.round((K.width || A.clientWidth) * B) || 0, x = Math.round((K.height || A.clientHeight) * B) || 0;
1768
- W > 0 && (m.width = W, m.height = x), x === 0 && console.warn(
1769
- "[fluidity-js] Container has zero height — simulation will not render. Avoid height:auto or percentage heights without a sized ancestor. Use explicit pixel values instead."
1770
- );
1771
- const Q = new qC(m, {
1772
- workerEnabled: Z,
1621
+ m.id = `fluid_canvas_${Date.now()}`, m.style.cssText = "position:absolute;inset:0;width:100%;height:100%;display:block;", c.appendChild(m);
1622
+ const { workerEnabled: B, quality: r, config: w } = d.current, n = (window.devicePixelRatio || 1) * S.current, y = c.getBoundingClientRect(), v = Math.round((y.width || c.clientWidth) * n) || 0, Y = Math.round((y.height || c.clientHeight) * n) || 0;
1623
+ v > 0 && (m.width = v, m.height = Y);
1624
+ const T = new gi(m, {
1625
+ workerEnabled: B,
1773
1626
  webGPUEnabled: C,
1774
1627
  alphaEnabled: i,
1775
1628
  quality: r,
1776
- config: b
1629
+ config: w
1777
1630
  });
1778
- u.current = Q;
1779
- const Tg = new ResizeObserver((CI) => {
1631
+ Z.current = T, v > 0 && Y > 0 && T.resize(v, Y);
1632
+ const Jg = new ResizeObserver((CI) => {
1780
1633
  for (const iI of CI) {
1781
- const zg = (window.devicePixelRatio || 1) * p.current, { inlineSize: eI, blockSize: sI } = iI.contentBoxSize[0];
1782
- Q.resize(Math.round(eI * zg), Math.round(sI * zg));
1634
+ const zg = (window.devicePixelRatio || 1) * S.current, { inlineSize: eI, blockSize: sI } = iI.contentBoxSize[0];
1635
+ T.resize(Math.round(eI * zg), Math.round(sI * zg));
1783
1636
  }
1784
1637
  });
1785
- return Tg.observe(A), () => {
1786
- Tg.disconnect(), Q.destroy(), m.remove(), u.current = null;
1638
+ return Jg.observe(c), () => {
1639
+ Jg.disconnect(), T.destroy(), m.remove(), Z.current = null;
1787
1640
  };
1788
- }, [C, i]), tg(() => {
1789
- p.current = Math.max(0.1, Math.min(1, s ?? gI.dpr ?? 1));
1790
- const A = a.current;
1791
- a.current = { pixelRatio: s, simResolution: l };
1792
- const m = u.current, Z = e.current;
1793
- if (!m || !Z || A.pixelRatio === s && A.simResolution === l)
1641
+ }, [C, i]), lg(() => {
1642
+ S.current = Math.max(0.1, Math.min(1, s ?? gI.dpr ?? 1));
1643
+ const c = a.current;
1644
+ a.current = { pixelRatio: s, simResolution: t };
1645
+ const m = Z.current, B = e.current;
1646
+ if (!m || !B || c.pixelRatio === s && c.simResolution === t)
1794
1647
  return;
1795
- m.updateQuality({ dpr: s, sim: l });
1796
- const r = (window.devicePixelRatio || 1) * p.current, b = Z.clientWidth, B = Z.clientHeight;
1797
- b > 0 && B > 0 && m.resize(Math.round(b * r), Math.round(B * r));
1798
- }, [s, l, C, i]), u;
1648
+ m.updateQuality({ dpr: s, sim: t });
1649
+ const r = (window.devicePixelRatio || 1) * S.current, w = B.clientWidth, n = B.clientHeight;
1650
+ w > 0 && n > 0 && m.resize(Math.round(w * r), Math.round(n * r));
1651
+ }, [s, t, C, i]), Z;
1799
1652
  }
1800
- const Ci = gC(function({
1653
+ const ei = CC(function({
1801
1654
  text: g,
1802
1655
  fontSize: C = mg.fontSize,
1803
1656
  color: i = mg.color,
1804
1657
  fontFamily: s = mg.fontFamily,
1805
- fontWeight: l = mg.fontWeight,
1806
- className: t,
1807
- style: S,
1808
- preset: u,
1809
- algorithm: c,
1810
- backgroundColor: p = mg.backgroundColor,
1658
+ fontWeight: t = mg.fontWeight,
1659
+ className: l,
1660
+ style: u,
1661
+ preset: Z,
1662
+ algorithm: d,
1663
+ backgroundColor: S = mg.backgroundColor,
1811
1664
  backgroundSrc: a,
1812
- backgroundSize: A = mg.backgroundSize,
1665
+ backgroundSize: c = mg.backgroundSize,
1813
1666
  mouseEnabled: m = mg.mouseEnabled,
1814
- workerEnabled: Z = mg.workerEnabled,
1667
+ workerEnabled: B = mg.workerEnabled,
1815
1668
  webGPUEnabled: r = !0,
1816
- alphaEnabled: b = !0,
1817
- pixelRatio: B = gI.dpr,
1818
- simResolution: K = gI.sim,
1669
+ alphaEnabled: w = !0,
1670
+ pixelRatio: n = gI.dpr,
1671
+ simResolution: y = gI.sim,
1819
1672
  // FluidConfig flat props
1820
- densityDissipation: W,
1821
- velocityDissipation: x,
1822
- pressureIterations: Q,
1823
- curl: Tg,
1673
+ densityDissipation: v,
1674
+ velocityDissipation: Y,
1675
+ pressureIterations: T,
1676
+ curl: Jg,
1824
1677
  splatRadius: CI,
1825
1678
  splatForce: iI,
1826
1679
  refraction: zg,
1827
1680
  specularExp: eI,
1828
1681
  shine: sI,
1829
- waterColor: UI,
1682
+ waterColor: MI,
1830
1683
  glowColor: xI,
1831
- warpStrength: lI
1832
- }, tI) {
1833
- const J = Qg(null), oI = Object.fromEntries(
1834
- Object.entries({ densityDissipation: W, velocityDissipation: x, pressureIterations: Q, curl: Tg, splatRadius: CI, splatForce: iI, refraction: zg, specularExp: eI, shine: sI, waterColor: UI, glowColor: xI, algorithm: c, warpStrength: lI }).filter(([, G]) => G !== void 0)
1835
- ), n = SC(J, {
1836
- workerEnabled: Z,
1684
+ warpStrength: tI
1685
+ }, lI) {
1686
+ const J = Ng(null), oI = Object.fromEntries(
1687
+ Object.entries({
1688
+ densityDissipation: v,
1689
+ velocityDissipation: Y,
1690
+ pressureIterations: T,
1691
+ curl: Jg,
1692
+ splatRadius: CI,
1693
+ splatForce: iI,
1694
+ refraction: zg,
1695
+ specularExp: eI,
1696
+ shine: sI,
1697
+ waterColor: MI,
1698
+ glowColor: xI,
1699
+ algorithm: d,
1700
+ warpStrength: tI
1701
+ }).filter(([, p]) => p !== void 0)
1702
+ ), G = ZC(J, {
1703
+ workerEnabled: B,
1837
1704
  webGPUEnabled: r,
1838
- alphaEnabled: b,
1839
- pixelRatio: B,
1840
- simResolution: K,
1841
- config: Eg(uI(oI, u, EI))
1705
+ alphaEnabled: w,
1706
+ pixelRatio: n,
1707
+ simResolution: y,
1708
+ config: Eg(ZI(oI, Z, jI))
1842
1709
  });
1843
- IC(
1844
- tI,
1710
+ iC(
1711
+ lI,
1845
1712
  () => ({
1846
1713
  reset() {
1847
- var G;
1848
- (G = n.current) == null || G.setTextSource({ text: g, fontSize: C, color: i, fontFamily: s, fontWeight: l });
1714
+ var p;
1715
+ (p = G.current) == null || p.setTextSource({ text: g, fontSize: C, color: i, fontFamily: s, fontWeight: t });
1849
1716
  },
1850
- move(G, y, Y = 1) {
1717
+ move(p, V, k = 1) {
1851
1718
  var R;
1852
- (R = n.current) == null || R.handleMove(G, y, Y);
1719
+ (R = G.current) == null || R.handleMove(p, V, k);
1853
1720
  },
1854
- splat(G, y, Y, R, $ = 1) {
1855
- var ug;
1856
- (ug = n.current) == null || ug.splat(G, y, Y, R, $);
1721
+ splat(p, V, k, R, $ = 1) {
1722
+ var Zg;
1723
+ (Zg = G.current) == null || Zg.splat(p, V, k, R, $);
1857
1724
  },
1858
- updateConfig(G) {
1859
- var y;
1860
- (y = n.current) == null || y.updateConfig(Eg(G));
1725
+ updateConfig(p) {
1726
+ var V;
1727
+ (V = G.current) == null || V.updateConfig(Eg(p));
1861
1728
  }
1862
1729
  }),
1863
- [g, C, i, s, l]
1864
- ), tg(() => {
1865
- var G;
1866
- (G = n.current) == null || G.setTextSource({ text: g, fontSize: C, color: i, fontFamily: s, fontWeight: l });
1867
- }, [g, C, i, s, l, r, b]);
1868
- const T = JSON.stringify(oI);
1869
- return tg(() => {
1870
- var G;
1871
- (G = n.current) == null || G.updateConfig(
1872
- Eg(uI(oI, u, EI))
1730
+ [g, C, i, s, t]
1731
+ ), lg(() => {
1732
+ var p;
1733
+ (p = G.current) == null || p.setTextSource({ text: g, fontSize: C, color: i, fontFamily: s, fontWeight: t });
1734
+ }, [g, C, i, s, t, r, w]);
1735
+ const z = JSON.stringify(oI);
1736
+ return lg(() => {
1737
+ var p;
1738
+ (p = G.current) == null || p.updateConfig(
1739
+ Eg(ZI(oI, Z, jI))
1873
1740
  );
1874
- }, [u, T, r, b]), tg(() => {
1875
- var y;
1741
+ }, [Z, z, r, w]), lg(() => {
1742
+ var V;
1876
1743
  if (!a) {
1877
- (y = n.current) == null || y.setBackground(null);
1744
+ (V = G.current) == null || V.setBackground(null);
1878
1745
  return;
1879
1746
  }
1880
- let G = !1;
1881
- return zI(a).then((Y) => {
1747
+ let p = !1;
1748
+ return NI(a).then((k) => {
1882
1749
  var R;
1883
- if (G) {
1884
- Y.close();
1750
+ if (p) {
1751
+ k.close();
1885
1752
  return;
1886
1753
  }
1887
- (R = n.current) == null || R.setBackground(Y, A);
1888
- }).catch((Y) => console.error("[fluidity-js] backgroundSrc load failed:", Y)), () => {
1889
- G = !0;
1754
+ (R = G.current) == null || R.setBackground(k, c);
1755
+ }).catch((k) => yI()), () => {
1756
+ p = !0;
1890
1757
  };
1891
- }, [a, A, r, b]), tg(() => {
1758
+ }, [a, c, r, w]), lg(() => {
1892
1759
  if (!m)
1893
1760
  return;
1894
- const G = J.current;
1895
- if (!G)
1761
+ const p = J.current;
1762
+ if (!p)
1896
1763
  return;
1897
- const y = (R) => {
1898
- var ug;
1899
- const $ = G.getBoundingClientRect();
1900
- (ug = n.current) == null || ug.handleMove(R.clientX - $.left, R.clientY - $.top, 2);
1901
- }, Y = (R) => {
1902
- var QI;
1764
+ const V = (R) => {
1765
+ var Zg;
1766
+ const $ = p.getBoundingClientRect();
1767
+ (Zg = G.current) == null || Zg.handleMove(R.clientX - $.left, R.clientY - $.top, 2);
1768
+ }, k = (R) => {
1769
+ var OI;
1903
1770
  R.preventDefault();
1904
- const $ = G.getBoundingClientRect(), ug = R.touches[0];
1905
- (QI = n.current) == null || QI.handleMove(ug.clientX - $.left, ug.clientY - $.top, 1);
1771
+ const $ = p.getBoundingClientRect(), Zg = R.touches[0];
1772
+ (OI = G.current) == null || OI.handleMove(Zg.clientX - $.left, Zg.clientY - $.top, 1);
1906
1773
  };
1907
- return G.addEventListener("mousemove", y), G.addEventListener("touchmove", Y, { passive: !1 }), () => {
1908
- G.removeEventListener("mousemove", y), G.removeEventListener("touchmove", Y);
1774
+ return p.addEventListener("mousemove", V), p.addEventListener("touchmove", k, { passive: !1 }), () => {
1775
+ p.removeEventListener("mousemove", V), p.removeEventListener("touchmove", k);
1909
1776
  };
1910
- }, [m]), /* @__PURE__ */ $I(
1777
+ }, [m]), /* @__PURE__ */ IC(
1911
1778
  "div",
1912
1779
  {
1913
1780
  ref: J,
1914
- className: t,
1781
+ className: l,
1915
1782
  style: {
1916
1783
  position: "relative",
1917
1784
  display: "block",
1918
1785
  width: "100%",
1919
1786
  height: "100%",
1920
- background: p,
1921
- ...S
1787
+ background: S,
1788
+ ...u
1922
1789
  }
1923
1790
  }
1924
1791
  );
1925
- }), ii = gC(function({
1792
+ }), si = CC(function({
1926
1793
  src: g,
1927
- effect: C = Gg.effect,
1928
- imageSize: i = Gg.imageSize,
1794
+ effect: C = rg.effect,
1795
+ imageSize: i = rg.imageSize,
1929
1796
  className: s,
1930
- style: l,
1931
- preset: t,
1932
- algorithm: S,
1933
- backgroundColor: u = Gg.backgroundColor,
1934
- backgroundSrc: c,
1935
- backgroundSize: p = Gg.backgroundSize,
1936
- mouseEnabled: a = Gg.mouseEnabled,
1937
- workerEnabled: A = Gg.workerEnabled,
1797
+ style: t,
1798
+ preset: l,
1799
+ algorithm: u,
1800
+ backgroundColor: Z = rg.backgroundColor,
1801
+ backgroundSrc: d,
1802
+ backgroundSize: S = rg.backgroundSize,
1803
+ mouseEnabled: a = rg.mouseEnabled,
1804
+ workerEnabled: c = rg.workerEnabled,
1938
1805
  webGPUEnabled: m = !0,
1939
- alphaEnabled: Z = !0,
1806
+ alphaEnabled: B = !0,
1940
1807
  pixelRatio: r = gI.dpr,
1941
- simResolution: b = gI.sim,
1808
+ simResolution: w = gI.sim,
1942
1809
  // FluidConfig flat props
1943
- densityDissipation: B,
1944
- velocityDissipation: K,
1945
- pressureIterations: W,
1946
- curl: x,
1947
- splatRadius: Q,
1948
- splatForce: Tg,
1810
+ densityDissipation: n,
1811
+ velocityDissipation: y,
1812
+ pressureIterations: v,
1813
+ curl: Y,
1814
+ splatRadius: T,
1815
+ splatForce: Jg,
1949
1816
  refraction: CI,
1950
1817
  specularExp: iI,
1951
1818
  shine: zg,
1952
1819
  waterColor: eI,
1953
1820
  glowColor: sI,
1954
- warpStrength: UI
1821
+ warpStrength: MI
1955
1822
  }, xI) {
1956
- const lI = Qg(null), tI = Object.fromEntries(
1957
- Object.entries({ densityDissipation: B, velocityDissipation: K, pressureIterations: W, curl: x, splatRadius: Q, splatForce: Tg, refraction: CI, specularExp: iI, shine: zg, waterColor: eI, glowColor: sI, algorithm: S, warpStrength: UI }).filter(([, n]) => n !== void 0)
1958
- ), J = SC(lI, {
1959
- workerEnabled: A,
1823
+ const tI = Ng(null), lI = Object.fromEntries(
1824
+ Object.entries({
1825
+ densityDissipation: n,
1826
+ velocityDissipation: y,
1827
+ pressureIterations: v,
1828
+ curl: Y,
1829
+ splatRadius: T,
1830
+ splatForce: Jg,
1831
+ refraction: CI,
1832
+ specularExp: iI,
1833
+ shine: zg,
1834
+ waterColor: eI,
1835
+ glowColor: sI,
1836
+ algorithm: u,
1837
+ warpStrength: MI
1838
+ }).filter(([, G]) => G !== void 0)
1839
+ ), J = ZC(tI, {
1840
+ workerEnabled: c,
1960
1841
  webGPUEnabled: m,
1961
- alphaEnabled: Z,
1842
+ alphaEnabled: B,
1962
1843
  pixelRatio: r,
1963
- simResolution: b,
1964
- config: Eg(uI(tI, t))
1844
+ simResolution: w,
1845
+ config: Eg(ZI(lI, l))
1965
1846
  });
1966
- IC(
1847
+ iC(
1967
1848
  xI,
1968
1849
  () => ({
1969
1850
  reset() {
1970
- var n;
1971
- g && ((n = J.current) == null || n.setImageSource(g, C, i));
1851
+ var G;
1852
+ g && ((G = J.current) == null || G.setImageSource(g, C, i));
1972
1853
  },
1973
- move(n, T, G = 1) {
1974
- var y;
1975
- (y = J.current) == null || y.handleMove(n, T, G);
1854
+ move(G, z, p = 1) {
1855
+ var V;
1856
+ (V = J.current) == null || V.handleMove(G, z, p);
1976
1857
  },
1977
- splat(n, T, G, y, Y = 1) {
1858
+ splat(G, z, p, V, k = 1) {
1978
1859
  var R;
1979
- (R = J.current) == null || R.splat(n, T, G, y, Y);
1860
+ (R = J.current) == null || R.splat(G, z, p, V, k);
1980
1861
  },
1981
- updateConfig(n) {
1982
- var T;
1983
- (T = J.current) == null || T.updateConfig(Eg(n));
1862
+ updateConfig(G) {
1863
+ var z;
1864
+ (z = J.current) == null || z.updateConfig(Eg(G));
1984
1865
  }
1985
1866
  }),
1986
1867
  [g, C, i]
1987
- ), tg(() => {
1988
- var n;
1989
- g && ((n = J.current) == null || n.setImageSource(g, C, i));
1990
- }, [g, C, i, m, Z]);
1991
- const oI = JSON.stringify(tI);
1992
- return tg(() => {
1993
- var n;
1994
- (n = J.current) == null || n.updateConfig(
1995
- Eg(uI(tI, t))
1996
- );
1997
- }, [t, oI, m, Z]), tg(() => {
1998
- var T;
1999
- if (!c) {
2000
- (T = J.current) == null || T.setBackground(null);
1868
+ ), lg(() => {
1869
+ var G;
1870
+ g && ((G = J.current) == null || G.setImageSource(g, C, i));
1871
+ }, [g, C, i, m, B]);
1872
+ const oI = JSON.stringify(lI);
1873
+ return lg(() => {
1874
+ var G;
1875
+ (G = J.current) == null || G.updateConfig(Eg(ZI(lI, l)));
1876
+ }, [l, oI, m, B]), lg(() => {
1877
+ var z;
1878
+ if (!d) {
1879
+ (z = J.current) == null || z.setBackground(null);
2001
1880
  return;
2002
1881
  }
2003
- let n = !1;
2004
- return zI(c).then((G) => {
2005
- var y;
2006
- if (n) {
2007
- G.close();
1882
+ let G = !1;
1883
+ return NI(d).then((p) => {
1884
+ var V;
1885
+ if (G) {
1886
+ p.close();
2008
1887
  return;
2009
1888
  }
2010
- (y = J.current) == null || y.setBackground(G, p);
2011
- }).catch((G) => console.error("[fluidity-js] backgroundSrc load failed:", G)), () => {
2012
- n = !0;
1889
+ (V = J.current) == null || V.setBackground(p, S);
1890
+ }).catch((p) => yI()), () => {
1891
+ G = !0;
2013
1892
  };
2014
- }, [c, p, m, Z]), tg(() => {
1893
+ }, [d, S, m, B]), lg(() => {
2015
1894
  if (!a)
2016
1895
  return;
2017
- const n = lI.current;
2018
- if (!n)
1896
+ const G = tI.current;
1897
+ if (!G)
2019
1898
  return;
2020
- const T = (y) => {
1899
+ const z = (V) => {
2021
1900
  var R;
2022
- const Y = n.getBoundingClientRect();
2023
- (R = J.current) == null || R.handleMove(y.clientX - Y.left, y.clientY - Y.top, 2);
2024
- }, G = (y) => {
1901
+ const k = G.getBoundingClientRect();
1902
+ (R = J.current) == null || R.handleMove(V.clientX - k.left, V.clientY - k.top, 2);
1903
+ }, p = (V) => {
2025
1904
  var $;
2026
- y.preventDefault();
2027
- const Y = n.getBoundingClientRect(), R = y.touches[0];
2028
- ($ = J.current) == null || $.handleMove(R.clientX - Y.left, R.clientY - Y.top, 1);
1905
+ V.preventDefault();
1906
+ const k = G.getBoundingClientRect(), R = V.touches[0];
1907
+ ($ = J.current) == null || $.handleMove(R.clientX - k.left, R.clientY - k.top, 1);
2029
1908
  };
2030
- return n.addEventListener("mousemove", T), n.addEventListener("touchmove", G, { passive: !1 }), () => {
2031
- n.removeEventListener("mousemove", T), n.removeEventListener("touchmove", G);
1909
+ return G.addEventListener("mousemove", z), G.addEventListener("touchmove", p, { passive: !1 }), () => {
1910
+ G.removeEventListener("mousemove", z), G.removeEventListener("touchmove", p);
2032
1911
  };
2033
- }, [a]), /* @__PURE__ */ $I(
1912
+ }, [a]), /* @__PURE__ */ IC(
2034
1913
  "div",
2035
1914
  {
2036
- ref: lI,
1915
+ ref: tI,
2037
1916
  className: s,
2038
1917
  style: {
2039
1918
  position: "relative",
2040
1919
  display: "block",
2041
1920
  width: "100%",
2042
1921
  height: "100%",
2043
- background: u,
2044
- ...l
1922
+ background: Z,
1923
+ ...t
2045
1924
  }
2046
1925
  }
2047
1926
  );
2048
1927
  });
2049
1928
  export {
2050
- CC as DEFAULT_CONFIG,
2051
- EI as DEFAULT_CONFIG_TEXT,
2052
- Gg as DEFAULT_PROPS_IMAGE,
2053
- iC as DEFAULT_PROPS_SHARED,
1929
+ eC as DEFAULT_CONFIG,
1930
+ jI as DEFAULT_CONFIG_TEXT,
1931
+ rg as DEFAULT_PROPS_IMAGE,
1932
+ sC as DEFAULT_PROPS_SHARED,
2054
1933
  mg as DEFAULT_PROPS_TEXT,
2055
- qC as FluidController,
2056
- ii as FluidImage,
2057
- yI as FluidSimulation,
2058
- Ci as FluidText,
2059
- pC as PRESETS,
2060
- mC as PROP_RANGES,
2061
- zI as loadImageBitmap,
2062
- uI as mergeConfig,
1934
+ gi as FluidController,
1935
+ si as FluidImage,
1936
+ XI as FluidSimulation,
1937
+ ei as FluidText,
1938
+ nC as PRESETS,
1939
+ BC as PROP_RANGES,
1940
+ NI as loadImageBitmap,
1941
+ ZI as mergeConfig,
2063
1942
  Eg as normalizeConfig,
2064
- bI as parseColor,
2065
- SC as useFluid
1943
+ wI as parseColor,
1944
+ ZC as useFluid
2066
1945
  };