@jayf0x/fluidity-js 0.2.1 → 0.2.3

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 EI = Object.defineProperty;
2
- var jI = (e, g, C) => g in e ? EI(e, g, { enumerable: !0, configurable: !0, writable: !0, value: C }) : e[g] = C;
3
- var sI = (e, g, C) => (jI(e, typeof g != "symbol" ? g + "" : g, C), C), nI = (e, g, C) => {
1
+ var qI = Object.defineProperty;
2
+ var $I = (e, g, C) => g in e ? qI(e, g, { enumerable: !0, configurable: !0, writable: !0, value: C }) : e[g] = C;
3
+ var oI = (e, g, C) => ($I(e, typeof g != "symbol" ? g + "" : g, C), C), LI = (e, g, C) => {
4
4
  if (!g.has(e))
5
5
  throw TypeError("Cannot " + C);
6
6
  };
7
- var I = (e, g, C) => (nI(e, g, "read from private field"), C ? C.call(e) : g.get(e)), S = (e, g, C) => {
7
+ var I = (e, g, C) => (LI(e, g, "read from private field"), C ? C.call(e) : g.get(e)), d = (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
- }, l = (e, g, C, i) => (nI(e, g, "write to private field"), i ? i.call(e, C) : g.set(e, C), C);
12
- var h = (e, g, C) => (nI(e, g, "access private method"), C);
13
- import { jsx as UI } from "react/jsx-runtime";
14
- import { useRef as Mg, useEffect as eg, forwardRef as kI, useImperativeHandle as xI } from "react";
15
- const fI = {
11
+ }, o = (e, g, C, i) => (LI(e, g, "write to private field"), i ? i.call(e, C) : g.set(e, C), C);
12
+ var h = (e, g, C) => (LI(e, g, "access private method"), C);
13
+ import { jsx as xI } from "react/jsx-runtime";
14
+ import { useRef as Tg, useEffect as sg, forwardRef as FI, useImperativeHandle as DI } from "react";
15
+ const TI = {
16
16
  densityDissipation: 0.992,
17
17
  velocityDissipation: 0.93,
18
18
  pressureIterations: 1,
@@ -22,12 +22,12 @@ const fI = {
22
22
  refraction: 0.25,
23
23
  specularExp: 1.01,
24
24
  shine: 0.01,
25
- waterColor: [0, 0, 0],
26
- glowColor: [0.7, 0.85, 1],
25
+ waterColor: "#000000",
26
+ glowColor: "#b3d9ff",
27
27
  algorithm: "standard",
28
28
  warpStrength: 0.015
29
- }, HI = {
30
- ...fI,
29
+ }, UI = {
30
+ ...TI,
31
31
  densityDissipation: 0.99,
32
32
  velocityDissipation: 0.98,
33
33
  pressureIterations: 3,
@@ -37,24 +37,24 @@ const fI = {
37
37
  refraction: 0.25,
38
38
  specularExp: 1,
39
39
  shine: 0.1,
40
- glowColor: [0, 0.502, 1]
41
- }, PI = { dpr: 1, sim: 0.5 }, mI = {
40
+ glowColor: "#0080ff"
41
+ }, gC = { dpr: 1, sim: 0.5 }, wI = {
42
42
  backgroundColor: "#0a0a0a",
43
43
  backgroundSize: "cover",
44
44
  isMouseEnabled: !0,
45
45
  isWorkerEnabled: !0,
46
- quality: PI
47
- }, Bg = {
48
- ...mI,
46
+ quality: gC
47
+ }, ng = {
48
+ ...wI,
49
49
  effect: 0,
50
50
  imageSize: "cover"
51
- }, Sg = {
52
- ...mI,
51
+ }, ag = {
52
+ ...wI,
53
53
  fontSize: 100,
54
54
  color: "#ffffff",
55
55
  fontFamily: "sans-serif",
56
56
  fontWeight: 900
57
- }, _I = {
57
+ }, IC = {
58
58
  calm: {
59
59
  densityDissipation: 0.999,
60
60
  velocityDissipation: 0.98,
@@ -63,8 +63,8 @@ const fI = {
63
63
  splatForce: 0.5,
64
64
  refraction: 0.15,
65
65
  shine: 5e-3,
66
- glowColor: [0.6, 0.85, 1],
67
- waterColor: [0, 0.02, 0.05]
66
+ glowColor: "#99d9ff",
67
+ waterColor: "#00050d"
68
68
  },
69
69
  sand: {
70
70
  densityDissipation: 0.997,
@@ -75,8 +75,8 @@ const fI = {
75
75
  refraction: 0.8,
76
76
  specularExp: 0.1,
77
77
  shine: 0.05,
78
- glowColor: [0.027, 0.027, 0.027],
79
- waterColor: [0.451, 0.329, 0.125]
78
+ glowColor: "#070707",
79
+ waterColor: "#735420"
80
80
  },
81
81
  wave: {
82
82
  densityDissipation: 0.994,
@@ -86,8 +86,8 @@ const fI = {
86
86
  splatForce: 1.2,
87
87
  refraction: 0.35,
88
88
  shine: 0.03,
89
- glowColor: [0.5, 0.8, 1],
90
- waterColor: [0, 0.01, 0.03]
89
+ glowColor: "#80ccff",
90
+ waterColor: "#000308"
91
91
  },
92
92
  neon: {
93
93
  densityDissipation: 0.985,
@@ -98,8 +98,8 @@ const fI = {
98
98
  refraction: 0.25,
99
99
  specularExp: 0.5,
100
100
  shine: 0.14,
101
- glowColor: [1, 0.2, 0.8],
102
- waterColor: [0.05, 0, 0.08]
101
+ glowColor: "#ff33cc",
102
+ waterColor: "#0d0014"
103
103
  },
104
104
  smoke: {
105
105
  densityDissipation: 0.996,
@@ -109,128 +109,142 @@ const fI = {
109
109
  splatForce: 0.8,
110
110
  refraction: 0.08,
111
111
  shine: 0,
112
- glowColor: [0.5, 0.5, 0.5],
113
- waterColor: [0.06, 0.06, 0.06]
112
+ glowColor: "#808080",
113
+ waterColor: "#0f0f0f"
114
114
  }
115
115
  };
116
- function qg(e = {}, g, C = fI) {
117
- return { ...g ? { ...C, ..._I[g] } : C, ...e };
116
+ function AI(e) {
117
+ if (Array.isArray(e))
118
+ return e;
119
+ const g = e.slice(1, 7);
120
+ return g.length === 3 ? [
121
+ parseInt(g[0] + g[0], 16) / 255,
122
+ parseInt(g[1] + g[1], 16) / 255,
123
+ parseInt(g[2] + g[2], 16) / 255
124
+ ] : [
125
+ parseInt(g.slice(0, 2), 16) / 255,
126
+ parseInt(g.slice(2, 4), 16) / 255,
127
+ parseInt(g.slice(4, 6), 16) / 255
128
+ ];
118
129
  }
119
- function Qg(e, g, C, i, s = "cover") {
120
- let t;
121
- 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);
122
- const o = e * t, a = g * t;
123
- return { x: (C - o) / 2, y: (i - a) / 2, drawW: o, drawH: a };
130
+ function II(e = {}, g, C = TI) {
131
+ return { ...g ? { ...C, ...IC[g] } : C, ...e };
132
+ }
133
+ function jg(e, g, C, i, s = "cover") {
134
+ let l;
135
+ 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);
136
+ const t = e * l, a = g * l;
137
+ return { x: (C - t) / 2, y: (i - a) / 2, drawW: t, drawH: a };
124
138
  }
125
- function qI(e, g, C, i, s = null, t = "cover") {
126
- const { text: o, fontSize: a, color: u, fontFamily: A = "sans-serif", fontWeight: p = 900 } = i, c = new OffscreenCanvas(g, C), d = c.getContext("2d");
127
- ((b) => {
139
+ function CC(e, g, C, i, s = null, l = "cover") {
140
+ const { text: t, fontSize: a, color: u, fontFamily: c = "sans-serif", fontWeight: Z = 900 } = i, S = new OffscreenCanvas(g, C), A = S.getContext("2d");
141
+ ((L) => {
128
142
  if (s) {
129
- d.clearRect(0, 0, g, C), d.fillStyle = "black", d.fillRect(0, 0, g, C);
130
- const { x: n, y: r, drawW: R, drawH: B } = Qg(
143
+ A.clearRect(0, 0, g, C), A.fillStyle = "black", A.fillRect(0, 0, g, C);
144
+ const { x: G, y: K, drawW: b, drawH: Y } = jg(
131
145
  s.width,
132
146
  s.height,
133
147
  g,
134
148
  C,
135
- t
149
+ l
136
150
  );
137
- d.drawImage(s, n, r, R, B);
151
+ A.drawImage(s, G, K, b, Y);
138
152
  } else
139
- d.fillStyle = "black", d.fillRect(0, 0, g, C);
140
- d.fillStyle = b, d.font = `${p} ${a}px ${A}`, d.textAlign = "center", d.textBaseline = "middle", d.fillText(o, g / 2, C / 2);
153
+ A.fillStyle = "black", A.fillRect(0, 0, g, C);
154
+ A.fillStyle = L, A.font = `${Z} ${a}px ${c}`, A.textAlign = "center", A.textBaseline = "middle", A.fillText(t, g / 2, C / 2);
141
155
  })(u);
142
- const m = Pg(e, c);
143
- d.fillStyle = "black", d.fillRect(0, 0, g, C), d.fillStyle = "white", d.font = `${p} ${a}px ${A}`, d.textAlign = "center", d.textBaseline = "middle", d.fillText(o, g / 2, C / 2);
144
- const w = Pg(e, c);
145
- return { backgroundTex: m, obstacleTex: w, coverageTex: w };
156
+ const m = $g(e, S);
157
+ A.fillStyle = "black", A.fillRect(0, 0, g, C), A.fillStyle = "white", A.font = `${Z} ${a}px ${c}`, A.textAlign = "center", A.textBaseline = "middle", A.fillText(t, g / 2, C / 2);
158
+ const r = $g(e, S);
159
+ return { backgroundTex: m, obstacleTex: r, coverageTex: r };
146
160
  }
147
- function $I(e, g, C, i, s = 0, t = "cover", o = null, a = "cover") {
148
- const u = new OffscreenCanvas(C, i), A = u.getContext("2d"), { x: p, y: c, drawW: d, drawH: Z } = Qg(g.width, g.height, C, i, t);
149
- if (A.clearRect(0, 0, C, i), A.fillStyle = "black", A.fillRect(0, 0, C, i), o) {
161
+ function iC(e, g, C, i, s = 0, l = "cover", t = null, a = "cover") {
162
+ const u = new OffscreenCanvas(C, i), c = u.getContext("2d"), { x: Z, y: S, drawW: A, drawH: B } = jg(g.width, g.height, C, i, l);
163
+ if (c.clearRect(0, 0, C, i), c.fillStyle = "black", c.fillRect(0, 0, C, i), t) {
150
164
  const {
151
- x: n,
152
- y: r,
153
- drawW: R,
154
- drawH: B
155
- } = Qg(o.width, o.height, C, i, a);
156
- A.filter = `brightness(${s}) blur(8px)`, A.drawImage(o, n, r, R, B), A.filter = "none";
165
+ x: G,
166
+ y: K,
167
+ drawW: b,
168
+ drawH: Y
169
+ } = jg(t.width, t.height, C, i, a);
170
+ c.filter = `brightness(${s}) blur(8px)`, c.drawImage(t, G, K, b, Y), c.filter = "none";
157
171
  }
158
- A.drawImage(g, p, c, d, Z);
159
- const m = Pg(e, u);
160
- A.clearRect(0, 0, C, i), A.fillStyle = "black", A.fillRect(0, 0, C, i), A.filter = `brightness(${s}) blur(8px)`, A.drawImage(g, p, c, d, Z), A.filter = "none";
161
- const w = Pg(e, u);
162
- A.clearRect(0, 0, C, i), A.fillStyle = "black", A.fillRect(0, 0, C, i), A.fillStyle = "white", A.fillRect(
163
- Math.max(0, p),
164
- Math.max(0, c),
165
- Math.min(d, C - Math.max(0, p)),
166
- Math.min(Z, i - Math.max(0, c))
172
+ c.drawImage(g, Z, S, A, B);
173
+ const m = $g(e, u);
174
+ c.clearRect(0, 0, C, i), c.fillStyle = "black", c.fillRect(0, 0, C, i), c.filter = `brightness(${s}) blur(8px)`, c.drawImage(g, Z, S, A, B), c.filter = "none";
175
+ const r = $g(e, u);
176
+ c.clearRect(0, 0, C, i), c.fillStyle = "black", c.fillRect(0, 0, C, i), c.fillStyle = "white", c.fillRect(
177
+ Math.max(0, Z),
178
+ Math.max(0, S),
179
+ Math.min(A, C - Math.max(0, Z)),
180
+ Math.min(B, i - Math.max(0, S))
167
181
  );
168
- const b = Pg(e, u);
169
- return { backgroundTex: m, obstacleTex: w, coverageTex: b };
182
+ const L = $g(e, u);
183
+ return { backgroundTex: m, obstacleTex: r, coverageTex: L };
170
184
  }
171
- function Pg(e, g) {
185
+ function $g(e, g) {
172
186
  const C = e.createTexture();
173
187
  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;
174
188
  }
175
- function gC(e, g, C, i, s = null, t = "cover") {
176
- const { text: o, fontSize: a, color: u, fontFamily: A = "sans-serif", fontWeight: p = 900 } = i, c = new OffscreenCanvas(g, C), d = c.getContext("2d");
177
- ((b) => {
189
+ function eC(e, g, C, i, s = null, l = "cover") {
190
+ const { text: t, fontSize: a, color: u, fontFamily: c = "sans-serif", fontWeight: Z = 900 } = i, S = new OffscreenCanvas(g, C), A = S.getContext("2d");
191
+ ((L) => {
178
192
  if (s) {
179
- d.clearRect(0, 0, g, C), d.fillStyle = "black", d.fillRect(0, 0, g, C);
180
- const { x: n, y: r, drawW: R, drawH: B } = Qg(
193
+ A.clearRect(0, 0, g, C), A.fillStyle = "black", A.fillRect(0, 0, g, C);
194
+ const { x: G, y: K, drawW: b, drawH: Y } = jg(
181
195
  s.width,
182
196
  s.height,
183
197
  g,
184
198
  C,
185
- t
199
+ l
186
200
  );
187
- d.drawImage(s, n, r, R, B);
201
+ A.drawImage(s, G, K, b, Y);
188
202
  } else
189
- d.fillStyle = "black", d.fillRect(0, 0, g, C);
190
- d.fillStyle = b, d.font = `${p} ${a}px ${A}`, d.textAlign = "center", d.textBaseline = "middle", d.fillText(o, g / 2, C / 2);
203
+ A.fillStyle = "black", A.fillRect(0, 0, g, C);
204
+ A.fillStyle = L, A.font = `${Z} ${a}px ${c}`, A.textAlign = "center", A.textBaseline = "middle", A.fillText(t, g / 2, C / 2);
191
205
  })(u);
192
- const m = _g(e, c, g, C);
193
- d.fillStyle = "black", d.fillRect(0, 0, g, C), d.fillStyle = "white", d.font = `${p} ${a}px ${A}`, d.textAlign = "center", d.textBaseline = "middle", d.fillText(o, g / 2, C / 2);
194
- const w = _g(e, c, g, C);
206
+ const m = gI(e, S, g, C);
207
+ A.fillStyle = "black", A.fillRect(0, 0, g, C), A.fillStyle = "white", A.font = `${Z} ${a}px ${c}`, A.textAlign = "center", A.textBaseline = "middle", A.fillText(t, g / 2, C / 2);
208
+ const r = gI(e, S, g, C);
195
209
  return {
196
210
  backgroundTex: m,
197
211
  backgroundView: m.createView(),
198
- obstacleTex: w,
199
- obstacleView: w.createView(),
200
- coverageTex: w,
201
- coverageView: w.createView(),
212
+ obstacleTex: r,
213
+ obstacleView: r.createView(),
214
+ coverageTex: r,
215
+ coverageView: r.createView(),
202
216
  sharedCoverage: !0
203
217
  };
204
218
  }
205
- function IC(e, g, C, i, s = 0, t = "cover", o = null, a = "cover") {
206
- const u = new OffscreenCanvas(C, i), A = u.getContext("2d"), { x: p, y: c, drawW: d, drawH: Z } = Qg(g.width, g.height, C, i, t);
207
- if (A.clearRect(0, 0, C, i), A.fillStyle = "black", A.fillRect(0, 0, C, i), o) {
208
- const { x: n, y: r, drawW: R, drawH: B } = Qg(
209
- o.width,
210
- o.height,
219
+ function sC(e, g, C, i, s = 0, l = "cover", t = null, a = "cover") {
220
+ const u = new OffscreenCanvas(C, i), c = u.getContext("2d"), { x: Z, y: S, drawW: A, drawH: B } = jg(g.width, g.height, C, i, l);
221
+ if (c.clearRect(0, 0, C, i), c.fillStyle = "black", c.fillRect(0, 0, C, i), t) {
222
+ const { x: G, y: K, drawW: b, drawH: Y } = jg(
223
+ t.width,
224
+ t.height,
211
225
  C,
212
226
  i,
213
227
  a
214
228
  );
215
- A.filter = `brightness(${s}) blur(8px)`, A.drawImage(o, n, r, R, B), A.filter = "none";
229
+ c.filter = `brightness(${s}) blur(8px)`, c.drawImage(t, G, K, b, Y), c.filter = "none";
216
230
  }
217
- A.drawImage(g, p, c, d, Z);
218
- const m = _g(e, u, C, i);
219
- A.clearRect(0, 0, C, i), A.fillStyle = "black", A.fillRect(0, 0, C, i), A.filter = `brightness(${s}) blur(8px)`, A.drawImage(g, p, c, d, Z), A.filter = "none";
220
- const w = _g(e, u, C, i);
221
- A.clearRect(0, 0, C, i), A.fillStyle = "black", A.fillRect(0, 0, C, i), A.fillStyle = "white", A.fillRect(Math.max(0, p), Math.max(0, c), Math.min(d, C - Math.max(0, p)), Math.min(Z, i - Math.max(0, c)));
222
- const b = _g(e, u, C, i);
231
+ c.drawImage(g, Z, S, A, B);
232
+ const m = gI(e, u, C, i);
233
+ c.clearRect(0, 0, C, i), c.fillStyle = "black", c.fillRect(0, 0, C, i), c.filter = `brightness(${s}) blur(8px)`, c.drawImage(g, Z, S, A, B), c.filter = "none";
234
+ const r = gI(e, u, C, i);
235
+ c.clearRect(0, 0, C, i), c.fillStyle = "black", c.fillRect(0, 0, C, i), c.fillStyle = "white", c.fillRect(Math.max(0, Z), Math.max(0, S), Math.min(A, C - Math.max(0, Z)), Math.min(B, i - Math.max(0, S)));
236
+ const L = gI(e, u, C, i);
223
237
  return {
224
238
  backgroundTex: m,
225
239
  backgroundView: m.createView(),
226
- obstacleTex: w,
227
- obstacleView: w.createView(),
228
- coverageTex: b,
229
- coverageView: b.createView(),
240
+ obstacleTex: r,
241
+ obstacleView: r.createView(),
242
+ coverageTex: L,
243
+ coverageView: L.createView(),
230
244
  sharedCoverage: !1
231
245
  };
232
246
  }
233
- function _g(e, g, C, i) {
247
+ function gI(e, g, C, i) {
234
248
  const s = e.createTexture({
235
249
  size: [C, i],
236
250
  format: "rgba8unorm",
@@ -242,14 +256,14 @@ function _g(e, g, C, i) {
242
256
  [C, i]
243
257
  ), s;
244
258
  }
245
- async function KI(e) {
259
+ async function XI(e) {
246
260
  const g = await fetch(e);
247
261
  if (!g.ok)
248
262
  throw new Error(`Failed to fetch image: ${e} (${g.status})`);
249
263
  const C = await g.blob();
250
264
  return createImageBitmap(C);
251
265
  }
252
- const ag = (
266
+ const Zg = (
253
267
  /* glsl */
254
268
  `
255
269
  precision highp float;
@@ -266,7 +280,7 @@ const ag = (
266
280
  gl_Position = vec4(aPosition, 0.0, 1.0);
267
281
  }
268
282
  `
269
- ), CC = (
283
+ ), lC = (
270
284
  /* glsl */
271
285
  `
272
286
  precision highp float;
@@ -283,7 +297,7 @@ const ag = (
283
297
  gl_FragColor = dissipation * texture2D(uSource, coord);
284
298
  }
285
299
  `
286
- ), iC = (
300
+ ), tC = (
287
301
  /* glsl */
288
302
  `
289
303
  precision highp float;
@@ -298,7 +312,7 @@ const ag = (
298
312
  gl_FragColor = vec4(0.5 * (R - L + T - B), 0.0, 0.0, 1.0);
299
313
  }
300
314
  `
301
- ), eC = (
315
+ ), oC = (
302
316
  /* glsl */
303
317
  `
304
318
  precision highp float;
@@ -316,7 +330,7 @@ const ag = (
316
330
  gl_FragColor = vec4((L + R + B + T - div) * 0.25, 0.0, 0.0, 1.0);
317
331
  }
318
332
  `
319
- ), sC = (
333
+ ), AC = (
320
334
  /* glsl */
321
335
  `
322
336
  precision highp float;
@@ -334,7 +348,7 @@ const ag = (
334
348
  gl_FragColor = vec4(vel, 0.0, 1.0);
335
349
  }
336
350
  `
337
- ), tC = (
351
+ ), cC = (
338
352
  /* glsl */
339
353
  `
340
354
  precision highp float;
@@ -351,7 +365,7 @@ const ag = (
351
365
  gl_FragColor = vec4(texture2D(uTarget, vUv).xyz + splat, 1.0);
352
366
  }
353
367
  `
354
- ), lC = (
368
+ ), dC = (
355
369
  /* glsl */
356
370
  `
357
371
  precision highp float;
@@ -365,7 +379,7 @@ const ag = (
365
379
  gl_FragColor = vec4(0.5 * (R - L - T + B), 0.0, 0.0, 1.0);
366
380
  }
367
381
  `
368
- ), oC = (
382
+ ), SC = (
369
383
  /* glsl */
370
384
  `
371
385
  precision highp float;
@@ -386,7 +400,7 @@ const ag = (
386
400
  gl_FragColor = vec4(texture2D(uVelocity, vUv).xy + force * dt, 0.0, 1.0);
387
401
  }
388
402
  `
389
- ), AC = (
403
+ ), aC = (
390
404
  /* glsl */
391
405
  `
392
406
  precision highp float;
@@ -406,6 +420,7 @@ const ag = (
406
420
  uniform float uShine;
407
421
  uniform float uWarpStrength;
408
422
  uniform int uAlgorithm;
423
+ uniform int uEnableAlpha;
409
424
 
410
425
  void main () {
411
426
  float obs = texture2D(uObstacle, vUv).r;
@@ -480,56 +495,60 @@ const ag = (
480
495
  color = mix(color, bg * 0.5, obs * 0.2);
481
496
  }
482
497
 
483
- // Premultiplied alpha transparent where there is neither content nor fluid,
484
- // letting the CSS backgroundColor on the container div show through.
498
+ // Output: premultiplied alpha when transparency is enabled (lets CSS backgroundColor
499
+ // show through), or straight opaque colour when enableAlpha is off (perf mode).
485
500
  float alpha = clamp(max(density * 1.5, coverage), 0.0, 1.0);
486
- gl_FragColor = vec4(color * alpha, alpha);
501
+ if (uEnableAlpha == 1) {
502
+ gl_FragColor = vec4(color * alpha, alpha);
503
+ } else {
504
+ gl_FragColor = vec4(color, 1.0);
505
+ }
487
506
  }
488
507
  `
489
508
  );
490
- function dC(e) {
491
- const g = { alpha: !0, depth: !1, stencil: !1, antialias: !0, preserveDrawingBuffer: !1 };
492
- let C = e.getContext("webgl2", g);
493
- const i = !!C;
494
- i || (C = e.getContext("webgl", g), C.getExtension("EXT_color_buffer_half_float"));
495
- const s = i ? null : C.getExtension("OES_texture_half_float"), t = i ? C.HALF_FLOAT : s.HALF_FLOAT_OES;
496
- return C.getExtension("EXT_color_buffer_float"), C.getExtension("OES_texture_half_float_linear"), {
497
- type: i ? "webgl2" : "webgl1",
498
- gl: C,
499
- isWebGL2: i,
509
+ function ZC(e, g = !0) {
510
+ const C = { alpha: g, depth: !1, stencil: !1, antialias: !0, preserveDrawingBuffer: !1 };
511
+ let i = e.getContext("webgl2", C);
512
+ const s = !!i;
513
+ s || (i = e.getContext("webgl", C), i.getExtension("EXT_color_buffer_half_float"));
514
+ const l = s ? null : i.getExtension("OES_texture_half_float"), t = s ? i.HALF_FLOAT : l.HALF_FLOAT_OES;
515
+ return i.getExtension("EXT_color_buffer_float"), i.getExtension("OES_texture_half_float_linear"), {
516
+ type: s ? "webgl2" : "webgl1",
517
+ gl: i,
518
+ isWebGL2: s,
500
519
  ext: {
501
- internalFormat: i ? C.RGBA16F : C.RGBA,
502
- format: C.RGBA,
520
+ internalFormat: s ? i.RGBA16F : i.RGBA,
521
+ format: i.RGBA,
503
522
  type: t
504
523
  }
505
524
  };
506
525
  }
507
- async function cC(e) {
526
+ async function uC(e, g = !0) {
508
527
  if (typeof navigator > "u" || !navigator.gpu)
509
528
  return null;
510
529
  try {
511
- const g = await navigator.gpu.requestAdapter();
512
- if (!g)
530
+ const C = await navigator.gpu.requestAdapter();
531
+ if (!C)
513
532
  return null;
514
- const C = await g.requestDevice(), i = e.getContext("webgpu");
515
- if (!i)
533
+ const i = await C.requestDevice(), s = e.getContext("webgpu");
534
+ if (!s)
516
535
  return null;
517
- const s = navigator.gpu.getPreferredCanvasFormat();
518
- return i.configure({ device: C, format: s, alphaMode: "premultiplied" }), { type: "webgpu", adapter: g, device: C, context: i, format: s };
536
+ const l = navigator.gpu.getPreferredCanvasFormat();
537
+ return s.configure({ device: i, format: l, alphaMode: g ? "premultiplied" : "opaque" }), { type: "webgpu", adapter: C, device: i, context: s, format: l };
519
538
  } catch {
520
539
  return null;
521
540
  }
522
541
  }
523
- class pg {
542
+ class ug {
524
543
  constructor(g, C, i) {
525
- sI(this, "program");
526
- sI(this, "uniforms", {});
527
- sI(this, "_gl");
544
+ oI(this, "program");
545
+ oI(this, "uniforms", {});
546
+ oI(this, "_gl");
528
547
  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);
529
548
  const s = g.getProgramParameter(this.program, g.ACTIVE_UNIFORMS);
530
- for (let t = 0; t < s; t++) {
531
- const o = g.getActiveUniform(this.program, t).name;
532
- this.uniforms[o] = g.getUniformLocation(this.program, o);
549
+ for (let l = 0; l < s; l++) {
550
+ const t = g.getActiveUniform(this.program, l).name;
551
+ this.uniforms[t] = g.getUniformLocation(this.program, t);
533
552
  }
534
553
  }
535
554
  _compile(g, C) {
@@ -543,49 +562,49 @@ class pg {
543
562
  this._gl.deleteProgram(this.program);
544
563
  }
545
564
  }
546
- function SC(e) {
565
+ function BC(e) {
547
566
  return {
548
- advection: new pg(e, ag, CC),
549
- divergence: new pg(e, ag, iC),
550
- pressure: new pg(e, ag, eC),
551
- gradientSubtract: new pg(e, ag, sC),
552
- splat: new pg(e, ag, tC),
553
- curl: new pg(e, ag, lC),
554
- vorticity: new pg(e, ag, oC),
555
- display: new pg(e, ag, AC)
567
+ advection: new ug(e, Zg, lC),
568
+ divergence: new ug(e, Zg, tC),
569
+ pressure: new ug(e, Zg, oC),
570
+ gradientSubtract: new ug(e, Zg, AC),
571
+ splat: new ug(e, Zg, cC),
572
+ curl: new ug(e, Zg, dC),
573
+ vorticity: new ug(e, Zg, SC),
574
+ display: new ug(e, Zg, aC)
556
575
  };
557
576
  }
558
- function oI(e, g, C, i) {
577
+ function SI(e, g, C, i) {
559
578
  e.activeTexture(e.TEXTURE0);
560
579
  const s = e.createTexture();
561
580
  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);
562
- const t = e.createFramebuffer();
563
- 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 };
581
+ const l = e.createFramebuffer();
582
+ 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 };
564
583
  }
565
- function GI(e, g, C, i) {
566
- let s = oI(e, g, C, i), t = oI(e, g, C, i);
584
+ function bI(e, g, C, i) {
585
+ let s = SI(e, g, C, i), l = SI(e, g, C, i);
567
586
  return {
568
587
  get read() {
569
588
  return s;
570
589
  },
571
590
  get write() {
572
- return t;
591
+ return l;
573
592
  },
574
593
  swap() {
575
- [s, t] = [t, s];
594
+ [s, l] = [l, s];
576
595
  },
577
596
  dispose() {
578
- e.deleteTexture(s.tex), e.deleteFramebuffer(s.fbo), e.deleteTexture(t.tex), e.deleteFramebuffer(t.fbo);
597
+ e.deleteTexture(s.tex), e.deleteFramebuffer(s.fbo), e.deleteTexture(l.tex), e.deleteFramebuffer(l.fbo);
579
598
  }
580
599
  };
581
600
  }
582
- function aC(e) {
601
+ function nC(e) {
583
602
  const g = e.createBuffer();
584
603
  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) {
585
604
  e.bindFramebuffer(e.FRAMEBUFFER, i), e.drawArrays(e.TRIANGLE_FAN, 0, 4);
586
605
  };
587
606
  }
588
- const wg = (
607
+ const bg = (
589
608
  /* wgsl */
590
609
  `
591
610
  struct VSOut {
@@ -596,10 +615,10 @@ struct VSOut {
596
615
  @location(3) vT : vec2f,
597
616
  @location(4) vB : vec2f,
598
617
  }`
599
- ), pC = (
618
+ ), mC = (
600
619
  /* wgsl */
601
620
  `
602
- ${wg}
621
+ ${bg}
603
622
 
604
623
  struct U {
605
624
  texelSize : vec2f,
@@ -633,10 +652,10 @@ struct U {
633
652
  return u.dissipation * src;
634
653
  }
635
654
  `
636
- ), uC = (
655
+ ), GC = (
637
656
  /* wgsl */
638
657
  `
639
- ${wg}
658
+ ${bg}
640
659
 
641
660
  struct U { texelSize: vec2f, _pad: vec2f }
642
661
  @group(0) @binding(0) var<uniform> u : U;
@@ -663,10 +682,10 @@ struct U { texelSize: vec2f, _pad: vec2f }
663
682
  return vec4f(0.5 * (R - L + T - B), 0.0, 0.0, 1.0);
664
683
  }
665
684
  `
666
- ), BC = (
685
+ ), pC = (
667
686
  /* wgsl */
668
687
  `
669
- ${wg}
688
+ ${bg}
670
689
 
671
690
  struct U { texelSize: vec2f, _pad: vec2f }
672
691
  @group(0) @binding(0) var<uniform> u : U;
@@ -696,10 +715,10 @@ struct U { texelSize: vec2f, _pad: vec2f }
696
715
  return vec4f((L + R + B + T - dv) * 0.25, 0.0, 0.0, 1.0);
697
716
  }
698
717
  `
699
- ), ZC = (
718
+ ), rC = (
700
719
  /* wgsl */
701
720
  `
702
- ${wg}
721
+ ${bg}
703
722
 
704
723
  struct U { texelSize: vec2f, _pad: vec2f }
705
724
  @group(0) @binding(0) var<uniform> u : U;
@@ -731,10 +750,10 @@ struct U { texelSize: vec2f, _pad: vec2f }
731
750
  return vec4f(vel, 0.0, 1.0);
732
751
  }
733
752
  `
734
- ), mC = (
753
+ ), wC = (
735
754
  /* wgsl */
736
755
  `
737
- ${wg}
756
+ ${bg}
738
757
 
739
758
  // texelSize occupies bytes 0-7 for the shared vertex stage; aspectRatio/radius fill the rest.
740
759
  struct U {
@@ -767,10 +786,10 @@ struct U {
767
786
  return vec4f(textureSample(uTgt, samp, i.uv).xyz + sp, 1.0);
768
787
  }
769
788
  `
770
- ), nC = (
789
+ ), LC = (
771
790
  /* wgsl */
772
791
  `
773
- ${wg}
792
+ ${bg}
774
793
 
775
794
  struct U { texelSize: vec2f, _pad: vec2f }
776
795
  @group(0) @binding(0) var<uniform> u : U;
@@ -796,10 +815,10 @@ struct U { texelSize: vec2f, _pad: vec2f }
796
815
  return vec4f(0.5 * (R - L - T + B), 0.0, 0.0, 1.0);
797
816
  }
798
817
  `
799
- ), GC = (
818
+ ), bC = (
800
819
  /* wgsl */
801
820
  `
802
- ${wg}
821
+ ${bg}
803
822
 
804
823
  struct U {
805
824
  texelSize: vec2f,
@@ -835,10 +854,10 @@ struct U {
835
854
  return vec4f(vel, 0.0, 1.0);
836
855
  }
837
856
  `
838
- ), rC = (
857
+ ), hC = (
839
858
  /* wgsl */
840
859
  `
841
- ${wg}
860
+ ${bg}
842
861
 
843
862
  struct U {
844
863
  texelSize : vec2f,
@@ -849,7 +868,7 @@ struct U {
849
868
  shine : f32,
850
869
  warpStrength: f32,
851
870
  algorithm : i32,
852
- _pad : f32,
871
+ enableAlpha : i32,
853
872
  }
854
873
  @group(0) @binding(0) var<uniform> u : U;
855
874
  @group(0) @binding(1) var samp : sampler;
@@ -929,13 +948,16 @@ struct U {
929
948
  }
930
949
 
931
950
  let alpha = clamp(max(density * 1.5, cov), 0.0, 1.0);
932
- return vec4f(color * alpha, alpha);
951
+ if (u.enableAlpha == 1) {
952
+ return vec4f(color * alpha, alpha);
953
+ }
954
+ return vec4f(color, 1.0);
933
955
  }
934
956
  `
935
- ), LC = {
957
+ ), KC = {
936
958
  arrayStride: 8,
937
959
  attributes: [{ shaderLocation: 0, offset: 0, format: "float32x2" }]
938
- }, XI = new Float32Array([
960
+ }, WI = new Float32Array([
939
961
  -1,
940
962
  -1,
941
963
  -1,
@@ -949,11 +971,11 @@ struct U {
949
971
  1,
950
972
  1
951
973
  ]);
952
- function wC(e) {
953
- const g = e.createBuffer({ size: XI.byteLength, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST });
954
- return e.queue.writeBuffer(g, 0, XI), g;
974
+ function VC(e) {
975
+ const g = e.createBuffer({ size: WI.byteLength, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST });
976
+ return e.queue.writeBuffer(g, 0, WI), g;
955
977
  }
956
- function AI(e, g, C, i) {
978
+ function aI(e, g, C, i) {
957
979
  const s = e.createTexture({
958
980
  size: [C, i],
959
981
  format: g,
@@ -961,73 +983,77 @@ function AI(e, g, C, i) {
961
983
  });
962
984
  return { tex: s, view: s.createView(), width: C, height: i };
963
985
  }
964
- function rI(e, g, C, i) {
965
- let s = AI(e, g, C, i), t = AI(e, g, C, i);
986
+ function hI(e, g, C, i) {
987
+ let s = aI(e, g, C, i), l = aI(e, g, C, i);
966
988
  return {
967
989
  get read() {
968
990
  return s;
969
991
  },
970
992
  get write() {
971
- return t;
993
+ return l;
972
994
  },
973
995
  swap() {
974
- [s, t] = [t, s];
996
+ [s, l] = [l, s];
975
997
  },
976
998
  dispose() {
977
- s.tex.destroy(), t.tex.destroy();
999
+ s.tex.destroy(), l.tex.destroy();
978
1000
  }
979
1001
  };
980
1002
  }
981
- function ug(e, g, C) {
982
- const i = e.createShaderModule({ code: g });
1003
+ function Bg(e, g, C, i) {
1004
+ const s = e.createShaderModule({ code: g });
983
1005
  return e.createRenderPipeline({
984
1006
  layout: "auto",
985
- vertex: { module: i, entryPoint: "vs", buffers: [LC] },
986
- fragment: { module: i, entryPoint: "fs", targets: [{ format: C }] },
1007
+ vertex: { module: s, entryPoint: "vs", buffers: [KC] },
1008
+ fragment: { module: s, entryPoint: "fs", targets: [{ format: C, ...i ? { blend: i } : {} }] },
987
1009
  primitive: { topology: "triangle-list" }
988
1010
  });
989
1011
  }
990
- function bC(e, g) {
991
- const C = "rgba16float";
1012
+ const yC = {
1013
+ color: { operation: "add", srcFactor: "one", dstFactor: "zero" },
1014
+ alpha: { operation: "add", srcFactor: "one", dstFactor: "zero" }
1015
+ };
1016
+ function HC(e, g, C = !0) {
1017
+ const i = "rgba16float";
992
1018
  return {
993
- advection: ug(e, pC, C),
994
- divergence: ug(e, uC, C),
995
- pressure: ug(e, BC, C),
996
- gradientSubtract: ug(e, ZC, C),
997
- splat: ug(e, mC, C),
998
- curl: ug(e, nC, C),
999
- vorticity: ug(e, GC, C),
1000
- display: ug(e, rC, g)
1019
+ advection: Bg(e, mC, i),
1020
+ divergence: Bg(e, GC, i),
1021
+ pressure: Bg(e, pC, i),
1022
+ gradientSubtract: Bg(e, rC, i),
1023
+ splat: Bg(e, wC, i),
1024
+ curl: Bg(e, LC, i),
1025
+ vorticity: Bg(e, bC, i),
1026
+ display: Bg(e, hC, g, C ? void 0 : yC)
1001
1027
  };
1002
1028
  }
1003
- function hC(e) {
1029
+ function XC(e) {
1004
1030
  return e.createSampler({ magFilter: "linear", minFilter: "linear", addressModeU: "clamp-to-edge", addressModeV: "clamp-to-edge" });
1005
1031
  }
1006
- function _(e, g) {
1032
+ function q(e, g) {
1007
1033
  return e.createBuffer({ size: g, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST });
1008
1034
  }
1009
- function RI(e, g, C, i, s, t) {
1010
- const o = new Float32Array([C, i, s, t]);
1011
- e.queue.writeBuffer(g, 0, o);
1035
+ function YI(e, g, C, i, s, l) {
1036
+ const t = new Float32Array([C, i, s, l]);
1037
+ e.queue.writeBuffer(g, 0, t);
1012
1038
  }
1013
- function tI(e, g, C, i) {
1039
+ function cI(e, g, C, i) {
1014
1040
  const s = new Float32Array([C, i, 0, 0]);
1015
1041
  e.queue.writeBuffer(g, 0, s);
1016
1042
  }
1017
- function KC(e, g, C, i, s, t) {
1018
- const o = new Float32Array([C, i, s, t]);
1019
- e.queue.writeBuffer(g, 0, o);
1043
+ function vC(e, g, C, i, s, l) {
1044
+ const t = new Float32Array([C, i, s, l]);
1045
+ e.queue.writeBuffer(g, 0, t);
1020
1046
  }
1021
- function lI(e, g, C, i, s, t, o, a, u, A, p) {
1022
- const c = new Float32Array(12);
1023
- c[0] = C, c[1] = i, c[2] = s, c[3] = t, c[4] = o, c[5] = a, c[6] = u, c[7] = 0, c[8] = A, c[9] = p, c[10] = 0, c[11] = 0, e.queue.writeBuffer(g, 0, c);
1047
+ function dI(e, g, C, i, s, l, t, a, u, c, Z) {
1048
+ const S = new Float32Array(12);
1049
+ S[0] = C, S[1] = i, S[2] = s, S[3] = l, S[4] = t, S[5] = a, S[6] = u, S[7] = 0, S[8] = c, S[9] = Z, S[10] = 0, S[11] = 0, e.queue.writeBuffer(g, 0, S);
1024
1050
  }
1025
- function yC(e, g, C, i, s, t, o, a, u, A, p) {
1026
- const c = new Float32Array(16), d = new Int32Array(c.buffer);
1027
- c[0] = C, c[1] = i, c[2] = s, c[3] = t, c[4] = o[0], c[5] = o[1], c[6] = o[2], c[7] = 0, c[8] = a[0], c[9] = a[1], c[10] = a[2], c[11] = 0, c[12] = u, c[13] = A, d[14] = p, e.queue.writeBuffer(g, 0, c);
1051
+ function RC(e, g, C, i, s, l, t, a, u, c, Z, S) {
1052
+ const A = new Float32Array(16), B = new Int32Array(A.buffer);
1053
+ 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] = a[0], A[9] = a[1], A[10] = a[2], A[11] = 0, A[12] = u, A[13] = c, B[14] = Z, B[15] = S ? 1 : 0, e.queue.writeBuffer(g, 0, A);
1028
1054
  }
1029
- function N(e, g, C, i, s) {
1030
- const t = e.beginRenderPass({
1055
+ function Q(e, g, C, i, s) {
1056
+ const l = e.beginRenderPass({
1031
1057
  colorAttachments: [{
1032
1058
  view: s,
1033
1059
  clearValue: [0, 0, 0, 0],
@@ -1035,10 +1061,10 @@ function N(e, g, C, i, s) {
1035
1061
  storeOp: "store"
1036
1062
  }]
1037
1063
  });
1038
- t.setPipeline(g), t.setBindGroup(0, C), t.setVertexBuffer(0, i), t.draw(6), t.end();
1064
+ l.setPipeline(g), l.setBindGroup(0, C), l.setVertexBuffer(0, i), l.draw(6), l.end();
1039
1065
  }
1040
- function VC(e, g, C, i, s) {
1041
- const t = e.beginRenderPass({
1066
+ function UC(e, g, C, i, s) {
1067
+ const l = e.beginRenderPass({
1042
1068
  colorAttachments: [{
1043
1069
  view: s,
1044
1070
  clearValue: [0, 0, 0, 0],
@@ -1046,147 +1072,148 @@ function VC(e, g, C, i, s) {
1046
1072
  storeOp: "store"
1047
1073
  }]
1048
1074
  });
1049
- t.setPipeline(g), t.setBindGroup(0, C), t.setVertexBuffer(0, i), t.draw(6), t.end();
1075
+ l.setPipeline(g), l.setBindGroup(0, C), l.setVertexBuffer(0, i), l.draw(6), l.end();
1050
1076
  }
1051
- const vI = typeof requestAnimationFrame < "u" ? requestAnimationFrame.bind(globalThis) : (e) => setTimeout(e, 1e3 / 60), HC = typeof cancelAnimationFrame < "u" ? cancelAnimationFrame.bind(globalThis) : clearTimeout, Og = 0.016, WI = { standard: 0, glass: 1, ink: 2, aurora: 3, ripple: 4 };
1052
- var bg, Q, $g, hg, Fg, x, H, q, $, gg, sg, T, Ig, F, Dg, Kg, Tg, f, y, Zg, Cg, mg, z, yg, Vg, Hg, Xg, Rg, tg, lg, vg, Wg, Yg, V, X, O, E, D, Jg, og, J, ng, Ag, L, k, ig, Ug, gI, cI, MI, kg, Eg, II, LI, Gg, fg, xg, jg, CI, wI, iI, bI, SI, FI, aI, DI, pI, TI, uI, JI, BI, zI;
1053
- const yI = class yI {
1077
+ const kI = typeof requestAnimationFrame < "u" ? requestAnimationFrame.bind(globalThis) : (e) => setTimeout(e, 1e3 / 60), WC = typeof cancelAnimationFrame < "u" ? cancelAnimationFrame.bind(globalThis) : clearTimeout, Pg = 0.016, MI = { standard: 0, glass: 1, ink: 2, aurora: 3, ripple: 4 };
1078
+ var hg, O, CI, Kg, Jg, M, X, $, gg, Ig, lg, J, Cg, D, zg, Vg, Ng, f, y, mg, ig, Gg, N, yg, Hg, Xg, vg, Rg, tg, og, Ug, Wg, Yg, H, v, E, j, T, Qg, Ag, z, pg, cg, w, k, eg, kg, iI, Mg, uI, JI, fg, _g, eI, KI, rg, Dg, xg, qg, sI, VI, lI, yI, BI, zI, nI, NI, mI, QI, GI, OI, pI, EI;
1079
+ const vI = class vI {
1054
1080
  // ── Constructor ─────────────────────────────────────────────────────────────
1055
- constructor(g, C = {}, i = {}, s) {
1081
+ constructor(g, C = {}, i = {}, s, l = !0) {
1056
1082
  // ---------------------------------------------------------------------------
1057
1083
  // Private — GPU initialisation
1058
1084
  // ---------------------------------------------------------------------------
1059
- S(this, cI);
1085
+ d(this, uI);
1060
1086
  // ---------------------------------------------------------------------------
1061
1087
  // Private — shared helpers
1062
1088
  // ---------------------------------------------------------------------------
1063
- S(this, kg);
1064
- S(this, II);
1065
- S(this, Gg);
1066
- S(this, xg);
1067
- S(this, CI);
1068
- S(this, iI);
1089
+ d(this, fg);
1090
+ d(this, eI);
1091
+ d(this, rg);
1092
+ d(this, xg);
1093
+ d(this, sI);
1094
+ d(this, lI);
1069
1095
  // ---------------------------------------------------------------------------
1070
1096
  // Private — frame dispatch
1071
1097
  // ---------------------------------------------------------------------------
1072
- S(this, SI);
1098
+ d(this, BI);
1073
1099
  // ---------------------------------------------------------------------------
1074
1100
  // Private — WebGPU simulation step
1075
1101
  // ---------------------------------------------------------------------------
1076
- S(this, aI);
1102
+ d(this, nI);
1077
1103
  // ---------------------------------------------------------------------------
1078
1104
  // Private — WebGPU direct splat
1079
1105
  // ---------------------------------------------------------------------------
1080
- S(this, pI);
1106
+ d(this, mI);
1081
1107
  // ---------------------------------------------------------------------------
1082
1108
  // Private — WebGL splat
1083
1109
  // ---------------------------------------------------------------------------
1084
- S(this, uI);
1110
+ d(this, GI);
1085
1111
  // ---------------------------------------------------------------------------
1086
1112
  // Private — WebGL simulation step (unchanged from original)
1087
1113
  // ---------------------------------------------------------------------------
1088
- S(this, BI);
1089
- S(this, bg, void 0);
1114
+ d(this, pI);
1115
+ d(this, hg, void 0);
1090
1116
  // ── WebGL path ──────────────────────────────────────────────────────────────
1091
- S(this, Q, null);
1092
- S(this, $g, null);
1093
- S(this, hg, null);
1094
- S(this, Fg, null);
1095
- S(this, x, null);
1096
- S(this, H, null);
1097
- S(this, q, null);
1098
- S(this, $, null);
1099
- S(this, gg, null);
1100
- S(this, sg, null);
1101
- S(this, T, null);
1102
- S(this, Ig, null);
1117
+ d(this, O, null);
1118
+ d(this, CI, null);
1119
+ d(this, Kg, null);
1120
+ d(this, Jg, null);
1121
+ d(this, M, null);
1122
+ d(this, X, null);
1123
+ d(this, $, null);
1124
+ d(this, gg, null);
1125
+ d(this, Ig, null);
1126
+ d(this, lg, null);
1127
+ d(this, J, null);
1128
+ d(this, Cg, null);
1103
1129
  // ── WebGPU path ─────────────────────────────────────────────────────────────
1104
- S(this, F, null);
1105
- S(this, Dg, null);
1106
- S(this, Kg, null);
1107
- S(this, Tg, null);
1108
- S(this, f, null);
1109
- S(this, y, null);
1110
- S(this, Zg, null);
1111
- S(this, Cg, null);
1112
- S(this, mg, null);
1113
- S(this, z, null);
1130
+ d(this, D, null);
1131
+ d(this, zg, null);
1132
+ d(this, Vg, null);
1133
+ d(this, Ng, null);
1134
+ d(this, f, null);
1135
+ d(this, y, null);
1136
+ d(this, mg, null);
1137
+ d(this, ig, null);
1138
+ d(this, Gg, null);
1139
+ d(this, N, null);
1114
1140
  // Pre-allocated uniform buffers (sizes: see gpu-utils writeXxx docs)
1115
1141
  // Velocity/density advection use separate buffers — writeBuffer is a queue op;
1116
1142
  // a second write to the same buffer before queue.submit() aliases both passes.
1117
- S(this, yg, null);
1143
+ d(this, yg, null);
1118
1144
  // 16 bytes — velocity advection
1119
- S(this, Vg, null);
1145
+ d(this, Hg, null);
1120
1146
  // 16 bytes — density advection
1121
- S(this, Hg, null);
1147
+ d(this, Xg, null);
1122
1148
  // 16 bytes
1123
- S(this, Xg, null);
1149
+ d(this, vg, null);
1124
1150
  // 16 bytes
1125
- S(this, Rg, null);
1151
+ d(this, Rg, null);
1126
1152
  // 16 bytes
1127
- S(this, tg, null);
1153
+ d(this, tg, null);
1128
1154
  // 48 bytes — velocity splat
1129
- S(this, lg, null);
1155
+ d(this, og, null);
1130
1156
  // 48 bytes — density splat
1131
- S(this, vg, null);
1157
+ d(this, Ug, null);
1132
1158
  // 16 bytes
1133
- S(this, Wg, null);
1159
+ d(this, Wg, null);
1134
1160
  // 16 bytes
1135
- S(this, Yg, null);
1161
+ d(this, Yg, null);
1136
1162
  // 64 bytes
1137
1163
  // ── Shared state ────────────────────────────────────────────────────────────
1138
- S(this, V, 0);
1139
- S(this, X, 0);
1140
- S(this, O, 0);
1141
- S(this, E, 0);
1142
- S(this, D, 1);
1143
- S(this, Jg, 1);
1144
- S(this, og, 0.5);
1145
- S(this, J, null);
1146
- S(this, ng, "cover");
1147
- S(this, Ag, void 0);
1148
- S(this, L, { x: 0, y: 0, dx: 0, dy: 0, targetX: 0, targetY: 0, moved: !1 });
1149
- S(this, k, null);
1150
- S(this, ig, null);
1151
- S(this, Ug, !1);
1152
- S(this, gI, !1);
1153
- if (l(this, bg, g), l(this, Jg, Math.max(0.1, Math.min(1, i.dpr ?? 1))), l(this, og, Math.max(0.1, Math.min(1, i.sim ?? 0.5))), l(this, Ag, qg(C)), s)
1154
- l(this, F, s), h(this, cI, MI).call(this, s);
1164
+ d(this, H, 0);
1165
+ d(this, v, 0);
1166
+ d(this, E, 0);
1167
+ d(this, j, 0);
1168
+ d(this, T, 1);
1169
+ d(this, Qg, 1);
1170
+ d(this, Ag, 0.5);
1171
+ d(this, z, null);
1172
+ d(this, pg, "cover");
1173
+ d(this, cg, void 0);
1174
+ d(this, w, { x: 0, y: 0, dx: 0, dy: 0, targetX: 0, targetY: 0, moved: !1 });
1175
+ d(this, k, null);
1176
+ d(this, eg, null);
1177
+ d(this, kg, !1);
1178
+ d(this, iI, !1);
1179
+ d(this, Mg, !0);
1180
+ if (o(this, hg, g), o(this, Qg, 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, cg, II(C)), o(this, Mg, l), s)
1181
+ o(this, D, s), h(this, uI, JI).call(this, s);
1155
1182
  else {
1156
- const { gl: t, ext: o } = dC(g);
1157
- l(this, Q, t), l(this, $g, o), l(this, hg, SC(t)), l(this, Fg, aC(t)), t.clearColor(0, 0, 0, 0);
1183
+ const { gl: t, ext: a } = ZC(g, l);
1184
+ o(this, O, t), o(this, CI, a), o(this, Kg, BC(t)), o(this, Jg, nC(t)), t.clearColor(0, 0, 0, l ? 0 : 1);
1158
1185
  }
1159
1186
  }
1160
1187
  /**
1161
1188
  * WebGPU-first factory. Tries WebGPU, falls back to WebGL2 → WebGL1.
1162
1189
  * This is the recommended entry point when WebGPU support is desired.
1163
1190
  */
1164
- static async create(g, C = {}, i = {}, s = !0) {
1165
- const t = s ? await cC(g) : null;
1166
- return new yI(g, C, i, t ?? void 0);
1191
+ static async create(g, C = {}, i = {}, s = !0, l = !0) {
1192
+ const t = s ? await uC(g, l) : null;
1193
+ return new vI(g, C, i, t ?? void 0, l);
1167
1194
  }
1168
1195
  // ---------------------------------------------------------------------------
1169
1196
  // Public API
1170
1197
  // ---------------------------------------------------------------------------
1171
1198
  setTextSource(g) {
1172
- l(this, k, { type: "text", opts: g }), h(this, kg, Eg).call(this), h(this, Gg, fg).call(this), h(this, xg, jg).call(this);
1199
+ o(this, k, { type: "text", opts: g }), h(this, fg, _g).call(this), h(this, rg, Dg).call(this), h(this, xg, qg).call(this);
1173
1200
  }
1174
1201
  async setImageSource(g, C = 0, i = "cover") {
1175
- const s = await KI(g);
1176
- if (I(this, gI)) {
1202
+ const s = await XI(g);
1203
+ if (I(this, iI)) {
1177
1204
  s.close();
1178
1205
  return;
1179
1206
  }
1180
- l(this, k, { type: "image", bitmap: s, effect: C, size: i }), h(this, kg, Eg).call(this), h(this, Gg, fg).call(this), h(this, xg, jg).call(this);
1207
+ o(this, k, { type: "image", bitmap: s, effect: C, size: i }), h(this, fg, _g).call(this), h(this, rg, Dg).call(this), h(this, xg, qg).call(this);
1181
1208
  }
1182
1209
  setImageBitmap(g, C = 0, i = "cover") {
1183
- l(this, k, { type: "image", bitmap: g, effect: C, size: i }), h(this, kg, Eg).call(this), h(this, Gg, fg).call(this), h(this, xg, jg).call(this);
1210
+ o(this, k, { type: "image", bitmap: g, effect: C, size: i }), h(this, fg, _g).call(this), h(this, rg, Dg).call(this), h(this, xg, qg).call(this);
1184
1211
  }
1185
1212
  setBackground(g, C = "cover") {
1186
- I(this, J) && I(this, J) !== g && I(this, J).close(), l(this, J, g), l(this, ng, C ?? "cover"), I(this, k) && I(this, V) > 0 && I(this, X) > 0 && h(this, Gg, fg).call(this);
1213
+ I(this, z) && I(this, z) !== g && I(this, z).close(), o(this, z, g), o(this, pg, C ?? "cover"), I(this, k) && I(this, H) > 0 && I(this, v) > 0 && h(this, rg, Dg).call(this);
1187
1214
  }
1188
1215
  handleMove(g, C, i = 1) {
1189
- 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;
1216
+ 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;
1190
1217
  }
1191
1218
  /**
1192
1219
  * Immediately applies one fluid splat at (x, y) with explicit velocity (vx, vy).
@@ -1195,365 +1222,367 @@ const yI = class yI {
1195
1222
  * where you want N independent injection points per frame without flooding the
1196
1223
  * mouse-state machine or the worker message queue.
1197
1224
  */
1198
- splat(g, C, i, s, t = 1) {
1199
- !I(this, Ug) || I(this, V) === 0 || (I(this, F) ? h(this, pI, TI).call(this, g, C, i, s, t) : h(this, uI, JI).call(this, g, C, i, s, t));
1225
+ splat(g, C, i, s, l = 1) {
1226
+ !I(this, kg) || I(this, H) === 0 || (I(this, D) ? h(this, mI, QI).call(this, g, C, i, s, l) : h(this, GI, OI).call(this, g, C, i, s, l));
1200
1227
  }
1201
1228
  updateQuality(g) {
1202
- g.dpr !== void 0 && l(this, Jg, Math.max(0.1, Math.min(1, g.dpr))), g.sim !== void 0 && l(this, og, Math.max(0.1, Math.min(1, g.sim)));
1229
+ g.dpr !== void 0 && o(this, Qg, 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)));
1203
1230
  }
1204
1231
  resize(g, C, i) {
1205
- if (i !== void 0 ? l(this, D, i) : typeof window < "u" && window.devicePixelRatio && l(this, D, window.devicePixelRatio), g !== void 0 && g > 0) {
1232
+ if (i !== void 0 ? o(this, T, i) : typeof window < "u" && window.devicePixelRatio && o(this, T, window.devicePixelRatio), g !== void 0 && g > 0) {
1206
1233
  if (C === void 0 || C <= 0)
1207
1234
  return;
1208
- l(this, V, I(this, bg).width = g), l(this, X, I(this, bg).height = C), l(this, O, Math.max(1, Math.round(g * I(this, og)))), l(this, E, Math.max(1, Math.round(C * I(this, og)))), h(this, II, LI).call(this);
1235
+ o(this, H, I(this, hg).width = g), o(this, v, I(this, hg).height = C), o(this, E, Math.max(1, Math.round(g * I(this, Ag)))), o(this, j, Math.max(1, Math.round(C * I(this, Ag)))), h(this, eI, KI).call(this);
1209
1236
  } else
1210
- h(this, kg, Eg).call(this);
1211
- I(this, k) && h(this, Gg, fg).call(this), h(this, xg, jg).call(this);
1237
+ h(this, fg, _g).call(this);
1238
+ I(this, k) && h(this, rg, Dg).call(this), h(this, xg, qg).call(this);
1212
1239
  }
1213
1240
  updateConfig(g) {
1214
- Object.assign(I(this, Ag), g);
1241
+ Object.assign(I(this, cg), g);
1215
1242
  }
1216
1243
  destroy() {
1217
- var g, C, i, s, t, o, a, u, A, p, c;
1218
- if (l(this, gI, !0), this.stop(), h(this, CI, wI).call(this), h(this, iI, bI).call(this), I(this, J) && (I(this, J).close(), l(this, J, null)), I(this, F))
1219
- (g = I(this, yg)) == null || g.destroy(), (C = I(this, Vg)) == null || C.destroy(), (i = I(this, Hg)) == null || i.destroy(), (s = I(this, Xg)) == null || s.destroy(), (t = I(this, Rg)) == null || t.destroy(), (o = I(this, tg)) == null || o.destroy(), (a = I(this, lg)) == null || a.destroy(), (u = I(this, vg)) == null || u.destroy(), (A = I(this, Wg)) == null || A.destroy(), (p = I(this, Yg)) == null || p.destroy(), (c = I(this, Kg)) == null || c.destroy(), I(this, F).device.destroy();
1244
+ var g, C, i, s, l, t, a, u, c, Z, S;
1245
+ if (o(this, iI, !0), this.stop(), h(this, sI, VI).call(this), h(this, lI, yI).call(this), I(this, z) && (I(this, z).close(), o(this, z, null)), I(this, D))
1246
+ (g = I(this, yg)) == null || g.destroy(), (C = I(this, Hg)) == null || C.destroy(), (i = I(this, Xg)) == null || i.destroy(), (s = I(this, vg)) == null || s.destroy(), (l = I(this, Rg)) == null || l.destroy(), (t = I(this, tg)) == null || t.destroy(), (a = I(this, og)) == null || a.destroy(), (u = I(this, Ug)) == null || u.destroy(), (c = I(this, Wg)) == null || c.destroy(), (Z = I(this, Yg)) == null || Z.destroy(), (S = I(this, Vg)) == null || S.destroy(), I(this, D).device.destroy();
1220
1247
  else {
1221
- const d = I(this, Q);
1222
- for (const m of Object.values(I(this, hg)))
1248
+ const A = I(this, O);
1249
+ for (const m of Object.values(I(this, Kg)))
1223
1250
  m.dispose();
1224
- const Z = d.getExtension("WEBGL_lose_context");
1225
- Z == null || Z.loseContext();
1251
+ const B = A.getExtension("WEBGL_lose_context");
1252
+ B == null || B.loseContext();
1226
1253
  }
1227
1254
  }
1228
1255
  // ---------------------------------------------------------------------------
1229
1256
  // Loop control
1230
1257
  // ---------------------------------------------------------------------------
1231
1258
  start() {
1232
- if (I(this, ig) !== null)
1259
+ if (I(this, eg) !== null)
1233
1260
  return;
1234
1261
  const g = () => {
1235
- h(this, SI, FI).call(this), l(this, ig, vI(g));
1262
+ h(this, BI, zI).call(this), o(this, eg, kI(g));
1236
1263
  };
1237
- l(this, ig, vI(g));
1264
+ o(this, eg, kI(g));
1238
1265
  }
1239
1266
  stop() {
1240
- I(this, ig) !== null && (HC(I(this, ig)), l(this, ig, null));
1267
+ I(this, eg) !== null && (WC(I(this, eg)), o(this, eg, null));
1241
1268
  }
1242
1269
  get isRunning() {
1243
- return I(this, ig) !== null;
1270
+ return I(this, eg) !== null;
1244
1271
  }
1245
1272
  };
1246
- bg = new WeakMap(), Q = new WeakMap(), $g = new WeakMap(), hg = new WeakMap(), Fg = new WeakMap(), x = new WeakMap(), H = new WeakMap(), q = new WeakMap(), $ = new WeakMap(), gg = new WeakMap(), sg = new WeakMap(), T = new WeakMap(), Ig = new WeakMap(), F = new WeakMap(), Dg = new WeakMap(), Kg = new WeakMap(), Tg = new WeakMap(), f = new WeakMap(), y = new WeakMap(), Zg = new WeakMap(), Cg = new WeakMap(), mg = new WeakMap(), z = new WeakMap(), yg = new WeakMap(), Vg = new WeakMap(), Hg = new WeakMap(), Xg = new WeakMap(), Rg = new WeakMap(), tg = new WeakMap(), lg = new WeakMap(), vg = new WeakMap(), Wg = new WeakMap(), Yg = new WeakMap(), V = new WeakMap(), X = new WeakMap(), O = new WeakMap(), E = new WeakMap(), D = new WeakMap(), Jg = new WeakMap(), og = new WeakMap(), J = new WeakMap(), ng = new WeakMap(), Ag = new WeakMap(), L = new WeakMap(), k = new WeakMap(), ig = new WeakMap(), Ug = new WeakMap(), gI = new WeakMap(), cI = new WeakSet(), MI = function(g) {
1273
+ hg = new WeakMap(), O = new WeakMap(), CI = new WeakMap(), Kg = new WeakMap(), Jg = new WeakMap(), M = new WeakMap(), X = new WeakMap(), $ = new WeakMap(), gg = new WeakMap(), Ig = new WeakMap(), lg = new WeakMap(), J = new WeakMap(), Cg = new WeakMap(), D = new WeakMap(), zg = new WeakMap(), Vg = new WeakMap(), Ng = new WeakMap(), f = new WeakMap(), y = new WeakMap(), mg = new WeakMap(), ig = new WeakMap(), Gg = new WeakMap(), N = new WeakMap(), yg = new WeakMap(), Hg = new WeakMap(), Xg = new WeakMap(), vg = new WeakMap(), Rg = new WeakMap(), tg = new WeakMap(), og = new WeakMap(), Ug = new WeakMap(), Wg = new WeakMap(), Yg = new WeakMap(), H = new WeakMap(), v = new WeakMap(), E = new WeakMap(), j = new WeakMap(), T = new WeakMap(), Qg = new WeakMap(), Ag = new WeakMap(), z = new WeakMap(), pg = new WeakMap(), cg = new WeakMap(), w = new WeakMap(), k = new WeakMap(), eg = new WeakMap(), kg = new WeakMap(), iI = new WeakMap(), Mg = new WeakMap(), uI = new WeakSet(), JI = function(g) {
1247
1274
  const { device: C, format: i } = g;
1248
- l(this, Dg, bC(C, i)), l(this, Kg, wC(C)), l(this, Tg, hC(C)), l(this, yg, _(C, 16)), l(this, Vg, _(C, 16)), l(this, Hg, _(C, 16)), l(this, Xg, _(C, 16)), l(this, Rg, _(C, 16)), l(this, tg, _(C, 48)), l(this, lg, _(C, 48)), l(this, vg, _(C, 16)), l(this, Wg, _(C, 16)), l(this, Yg, _(C, 64));
1249
- }, kg = new WeakSet(), Eg = function() {
1250
- const g = I(this, bg);
1251
- "clientWidth" in g && g.clientWidth > 0 ? (l(this, D, (typeof window < "u" && window.devicePixelRatio || 1) * I(this, Jg)), l(this, V, g.width = Math.round(g.clientWidth * I(this, D))), l(this, X, g.height = Math.round(g.clientHeight * I(this, D)))) : (l(this, V, g.width), l(this, X, g.height)), !(I(this, V) === 0 || I(this, X) === 0) && (l(this, O, Math.max(1, Math.round(I(this, V) * I(this, og)))), l(this, E, Math.max(1, Math.round(I(this, X) * I(this, og)))), h(this, II, LI).call(this));
1252
- }, II = new WeakSet(), LI = function() {
1253
- if (h(this, CI, wI).call(this), I(this, F)) {
1254
- const { device: g } = I(this, F), C = "rgba16float", i = I(this, O), s = I(this, E);
1255
- l(this, f, rI(g, C, i, s)), l(this, y, rI(g, C, i, s)), l(this, Cg, rI(g, C, i, s)), l(this, Zg, AI(g, C, i, s)), l(this, mg, AI(g, C, i, s));
1275
+ o(this, zg, HC(C, i, I(this, Mg))), o(this, Vg, VC(C)), o(this, Ng, XC(C)), o(this, yg, q(C, 16)), o(this, Hg, q(C, 16)), o(this, Xg, q(C, 16)), o(this, vg, q(C, 16)), o(this, Rg, q(C, 16)), o(this, tg, q(C, 48)), o(this, og, q(C, 48)), o(this, Ug, q(C, 16)), o(this, Wg, q(C, 16)), o(this, Yg, q(C, 64));
1276
+ }, fg = new WeakSet(), _g = function() {
1277
+ const g = I(this, hg);
1278
+ "clientWidth" in g && g.clientWidth > 0 ? (o(this, T, (typeof window < "u" && window.devicePixelRatio || 1) * I(this, Qg)), o(this, H, g.width = Math.round(g.clientWidth * I(this, T))), o(this, v, g.height = Math.round(g.clientHeight * I(this, T)))) : (o(this, H, g.width), o(this, v, g.height)), !(I(this, H) === 0 || I(this, v) === 0) && (o(this, E, Math.max(1, Math.round(I(this, H) * I(this, Ag)))), o(this, j, Math.max(1, Math.round(I(this, v) * I(this, Ag)))), h(this, eI, KI).call(this));
1279
+ }, eI = new WeakSet(), KI = function() {
1280
+ if (h(this, sI, VI).call(this), I(this, D)) {
1281
+ const { device: g } = I(this, D), C = "rgba16float", i = I(this, E), s = I(this, j);
1282
+ o(this, f, hI(g, C, i, s)), o(this, y, hI(g, C, i, s)), o(this, ig, hI(g, C, i, s)), o(this, mg, aI(g, C, i, s)), o(this, Gg, aI(g, C, i, s));
1256
1283
  } else {
1257
- const g = I(this, Q), C = I(this, $g), i = I(this, O), s = I(this, E);
1258
- l(this, x, GI(g, C, i, s)), l(this, H, GI(g, C, i, s)), l(this, $, GI(g, C, i, s)), l(this, q, oI(g, C, i, s)), l(this, gg, oI(g, C, i, s));
1284
+ const g = I(this, O), C = I(this, CI), i = I(this, E), s = I(this, j);
1285
+ o(this, M, bI(g, C, i, s)), o(this, X, bI(g, C, i, s)), o(this, gg, bI(g, C, i, s)), o(this, $, SI(g, C, i, s)), o(this, Ig, SI(g, C, i, s));
1259
1286
  }
1260
- }, Gg = new WeakSet(), fg = function() {
1261
- if (!(!I(this, k) || I(this, V) === 0 || I(this, X) === 0)) {
1262
- if (h(this, iI, bI).call(this), I(this, F)) {
1263
- const { device: g } = I(this, F);
1264
- I(this, k).type === "text" ? l(this, z, gC(
1287
+ }, rg = new WeakSet(), Dg = function() {
1288
+ if (!(!I(this, k) || I(this, H) === 0 || I(this, v) === 0)) {
1289
+ if (h(this, lI, yI).call(this), I(this, D)) {
1290
+ const { device: g } = I(this, D);
1291
+ I(this, k).type === "text" ? o(this, N, eC(
1265
1292
  g,
1266
- I(this, V),
1267
- I(this, X),
1293
+ I(this, H),
1294
+ I(this, v),
1268
1295
  I(this, k).opts,
1269
- I(this, J),
1270
- I(this, ng)
1271
- )) : l(this, z, IC(
1296
+ I(this, z),
1297
+ I(this, pg)
1298
+ )) : o(this, N, sC(
1272
1299
  g,
1273
1300
  I(this, k).bitmap,
1274
- I(this, V),
1275
- I(this, X),
1301
+ I(this, H),
1302
+ I(this, v),
1276
1303
  I(this, k).effect,
1277
1304
  I(this, k).size,
1278
- I(this, J),
1279
- I(this, ng)
1305
+ I(this, z),
1306
+ I(this, pg)
1280
1307
  ));
1281
1308
  } else {
1282
- const g = I(this, Q);
1309
+ const g = I(this, O);
1283
1310
  if (I(this, k).type === "text") {
1284
- const { backgroundTex: C, obstacleTex: i, coverageTex: s } = qI(
1311
+ const { backgroundTex: C, obstacleTex: i, coverageTex: s } = CC(
1285
1312
  g,
1286
- I(this, V),
1287
- I(this, X),
1313
+ I(this, H),
1314
+ I(this, v),
1288
1315
  I(this, k).opts,
1289
- I(this, J),
1290
- I(this, ng)
1316
+ I(this, z),
1317
+ I(this, pg)
1291
1318
  );
1292
- l(this, sg, C), l(this, T, i), l(this, Ig, s);
1319
+ o(this, lg, C), o(this, J, i), o(this, Cg, s);
1293
1320
  } else {
1294
- const { backgroundTex: C, obstacleTex: i, coverageTex: s } = $I(
1321
+ const { backgroundTex: C, obstacleTex: i, coverageTex: s } = iC(
1295
1322
  g,
1296
1323
  I(this, k).bitmap,
1297
- I(this, V),
1298
- I(this, X),
1324
+ I(this, H),
1325
+ I(this, v),
1299
1326
  I(this, k).effect,
1300
1327
  I(this, k).size,
1301
- I(this, J),
1302
- I(this, ng)
1328
+ I(this, z),
1329
+ I(this, pg)
1303
1330
  );
1304
- l(this, sg, C), l(this, T, i), l(this, Ig, s);
1331
+ o(this, lg, C), o(this, J, i), o(this, Cg, s);
1305
1332
  }
1306
1333
  }
1307
- l(this, Ug, !0);
1334
+ o(this, kg, !0);
1308
1335
  }
1309
- }, xg = new WeakSet(), jg = function() {
1310
- I(this, Ug) && !this.isRunning && this.start();
1311
- }, CI = new WeakSet(), wI = function() {
1312
- var g, C, i, s, t, o, a, u;
1313
- if (I(this, F))
1314
- (g = I(this, f)) == null || g.dispose(), (C = I(this, y)) == null || C.dispose(), (i = I(this, Cg)) == null || i.dispose(), (s = I(this, Zg)) == null || s.tex.destroy(), (t = I(this, mg)) == null || t.tex.destroy(), l(this, f, l(this, y, l(this, Cg, null))), l(this, Zg, l(this, mg, null));
1336
+ }, xg = new WeakSet(), qg = function() {
1337
+ I(this, kg) && !this.isRunning && this.start();
1338
+ }, sI = new WeakSet(), VI = function() {
1339
+ var g, C, i, s, l, t, a, u;
1340
+ if (I(this, D))
1341
+ (g = I(this, f)) == null || g.dispose(), (C = I(this, y)) == null || C.dispose(), (i = I(this, ig)) == null || i.dispose(), (s = I(this, mg)) == null || s.tex.destroy(), (l = I(this, Gg)) == null || l.tex.destroy(), o(this, f, o(this, y, o(this, ig, null))), o(this, mg, o(this, Gg, null));
1315
1342
  else {
1316
- const A = I(this, Q);
1317
- (o = I(this, x)) == null || o.dispose(), (a = I(this, H)) == null || a.dispose(), (u = I(this, $)) == null || u.dispose(), I(this, q) && (A.deleteTexture(I(this, q).tex), A.deleteFramebuffer(I(this, q).fbo)), I(this, gg) && (A.deleteTexture(I(this, gg).tex), A.deleteFramebuffer(I(this, gg).fbo)), l(this, x, l(this, H, l(this, $, l(this, q, l(this, gg, null)))));
1343
+ const c = I(this, O);
1344
+ (t = I(this, M)) == null || t.dispose(), (a = I(this, X)) == null || a.dispose(), (u = I(this, gg)) == null || u.dispose(), I(this, $) && (c.deleteTexture(I(this, $).tex), c.deleteFramebuffer(I(this, $).fbo)), I(this, Ig) && (c.deleteTexture(I(this, Ig).tex), c.deleteFramebuffer(I(this, Ig).fbo)), o(this, M, o(this, X, o(this, gg, o(this, $, o(this, Ig, null)))));
1318
1345
  }
1319
- }, iI = new WeakSet(), bI = function() {
1320
- if (I(this, F))
1321
- I(this, z) && (I(this, z).backgroundTex.destroy(), I(this, z).obstacleTex.destroy(), I(this, z).sharedCoverage || I(this, z).coverageTex.destroy(), l(this, z, null));
1346
+ }, lI = new WeakSet(), yI = function() {
1347
+ if (I(this, D))
1348
+ I(this, N) && (I(this, N).backgroundTex.destroy(), I(this, N).obstacleTex.destroy(), I(this, N).sharedCoverage || I(this, N).coverageTex.destroy(), o(this, N, null));
1322
1349
  else {
1323
- const g = I(this, Q);
1324
- I(this, sg) && g.deleteTexture(I(this, sg)), I(this, T) && g.deleteTexture(I(this, T)), I(this, Ig) && I(this, Ig) !== I(this, T) && g.deleteTexture(I(this, Ig)), l(this, sg, l(this, T, l(this, Ig, null)));
1350
+ const g = I(this, O);
1351
+ I(this, lg) && g.deleteTexture(I(this, lg)), I(this, J) && g.deleteTexture(I(this, J)), I(this, Cg) && I(this, Cg) !== I(this, J) && g.deleteTexture(I(this, Cg)), o(this, lg, o(this, J, o(this, Cg, null)));
1325
1352
  }
1326
- }, SI = new WeakSet(), FI = function() {
1327
- !I(this, Ug) || I(this, V) === 0 || (I(this, F) ? h(this, aI, DI).call(this) : h(this, BI, zI).call(this));
1328
- }, aI = new WeakSet(), DI = function() {
1329
- const g = I(this, F), C = g.device, i = I(this, Dg), s = I(this, Kg), t = I(this, Tg), o = I(this, Ag), a = I(this, z);
1353
+ }, BI = new WeakSet(), zI = function() {
1354
+ !I(this, kg) || I(this, H) === 0 || (I(this, D) ? h(this, nI, NI).call(this) : h(this, pI, EI).call(this));
1355
+ }, nI = new WeakSet(), NI = function() {
1356
+ const g = I(this, D), C = g.device, i = I(this, zg), s = I(this, Vg), l = I(this, Ng), t = I(this, cg), a = I(this, N);
1330
1357
  if (!I(this, f) || !I(this, y))
1331
1358
  return;
1332
- 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;
1333
- const u = I(this, O), A = I(this, E), p = I(this, V), c = I(this, X), d = 1 / u, Z = 1 / A;
1334
- RI(C, I(this, yg), d, Z, Og, o.velocityDissipation), tI(C, I(this, Hg), d, Z), tI(C, I(this, Xg), d, Z), tI(C, I(this, Rg), d, Z), tI(C, I(this, vg), d, Z), KC(C, I(this, Wg), d, Z, o.curl, Og), yC(
1359
+ 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;
1360
+ const u = I(this, E), c = I(this, j), Z = I(this, H), S = I(this, v), A = 1 / u, B = 1 / c;
1361
+ YI(C, I(this, yg), A, B, Pg, t.velocityDissipation), cI(C, I(this, Xg), A, B), cI(C, I(this, vg), A, B), cI(C, I(this, Rg), A, B), cI(C, I(this, Ug), A, B), vC(C, I(this, Wg), A, B, t.curl, Pg), RC(
1335
1362
  C,
1336
1363
  I(this, Yg),
1337
- 1 / p,
1338
- 1 / c,
1339
- o.refraction,
1340
- o.specularExp,
1341
- o.waterColor,
1342
- o.glowColor,
1343
- o.shine,
1344
- o.warpStrength ?? 0.015,
1345
- WI[o.algorithm] ?? 0
1364
+ 1 / Z,
1365
+ 1 / S,
1366
+ t.refraction,
1367
+ t.specularExp,
1368
+ AI(t.waterColor),
1369
+ AI(t.glowColor),
1370
+ t.shine,
1371
+ t.warpStrength ?? 0.015,
1372
+ MI[t.algorithm] ?? 0,
1373
+ I(this, Mg)
1346
1374
  );
1347
- const m = C.createCommandEncoder(), w = (n, r) => C.createBindGroup({ layout: n.getBindGroupLayout(0), entries: r }), b = { binding: 1, resource: t };
1375
+ const m = C.createCommandEncoder(), r = (G, K) => C.createBindGroup({ layout: G.getBindGroupLayout(0), entries: K }), L = { binding: 1, resource: l };
1348
1376
  {
1349
- const n = w(i.advection, [
1377
+ const G = r(i.advection, [
1350
1378
  { binding: 0, resource: { buffer: I(this, yg) } },
1351
- b,
1379
+ L,
1352
1380
  { binding: 2, resource: I(this, y).read.view },
1353
1381
  { binding: 3, resource: I(this, y).read.view },
1354
1382
  { binding: 4, resource: a.obstacleView }
1355
1383
  ]);
1356
- N(m, i.advection, n, s, I(this, y).write.view);
1384
+ Q(m, i.advection, G, s, I(this, y).write.view);
1357
1385
  }
1358
1386
  I(this, y).swap();
1359
1387
  {
1360
- RI(C, I(this, Vg), d, Z, Og, o.densityDissipation);
1361
- const n = w(i.advection, [
1362
- { binding: 0, resource: { buffer: I(this, Vg) } },
1363
- b,
1388
+ YI(C, I(this, Hg), A, B, Pg, t.densityDissipation);
1389
+ const G = r(i.advection, [
1390
+ { binding: 0, resource: { buffer: I(this, Hg) } },
1391
+ L,
1364
1392
  { binding: 2, resource: I(this, y).read.view },
1365
1393
  { binding: 3, resource: I(this, f).read.view },
1366
1394
  { binding: 4, resource: a.obstacleView }
1367
1395
  ]);
1368
- N(m, i.advection, n, s, I(this, f).write.view);
1396
+ Q(m, i.advection, G, s, I(this, f).write.view);
1369
1397
  }
1370
1398
  I(this, f).swap();
1371
1399
  {
1372
- const n = w(i.curl, [
1373
- { binding: 0, resource: { buffer: I(this, vg) } },
1374
- b,
1400
+ const G = r(i.curl, [
1401
+ { binding: 0, resource: { buffer: I(this, Ug) } },
1402
+ L,
1375
1403
  { binding: 2, resource: I(this, y).read.view }
1376
1404
  ]);
1377
- N(m, i.curl, n, s, I(this, mg).view);
1405
+ Q(m, i.curl, G, s, I(this, Gg).view);
1378
1406
  }
1379
1407
  {
1380
- const n = w(i.vorticity, [
1408
+ const G = r(i.vorticity, [
1381
1409
  { binding: 0, resource: { buffer: I(this, Wg) } },
1382
- b,
1410
+ L,
1383
1411
  { binding: 2, resource: I(this, y).read.view },
1384
- { binding: 3, resource: I(this, mg).view }
1412
+ { binding: 3, resource: I(this, Gg).view }
1385
1413
  ]);
1386
- N(m, i.vorticity, n, s, I(this, y).write.view);
1414
+ Q(m, i.vorticity, G, s, I(this, y).write.view);
1387
1415
  }
1388
- if (I(this, y).swap(), I(this, L).moved) {
1389
- const n = I(this, L).x * I(this, D) / p, r = I(this, L).y * I(this, D) / c;
1390
- lI(
1416
+ if (I(this, y).swap(), I(this, w).moved) {
1417
+ const G = I(this, w).x * I(this, T) / Z, K = I(this, w).y * I(this, T) / S;
1418
+ dI(
1391
1419
  C,
1392
1420
  I(this, tg),
1393
- d,
1394
- Z,
1395
- p / c,
1396
- o.splatRadius,
1397
- I(this, L).dx * o.splatForce,
1398
- I(this, L).dy * o.splatForce,
1421
+ A,
1422
+ B,
1423
+ Z / S,
1424
+ t.splatRadius,
1425
+ I(this, w).dx * t.splatForce,
1426
+ I(this, w).dy * t.splatForce,
1399
1427
  0,
1400
- n,
1401
- r
1428
+ G,
1429
+ K
1402
1430
  );
1403
1431
  {
1404
- const R = w(i.splat, [
1432
+ const b = r(i.splat, [
1405
1433
  { binding: 0, resource: { buffer: I(this, tg) } },
1406
- b,
1434
+ L,
1407
1435
  { binding: 2, resource: I(this, y).read.view }
1408
1436
  ]);
1409
- N(m, i.splat, R, s, I(this, y).write.view);
1437
+ Q(m, i.splat, b, s, I(this, y).write.view);
1410
1438
  }
1411
- I(this, y).swap(), lI(
1439
+ I(this, y).swap(), dI(
1412
1440
  C,
1413
- I(this, lg),
1414
- d,
1415
- Z,
1416
- p / c,
1417
- o.splatRadius,
1441
+ I(this, og),
1442
+ A,
1443
+ B,
1444
+ Z / S,
1445
+ t.splatRadius,
1418
1446
  1,
1419
1447
  1,
1420
1448
  1,
1421
- n,
1422
- r
1449
+ G,
1450
+ K
1423
1451
  );
1424
1452
  {
1425
- const R = w(i.splat, [
1426
- { binding: 0, resource: { buffer: I(this, lg) } },
1427
- b,
1453
+ const b = r(i.splat, [
1454
+ { binding: 0, resource: { buffer: I(this, og) } },
1455
+ L,
1428
1456
  { binding: 2, resource: I(this, f).read.view }
1429
1457
  ]);
1430
- N(m, i.splat, R, s, I(this, f).write.view);
1458
+ Q(m, i.splat, b, s, I(this, f).write.view);
1431
1459
  }
1432
- I(this, f).swap(), I(this, L).moved = !1;
1460
+ I(this, f).swap(), I(this, w).moved = !1;
1433
1461
  }
1434
1462
  {
1435
- const n = w(i.divergence, [
1436
- { binding: 0, resource: { buffer: I(this, Hg) } },
1437
- b,
1463
+ const G = r(i.divergence, [
1464
+ { binding: 0, resource: { buffer: I(this, Xg) } },
1465
+ L,
1438
1466
  { binding: 2, resource: I(this, y).read.view },
1439
1467
  { binding: 3, resource: a.obstacleView }
1440
1468
  ]);
1441
- N(m, i.divergence, n, s, I(this, Zg).view);
1469
+ Q(m, i.divergence, G, s, I(this, mg).view);
1442
1470
  }
1443
- for (let n = 0; n < o.pressureIterations; n++) {
1444
- const r = w(i.pressure, [
1445
- { binding: 0, resource: { buffer: I(this, Xg) } },
1446
- b,
1447
- { binding: 2, resource: I(this, Cg).read.view },
1448
- { binding: 3, resource: I(this, Zg).view },
1471
+ for (let G = 0; G < t.pressureIterations; G++) {
1472
+ const K = r(i.pressure, [
1473
+ { binding: 0, resource: { buffer: I(this, vg) } },
1474
+ L,
1475
+ { binding: 2, resource: I(this, ig).read.view },
1476
+ { binding: 3, resource: I(this, mg).view },
1449
1477
  { binding: 4, resource: a.obstacleView }
1450
1478
  ]);
1451
- N(m, i.pressure, r, s, I(this, Cg).write.view), I(this, Cg).swap();
1479
+ Q(m, i.pressure, K, s, I(this, ig).write.view), I(this, ig).swap();
1452
1480
  }
1453
1481
  {
1454
- const n = w(i.gradientSubtract, [
1482
+ const G = r(i.gradientSubtract, [
1455
1483
  { binding: 0, resource: { buffer: I(this, Rg) } },
1456
- b,
1457
- { binding: 2, resource: I(this, Cg).read.view },
1484
+ L,
1485
+ { binding: 2, resource: I(this, ig).read.view },
1458
1486
  { binding: 3, resource: I(this, y).read.view },
1459
1487
  { binding: 4, resource: a.obstacleView }
1460
1488
  ]);
1461
- N(m, i.gradientSubtract, n, s, I(this, y).write.view);
1489
+ Q(m, i.gradientSubtract, G, s, I(this, y).write.view);
1462
1490
  }
1463
1491
  I(this, y).swap();
1464
1492
  {
1465
- const n = g.context.getCurrentTexture().createView(), r = w(i.display, [
1493
+ const G = g.context.getCurrentTexture().createView(), K = r(i.display, [
1466
1494
  { binding: 0, resource: { buffer: I(this, Yg) } },
1467
- b,
1495
+ L,
1468
1496
  { binding: 2, resource: I(this, f).read.view },
1469
1497
  { binding: 3, resource: a.obstacleView },
1470
1498
  { binding: 4, resource: a.backgroundView },
1471
1499
  { binding: 5, resource: a.coverageView },
1472
1500
  { binding: 6, resource: I(this, y).read.view }
1473
1501
  ]);
1474
- VC(m, i.display, r, s, n);
1502
+ UC(m, i.display, K, s, G);
1475
1503
  }
1476
1504
  C.queue.submit([m.finish()]);
1477
- }, pI = new WeakSet(), TI = function(g, C, i, s, t) {
1478
- const a = I(this, F).device, u = I(this, Dg).splat, A = I(this, Kg), p = I(this, Tg), c = I(this, Ag), d = I(this, O), Z = I(this, E), m = 1 / d, w = 1 / Z, b = a.createCommandEncoder(), n = { binding: 1, resource: p }, r = (W) => a.createBindGroup({ layout: u.getBindGroupLayout(0), entries: W }), R = g * I(this, D) / I(this, V), B = C * I(this, D) / I(this, X);
1479
- lI(
1505
+ }, mI = new WeakSet(), QI = function(g, C, i, s, l) {
1506
+ const a = I(this, D).device, u = I(this, zg).splat, c = I(this, Vg), Z = I(this, Ng), S = I(this, cg), A = I(this, E), B = I(this, j), m = 1 / A, r = 1 / B, L = a.createCommandEncoder(), G = { binding: 1, resource: Z }, K = (n) => a.createBindGroup({ layout: u.getBindGroupLayout(0), entries: n }), b = g * I(this, T) / I(this, H), Y = C * I(this, T) / I(this, v);
1507
+ dI(
1480
1508
  a,
1481
1509
  I(this, tg),
1482
1510
  m,
1483
- w,
1484
- I(this, V) / I(this, X),
1485
- c.splatRadius,
1486
- i * c.splatForce * t,
1487
- s * c.splatForce * t,
1511
+ r,
1512
+ I(this, H) / I(this, v),
1513
+ S.splatRadius,
1514
+ i * S.splatForce * l,
1515
+ s * S.splatForce * l,
1488
1516
  0,
1489
- R,
1490
- B
1517
+ b,
1518
+ Y
1491
1519
  );
1492
1520
  {
1493
- const W = r([
1521
+ const n = K([
1494
1522
  { binding: 0, resource: { buffer: I(this, tg) } },
1495
- n,
1523
+ G,
1496
1524
  { binding: 2, resource: I(this, y).read.view }
1497
1525
  ]);
1498
- N(b, u, W, A, I(this, y).write.view);
1526
+ Q(L, u, n, c, I(this, y).write.view);
1499
1527
  }
1500
- I(this, y).swap(), lI(
1528
+ I(this, y).swap(), dI(
1501
1529
  a,
1502
- I(this, lg),
1530
+ I(this, og),
1503
1531
  m,
1504
- w,
1505
- I(this, V) / I(this, X),
1506
- c.splatRadius,
1507
- t,
1508
- t,
1509
- t,
1510
- R,
1511
- B
1532
+ r,
1533
+ I(this, H) / I(this, v),
1534
+ S.splatRadius,
1535
+ l,
1536
+ l,
1537
+ l,
1538
+ b,
1539
+ Y
1512
1540
  );
1513
1541
  {
1514
- const W = r([
1515
- { binding: 0, resource: { buffer: I(this, lg) } },
1516
- n,
1542
+ const n = K([
1543
+ { binding: 0, resource: { buffer: I(this, og) } },
1544
+ G,
1517
1545
  { binding: 2, resource: I(this, f).read.view }
1518
1546
  ]);
1519
- N(b, u, W, A, I(this, f).write.view);
1547
+ Q(L, u, n, c, I(this, f).write.view);
1520
1548
  }
1521
- I(this, f).swap(), a.queue.submit([b.finish()]);
1522
- }, uI = new WeakSet(), JI = function(g, C, i, s, t) {
1523
- const o = I(this, Q), a = I(this, Ag), u = I(this, hg).splat, A = I(this, Fg);
1524
- o.viewport(0, 0, I(this, O), I(this, E)), u.bind(), o.uniform1f(u.uniforms.aspectRatio, I(this, V) / I(this, X)), o.uniform2f(u.uniforms.point, g * I(this, D) / I(this, V), 1 - C * I(this, D) / I(this, X)), o.uniform1f(u.uniforms.radius, a.splatRadius), o.uniform1i(u.uniforms.uTarget, 0), o.activeTexture(o.TEXTURE0), o.bindTexture(o.TEXTURE_2D, I(this, H).read.tex), o.uniform3f(u.uniforms.color, i * a.splatForce * t, -s * a.splatForce * t, 0), A(I(this, H).write.fbo), I(this, H).swap(), o.activeTexture(o.TEXTURE0), o.bindTexture(o.TEXTURE_2D, I(this, x).read.tex), o.uniform3f(u.uniforms.color, t, t, t), A(I(this, x).write.fbo), I(this, x).swap();
1525
- }, BI = new WeakSet(), zI = function() {
1526
- if (!I(this, x) || !I(this, H))
1549
+ I(this, f).swap(), a.queue.submit([L.finish()]);
1550
+ }, GI = new WeakSet(), OI = function(g, C, i, s, l) {
1551
+ const t = I(this, O), a = I(this, cg), u = I(this, Kg).splat, c = I(this, Jg);
1552
+ t.viewport(0, 0, I(this, E), I(this, j)), u.bind(), t.uniform1f(u.uniforms.aspectRatio, I(this, H) / I(this, v)), t.uniform2f(u.uniforms.point, g * I(this, T) / I(this, H), 1 - C * I(this, T) / I(this, v)), t.uniform1f(u.uniforms.radius, a.splatRadius), t.uniform1i(u.uniforms.uTarget, 0), t.activeTexture(t.TEXTURE0), t.bindTexture(t.TEXTURE_2D, I(this, X).read.tex), t.uniform3f(u.uniforms.color, i * a.splatForce * l, -s * a.splatForce * l, 0), c(I(this, X).write.fbo), I(this, X).swap(), t.activeTexture(t.TEXTURE0), t.bindTexture(t.TEXTURE_2D, I(this, M).read.tex), t.uniform3f(u.uniforms.color, l, l, l), c(I(this, M).write.fbo), I(this, M).swap();
1553
+ }, pI = new WeakSet(), EI = function() {
1554
+ if (!I(this, M) || !I(this, X))
1527
1555
  return;
1528
- const g = I(this, Q), C = I(this, Ag), { advection: i, divergence: s, pressure: t, gradientSubtract: o, splat: a, curl: u, vorticity: A, display: p } = I(this, hg);
1529
- 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;
1530
- const c = I(this, O), d = I(this, E), Z = I(this, Fg);
1531
- g.viewport(0, 0, c, d), i.bind(), g.uniform2f(i.uniforms.texelSize, 1 / c, 1 / d), g.uniform1f(i.uniforms.dt, Og), g.uniform1i(i.uniforms.uObstacle, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, T)), 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), Z(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, x).read.tex), Z(I(this, x).write.fbo), I(this, x).swap(), u.bind(), g.uniform2f(u.uniforms.texelSize, 1 / c, 1 / d), g.uniform1i(u.uniforms.uVelocity, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, H).read.tex), Z(I(this, gg).fbo), A.bind(), g.uniform2f(A.uniforms.texelSize, 1 / c, 1 / d), g.uniform1f(A.uniforms.curl, C.curl), g.uniform1f(A.uniforms.dt, Og), g.uniform1i(A.uniforms.uVelocity, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, H).read.tex), g.uniform1i(A.uniforms.uCurl, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, gg).tex), Z(I(this, H).write.fbo), I(this, H).swap(), I(this, L).moved && (a.bind(), g.uniform1f(a.uniforms.aspectRatio, I(this, V) / I(this, X)), g.uniform2f(a.uniforms.point, I(this, L).x * I(this, D) / I(this, V), 1 - I(this, L).y * I(this, D) / I(this, X)), g.uniform1f(a.uniforms.radius, C.splatRadius), g.uniform1i(a.uniforms.uTarget, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, H).read.tex), g.uniform3f(a.uniforms.color, I(this, L).dx * C.splatForce, -I(this, L).dy * C.splatForce, 0), Z(I(this, H).write.fbo), I(this, H).swap(), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, x).read.tex), g.uniform3f(a.uniforms.color, 1, 1, 1), Z(I(this, x).write.fbo), I(this, x).swap(), I(this, L).moved = !1), s.bind(), g.uniform2f(s.uniforms.texelSize, 1 / c, 1 / d), 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, T)), Z(I(this, q).fbo), t.bind(), g.uniform2f(t.uniforms.texelSize, 1 / c, 1 / d), g.uniform1i(t.uniforms.uDivergence, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, q).tex), g.uniform1i(t.uniforms.uObstacle, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, T));
1556
+ const g = I(this, O), C = I(this, cg), { advection: i, divergence: s, pressure: l, gradientSubtract: t, splat: a, curl: u, vorticity: c, display: Z } = I(this, Kg);
1557
+ 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;
1558
+ const S = I(this, E), A = I(this, j), B = I(this, Jg);
1559
+ g.viewport(0, 0, S, A), i.bind(), g.uniform2f(i.uniforms.texelSize, 1 / S, 1 / A), g.uniform1f(i.uniforms.dt, Pg), g.uniform1i(i.uniforms.uObstacle, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, J)), 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), B(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), B(I(this, M).write.fbo), I(this, M).swap(), u.bind(), g.uniform2f(u.uniforms.texelSize, 1 / S, 1 / A), g.uniform1i(u.uniforms.uVelocity, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, X).read.tex), B(I(this, Ig).fbo), c.bind(), g.uniform2f(c.uniforms.texelSize, 1 / S, 1 / A), g.uniform1f(c.uniforms.curl, C.curl), g.uniform1f(c.uniforms.dt, Pg), g.uniform1i(c.uniforms.uVelocity, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, X).read.tex), g.uniform1i(c.uniforms.uCurl, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, Ig).tex), B(I(this, X).write.fbo), I(this, X).swap(), I(this, w).moved && (a.bind(), g.uniform1f(a.uniforms.aspectRatio, I(this, H) / I(this, v)), g.uniform2f(a.uniforms.point, I(this, w).x * I(this, T) / I(this, H), 1 - I(this, w).y * I(this, T) / I(this, v)), g.uniform1f(a.uniforms.radius, C.splatRadius), g.uniform1i(a.uniforms.uTarget, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, X).read.tex), g.uniform3f(a.uniforms.color, I(this, w).dx * C.splatForce, -I(this, w).dy * C.splatForce, 0), B(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(a.uniforms.color, 1, 1, 1), B(I(this, M).write.fbo), I(this, M).swap(), I(this, w).moved = !1), s.bind(), g.uniform2f(s.uniforms.texelSize, 1 / S, 1 / A), 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, J)), B(I(this, $).fbo), l.bind(), g.uniform2f(l.uniforms.texelSize, 1 / S, 1 / A), g.uniform1i(l.uniforms.uDivergence, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, $).tex), g.uniform1i(l.uniforms.uObstacle, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, J));
1532
1560
  for (let m = 0; m < C.pressureIterations; m++)
1533
- g.uniform1i(t.uniforms.uPressure, 2), g.activeTexture(g.TEXTURE2), g.bindTexture(g.TEXTURE_2D, I(this, $).read.tex), Z(I(this, $).write.fbo), I(this, $).swap();
1534
- o.bind(), g.uniform2f(o.uniforms.texelSize, 1 / c, 1 / d), g.uniform1i(o.uniforms.uPressure, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, $).read.tex), g.uniform1i(o.uniforms.uVelocity, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, H).read.tex), g.uniform1i(o.uniforms.uObstacle, 2), g.activeTexture(g.TEXTURE2), g.bindTexture(g.TEXTURE_2D, I(this, T)), Z(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, C.waterColor), g.uniform3fv(p.uniforms.uGlowColor, 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, WI[C.algorithm] ?? 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, x).read.tex), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, T)), g.activeTexture(g.TEXTURE2), g.bindTexture(g.TEXTURE_2D, I(this, sg)), g.activeTexture(g.TEXTURE3), g.bindTexture(g.TEXTURE_2D, I(this, Ig)), 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), Z(null);
1561
+ g.uniform1i(l.uniforms.uPressure, 2), g.activeTexture(g.TEXTURE2), g.bindTexture(g.TEXTURE_2D, I(this, gg).read.tex), B(I(this, gg).write.fbo), I(this, gg).swap();
1562
+ t.bind(), g.uniform2f(t.uniforms.texelSize, 1 / S, 1 / A), g.uniform1i(t.uniforms.uPressure, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, gg).read.tex), g.uniform1i(t.uniforms.uVelocity, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, X).read.tex), g.uniform1i(t.uniforms.uObstacle, 2), g.activeTexture(g.TEXTURE2), g.bindTexture(g.TEXTURE_2D, I(this, J)), B(I(this, X).write.fbo), I(this, X).swap(), g.viewport(0, 0, I(this, H), I(this, v)), g.bindFramebuffer(g.FRAMEBUFFER, null), g.clear(g.COLOR_BUFFER_BIT), Z.bind(), g.uniform2f(Z.uniforms.texelSize, 1 / I(this, H), 1 / I(this, v)), g.uniform3fv(Z.uniforms.uWaterColor, AI(C.waterColor)), g.uniform3fv(Z.uniforms.uGlowColor, AI(C.glowColor)), g.uniform1f(Z.uniforms.uRefraction, C.refraction), g.uniform1f(Z.uniforms.uSpecularExp, C.specularExp), g.uniform1f(Z.uniforms.uShine, C.shine), g.uniform1f(Z.uniforms.uWarpStrength, C.warpStrength ?? 0.015), g.uniform1i(Z.uniforms.uAlgorithm, MI[C.algorithm] ?? 0), g.uniform1i(Z.uniforms.uEnableAlpha, I(this, Mg) ? 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, J)), g.activeTexture(g.TEXTURE2), g.bindTexture(g.TEXTURE_2D, I(this, lg)), g.activeTexture(g.TEXTURE3), g.bindTexture(g.TEXTURE_2D, I(this, Cg)), g.activeTexture(g.TEXTURE4), g.bindTexture(g.TEXTURE_2D, I(this, X).read.tex), g.uniform1i(Z.uniforms.uTexture, 0), g.uniform1i(Z.uniforms.uObstacle, 1), g.uniform1i(Z.uniforms.uBackground, 2), g.uniform1i(Z.uniforms.uCoverage, 3), g.uniform1i(Z.uniforms.uVelocity, 4), B(null);
1535
1563
  };
1536
- let dI = yI;
1537
- const NI = "dmFyIGd0ID0gT2JqZWN0LmRlZmluZVByb3BlcnR5Owp2YXIgYnQgPSAoaSwgZSwgcikgPT4gZSBpbiBpID8gZ3QoaSwgZSwgeyBlbnVtZXJhYmxlOiAhMCwgY29uZmlndXJhYmxlOiAhMCwgd3JpdGFibGU6ICEwLCB2YWx1ZTogciB9KSA6IGlbZV0gPSByOwp2YXIga2UgPSAoaSwgZSwgcikgPT4gKGJ0KGksIHR5cGVvZiBlICE9ICJzeW1ib2wiID8gZSArICIiIDogZSwgciksIHIpLCBKZSA9IChpLCBlLCByKSA9PiB7CiAgaWYgKCFlLmhhcyhpKSkKICAgIHRocm93IFR5cGVFcnJvcigiQ2Fubm90ICIgKyByKTsKfTsKdmFyIHQgPSAoaSwgZSwgcikgPT4gKEplKGksIGUsICJyZWFkIGZyb20gcHJpdmF0ZSBmaWVsZCIpLCByID8gci5jYWxsKGkpIDogZS5nZXQoaSkpLCB2ID0gKGksIGUsIHIpID0+IHsKICBpZiAoZS5oYXMoaSkpCiAgICB0aHJvdyBUeXBlRXJyb3IoIkNhbm5vdCBhZGQgdGhlIHNhbWUgcHJpdmF0ZSBtZW1iZXIgbW9yZSB0aGFuIG9uY2UiKTsKICBlIGluc3RhbmNlb2YgV2Vha1NldCA/IGUuYWRkKGkpIDogZS5zZXQoaSwgcik7Cn0sIHUgPSAoaSwgZSwgciwgcykgPT4gKEplKGksIGUsICJ3cml0ZSB0byBwcml2YXRlIGZpZWxkIiksIHMgPyBzLmNhbGwoaSwgcikgOiBlLnNldChpLCByKSwgcik7CnZhciBTID0gKGksIGUsIHIpID0+IChKZShpLCBlLCAiYWNjZXNzIHByaXZhdGUgbWV0aG9kIiksIHIpOwpjb25zdCBjdCA9IHsKICBkZW5zaXR5RGlzc2lwYXRpb246IDAuOTkyLAogIHZlbG9jaXR5RGlzc2lwYXRpb246IDAuOTMsCiAgcHJlc3N1cmVJdGVyYXRpb25zOiAxLAogIGN1cmw6IDFlLTQsCiAgc3BsYXRSYWRpdXM6IDRlLTMsCiAgc3BsYXRGb3JjZTogMC45MSwKICByZWZyYWN0aW9uOiAwLjI1LAogIHNwZWN1bGFyRXhwOiAxLjAxLAogIHNoaW5lOiAwLjAxLAogIHdhdGVyQ29sb3I6IFswLCAwLCAwXSwKICBnbG93Q29sb3I6IFswLjcsIDAuODUsIDFdLAogIGFsZ29yaXRobTogInN0YW5kYXJkIiwKICB3YXJwU3RyZW5ndGg6IDAuMDE1Cn07Cih7CiAgLi4uY3QKfSk7CmNvbnN0IFR0ID0gewogIGNhbG06IHsKICAgIGRlbnNpdHlEaXNzaXBhdGlvbjogMC45OTksCiAgICB2ZWxvY2l0eURpc3NpcGF0aW9uOiAwLjk4LAogICAgY3VybDogMWUtNCwKICAgIHNwbGF0UmFkaXVzOiAzZS0zLAogICAgc3BsYXRGb3JjZTogMC41LAogICAgcmVmcmFjdGlvbjogMC4xNSwKICAgIHNoaW5lOiA1ZS0zLAogICAgZ2xvd0NvbG9yOiBbMC42LCAwLjg1LCAxXSwKICAgIHdhdGVyQ29sb3I6IFswLCAwLjAyLCAwLjA1XQogIH0sCiAgc2FuZDogewogICAgZGVuc2l0eURpc3NpcGF0aW9uOiAwLjk5NywKICAgIHZlbG9jaXR5RGlzc2lwYXRpb246IDAuOTgsCiAgICBjdXJsOiAxLAogICAgc3BsYXRSYWRpdXM6IDAuMDEsCiAgICBzcGxhdEZvcmNlOiAwLjksCiAgICByZWZyYWN0aW9uOiAwLjgsCiAgICBzcGVjdWxhckV4cDogMC4xLAogICAgc2hpbmU6IDAuMDUsCiAgICBnbG93Q29sb3I6IFswLjAyNywgMC4wMjcsIDAuMDI3XSwKICAgIHdhdGVyQ29sb3I6IFswLjQ1MSwgMC4zMjksIDAuMTI1XQogIH0sCiAgd2F2ZTogewogICAgZGVuc2l0eURpc3NpcGF0aW9uOiAwLjk5NCwKICAgIHZlbG9jaXR5RGlzc2lwYXRpb246IDAuOTIsCiAgICBjdXJsOiAwLjIsCiAgICBzcGxhdFJhZGl1czogNWUtMywKICAgIHNwbGF0Rm9yY2U6IDEuMiwKICAgIHJlZnJhY3Rpb246IDAuMzUsCiAgICBzaGluZTogMC4wMywKICAgIGdsb3dDb2xvcjogWzAuNSwgMC44LCAxXSwKICAgIHdhdGVyQ29sb3I6IFswLCAwLjAxLCAwLjAzXQogIH0sCiAgbmVvbjogewogICAgZGVuc2l0eURpc3NpcGF0aW9uOiAwLjk4NSwKICAgIHZlbG9jaXR5RGlzc2lwYXRpb246IDAuOTMsCiAgICBjdXJsOiAwLjA1LAogICAgc3BsYXRSYWRpdXM6IDhlLTMsCiAgICBzcGxhdEZvcmNlOiAxLjUsCiAgICByZWZyYWN0aW9uOiAwLjI1LAogICAgc3BlY3VsYXJFeHA6IDAuNSwKICAgIHNoaW5lOiAwLjE0LAogICAgZ2xvd0NvbG9yOiBbMSwgMC4yLCAwLjhdLAogICAgd2F0ZXJDb2xvcjogWzAuMDUsIDAsIDAuMDhdCiAgfSwKICBzbW9rZTogewogICAgZGVuc2l0eURpc3NpcGF0aW9uOiAwLjk5NiwKICAgIHZlbG9jaXR5RGlzc2lwYXRpb246IDAuOTcsCiAgICBjdXJsOiAwLjA0LAogICAgc3BsYXRSYWRpdXM6IDllLTMsCiAgICBzcGxhdEZvcmNlOiAwLjgsCiAgICByZWZyYWN0aW9uOiAwLjA4LAogICAgc2hpbmU6IDAsCiAgICBnbG93Q29sb3I6IFswLjUsIDAuNSwgMC41XSwKICAgIHdhdGVyQ29sb3I6IFswLjA2LCAwLjA2LCAwLjA2XQogIH0KfTsKZnVuY3Rpb24geXQoaSA9IHt9LCBlLCByID0gY3QpIHsKICByZXR1cm4geyAuLi5lID8geyAuLi5yLCAuLi5UdFtlXSB9IDogciwgLi4uaSB9Owp9CmNvbnN0IHJlID0gKAogIC8qIGdsc2wgKi8KICBgCiAgcHJlY2lzaW9uIGhpZ2hwIGZsb2F0OwogIGF0dHJpYnV0ZSB2ZWMyIGFQb3NpdGlvbjsKICB2YXJ5aW5nIHZlYzIgdlV2OwogIHZhcnlpbmcgdmVjMiB2TDsgdmFyeWluZyB2ZWMyIHZSOyB2YXJ5aW5nIHZlYzIgdlQ7IHZhcnlpbmcgdmVjMiB2QjsKICB1bmlmb3JtIHZlYzIgdGV4ZWxTaXplOwogIHZvaWQgbWFpbiAoKSB7CiAgICB2VXYgPSBhUG9zaXRpb24gKiAwLjUgKyAwLjU7CiAgICB2TCA9IHZVdiAtIHZlYzIodGV4ZWxTaXplLngsIDAuMCk7CiAgICB2UiA9IHZVdiArIHZlYzIodGV4ZWxTaXplLngsIDAuMCk7CiAgICB2VCA9IHZVdiArIHZlYzIoMC4wLCB0ZXhlbFNpemUueSk7CiAgICB2QiA9IHZVdiAtIHZlYzIoMC4wLCB0ZXhlbFNpemUueSk7CiAgICBnbF9Qb3NpdGlvbiA9IHZlYzQoYVBvc2l0aW9uLCAwLjAsIDEuMCk7CiAgfQpgCiksIFN0ID0gKAogIC8qIGdsc2wgKi8KICBgCiAgcHJlY2lzaW9uIGhpZ2hwIGZsb2F0OwogIHZhcnlpbmcgdmVjMiB2VXY7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdVZlbG9jaXR5OwogIHVuaWZvcm0gc2FtcGxlcjJEIHVTb3VyY2U7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdU9ic3RhY2xlOwogIHVuaWZvcm0gdmVjMiB0ZXhlbFNpemU7CiAgdW5pZm9ybSBmbG9hdCBkdDsKICB1bmlmb3JtIGZsb2F0IGRpc3NpcGF0aW9uOwogIHZvaWQgbWFpbiAoKSB7CiAgICBpZiAodGV4dHVyZTJEKHVPYnN0YWNsZSwgdlV2KS5yID4gMC41KSB7IGdsX0ZyYWdDb2xvciA9IHZlYzQoMC4wKTsgcmV0dXJuOyB9CiAgICB2ZWMyIGNvb3JkID0gdlV2IC0gZHQgKiB0ZXh0dXJlMkQodVZlbG9jaXR5LCB2VXYpLnh5ICogdGV4ZWxTaXplOwogICAgZ2xfRnJhZ0NvbG9yID0gZGlzc2lwYXRpb24gKiB0ZXh0dXJlMkQodVNvdXJjZSwgY29vcmQpOwogIH0KYAopLCB3dCA9ICgKICAvKiBnbHNsICovCiAgYAogIHByZWNpc2lvbiBoaWdocCBmbG9hdDsKICB2YXJ5aW5nIHZlYzIgdkw7IHZhcnlpbmcgdmVjMiB2UjsgdmFyeWluZyB2ZWMyIHZUOyB2YXJ5aW5nIHZlYzIgdkI7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdVZlbG9jaXR5OwogIHVuaWZvcm0gc2FtcGxlcjJEIHVPYnN0YWNsZTsKICB2b2lkIG1haW4gKCkgewogICAgZmxvYXQgTCA9IHRleHR1cmUyRCh1T2JzdGFjbGUsIHZMKS5yID4gMC41ID8gMC4wIDogdGV4dHVyZTJEKHVWZWxvY2l0eSwgdkwpLng7CiAgICBmbG9hdCBSID0gdGV4dHVyZTJEKHVPYnN0YWNsZSwgdlIpLnIgPiAwLjUgPyAwLjAgOiB0ZXh0dXJlMkQodVZlbG9jaXR5LCB2UikueDsKICAgIGZsb2F0IFQgPSB0ZXh0dXJlMkQodU9ic3RhY2xlLCB2VCkuciA+IDAuNSA/IDAuMCA6IHRleHR1cmUyRCh1VmVsb2NpdHksIHZUKS55OwogICAgZmxvYXQgQiA9IHRleHR1cmUyRCh1T2JzdGFjbGUsIHZCKS5yID4gMC41ID8gMC4wIDogdGV4dHVyZTJEKHVWZWxvY2l0eSwgdkIpLnk7CiAgICBnbF9GcmFnQ29sb3IgPSB2ZWM0KDAuNSAqIChSIC0gTCArIFQgLSBCKSwgMC4wLCAwLjAsIDEuMCk7CiAgfQpgCiksIFJ0ID0gKAogIC8qIGdsc2wgKi8KICBgCiAgcHJlY2lzaW9uIGhpZ2hwIGZsb2F0OwogIHZhcnlpbmcgdmVjMiB2VXY7IHZhcnlpbmcgdmVjMiB2TDsgdmFyeWluZyB2ZWMyIHZSOyB2YXJ5aW5nIHZlYzIgdlQ7IHZhcnlpbmcgdmVjMiB2QjsKICB1bmlmb3JtIHNhbXBsZXIyRCB1UHJlc3N1cmU7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdURpdmVyZ2VuY2U7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdU9ic3RhY2xlOwogIHZvaWQgbWFpbiAoKSB7CiAgICBmbG9hdCBDID0gdGV4dHVyZTJEKHVQcmVzc3VyZSwgdlV2KS54OwogICAgZmxvYXQgTCA9IHRleHR1cmUyRCh1T2JzdGFjbGUsIHZMKS5yID4gMC41ID8gQyA6IHRleHR1cmUyRCh1UHJlc3N1cmUsIHZMKS54OwogICAgZmxvYXQgUiA9IHRleHR1cmUyRCh1T2JzdGFjbGUsIHZSKS5yID4gMC41ID8gQyA6IHRleHR1cmUyRCh1UHJlc3N1cmUsIHZSKS54OwogICAgZmxvYXQgVCA9IHRleHR1cmUyRCh1T2JzdGFjbGUsIHZUKS5yID4gMC41ID8gQyA6IHRleHR1cmUyRCh1UHJlc3N1cmUsIHZUKS54OwogICAgZmxvYXQgQiA9IHRleHR1cmUyRCh1T2JzdGFjbGUsIHZCKS5yID4gMC41ID8gQyA6IHRleHR1cmUyRCh1UHJlc3N1cmUsIHZCKS54OwogICAgZmxvYXQgZGl2ID0gdGV4dHVyZTJEKHVEaXZlcmdlbmNlLCB2VXYpLng7CiAgICBnbF9GcmFnQ29sb3IgPSB2ZWM0KChMICsgUiArIEIgKyBUIC0gZGl2KSAqIDAuMjUsIDAuMCwgMC4wLCAxLjApOwogIH0KYAopLCBFdCA9ICgKICAvKiBnbHNsICovCiAgYAogIHByZWNpc2lvbiBoaWdocCBmbG9hdDsKICB2YXJ5aW5nIHZlYzIgdlV2OyB2YXJ5aW5nIHZlYzIgdkw7IHZhcnlpbmcgdmVjMiB2UjsgdmFyeWluZyB2ZWMyIHZUOyB2YXJ5aW5nIHZlYzIgdkI7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdVByZXNzdXJlOwogIHVuaWZvcm0gc2FtcGxlcjJEIHVWZWxvY2l0eTsKICB1bmlmb3JtIHNhbXBsZXIyRCB1T2JzdGFjbGU7CiAgdm9pZCBtYWluICgpIHsKICAgIGlmICh0ZXh0dXJlMkQodU9ic3RhY2xlLCB2VXYpLnIgPiAwLjUpIHsgZ2xfRnJhZ0NvbG9yID0gdmVjNCgwLjApOyByZXR1cm47IH0KICAgIGZsb2F0IEwgPSB0ZXh0dXJlMkQodVByZXNzdXJlLCB2TCkueDsKICAgIGZsb2F0IFIgPSB0ZXh0dXJlMkQodVByZXNzdXJlLCB2UikueDsKICAgIGZsb2F0IFQgPSB0ZXh0dXJlMkQodVByZXNzdXJlLCB2VCkueDsKICAgIGZsb2F0IEIgPSB0ZXh0dXJlMkQodVByZXNzdXJlLCB2QikueDsKICAgIHZlYzIgdmVsID0gdGV4dHVyZTJEKHVWZWxvY2l0eSwgdlV2KS54eSAtIHZlYzIoUiAtIEwsIFQgLSBCKTsKICAgIGdsX0ZyYWdDb2xvciA9IHZlYzQodmVsLCAwLjAsIDEuMCk7CiAgfQpgCiksIFV0ID0gKAogIC8qIGdsc2wgKi8KICBgCiAgcHJlY2lzaW9uIGhpZ2hwIGZsb2F0OwogIHZhcnlpbmcgdmVjMiB2VXY7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdVRhcmdldDsKICB1bmlmb3JtIGZsb2F0IGFzcGVjdFJhdGlvOwogIHVuaWZvcm0gdmVjMyBjb2xvcjsKICB1bmlmb3JtIHZlYzIgcG9pbnQ7CiAgdW5pZm9ybSBmbG9hdCByYWRpdXM7CiAgdm9pZCBtYWluICgpIHsKICAgIHZlYzIgcCA9IHZVdiAtIHBvaW50Lnh5OwogICAgcC54ICo9IGFzcGVjdFJhdGlvOwogICAgdmVjMyBzcGxhdCA9IGV4cCgtZG90KHAsIHApIC8gcmFkaXVzKSAqIGNvbG9yOwogICAgZ2xfRnJhZ0NvbG9yID0gdmVjNCh0ZXh0dXJlMkQodVRhcmdldCwgdlV2KS54eXogKyBzcGxhdCwgMS4wKTsKICB9CmAKKSwgRHQgPSAoCiAgLyogZ2xzbCAqLwogIGAKICBwcmVjaXNpb24gaGlnaHAgZmxvYXQ7CiAgdmFyeWluZyB2ZWMyIHZMOyB2YXJ5aW5nIHZlYzIgdlI7IHZhcnlpbmcgdmVjMiB2VDsgdmFyeWluZyB2ZWMyIHZCOwogIHVuaWZvcm0gc2FtcGxlcjJEIHVWZWxvY2l0eTsKICB2b2lkIG1haW4gKCkgewogICAgZmxvYXQgTCA9IHRleHR1cmUyRCh1VmVsb2NpdHksIHZMKS55OwogICAgZmxvYXQgUiA9IHRleHR1cmUyRCh1VmVsb2NpdHksIHZSKS55OwogICAgZmxvYXQgVCA9IHRleHR1cmUyRCh1VmVsb2NpdHksIHZUKS54OwogICAgZmxvYXQgQiA9IHRleHR1cmUyRCh1VmVsb2NpdHksIHZCKS54OwogICAgZ2xfRnJhZ0NvbG9yID0gdmVjNCgwLjUgKiAoUiAtIEwgLSBUICsgQiksIDAuMCwgMC4wLCAxLjApOwogIH0KYAopLCBfdCA9ICgKICAvKiBnbHNsICovCiAgYAogIHByZWNpc2lvbiBoaWdocCBmbG9hdDsKICB2YXJ5aW5nIHZlYzIgdlV2OyB2YXJ5aW5nIHZlYzIgdkw7IHZhcnlpbmcgdmVjMiB2UjsgdmFyeWluZyB2ZWMyIHZUOyB2YXJ5aW5nIHZlYzIgdkI7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdVZlbG9jaXR5OwogIHVuaWZvcm0gc2FtcGxlcjJEIHVDdXJsOwogIHVuaWZvcm0gZmxvYXQgY3VybDsKICB1bmlmb3JtIGZsb2F0IGR0OwogIHZvaWQgbWFpbiAoKSB7CiAgICBmbG9hdCBMID0gdGV4dHVyZTJEKHVDdXJsLCB2TCkueDsKICAgIGZsb2F0IFIgPSB0ZXh0dXJlMkQodUN1cmwsIHZSKS54OwogICAgZmxvYXQgVCA9IHRleHR1cmUyRCh1Q3VybCwgdlQpLng7CiAgICBmbG9hdCBCID0gdGV4dHVyZTJEKHVDdXJsLCB2QikueDsKICAgIGZsb2F0IEMgPSB0ZXh0dXJlMkQodUN1cmwsIHZVdikueDsKICAgIHZlYzIgZm9yY2UgPSAwLjUgKiB2ZWMyKGFicyhUKSAtIGFicyhCKSwgYWJzKFIpIC0gYWJzKEwpKTsKICAgIGZvcmNlIC89IGxlbmd0aChmb3JjZSkgKyAwLjAwMDE7CiAgICBmb3JjZSAqPSBjdXJsICogMzAuMCAqIEM7CiAgICBnbF9GcmFnQ29sb3IgPSB2ZWM0KHRleHR1cmUyRCh1VmVsb2NpdHksIHZVdikueHkgKyBmb3JjZSAqIGR0LCAwLjAsIDEuMCk7CiAgfQpgCiksIEN0ID0gKAogIC8qIGdsc2wgKi8KICBgCiAgcHJlY2lzaW9uIGhpZ2hwIGZsb2F0OwogIHZhcnlpbmcgdmVjMiB2VXY7CgogIHVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlOwogIHVuaWZvcm0gc2FtcGxlcjJEIHVPYnN0YWNsZTsKICB1bmlmb3JtIHNhbXBsZXIyRCB1QmFja2dyb3VuZDsKICB1bmlmb3JtIHNhbXBsZXIyRCB1Q292ZXJhZ2U7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdVZlbG9jaXR5OwoKICB1bmlmb3JtIHZlYzIgIHRleGVsU2l6ZTsKICB1bmlmb3JtIHZlYzMgIHVXYXRlckNvbG9yOwogIHVuaWZvcm0gdmVjMyAgdUdsb3dDb2xvcjsKICB1bmlmb3JtIGZsb2F0IHVSZWZyYWN0aW9uOwogIHVuaWZvcm0gZmxvYXQgdVNwZWN1bGFyRXhwOwogIHVuaWZvcm0gZmxvYXQgdVNoaW5lOwogIHVuaWZvcm0gZmxvYXQgdVdhcnBTdHJlbmd0aDsKICB1bmlmb3JtIGludCAgIHVBbGdvcml0aG07CgogIHZvaWQgbWFpbiAoKSB7CiAgICBmbG9hdCBvYnMgICAgICA9IHRleHR1cmUyRCh1T2JzdGFjbGUsICB2VXYpLnI7CiAgICAvLyBNYXNrIGRlbnNpdHkgaW5zaWRlIG9ic3RhY2xlcyBzbyBzcGxhdHMgZG9uJ3QgZmxpY2tlciB0aGUgdGV4dC9pbWFnZSBjb250ZW50LgogICAgZmxvYXQgZGVuc2l0eSAgPSBtYXgodGV4dHVyZTJEKHVUZXh0dXJlLCB2VXYpLnIsIDAuMCkgKiAoMS4wIC0gc3RlcCgwLjUsIG9icykpOwogICAgZmxvYXQgY292ZXJhZ2UgPSB0ZXh0dXJlMkQodUNvdmVyYWdlLCAgdlV2KS5yOwoKICAgIGZsb2F0IGRMID0gbWF4KHRleHR1cmUyRCh1VGV4dHVyZSwgdlV2IC0gdmVjMih0ZXhlbFNpemUueCAqIDIuMCwgMC4wKSkuciwgMC4wKTsKICAgIGZsb2F0IGRSID0gbWF4KHRleHR1cmUyRCh1VGV4dHVyZSwgdlV2ICsgdmVjMih0ZXhlbFNpemUueCAqIDIuMCwgMC4wKSkuciwgMC4wKTsKICAgIGZsb2F0IGRUID0gbWF4KHRleHR1cmUyRCh1VGV4dHVyZSwgdlV2ICsgdmVjMigwLjAsIHRleGVsU2l6ZS55ICogMi4wKSkuciwgMC4wKTsKICAgIGZsb2F0IGRCID0gbWF4KHRleHR1cmUyRCh1VGV4dHVyZSwgdlV2IC0gdmVjMigwLjAsIHRleGVsU2l6ZS55ICogMi4wKSkuciwgMC4wKTsKCiAgICB2ZWMzICBub3JtYWwgICA9IG5vcm1hbGl6ZSh2ZWMzKGRMIC0gZFIsIGRCIC0gZFQsIDAuMikpOwogICAgdmVjMyAgbGlnaHREaXIgPSBub3JtYWxpemUodmVjMygwLjUsIDEuMCwgMC41KSk7CiAgICB2ZWMzICBoYWxmViAgICA9IG5vcm1hbGl6ZShsaWdodERpciArIHZlYzMoMC4wLCAwLjAsIDEuMCkpOwogICAgZmxvYXQgc3BlYyAgICAgPSBwb3cobWF4KGRvdChub3JtYWwsIGhhbGZWKSwgMC4wKSwgdVNwZWN1bGFyRXhwKSAqIHVTaGluZSAqIGRlbnNpdHk7CgogICAgLy8gSW4gdHJhbnNwYXJlbnQgKG5vbi1jb3ZlcmFnZSkgYXJlYXMgdGhlIGJhY2tncm91bmQgdGV4dHVyZSBpcyBlbXB0eSBibGFjayBjYW52YXMuCiAgICAvLyBSZXBsYWNlIGl0IHdpdGggdVdhdGVyQ29sb3Igc28gZmx1aWQgY29sb3VyIGlzIG5vdCBjb250YW1pbmF0ZWQgYnkgdGhhdCBibGFjaywKICAgIC8vIGFsbG93aW5nIHRoZSBDU1MgYmFja2dyb3VuZENvbG9yIHRvIHNob3cgdGhyb3VnaCBjb3JyZWN0bHkgdmlhIHByZW11bHRpcGxpZWQgYWxwaGEuCiAgICB2ZWMzIGJnUmF3ID0gdGV4dHVyZTJEKHVCYWNrZ3JvdW5kLCB2VXYpLnJnYjsKICAgIHZlYzMgYmcgICAgPSBtaXgodVdhdGVyQ29sb3IsIGJnUmF3LCBjb3ZlcmFnZSk7CiAgICB2ZWMzIGNvbG9yID0gYmc7CgogICAgaWYgKHVBbGdvcml0aG0gPT0gMSkgewogICAgICAvLyDilIDilIAgZ2xhc3Mg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiAgICAgIC8vIFN0cm9uZyBVViBkaXN0b3J0aW9uIG9ubHkuIEltYWdlIGJlbmRzIGJ1dCBubyBjb2xvdXIgb3ZlcmxheS4KICAgICAgdmVjMiByZWZyVXYgPSBjbGFtcCh2VXYgKyBub3JtYWwueHkgKiB1UmVmcmFjdGlvbiAqIGRlbnNpdHkgKiAzLjAsIDAuMCwgMS4wKTsKICAgICAgdmVjMyByZWZyQmcgPSBtaXgodVdhdGVyQ29sb3IsIHRleHR1cmUyRCh1QmFja2dyb3VuZCwgbWl4KHZVdiwgcmVmclV2LCAxLjAgLSBvYnMpKS5yZ2IsIGNvdmVyYWdlKTsKICAgICAgY29sb3IgPSByZWZyQmcgKyBzcGVjICogdUdsb3dDb2xvciAqIDIuNTsKICAgICAgY29sb3IgPSBtaXgoY29sb3IsIGJnICogMC42LCBvYnMgKiAwLjMpOwoKICAgIH0gZWxzZSBpZiAodUFsZ29yaXRobSA9PSAyKSB7CiAgICAgIC8vIOKUgOKUgCBpbmsg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiAgICAgIC8vIERlbnNlIG9wYXF1ZSBwaWdtZW50IHRoYXQgc3RhaW5zLiBTdWJ0bGUgcmVmcmFjdGlvbiB1bmRlcm5lYXRoLgogICAgICBmbG9hdCBpbmtEICA9IG1pbihkZW5zaXR5ICogNC4wLCAxLjApOwogICAgICB2ZWMyIHJlZnJVdiA9IGNsYW1wKHZVdiArIG5vcm1hbC54eSAqIHVSZWZyYWN0aW9uICogZGVuc2l0eSAqIDAuNCwgMC4wLCAxLjApOwogICAgICB2ZWMzIHJlZnJCZyA9IG1peCh1V2F0ZXJDb2xvciwgdGV4dHVyZTJEKHVCYWNrZ3JvdW5kLCBtaXgodlV2LCByZWZyVXYsIDEuMCAtIG9icykpLnJnYiwgY292ZXJhZ2UpOwogICAgICBjb2xvciA9IG1peChyZWZyQmcsIHVXYXRlckNvbG9yICsgc3BlYyAqIHVHbG93Q29sb3IsIGlua0QpOwogICAgICBjb2xvciA9IG1peChjb2xvciwgYmcgKiAwLjUsIG9icyAqIDAuMTUpOwoKICAgIH0gZWxzZSBpZiAodUFsZ29yaXRobSA9PSAzKSB7CiAgICAgIC8vIOKUgOKUgCBhdXJvcmEg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiAgICAgIC8vIFZlbG9jaXR5IGZpZWxkIHdhcnBzIGJhY2tncm91bmQgVVZzIOKAlCBsaXF1aWQgbWV0YWwgLyBsYXZhLWxhbXAgZmVlbC4KICAgICAgdmVjMiAgdmVsICAgID0gdGV4dHVyZTJEKHVWZWxvY2l0eSwgdlV2KS54eTsKICAgICAgZmxvYXQgdmVsTWFnID0gY2xhbXAobGVuZ3RoKHZlbCkgKiAyMC4wLCAwLjAsIDEuMCk7CiAgICAgIHZlYzIgIHdhcnBVdiA9IGNsYW1wKHZVdiArIHZlbCAqIHVXYXJwU3RyZW5ndGgsIDAuMCwgMS4wKTsKICAgICAgdmVjMyAgd2FycEJnID0gbWl4KHVXYXRlckNvbG9yLCB0ZXh0dXJlMkQodUJhY2tncm91bmQsIHdhcnBVdikucmdiLCBjb3ZlcmFnZSk7CiAgICAgIGNvbG9yICA9IG1peChiZywgd2FycEJnLCB2ZWxNYWcgKiAoMS4wIC0gb2JzKSk7CiAgICAgIGNvbG9yICs9IHNwZWMgKiB1R2xvd0NvbG9yICogdmVsTWFnICogMS41OwogICAgICBjb2xvciArPSB1V2F0ZXJDb2xvciAqIGRlbnNpdHkgKiAwLjM7CiAgICAgIGNvbG9yICA9IG1peChjb2xvciwgYmcgKiAwLjUsIG9icyAqIDAuMik7CgogICAgfSBlbHNlIGlmICh1QWxnb3JpdGhtID09IDQpIHsKICAgICAgLy8g4pSA4pSAIHJpcHBsZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKICAgICAgLy8gRXhhZ2dlcmF0ZWQgbm9ybWFsIHBlcnR1cmJhdGlvbiArIEZyZXNuZWwgcmltIOKAlCBjYWxtIHdhdGVyIHN1cmZhY2UuCiAgICAgIHZlYzIgIHJpcHBsZVV2ID0gY2xhbXAodlV2ICsgbm9ybWFsLnh5ICogdVJlZnJhY3Rpb24gKiBkZW5zaXR5ICogNi4wLCAwLjAsIDEuMCk7CiAgICAgIHZlYzMgIHJlZnJCZyAgID0gbWl4KHVXYXRlckNvbG9yLCB0ZXh0dXJlMkQodUJhY2tncm91bmQsIG1peCh2VXYsIHJpcHBsZVV2LCAxLjAgLSBvYnMpKS5yZ2IsIGNvdmVyYWdlKTsKICAgICAgZmxvYXQgZnJlc25lbCAgPSBwb3coY2xhbXAoMS4wIC0gZG90KG5vcm1hbCwgdmVjMygwLjAsIDAuMCwgMS4wKSksIDAuMCwgMS4wKSwgMy4wKSAqIGRlbnNpdHk7CiAgICAgIGNvbG9yICA9IHJlZnJCZzsKICAgICAgY29sb3IgKz0gZnJlc25lbCAqIHVHbG93Q29sb3IgKiAyLjA7CiAgICAgIGNvbG9yICs9IHNwZWMgKiB1R2xvd0NvbG9yICogZGVuc2l0eSAqIDIuMDsKICAgICAgY29sb3IgID0gbWl4KGNvbG9yLCBiZyAqIDAuNSwgb2JzICogMC4yKTsKCiAgICB9IGVsc2UgewogICAgICAvLyDilIDilIAgc3RhbmRhcmQgKDApIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAogICAgICAvLyBPcmlnaW5hbDogY29sb3VyIG92ZXJsYXkgYmxlbmRlZCBvdmVyIHJlZnJhY3RlZCBiYWNrZ3JvdW5kLgogICAgICB2ZWMyIHJlZnJVdiA9IHZVdiArIG5vcm1hbC54eSAqIHVSZWZyYWN0aW9uICogZGVuc2l0eTsKICAgICAgdmVjMyByZWZyQmcgPSBtaXgodVdhdGVyQ29sb3IsIHRleHR1cmUyRCh1QmFja2dyb3VuZCwgbWl4KHZVdiwgcmVmclV2LCAxLjAgLSBvYnMpKS5yZ2IsIGNvdmVyYWdlKTsKICAgICAgY29sb3IgID0gbWl4KHJlZnJCZywgdVdhdGVyQ29sb3IsIG1pbihkZW5zaXR5ICogMS41LCAwLjgpKTsKICAgICAgY29sb3IgKz0gc3BlYyAqIHVHbG93Q29sb3I7CiAgICAgIGNvbG9yICA9IG1peChjb2xvciwgYmcgKiAwLjUsIG9icyAqIDAuMik7CiAgICB9CgogICAgLy8gUHJlbXVsdGlwbGllZCBhbHBoYSDigJQgdHJhbnNwYXJlbnQgd2hlcmUgdGhlcmUgaXMgbmVpdGhlciBjb250ZW50IG5vciBmbHVpZCwKICAgIC8vIGxldHRpbmcgdGhlIENTUyBiYWNrZ3JvdW5kQ29sb3Igb24gdGhlIGNvbnRhaW5lciBkaXYgc2hvdyB0aHJvdWdoLgogICAgZmxvYXQgYWxwaGEgPSBjbGFtcChtYXgoZGVuc2l0eSAqIDEuNSwgY292ZXJhZ2UpLCAwLjAsIDEuMCk7CiAgICBnbF9GcmFnQ29sb3IgPSB2ZWM0KGNvbG9yICogYWxwaGEsIGFscGhhKTsKICB9CmAKKTsKZnVuY3Rpb24gQnQoaSkgewogIGNvbnN0IGUgPSB7IGFscGhhOiAhMCwgZGVwdGg6ICExLCBzdGVuY2lsOiAhMSwgYW50aWFsaWFzOiAhMCwgcHJlc2VydmVEcmF3aW5nQnVmZmVyOiAhMSB9OwogIGxldCByID0gaS5nZXRDb250ZXh0KCJ3ZWJnbDIiLCBlKTsKICBjb25zdCBzID0gISFyOwogIHMgfHwgKHIgPSBpLmdldENvbnRleHQoIndlYmdsIiwgZSksIHIuZ2V0RXh0ZW5zaW9uKCJFWFRfY29sb3JfYnVmZmVyX2hhbGZfZmxvYXQiKSk7CiAgY29uc3QgbyA9IHMgPyBudWxsIDogci5nZXRFeHRlbnNpb24oIk9FU190ZXh0dXJlX2hhbGZfZmxvYXQiKSwgYSA9IHMgPyByLkhBTEZfRkxPQVQgOiBvLkhBTEZfRkxPQVRfT0VTOwogIHJldHVybiByLmdldEV4dGVuc2lvbigiRVhUX2NvbG9yX2J1ZmZlcl9mbG9hdCIpLCByLmdldEV4dGVuc2lvbigiT0VTX3RleHR1cmVfaGFsZl9mbG9hdF9saW5lYXIiKSwgewogICAgdHlwZTogcyA/ICJ3ZWJnbDIiIDogIndlYmdsMSIsCiAgICBnbDogciwKICAgIGlzV2ViR0wyOiBzLAogICAgZXh0OiB7CiAgICAgIGludGVybmFsRm9ybWF0OiBzID8gci5SR0JBMTZGIDogci5SR0JBLAogICAgICBmb3JtYXQ6IHIuUkdCQSwKICAgICAgdHlwZTogYQogICAgfQogIH07Cn0KYXN5bmMgZnVuY3Rpb24gVnQoaSkgewogIGlmICh0eXBlb2YgbmF2aWdhdG9yID4gInUiIHx8ICFuYXZpZ2F0b3IuZ3B1KQogICAgcmV0dXJuIG51bGw7CiAgdHJ5IHsKICAgIGNvbnN0IGUgPSBhd2FpdCBuYXZpZ2F0b3IuZ3B1LnJlcXVlc3RBZGFwdGVyKCk7CiAgICBpZiAoIWUpCiAgICAgIHJldHVybiBudWxsOwogICAgY29uc3QgciA9IGF3YWl0IGUucmVxdWVzdERldmljZSgpLCBzID0gaS5nZXRDb250ZXh0KCJ3ZWJncHUiKTsKICAgIGlmICghcykKICAgICAgcmV0dXJuIG51bGw7CiAgICBjb25zdCBvID0gbmF2aWdhdG9yLmdwdS5nZXRQcmVmZXJyZWRDYW52YXNGb3JtYXQoKTsKICAgIHJldHVybiBzLmNvbmZpZ3VyZSh7IGRldmljZTogciwgZm9ybWF0OiBvLCBhbHBoYU1vZGU6ICJwcmVtdWx0aXBsaWVkIiB9KSwgeyB0eXBlOiAid2ViZ3B1IiwgYWRhcHRlcjogZSwgZGV2aWNlOiByLCBjb250ZXh0OiBzLCBmb3JtYXQ6IG8gfTsKICB9IGNhdGNoIHsKICAgIHJldHVybiBudWxsOwogIH0KfQpjbGFzcyBpZSB7CiAgY29uc3RydWN0b3IoZSwgciwgcykgewogICAga2UodGhpcywgInByb2dyYW0iKTsKICAgIGtlKHRoaXMsICJ1bmlmb3JtcyIsIHt9KTsKICAgIGtlKHRoaXMsICJfZ2wiKTsKICAgIHRoaXMuX2dsID0gZSwgdGhpcy5wcm9ncmFtID0gZS5jcmVhdGVQcm9ncmFtKCksIGUuYXR0YWNoU2hhZGVyKHRoaXMucHJvZ3JhbSwgdGhpcy5fY29tcGlsZShlLlZFUlRFWF9TSEFERVIsIHIpKSwgZS5hdHRhY2hTaGFkZXIodGhpcy5wcm9ncmFtLCB0aGlzLl9jb21waWxlKGUuRlJBR01FTlRfU0hBREVSLCBzKSksIGUubGlua1Byb2dyYW0odGhpcy5wcm9ncmFtKTsKICAgIGNvbnN0IG8gPSBlLmdldFByb2dyYW1QYXJhbWV0ZXIodGhpcy5wcm9ncmFtLCBlLkFDVElWRV9VTklGT1JNUyk7CiAgICBmb3IgKGxldCBhID0gMDsgYSA8IG87IGErKykgewogICAgICBjb25zdCBuID0gZS5nZXRBY3RpdmVVbmlmb3JtKHRoaXMucHJvZ3JhbSwgYSkubmFtZTsKICAgICAgdGhpcy51bmlmb3Jtc1tuXSA9IGUuZ2V0VW5pZm9ybUxvY2F0aW9uKHRoaXMucHJvZ3JhbSwgbik7CiAgICB9CiAgfQogIF9jb21waWxlKGUsIHIpIHsKICAgIGNvbnN0IHMgPSB0aGlzLl9nbCwgbyA9IHMuY3JlYXRlU2hhZGVyKGUpOwogICAgcmV0dXJuIHMuc2hhZGVyU291cmNlKG8sIHIpLCBzLmNvbXBpbGVTaGFkZXIobyksIG87CiAgfQogIGJpbmQoKSB7CiAgICB0aGlzLl9nbC51c2VQcm9ncmFtKHRoaXMucHJvZ3JhbSk7CiAgfQogIGRpc3Bvc2UoKSB7CiAgICB0aGlzLl9nbC5kZWxldGVQcm9ncmFtKHRoaXMucHJvZ3JhbSk7CiAgfQp9CmZ1bmN0aW9uIFB0KGkpIHsKICByZXR1cm4gewogICAgYWR2ZWN0aW9uOiBuZXcgaWUoaSwgcmUsIFN0KSwKICAgIGRpdmVyZ2VuY2U6IG5ldyBpZShpLCByZSwgd3QpLAogICAgcHJlc3N1cmU6IG5ldyBpZShpLCByZSwgUnQpLAogICAgZ3JhZGllbnRTdWJ0cmFjdDogbmV3IGllKGksIHJlLCBFdCksCiAgICBzcGxhdDogbmV3IGllKGksIHJlLCBVdCksCiAgICBjdXJsOiBuZXcgaWUoaSwgcmUsIER0KSwKICAgIHZvcnRpY2l0eTogbmV3IGllKGksIHJlLCBfdCksCiAgICBkaXNwbGF5OiBuZXcgaWUoaSwgcmUsIEN0KQogIH07Cn0KZnVuY3Rpb24gJGUoaSwgZSwgciwgcykgewogIGkuYWN0aXZlVGV4dHVyZShpLlRFWFRVUkUwKTsKICBjb25zdCBvID0gaS5jcmVhdGVUZXh0dXJlKCk7CiAgaS5iaW5kVGV4dHVyZShpLlRFWFRVUkVfMkQsIG8pLCBpLnRleFBhcmFtZXRlcmkoaS5URVhUVVJFXzJELCBpLlRFWFRVUkVfTUlOX0ZJTFRFUiwgaS5MSU5FQVIpLCBpLnRleFBhcmFtZXRlcmkoaS5URVhUVVJFXzJELCBpLlRFWFRVUkVfTUFHX0ZJTFRFUiwgaS5MSU5FQVIpLCBpLnRleFBhcmFtZXRlcmkoaS5URVhUVVJFXzJELCBpLlRFWFRVUkVfV1JBUF9TLCBpLkNMQU1QX1RPX0VER0UpLCBpLnRleFBhcmFtZXRlcmkoaS5URVhUVVJFXzJELCBpLlRFWFRVUkVfV1JBUF9ULCBpLkNMQU1QX1RPX0VER0UpLCBpLnRleEltYWdlMkQoaS5URVhUVVJFXzJELCAwLCBlLmludGVybmFsRm9ybWF0LCByLCBzLCAwLCBlLmZvcm1hdCwgZS50eXBlLCBudWxsKTsKICBjb25zdCBhID0gaS5jcmVhdGVGcmFtZWJ1ZmZlcigpOwogIHJldHVybiBpLmJpbmRGcmFtZWJ1ZmZlcihpLkZSQU1FQlVGRkVSLCBhKSwgaS5mcmFtZWJ1ZmZlclRleHR1cmUyRChpLkZSQU1FQlVGRkVSLCBpLkNPTE9SX0FUVEFDSE1FTlQwLCBpLlRFWFRVUkVfMkQsIG8sIDApLCB7IHRleDogbywgZmJvOiBhLCB3aWR0aDogciwgaGVpZ2h0OiBzIH07Cn0KZnVuY3Rpb24gWmUoaSwgZSwgciwgcykgewogIGxldCBvID0gJGUoaSwgZSwgciwgcyksIGEgPSAkZShpLCBlLCByLCBzKTsKICByZXR1cm4gewogICAgZ2V0IHJlYWQoKSB7CiAgICAgIHJldHVybiBvOwogICAgfSwKICAgIGdldCB3cml0ZSgpIHsKICAgICAgcmV0dXJuIGE7CiAgICB9LAogICAgc3dhcCgpIHsKICAgICAgW28sIGFdID0gW2EsIG9dOwogICAgfSwKICAgIGRpc3Bvc2UoKSB7CiAgICAgIGkuZGVsZXRlVGV4dHVyZShvLnRleCksIGkuZGVsZXRlRnJhbWVidWZmZXIoby5mYm8pLCBpLmRlbGV0ZVRleHR1cmUoYS50ZXgpLCBpLmRlbGV0ZUZyYW1lYnVmZmVyKGEuZmJvKTsKICAgIH0KICB9Owp9CmZ1bmN0aW9uIE90KGkpIHsKICBjb25zdCBlID0gaS5jcmVhdGVCdWZmZXIoKTsKICByZXR1cm4gaS5iaW5kQnVmZmVyKGkuQVJSQVlfQlVGRkVSLCBlKSwgaS5idWZmZXJEYXRhKGkuQVJSQVlfQlVGRkVSLCBuZXcgRmxvYXQzMkFycmF5KFstMSwgLTEsIC0xLCAxLCAxLCAxLCAxLCAtMV0pLCBpLlNUQVRJQ19EUkFXKSwgaS52ZXJ0ZXhBdHRyaWJQb2ludGVyKDAsIDIsIGkuRkxPQVQsICExLCAwLCAwKSwgaS5lbmFibGVWZXJ0ZXhBdHRyaWJBcnJheSgwKSwgZnVuY3Rpb24ocykgewogICAgaS5iaW5kRnJhbWVidWZmZXIoaS5GUkFNRUJVRkZFUiwgcyksIGkuZHJhd0FycmF5cyhpLlRSSUFOR0xFX0ZBTiwgMCwgNCk7CiAgfTsKfQpjb25zdCBsZSA9ICgKICAvKiB3Z3NsICovCiAgYApzdHJ1Y3QgVlNPdXQgewogIEBidWlsdGluKHBvc2l0aW9uKSBwb3MgOiB2ZWM0ZiwKICBAbG9jYXRpb24oMCkgICAgICAgdXYgIDogdmVjMmYsCiAgQGxvY2F0aW9uKDEpICAgICAgIHZMICA6IHZlYzJmLAogIEBsb2NhdGlvbigyKSAgICAgICB2UiAgOiB2ZWMyZiwKICBAbG9jYXRpb24oMykgICAgICAgdlQgIDogdmVjMmYsCiAgQGxvY2F0aW9uKDQpICAgICAgIHZCICA6IHZlYzJmLAp9YAopLCBGdCA9ICgKICAvKiB3Z3NsICovCiAgYAoke2xlfQoKc3RydWN0IFUgewogIHRleGVsU2l6ZSAgOiB2ZWMyZiwKICBkdCAgICAgICAgIDogZjMyLAogIGRpc3NpcGF0aW9uOiBmMzIsCn0KQGdyb3VwKDApIEBiaW5kaW5nKDApIHZhcjx1bmlmb3JtPiB1ICAgICA6IFU7CkBncm91cCgwKSBAYmluZGluZygxKSB2YXIgICAgICAgICAgc2FtcCAgOiBzYW1wbGVyOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMikgdmFyICAgICAgICAgIHVWZWwgIDogdGV4dHVyZV8yZDxmMzI+OwpAZ3JvdXAoMCkgQGJpbmRpbmcoMykgdmFyICAgICAgICAgIHVTcmMgIDogdGV4dHVyZV8yZDxmMzI+OwpAZ3JvdXAoMCkgQGJpbmRpbmcoNCkgdmFyICAgICAgICAgIHVPYnMgIDogdGV4dHVyZV8yZDxmMzI+OwoKQHZlcnRleCBmbiB2cyhAbG9jYXRpb24oMCkgYTogdmVjMmYpIC0+IFZTT3V0IHsKICB2YXIgbzogVlNPdXQ7CiAgby51diA9IHZlYzJmKGEueCAqIDAuNSArIDAuNSwgMC41IC0gYS55ICogMC41KTsKICBvLnZMID0gby51diAtIHZlYzJmKHUudGV4ZWxTaXplLngsIDAuMCk7CiAgby52UiA9IG8udXYgKyB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlQgPSBvLnV2ICsgdmVjMmYoMC4wLCB1LnRleGVsU2l6ZS55KTsKICBvLnZCID0gby51diAtIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby5wb3MgPSB2ZWM0ZihhLCAwLjAsIDEuMCk7CiAgcmV0dXJuIG87Cn0KCkBmcmFnbWVudCBmbiBmcyhpOiBWU091dCkgLT4gQGxvY2F0aW9uKDApIHZlYzRmIHsKICAvLyBTYW1wbGUgYWxsIHRleHR1cmVzIGJlZm9yZSBicmFuY2hpbmcg4oCUIHRleHR1cmVTYW1wbGUgcmVxdWlyZXMgdW5pZm9ybSBjb250cm9sIGZsb3cKICBsZXQgb2JzICAgPSB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudXYpLnI7CiAgbGV0IHZlbCAgID0gdGV4dHVyZVNhbXBsZSh1VmVsLCBzYW1wLCBpLnV2KS54eTsKICBsZXQgY29vcmQgPSBpLnV2IC0gdS5kdCAqIHZlbCAqIHUudGV4ZWxTaXplOwogIGxldCBzcmMgICA9IHRleHR1cmVTYW1wbGUodVNyYywgc2FtcCwgY29vcmQpOwogIGlmIChvYnMgPiAwLjUpIHsgcmV0dXJuIHZlYzRmKDAuMCk7IH0KICByZXR1cm4gdS5kaXNzaXBhdGlvbiAqIHNyYzsKfQpgCiksIEx0ID0gKAogIC8qIHdnc2wgKi8KICBgCiR7bGV9CgpzdHJ1Y3QgVSB7IHRleGVsU2l6ZTogdmVjMmYsIF9wYWQ6IHZlYzJmIH0KQGdyb3VwKDApIEBiaW5kaW5nKDApIHZhcjx1bmlmb3JtPiB1ICAgIDogVTsKQGdyb3VwKDApIEBiaW5kaW5nKDEpIHZhciAgICAgICAgICBzYW1wIDogc2FtcGxlcjsKQGdyb3VwKDApIEBiaW5kaW5nKDIpIHZhciAgICAgICAgICB1VmVsIDogdGV4dHVyZV8yZDxmMzI+OwpAZ3JvdXAoMCkgQGJpbmRpbmcoMykgdmFyICAgICAgICAgIHVPYnMgOiB0ZXh0dXJlXzJkPGYzMj47CgpAdmVydGV4IGZuIHZzKEBsb2NhdGlvbigwKSBhOiB2ZWMyZikgLT4gVlNPdXQgewogIHZhciBvOiBWU091dDsKICBvLnV2ID0gdmVjMmYoYS54ICogMC41ICsgMC41LCAwLjUgLSBhLnkgKiAwLjUpOwogIG8udkwgPSBvLnV2IC0gdmVjMmYodS50ZXhlbFNpemUueCwgMC4wKTsKICBvLnZSID0gby51diArIHZlYzJmKHUudGV4ZWxTaXplLngsIDAuMCk7CiAgby52VCA9IG8udXYgKyB2ZWMyZigwLjAsIHUudGV4ZWxTaXplLnkpOwogIG8udkIgPSBvLnV2IC0gdmVjMmYoMC4wLCB1LnRleGVsU2l6ZS55KTsKICBvLnBvcyA9IHZlYzRmKGEsIDAuMCwgMS4wKTsKICByZXR1cm4gbzsKfQoKQGZyYWdtZW50IGZuIGZzKGk6IFZTT3V0KSAtPiBAbG9jYXRpb24oMCkgdmVjNGYgewogIGxldCBMID0gc2VsZWN0KHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS52TCkueCwgMC4wLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudkwpLnIgPiAwLjUpOwogIGxldCBSID0gc2VsZWN0KHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS52UikueCwgMC4wLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudlIpLnIgPiAwLjUpOwogIGxldCBUID0gc2VsZWN0KHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS52VCkueSwgMC4wLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudlQpLnIgPiAwLjUpOwogIGxldCBCID0gc2VsZWN0KHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS52QikueSwgMC4wLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudkIpLnIgPiAwLjUpOwogIHJldHVybiB2ZWM0ZigwLjUgKiAoUiAtIEwgKyBUIC0gQiksIDAuMCwgMC4wLCAxLjApOwp9CmAKKSwgQXQgPSAoCiAgLyogd2dzbCAqLwogIGAKJHtsZX0KCnN0cnVjdCBVIHsgdGV4ZWxTaXplOiB2ZWMyZiwgX3BhZDogdmVjMmYgfQpAZ3JvdXAoMCkgQGJpbmRpbmcoMCkgdmFyPHVuaWZvcm0+IHUgICAgOiBVOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMSkgdmFyICAgICAgICAgIHNhbXAgOiBzYW1wbGVyOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMikgdmFyICAgICAgICAgIHVQcmVzOiB0ZXh0dXJlXzJkPGYzMj47CkBncm91cCgwKSBAYmluZGluZygzKSB2YXIgICAgICAgICAgdURpdiA6IHRleHR1cmVfMmQ8ZjMyPjsKQGdyb3VwKDApIEBiaW5kaW5nKDQpIHZhciAgICAgICAgICB1T2JzIDogdGV4dHVyZV8yZDxmMzI+OwoKQHZlcnRleCBmbiB2cyhAbG9jYXRpb24oMCkgYTogdmVjMmYpIC0+IFZTT3V0IHsKICB2YXIgbzogVlNPdXQ7CiAgby51diA9IHZlYzJmKGEueCAqIDAuNSArIDAuNSwgMC41IC0gYS55ICogMC41KTsKICBvLnZMID0gby51diAtIHZlYzJmKHUudGV4ZWxTaXplLngsIDAuMCk7CiAgby52UiA9IG8udXYgKyB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlQgPSBvLnV2ICsgdmVjMmYoMC4wLCB1LnRleGVsU2l6ZS55KTsKICBvLnZCID0gby51diAtIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby5wb3MgPSB2ZWM0ZihhLCAwLjAsIDEuMCk7CiAgcmV0dXJuIG87Cn0KCkBmcmFnbWVudCBmbiBmcyhpOiBWU091dCkgLT4gQGxvY2F0aW9uKDApIHZlYzRmIHsKICBsZXQgQyAgPSB0ZXh0dXJlU2FtcGxlKHVQcmVzLCBzYW1wLCBpLnV2KS54OwogIGxldCBMICA9IHNlbGVjdCh0ZXh0dXJlU2FtcGxlKHVQcmVzLCBzYW1wLCBpLnZMKS54LCBDLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudkwpLnIgPiAwLjUpOwogIGxldCBSICA9IHNlbGVjdCh0ZXh0dXJlU2FtcGxlKHVQcmVzLCBzYW1wLCBpLnZSKS54LCBDLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudlIpLnIgPiAwLjUpOwogIGxldCBUICA9IHNlbGVjdCh0ZXh0dXJlU2FtcGxlKHVQcmVzLCBzYW1wLCBpLnZUKS54LCBDLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudlQpLnIgPiAwLjUpOwogIGxldCBCICA9IHNlbGVjdCh0ZXh0dXJlU2FtcGxlKHVQcmVzLCBzYW1wLCBpLnZCKS54LCBDLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudkIpLnIgPiAwLjUpOwogIGxldCBkdiA9IHRleHR1cmVTYW1wbGUodURpdiwgc2FtcCwgaS51dikueDsKICByZXR1cm4gdmVjNGYoKEwgKyBSICsgQiArIFQgLSBkdikgKiAwLjI1LCAwLjAsIDAuMCwgMS4wKTsKfQpgCiksIFh0ID0gKAogIC8qIHdnc2wgKi8KICBgCiR7bGV9CgpzdHJ1Y3QgVSB7IHRleGVsU2l6ZTogdmVjMmYsIF9wYWQ6IHZlYzJmIH0KQGdyb3VwKDApIEBiaW5kaW5nKDApIHZhcjx1bmlmb3JtPiB1ICAgIDogVTsKQGdyb3VwKDApIEBiaW5kaW5nKDEpIHZhciAgICAgICAgICBzYW1wIDogc2FtcGxlcjsKQGdyb3VwKDApIEBiaW5kaW5nKDIpIHZhciAgICAgICAgICB1UHJlczogdGV4dHVyZV8yZDxmMzI+OwpAZ3JvdXAoMCkgQGJpbmRpbmcoMykgdmFyICAgICAgICAgIHVWZWwgOiB0ZXh0dXJlXzJkPGYzMj47CkBncm91cCgwKSBAYmluZGluZyg0KSB2YXIgICAgICAgICAgdU9icyA6IHRleHR1cmVfMmQ8ZjMyPjsKCkB2ZXJ0ZXggZm4gdnMoQGxvY2F0aW9uKDApIGE6IHZlYzJmKSAtPiBWU091dCB7CiAgdmFyIG86IFZTT3V0OwogIG8udXYgPSB2ZWMyZihhLnggKiAwLjUgKyAwLjUsIDAuNSAtIGEueSAqIDAuNSk7CiAgby52TCA9IG8udXYgLSB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlIgPSBvLnV2ICsgdmVjMmYodS50ZXhlbFNpemUueCwgMC4wKTsKICBvLnZUID0gby51diArIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby52QiA9IG8udXYgLSB2ZWMyZigwLjAsIHUudGV4ZWxTaXplLnkpOwogIG8ucG9zID0gdmVjNGYoYSwgMC4wLCAxLjApOwogIHJldHVybiBvOwp9CgpAZnJhZ21lbnQgZm4gZnMoaTogVlNPdXQpIC0+IEBsb2NhdGlvbigwKSB2ZWM0ZiB7CiAgLy8gU2FtcGxlIGFsbCB0ZXh0dXJlcyBiZWZvcmUgYnJhbmNoaW5nIOKAlCB0ZXh0dXJlU2FtcGxlIHJlcXVpcmVzIHVuaWZvcm0gY29udHJvbCBmbG93CiAgbGV0IG9icyA9IHRleHR1cmVTYW1wbGUodU9icywgc2FtcCwgaS51dikucjsKICBsZXQgTCAgID0gdGV4dHVyZVNhbXBsZSh1UHJlcywgc2FtcCwgaS52TCkueDsKICBsZXQgUiAgID0gdGV4dHVyZVNhbXBsZSh1UHJlcywgc2FtcCwgaS52UikueDsKICBsZXQgVCAgID0gdGV4dHVyZVNhbXBsZSh1UHJlcywgc2FtcCwgaS52VCkueDsKICBsZXQgQiAgID0gdGV4dHVyZVNhbXBsZSh1UHJlcywgc2FtcCwgaS52QikueDsKICBsZXQgdmVsID0gdGV4dHVyZVNhbXBsZSh1VmVsLCBzYW1wLCBpLnV2KS54eSAtIHZlYzJmKFIgLSBMLCBUIC0gQik7CiAgaWYgKG9icyA+IDAuNSkgeyByZXR1cm4gdmVjNGYoMC4wKTsgfQogIHJldHVybiB2ZWM0Zih2ZWwsIDAuMCwgMS4wKTsKfQpgCiksIHp0ID0gKAogIC8qIHdnc2wgKi8KICBgCiR7bGV9CgovLyB0ZXhlbFNpemUgb2NjdXBpZXMgYnl0ZXMgMC03IGZvciB0aGUgc2hhcmVkIHZlcnRleCBzdGFnZTsgYXNwZWN0UmF0aW8vcmFkaXVzIGZpbGwgdGhlIHJlc3QuCnN0cnVjdCBVIHsKICB0ZXhlbFNpemUgIDogdmVjMmYsCiAgYXNwZWN0UmF0aW86IGYzMiwKICByYWRpdXMgICAgIDogZjMyLAogIGNvbG9yICAgICAgOiB2ZWM0ZiwgIC8vIHh5eiA9IGNvbG91ciwgdyB1bnVzZWQKICBwb2ludCAgICAgIDogdmVjMmYsCiAgX3BhZCAgICAgICA6IHZlYzJmLAp9CkBncm91cCgwKSBAYmluZGluZygwKSB2YXI8dW5pZm9ybT4gdSAgICA6IFU7CkBncm91cCgwKSBAYmluZGluZygxKSB2YXIgICAgICAgICAgc2FtcCA6IHNhbXBsZXI7CkBncm91cCgwKSBAYmluZGluZygyKSB2YXIgICAgICAgICAgdVRndCA6IHRleHR1cmVfMmQ8ZjMyPjsKCkB2ZXJ0ZXggZm4gdnMoQGxvY2F0aW9uKDApIGE6IHZlYzJmKSAtPiBWU091dCB7CiAgdmFyIG86IFZTT3V0OwogIG8udXYgPSB2ZWMyZihhLnggKiAwLjUgKyAwLjUsIDAuNSAtIGEueSAqIDAuNSk7CiAgby52TCA9IG8udXYgLSB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlIgPSBvLnV2ICsgdmVjMmYodS50ZXhlbFNpemUueCwgMC4wKTsKICBvLnZUID0gby51diArIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby52QiA9IG8udXYgLSB2ZWMyZigwLjAsIHUudGV4ZWxTaXplLnkpOwogIG8ucG9zID0gdmVjNGYoYSwgMC4wLCAxLjApOwogIHJldHVybiBvOwp9CgpAZnJhZ21lbnQgZm4gZnMoaTogVlNPdXQpIC0+IEBsb2NhdGlvbigwKSB2ZWM0ZiB7CiAgdmFyIHAgID0gaS51diAtIHUucG9pbnQ7CiAgcC54ICAgKj0gdS5hc3BlY3RSYXRpbzsKICBsZXQgc3AgPSBleHAoLWRvdChwLCBwKSAvIHUucmFkaXVzKSAqIHUuY29sb3IueHl6OwogIHJldHVybiB2ZWM0Zih0ZXh0dXJlU2FtcGxlKHVUZ3QsIHNhbXAsIGkudXYpLnh5eiArIHNwLCAxLjApOwp9CmAKKSwgTXQgPSAoCiAgLyogd2dzbCAqLwogIGAKJHtsZX0KCnN0cnVjdCBVIHsgdGV4ZWxTaXplOiB2ZWMyZiwgX3BhZDogdmVjMmYgfQpAZ3JvdXAoMCkgQGJpbmRpbmcoMCkgdmFyPHVuaWZvcm0+IHUgICAgOiBVOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMSkgdmFyICAgICAgICAgIHNhbXAgOiBzYW1wbGVyOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMikgdmFyICAgICAgICAgIHVWZWwgOiB0ZXh0dXJlXzJkPGYzMj47CgpAdmVydGV4IGZuIHZzKEBsb2NhdGlvbigwKSBhOiB2ZWMyZikgLT4gVlNPdXQgewogIHZhciBvOiBWU091dDsKICBvLnV2ID0gdmVjMmYoYS54ICogMC41ICsgMC41LCAwLjUgLSBhLnkgKiAwLjUpOwogIG8udkwgPSBvLnV2IC0gdmVjMmYodS50ZXhlbFNpemUueCwgMC4wKTsKICBvLnZSID0gby51diArIHZlYzJmKHUudGV4ZWxTaXplLngsIDAuMCk7CiAgby52VCA9IG8udXYgKyB2ZWMyZigwLjAsIHUudGV4ZWxTaXplLnkpOwogIG8udkIgPSBvLnV2IC0gdmVjMmYoMC4wLCB1LnRleGVsU2l6ZS55KTsKICBvLnBvcyA9IHZlYzRmKGEsIDAuMCwgMS4wKTsKICByZXR1cm4gbzsKfQoKQGZyYWdtZW50IGZuIGZzKGk6IFZTT3V0KSAtPiBAbG9jYXRpb24oMCkgdmVjNGYgewogIGxldCBMID0gdGV4dHVyZVNhbXBsZSh1VmVsLCBzYW1wLCBpLnZMKS55OwogIGxldCBSID0gdGV4dHVyZVNhbXBsZSh1VmVsLCBzYW1wLCBpLnZSKS55OwogIGxldCBUID0gdGV4dHVyZVNhbXBsZSh1VmVsLCBzYW1wLCBpLnZUKS54OwogIGxldCBCID0gdGV4dHVyZVNhbXBsZSh1VmVsLCBzYW1wLCBpLnZCKS54OwogIHJldHVybiB2ZWM0ZigwLjUgKiAoUiAtIEwgLSBUICsgQiksIDAuMCwgMC4wLCAxLjApOwp9CmAKKSwgR3QgPSAoCiAgLyogd2dzbCAqLwogIGAKJHtsZX0KCnN0cnVjdCBVIHsKICB0ZXhlbFNpemU6IHZlYzJmLAogIGN1cmwgICAgIDogZjMyLAogIGR0ICAgICAgIDogZjMyLAp9CkBncm91cCgwKSBAYmluZGluZygwKSB2YXI8dW5pZm9ybT4gdSAgICA6IFU7CkBncm91cCgwKSBAYmluZGluZygxKSB2YXIgICAgICAgICAgc2FtcCA6IHNhbXBsZXI7CkBncm91cCgwKSBAYmluZGluZygyKSB2YXIgICAgICAgICAgdVZlbCA6IHRleHR1cmVfMmQ8ZjMyPjsKQGdyb3VwKDApIEBiaW5kaW5nKDMpIHZhciAgICAgICAgICB1Q3JsIDogdGV4dHVyZV8yZDxmMzI+OwoKQHZlcnRleCBmbiB2cyhAbG9jYXRpb24oMCkgYTogdmVjMmYpIC0+IFZTT3V0IHsKICB2YXIgbzogVlNPdXQ7CiAgby51diA9IHZlYzJmKGEueCAqIDAuNSArIDAuNSwgMC41IC0gYS55ICogMC41KTsKICBvLnZMID0gby51diAtIHZlYzJmKHUudGV4ZWxTaXplLngsIDAuMCk7CiAgby52UiA9IG8udXYgKyB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlQgPSBvLnV2ICsgdmVjMmYoMC4wLCB1LnRleGVsU2l6ZS55KTsKICBvLnZCID0gby51diAtIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby5wb3MgPSB2ZWM0ZihhLCAwLjAsIDEuMCk7CiAgcmV0dXJuIG87Cn0KCkBmcmFnbWVudCBmbiBmcyhpOiBWU091dCkgLT4gQGxvY2F0aW9uKDApIHZlYzRmIHsKICBsZXQgTCAgICAgPSB0ZXh0dXJlU2FtcGxlKHVDcmwsIHNhbXAsIGkudkwpLng7CiAgbGV0IFIgICAgID0gdGV4dHVyZVNhbXBsZSh1Q3JsLCBzYW1wLCBpLnZSKS54OwogIGxldCBUICAgICA9IHRleHR1cmVTYW1wbGUodUNybCwgc2FtcCwgaS52VCkueDsKICBsZXQgQiAgICAgPSB0ZXh0dXJlU2FtcGxlKHVDcmwsIHNhbXAsIGkudkIpLng7CiAgbGV0IEMgICAgID0gdGV4dHVyZVNhbXBsZSh1Q3JsLCBzYW1wLCBpLnV2KS54OwogIHZhciBmb3JjZSA9IDAuNSAqIHZlYzJmKGFicyhUKSAtIGFicyhCKSwgYWJzKFIpIC0gYWJzKEwpKTsKICBmb3JjZSAgICAvPSBsZW5ndGgoZm9yY2UpICsgMC4wMDAxOwogIGZvcmNlICAgICo9IHUuY3VybCAqIDMwLjAgKiBDOwogIGxldCB2ZWwgICA9IHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS51dikueHkgKyBmb3JjZSAqIHUuZHQ7CiAgcmV0dXJuIHZlYzRmKHZlbCwgMC4wLCAxLjApOwp9CmAKKSwga3QgPSAoCiAgLyogd2dzbCAqLwogIGAKJHtsZX0KCnN0cnVjdCBVIHsKICB0ZXhlbFNpemUgICA6IHZlYzJmLAogIHJlZnJhY3Rpb24gIDogZjMyLAogIHNwZWN1bGFyRXhwIDogZjMyLAogIHdhdGVyQ29sb3IgIDogdmVjNGYsCiAgZ2xvd0NvbG9yICAgOiB2ZWM0ZiwKICBzaGluZSAgICAgICA6IGYzMiwKICB3YXJwU3RyZW5ndGg6IGYzMiwKICBhbGdvcml0aG0gICA6IGkzMiwKICBfcGFkICAgICAgICA6IGYzMiwKfQpAZ3JvdXAoMCkgQGJpbmRpbmcoMCkgdmFyPHVuaWZvcm0+IHUgICAgOiBVOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMSkgdmFyICAgICAgICAgIHNhbXAgOiBzYW1wbGVyOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMikgdmFyICAgICAgICAgIHVUZXggOiB0ZXh0dXJlXzJkPGYzMj47CkBncm91cCgwKSBAYmluZGluZygzKSB2YXIgICAgICAgICAgdU9icyA6IHRleHR1cmVfMmQ8ZjMyPjsKQGdyb3VwKDApIEBiaW5kaW5nKDQpIHZhciAgICAgICAgICB1QmcgIDogdGV4dHVyZV8yZDxmMzI+OwpAZ3JvdXAoMCkgQGJpbmRpbmcoNSkgdmFyICAgICAgICAgIHVDb3YgOiB0ZXh0dXJlXzJkPGYzMj47CkBncm91cCgwKSBAYmluZGluZyg2KSB2YXIgICAgICAgICAgdVZlbCA6IHRleHR1cmVfMmQ8ZjMyPjsKCkB2ZXJ0ZXggZm4gdnMoQGxvY2F0aW9uKDApIGE6IHZlYzJmKSAtPiBWU091dCB7CiAgdmFyIG86IFZTT3V0OwogIG8udXYgPSB2ZWMyZihhLnggKiAwLjUgKyAwLjUsIDAuNSAtIGEueSAqIDAuNSk7CiAgby52TCA9IG8udXYgLSB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlIgPSBvLnV2ICsgdmVjMmYodS50ZXhlbFNpemUueCwgMC4wKTsKICBvLnZUID0gby51diArIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby52QiA9IG8udXYgLSB2ZWMyZigwLjAsIHUudGV4ZWxTaXplLnkpOwogIG8ucG9zID0gdmVjNGYoYSwgMC4wLCAxLjApOwogIHJldHVybiBvOwp9CgpAZnJhZ21lbnQgZm4gZnMoaTogVlNPdXQpIC0+IEBsb2NhdGlvbigwKSB2ZWM0ZiB7CiAgbGV0IG9icyAgICAgPSB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudXYpLnI7CiAgbGV0IGRlbnNpdHkgPSBtYXgodGV4dHVyZVNhbXBsZSh1VGV4LCBzYW1wLCBpLnV2KS5yLCAwLjApICogKDEuMCAtIHN0ZXAoMC41LCBvYnMpKTsKICBsZXQgY292ICAgICA9IHRleHR1cmVTYW1wbGUodUNvdiwgc2FtcCwgaS51dikucjsKCiAgbGV0IHRzMiA9IHUudGV4ZWxTaXplICogMi4wOwogIGxldCBkTCAgPSBtYXgodGV4dHVyZVNhbXBsZSh1VGV4LCBzYW1wLCBpLnV2IC0gdmVjMmYodHMyLngsIDAuMCkpLnIsIDAuMCk7CiAgbGV0IGRSICA9IG1heCh0ZXh0dXJlU2FtcGxlKHVUZXgsIHNhbXAsIGkudXYgKyB2ZWMyZih0czIueCwgMC4wKSkuciwgMC4wKTsKICBsZXQgZFQgID0gbWF4KHRleHR1cmVTYW1wbGUodVRleCwgc2FtcCwgaS51diArIHZlYzJmKDAuMCwgdHMyLnkpKS5yLCAwLjApOwogIGxldCBkQiAgPSBtYXgodGV4dHVyZVNhbXBsZSh1VGV4LCBzYW1wLCBpLnV2IC0gdmVjMmYoMC4wLCB0czIueSkpLnIsIDAuMCk7CgogIGxldCBub3JtICA9IG5vcm1hbGl6ZSh2ZWMzZihkTCAtIGRSLCBkQiAtIGRULCAwLjIpKTsKICBsZXQgbGRpciAgPSBub3JtYWxpemUodmVjM2YoMC41LCAxLjAsIDAuNSkpOwogIGxldCBoYWxmViA9IG5vcm1hbGl6ZShsZGlyICsgdmVjM2YoMC4wLCAwLjAsIDEuMCkpOwogIGxldCBzcGVjICA9IHBvdyhtYXgoZG90KG5vcm0sIGhhbGZWKSwgMC4wKSwgdS5zcGVjdWxhckV4cCkgKiB1LnNoaW5lICogZGVuc2l0eTsKCiAgbGV0IGJnUmF3ID0gdGV4dHVyZVNhbXBsZSh1QmcsIHNhbXAsIGkudXYpLnJnYjsKICBsZXQgd2MgICAgPSB1LndhdGVyQ29sb3IucmdiOwogIGxldCBnYyAgICA9IHUuZ2xvd0NvbG9yLnJnYjsKICBsZXQgYmcgICAgPSBtaXgod2MsIGJnUmF3LCBjb3YpOwogIHZhciBjb2xvciA9IGJnOwoKICBpZiAodS5hbGdvcml0aG0gPT0gMSkgewogICAgbGV0IHJ1diA9IGNsYW1wKGkudXYgKyBub3JtLnh5ICogdS5yZWZyYWN0aW9uICogZGVuc2l0eSAqIDMuMCwgdmVjMmYoMC4wKSwgdmVjMmYoMS4wKSk7CiAgICBsZXQgcmJnID0gbWl4KHdjLCB0ZXh0dXJlU2FtcGxlKHVCZywgc2FtcCwgbWl4KGkudXYsIHJ1diwgMS4wIC0gb2JzKSkucmdiLCBjb3YpOwogICAgY29sb3IgICA9IHJiZyArIHNwZWMgKiBnYyAqIDIuNTsKICAgIGNvbG9yICAgPSBtaXgoY29sb3IsIGJnICogMC42LCBvYnMgKiAwLjMpOwogIH0gZWxzZSBpZiAodS5hbGdvcml0aG0gPT0gMikgewogICAgbGV0IGlua0QgPSBtaW4oZGVuc2l0eSAqIDQuMCwgMS4wKTsKICAgIGxldCBydXYgID0gY2xhbXAoaS51diArIG5vcm0ueHkgKiB1LnJlZnJhY3Rpb24gKiBkZW5zaXR5ICogMC40LCB2ZWMyZigwLjApLCB2ZWMyZigxLjApKTsKICAgIGxldCByYmcgID0gbWl4KHdjLCB0ZXh0dXJlU2FtcGxlKHVCZywgc2FtcCwgbWl4KGkudXYsIHJ1diwgMS4wIC0gb2JzKSkucmdiLCBjb3YpOwogICAgY29sb3IgICAgPSBtaXgocmJnLCB3YyArIHNwZWMgKiBnYywgaW5rRCk7CiAgICBjb2xvciAgICA9IG1peChjb2xvciwgYmcgKiAwLjUsIG9icyAqIDAuMTUpOwogIH0gZWxzZSBpZiAodS5hbGdvcml0aG0gPT0gMykgewogICAgbGV0IHZlbCAgICA9IHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS51dikueHk7CiAgICBsZXQgdmVsTWFnID0gY2xhbXAobGVuZ3RoKHZlbCkgKiAyMC4wLCAwLjAsIDEuMCk7CiAgICBsZXQgd3V2ICAgID0gY2xhbXAoaS51diArIHZlbCAqIHUud2FycFN0cmVuZ3RoLCB2ZWMyZigwLjApLCB2ZWMyZigxLjApKTsKICAgIGxldCB3YmcgICAgPSBtaXgod2MsIHRleHR1cmVTYW1wbGUodUJnLCBzYW1wLCB3dXYpLnJnYiwgY292KTsKICAgIGNvbG9yICAgICAgPSBtaXgoYmcsIHdiZywgdmVsTWFnICogKDEuMCAtIG9icykpOwogICAgY29sb3IgICAgICs9IHNwZWMgKiBnYyAqIHZlbE1hZyAqIDEuNTsKICAgIGNvbG9yICAgICArPSB3YyAqIGRlbnNpdHkgKiAwLjM7CiAgICBjb2xvciAgICAgID0gbWl4KGNvbG9yLCBiZyAqIDAuNSwgb2JzICogMC4yKTsKICB9IGVsc2UgaWYgKHUuYWxnb3JpdGhtID09IDQpIHsKICAgIGxldCBydXYgICA9IGNsYW1wKGkudXYgKyBub3JtLnh5ICogdS5yZWZyYWN0aW9uICogZGVuc2l0eSAqIDYuMCwgdmVjMmYoMC4wKSwgdmVjMmYoMS4wKSk7CiAgICBsZXQgcmJnICAgPSBtaXgod2MsIHRleHR1cmVTYW1wbGUodUJnLCBzYW1wLCBtaXgoaS51diwgcnV2LCAxLjAgLSBvYnMpKS5yZ2IsIGNvdik7CiAgICBsZXQgZnJlcyAgPSBwb3coY2xhbXAoMS4wIC0gZG90KG5vcm0sIHZlYzNmKDAuMCwgMC4wLCAxLjApKSwgMC4wLCAxLjApLCAzLjApICogZGVuc2l0eTsKICAgIGNvbG9yICAgICA9IHJiZzsKICAgIGNvbG9yICAgICs9IGZyZXMgKiBnYyAqIDIuMDsKICAgIGNvbG9yICAgICs9IHNwZWMgKiBnYyAqIGRlbnNpdHkgKiAyLjA7CiAgICBjb2xvciAgICAgPSBtaXgoY29sb3IsIGJnICogMC41LCBvYnMgKiAwLjIpOwogIH0gZWxzZSB7CiAgICBsZXQgcnV2ID0gaS51diArIG5vcm0ueHkgKiB1LnJlZnJhY3Rpb24gKiBkZW5zaXR5OwogICAgbGV0IHJiZyA9IG1peCh3YywgdGV4dHVyZVNhbXBsZSh1QmcsIHNhbXAsIG1peChpLnV2LCBydXYsIDEuMCAtIG9icykpLnJnYiwgY292KTsKICAgIGNvbG9yICAgPSBtaXgocmJnLCB3YywgbWluKGRlbnNpdHkgKiAxLjUsIDAuOCkpOwogICAgY29sb3IgICs9IHNwZWMgKiBnYzsKICAgIGNvbG9yICAgPSBtaXgoY29sb3IsIGJnICogMC41LCBvYnMgKiAwLjIpOwogIH0KCiAgbGV0IGFscGhhID0gY2xhbXAobWF4KGRlbnNpdHkgKiAxLjUsIGNvdiksIDAuMCwgMS4wKTsKICByZXR1cm4gdmVjNGYoY29sb3IgKiBhbHBoYSwgYWxwaGEpOwp9CmAKKSwgSXQgPSB7CiAgYXJyYXlTdHJpZGU6IDgsCiAgYXR0cmlidXRlczogW3sgc2hhZGVyTG9jYXRpb246IDAsIG9mZnNldDogMCwgZm9ybWF0OiAiZmxvYXQzMngyIiB9XQp9LCBhdCA9IG5ldyBGbG9hdDMyQXJyYXkoWwogIC0xLAogIC0xLAogIC0xLAogIDEsCiAgMSwKICAtMSwKICAxLAogIC0xLAogIC0xLAogIDEsCiAgMSwKICAxCl0pOwpmdW5jdGlvbiBXdChpKSB7CiAgY29uc3QgZSA9IGkuY3JlYXRlQnVmZmVyKHsgc2l6ZTogYXQuYnl0ZUxlbmd0aCwgdXNhZ2U6IEdQVUJ1ZmZlclVzYWdlLlZFUlRFWCB8IEdQVUJ1ZmZlclVzYWdlLkNPUFlfRFNUIH0pOwogIHJldHVybiBpLnF1ZXVlLndyaXRlQnVmZmVyKGUsIDAsIGF0KSwgZTsKfQpmdW5jdGlvbiBOZShpLCBlLCByLCBzKSB7CiAgY29uc3QgbyA9IGkuY3JlYXRlVGV4dHVyZSh7CiAgICBzaXplOiBbciwgc10sCiAgICBmb3JtYXQ6IGUsCiAgICB1c2FnZTogR1BVVGV4dHVyZVVzYWdlLlRFWFRVUkVfQklORElORyB8IEdQVVRleHR1cmVVc2FnZS5SRU5ERVJfQVRUQUNITUVOVCB8IEdQVVRleHR1cmVVc2FnZS5DT1BZX1NSQwogIH0pOwogIHJldHVybiB7IHRleDogbywgdmlldzogby5jcmVhdGVWaWV3KCksIHdpZHRoOiByLCBoZWlnaHQ6IHMgfTsKfQpmdW5jdGlvbiBldChpLCBlLCByLCBzKSB7CiAgbGV0IG8gPSBOZShpLCBlLCByLCBzKSwgYSA9IE5lKGksIGUsIHIsIHMpOwogIHJldHVybiB7CiAgICBnZXQgcmVhZCgpIHsKICAgICAgcmV0dXJuIG87CiAgICB9LAogICAgZ2V0IHdyaXRlKCkgewogICAgICByZXR1cm4gYTsKICAgIH0sCiAgICBzd2FwKCkgewogICAgICBbbywgYV0gPSBbYSwgb107CiAgICB9LAogICAgZGlzcG9zZSgpIHsKICAgICAgby50ZXguZGVzdHJveSgpLCBhLnRleC5kZXN0cm95KCk7CiAgICB9CiAgfTsKfQpmdW5jdGlvbiBzZShpLCBlLCByKSB7CiAgY29uc3QgcyA9IGkuY3JlYXRlU2hhZGVyTW9kdWxlKHsgY29kZTogZSB9KTsKICByZXR1cm4gaS5jcmVhdGVSZW5kZXJQaXBlbGluZSh7CiAgICBsYXlvdXQ6ICJhdXRvIiwKICAgIHZlcnRleDogeyBtb2R1bGU6IHMsIGVudHJ5UG9pbnQ6ICJ2cyIsIGJ1ZmZlcnM6IFtJdF0gfSwKICAgIGZyYWdtZW50OiB7IG1vZHVsZTogcywgZW50cnlQb2ludDogImZzIiwgdGFyZ2V0czogW3sgZm9ybWF0OiByIH1dIH0sCiAgICBwcmltaXRpdmU6IHsgdG9wb2xvZ3k6ICJ0cmlhbmdsZS1saXN0IiB9CiAgfSk7Cn0KZnVuY3Rpb24gJHQoaSwgZSkgewogIGNvbnN0IHIgPSAicmdiYTE2ZmxvYXQiOwogIHJldHVybiB7CiAgICBhZHZlY3Rpb246IHNlKGksIEZ0LCByKSwKICAgIGRpdmVyZ2VuY2U6IHNlKGksIEx0LCByKSwKICAgIHByZXNzdXJlOiBzZShpLCBBdCwgciksCiAgICBncmFkaWVudFN1YnRyYWN0OiBzZShpLCBYdCwgciksCiAgICBzcGxhdDogc2UoaSwgenQsIHIpLAogICAgY3VybDogc2UoaSwgTXQsIHIpLAogICAgdm9ydGljaXR5OiBzZShpLCBHdCwgciksCiAgICBkaXNwbGF5OiBzZShpLCBrdCwgZSkKICB9Owp9CmZ1bmN0aW9uIE50KGkpIHsKICByZXR1cm4gaS5jcmVhdGVTYW1wbGVyKHsgbWFnRmlsdGVyOiAibGluZWFyIiwgbWluRmlsdGVyOiAibGluZWFyIiwgYWRkcmVzc01vZGVVOiAiY2xhbXAtdG8tZWRnZSIsIGFkZHJlc3NNb2RlVjogImNsYW1wLXRvLWVkZ2UiIH0pOwp9CmZ1bmN0aW9uIFcoaSwgZSkgewogIHJldHVybiBpLmNyZWF0ZUJ1ZmZlcih7IHNpemU6IGUsIHVzYWdlOiBHUFVCdWZmZXJVc2FnZS5VTklGT1JNIHwgR1BVQnVmZmVyVXNhZ2UuQ09QWV9EU1QgfSk7Cn0KZnVuY3Rpb24gdXQoaSwgZSwgciwgcywgbywgYSkgewogIGNvbnN0IG4gPSBuZXcgRmxvYXQzMkFycmF5KFtyLCBzLCBvLCBhXSk7CiAgaS5xdWV1ZS53cml0ZUJ1ZmZlcihlLCAwLCBuKTsKfQpmdW5jdGlvbiBJZShpLCBlLCByLCBzKSB7CiAgY29uc3QgbyA9IG5ldyBGbG9hdDMyQXJyYXkoW3IsIHMsIDAsIDBdKTsKICBpLnF1ZXVlLndyaXRlQnVmZmVyKGUsIDAsIG8pOwp9CmZ1bmN0aW9uIHF0KGksIGUsIHIsIHMsIG8sIGEpIHsKICBjb25zdCBuID0gbmV3IEZsb2F0MzJBcnJheShbciwgcywgbywgYV0pOwogIGkucXVldWUud3JpdGVCdWZmZXIoZSwgMCwgbik7Cn0KZnVuY3Rpb24gV2UoaSwgZSwgciwgcywgbywgYSwgbiwgeCwgbSwgbCwgcCkgewogIGNvbnN0IGMgPSBuZXcgRmxvYXQzMkFycmF5KDEyKTsKICBjWzBdID0gciwgY1sxXSA9IHMsIGNbMl0gPSBvLCBjWzNdID0gYSwgY1s0XSA9IG4sIGNbNV0gPSB4LCBjWzZdID0gbSwgY1s3XSA9IDAsIGNbOF0gPSBsLCBjWzldID0gcCwgY1sxMF0gPSAwLCBjWzExXSA9IDAsIGkucXVldWUud3JpdGVCdWZmZXIoZSwgMCwgYyk7Cn0KZnVuY3Rpb24gSHQoaSwgZSwgciwgcywgbywgYSwgbiwgeCwgbSwgbCwgcCkgewogIGNvbnN0IGMgPSBuZXcgRmxvYXQzMkFycmF5KDE2KSwgZiA9IG5ldyBJbnQzMkFycmF5KGMuYnVmZmVyKTsKICBjWzBdID0gciwgY1sxXSA9IHMsIGNbMl0gPSBvLCBjWzNdID0gYSwgY1s0XSA9IG5bMF0sIGNbNV0gPSBuWzFdLCBjWzZdID0gblsyXSwgY1s3XSA9IDAsIGNbOF0gPSB4WzBdLCBjWzldID0geFsxXSwgY1sxMF0gPSB4WzJdLCBjWzExXSA9IDAsIGNbMTJdID0gbSwgY1sxM10gPSBsLCBmWzE0XSA9IHAsIGkucXVldWUud3JpdGVCdWZmZXIoZSwgMCwgYyk7Cn0KZnVuY3Rpb24geihpLCBlLCByLCBzLCBvKSB7CiAgY29uc3QgYSA9IGkuYmVnaW5SZW5kZXJQYXNzKHsKICAgIGNvbG9yQXR0YWNobWVudHM6IFt7CiAgICAgIHZpZXc6IG8sCiAgICAgIGNsZWFyVmFsdWU6IFswLCAwLCAwLCAwXSwKICAgICAgbG9hZE9wOiAiY2xlYXIiLAogICAgICBzdG9yZU9wOiAic3RvcmUiCiAgICB9XQogIH0pOwogIGEuc2V0UGlwZWxpbmUoZSksIGEuc2V0QmluZEdyb3VwKDAsIHIpLCBhLnNldFZlcnRleEJ1ZmZlcigwLCBzKSwgYS5kcmF3KDYpLCBhLmVuZCgpOwp9CmZ1bmN0aW9uIFl0KGksIGUsIHIsIHMsIG8pIHsKICBjb25zdCBhID0gaS5iZWdpblJlbmRlclBhc3MoewogICAgY29sb3JBdHRhY2htZW50czogW3sKICAgICAgdmlldzogbywKICAgICAgY2xlYXJWYWx1ZTogWzAsIDAsIDAsIDBdLAogICAgICBsb2FkT3A6ICJjbGVhciIsCiAgICAgIHN0b3JlT3A6ICJzdG9yZSIKICAgIH1dCiAgfSk7CiAgYS5zZXRQaXBlbGluZShlKSwgYS5zZXRCaW5kR3JvdXAoMCwgciksIGEuc2V0VmVydGV4QnVmZmVyKDAsIHMpLCBhLmRyYXcoNiksIGEuZW5kKCk7Cn0KZnVuY3Rpb24gQ2UoaSwgZSwgciwgcywgbyA9ICJjb3ZlciIpIHsKICBsZXQgYTsKICBvID09PSAiY292ZXIiID8gYSA9IE1hdGgubWF4KHIgLyBpLCBzIC8gZSkgOiBvID09PSAiY29udGFpbiIgPyBhID0gTWF0aC5taW4ociAvIGksIHMgLyBlKSA6IHR5cGVvZiBvID09ICJzdHJpbmciICYmIG8uZW5kc1dpdGgoIiUiKSA/IGEgPSBNYXRoLm1pbihyIC8gaSwgcyAvIGUpICogKHBhcnNlRmxvYXQobykgLyAxMDApIDogdHlwZW9mIG8gPT0gInN0cmluZyIgJiYgby5lbmRzV2l0aCgicHgiKSA/IGEgPSBwYXJzZUZsb2F0KG8pIC8gTWF0aC5tYXgoaSwgZSkgOiB0eXBlb2YgbyA9PSAibnVtYmVyIiA/IGEgPSBvIDogYSA9IE1hdGgubWF4KHIgLyBpLCBzIC8gZSk7CiAgY29uc3QgbiA9IGkgKiBhLCB4ID0gZSAqIGE7CiAgcmV0dXJuIHsgeDogKHIgLSBuKSAvIDIsIHk6IChzIC0geCkgLyAyLCBkcmF3VzogbiwgZHJhd0g6IHggfTsKfQpmdW5jdGlvbiBRdChpLCBlLCByLCBzLCBvID0gbnVsbCwgYSA9ICJjb3ZlciIpIHsKICBjb25zdCB7IHRleHQ6IG4sIGZvbnRTaXplOiB4LCBjb2xvcjogbSwgZm9udEZhbWlseTogbCA9ICJzYW5zLXNlcmlmIiwgZm9udFdlaWdodDogcCA9IDkwMCB9ID0gcywgYyA9IG5ldyBPZmZzY3JlZW5DYW52YXMoZSwgciksIGYgPSBjLmdldENvbnRleHQoIjJkIik7CiAgKChEKSA9PiB7CiAgICBpZiAobykgewogICAgICBmLmNsZWFyUmVjdCgwLCAwLCBlLCByKSwgZi5maWxsU3R5bGUgPSAiYmxhY2siLCBmLmZpbGxSZWN0KDAsIDAsIGUsIHIpOwogICAgICBjb25zdCB7IHg6IGcsIHk6IF8sIGRyYXdXOiBGLCBkcmF3SDogSSB9ID0gQ2UoCiAgICAgICAgby53aWR0aCwKICAgICAgICBvLmhlaWdodCwKICAgICAgICBlLAogICAgICAgIHIsCiAgICAgICAgYQogICAgICApOwogICAgICBmLmRyYXdJbWFnZShvLCBnLCBfLCBGLCBJKTsKICAgIH0gZWxzZQogICAgICBmLmZpbGxTdHlsZSA9ICJibGFjayIsIGYuZmlsbFJlY3QoMCwgMCwgZSwgcik7CiAgICBmLmZpbGxTdHlsZSA9IEQsIGYuZm9udCA9IGAke3B9ICR7eH1weCAke2x9YCwgZi50ZXh0QWxpZ24gPSAiY2VudGVyIiwgZi50ZXh0QmFzZWxpbmUgPSAibWlkZGxlIiwgZi5maWxsVGV4dChuLCBlIC8gMiwgciAvIDIpOwogIH0pKG0pOwogIGNvbnN0IGIgPSBGZShpLCBjKTsKICBmLmZpbGxTdHlsZSA9ICJibGFjayIsIGYuZmlsbFJlY3QoMCwgMCwgZSwgciksIGYuZmlsbFN0eWxlID0gIndoaXRlIiwgZi5mb250ID0gYCR7cH0gJHt4fXB4ICR7bH1gLCBmLnRleHRBbGlnbiA9ICJjZW50ZXIiLCBmLnRleHRCYXNlbGluZSA9ICJtaWRkbGUiLCBmLmZpbGxUZXh0KG4sIGUgLyAyLCByIC8gMik7CiAgY29uc3QgeSA9IEZlKGksIGMpOwogIHJldHVybiB7IGJhY2tncm91bmRUZXg6IGIsIG9ic3RhY2xlVGV4OiB5LCBjb3ZlcmFnZVRleDogeSB9Owp9CmZ1bmN0aW9uIGp0KGksIGUsIHIsIHMsIG8gPSAwLCBhID0gImNvdmVyIiwgbiA9IG51bGwsIHggPSAiY292ZXIiKSB7CiAgY29uc3QgbSA9IG5ldyBPZmZzY3JlZW5DYW52YXMociwgcyksIGwgPSBtLmdldENvbnRleHQoIjJkIiksIHsgeDogcCwgeTogYywgZHJhd1c6IGYsIGRyYXdIOiBkIH0gPSBDZShlLndpZHRoLCBlLmhlaWdodCwgciwgcywgYSk7CiAgaWYgKGwuY2xlYXJSZWN0KDAsIDAsIHIsIHMpLCBsLmZpbGxTdHlsZSA9ICJibGFjayIsIGwuZmlsbFJlY3QoMCwgMCwgciwgcyksIG4pIHsKICAgIGNvbnN0IHsKICAgICAgeDogZywKICAgICAgeTogXywKICAgICAgZHJhd1c6IEYsCiAgICAgIGRyYXdIOiBJCiAgICB9ID0gQ2Uobi53aWR0aCwgbi5oZWlnaHQsIHIsIHMsIHgpOwogICAgbC5maWx0ZXIgPSBgYnJpZ2h0bmVzcygke299KSBibHVyKDhweClgLCBsLmRyYXdJbWFnZShuLCBnLCBfLCBGLCBJKSwgbC5maWx0ZXIgPSAibm9uZSI7CiAgfQogIGwuZHJhd0ltYWdlKGUsIHAsIGMsIGYsIGQpOwogIGNvbnN0IGIgPSBGZShpLCBtKTsKICBsLmNsZWFyUmVjdCgwLCAwLCByLCBzKSwgbC5maWxsU3R5bGUgPSAiYmxhY2siLCBsLmZpbGxSZWN0KDAsIDAsIHIsIHMpLCBsLmZpbHRlciA9IGBicmlnaHRuZXNzKCR7b30pIGJsdXIoOHB4KWAsIGwuZHJhd0ltYWdlKGUsIHAsIGMsIGYsIGQpLCBsLmZpbHRlciA9ICJub25lIjsKICBjb25zdCB5ID0gRmUoaSwgbSk7CiAgbC5jbGVhclJlY3QoMCwgMCwgciwgcyksIGwuZmlsbFN0eWxlID0gImJsYWNrIiwgbC5maWxsUmVjdCgwLCAwLCByLCBzKSwgbC5maWxsU3R5bGUgPSAid2hpdGUiLCBsLmZpbGxSZWN0KAogICAgTWF0aC5tYXgoMCwgcCksCiAgICBNYXRoLm1heCgwLCBjKSwKICAgIE1hdGgubWluKGYsIHIgLSBNYXRoLm1heCgwLCBwKSksCiAgICBNYXRoLm1pbihkLCBzIC0gTWF0aC5tYXgoMCwgYykpCiAgKTsKICBjb25zdCBEID0gRmUoaSwgbSk7CiAgcmV0dXJuIHsgYmFja2dyb3VuZFRleDogYiwgb2JzdGFjbGVUZXg6IHksIGNvdmVyYWdlVGV4OiBEIH07Cn0KZnVuY3Rpb24gRmUoaSwgZSkgewogIGNvbnN0IHIgPSBpLmNyZWF0ZVRleHR1cmUoKTsKICByZXR1cm4gaS5iaW5kVGV4dHVyZShpLlRFWFRVUkVfMkQsIHIpLCBpLnBpeGVsU3RvcmVpKGkuVU5QQUNLX0ZMSVBfWV9XRUJHTCwgITApLCBpLnRleEltYWdlMkQoaS5URVhUVVJFXzJELCAwLCBpLlJHQkEsIGkuUkdCQSwgaS5VTlNJR05FRF9CWVRFLCBlKSwgaS50ZXhQYXJhbWV0ZXJpKGkuVEVYVFVSRV8yRCwgaS5URVhUVVJFX01JTl9GSUxURVIsIGkuTElORUFSKSwgaS50ZXhQYXJhbWV0ZXJpKGkuVEVYVFVSRV8yRCwgaS5URVhUVVJFX01BR19GSUxURVIsIGkuTElORUFSKSwgaS50ZXhQYXJhbWV0ZXJpKGkuVEVYVFVSRV8yRCwgaS5URVhUVVJFX1dSQVBfUywgaS5DTEFNUF9UT19FREdFKSwgaS50ZXhQYXJhbWV0ZXJpKGkuVEVYVFVSRV8yRCwgaS5URVhUVVJFX1dSQVBfVCwgaS5DTEFNUF9UT19FREdFKSwgcjsKfQpmdW5jdGlvbiBLdChpLCBlLCByLCBzLCBvID0gbnVsbCwgYSA9ICJjb3ZlciIpIHsKICBjb25zdCB7IHRleHQ6IG4sIGZvbnRTaXplOiB4LCBjb2xvcjogbSwgZm9udEZhbWlseTogbCA9ICJzYW5zLXNlcmlmIiwgZm9udFdlaWdodDogcCA9IDkwMCB9ID0gcywgYyA9IG5ldyBPZmZzY3JlZW5DYW52YXMoZSwgciksIGYgPSBjLmdldENvbnRleHQoIjJkIik7CiAgKChEKSA9PiB7CiAgICBpZiAobykgewogICAgICBmLmNsZWFyUmVjdCgwLCAwLCBlLCByKSwgZi5maWxsU3R5bGUgPSAiYmxhY2siLCBmLmZpbGxSZWN0KDAsIDAsIGUsIHIpOwogICAgICBjb25zdCB7IHg6IGcsIHk6IF8sIGRyYXdXOiBGLCBkcmF3SDogSSB9ID0gQ2UoCiAgICAgICAgby53aWR0aCwKICAgICAgICBvLmhlaWdodCwKICAgICAgICBlLAogICAgICAgIHIsCiAgICAgICAgYQogICAgICApOwogICAgICBmLmRyYXdJbWFnZShvLCBnLCBfLCBGLCBJKTsKICAgIH0gZWxzZQogICAgICBmLmZpbGxTdHlsZSA9ICJibGFjayIsIGYuZmlsbFJlY3QoMCwgMCwgZSwgcik7CiAgICBmLmZpbGxTdHlsZSA9IEQsIGYuZm9udCA9IGAke3B9ICR7eH1weCAke2x9YCwgZi50ZXh0QWxpZ24gPSAiY2VudGVyIiwgZi50ZXh0QmFzZWxpbmUgPSAibWlkZGxlIiwgZi5maWxsVGV4dChuLCBlIC8gMiwgciAvIDIpOwogIH0pKG0pOwogIGNvbnN0IGIgPSBMZShpLCBjLCBlLCByKTsKICBmLmZpbGxTdHlsZSA9ICJibGFjayIsIGYuZmlsbFJlY3QoMCwgMCwgZSwgciksIGYuZmlsbFN0eWxlID0gIndoaXRlIiwgZi5mb250ID0gYCR7cH0gJHt4fXB4ICR7bH1gLCBmLnRleHRBbGlnbiA9ICJjZW50ZXIiLCBmLnRleHRCYXNlbGluZSA9ICJtaWRkbGUiLCBmLmZpbGxUZXh0KG4sIGUgLyAyLCByIC8gMik7CiAgY29uc3QgeSA9IExlKGksIGMsIGUsIHIpOwogIHJldHVybiB7CiAgICBiYWNrZ3JvdW5kVGV4OiBiLAogICAgYmFja2dyb3VuZFZpZXc6IGIuY3JlYXRlVmlldygpLAogICAgb2JzdGFjbGVUZXg6IHksCiAgICBvYnN0YWNsZVZpZXc6IHkuY3JlYXRlVmlldygpLAogICAgY292ZXJhZ2VUZXg6IHksCiAgICBjb3ZlcmFnZVZpZXc6IHkuY3JlYXRlVmlldygpLAogICAgc2hhcmVkQ292ZXJhZ2U6ICEwCiAgfTsKfQpmdW5jdGlvbiBKdChpLCBlLCByLCBzLCBvID0gMCwgYSA9ICJjb3ZlciIsIG4gPSBudWxsLCB4ID0gImNvdmVyIikgewogIGNvbnN0IG0gPSBuZXcgT2Zmc2NyZWVuQ2FudmFzKHIsIHMpLCBsID0gbS5nZXRDb250ZXh0KCIyZCIpLCB7IHg6IHAsIHk6IGMsIGRyYXdXOiBmLCBkcmF3SDogZCB9ID0gQ2UoZS53aWR0aCwgZS5oZWlnaHQsIHIsIHMsIGEpOwogIGlmIChsLmNsZWFyUmVjdCgwLCAwLCByLCBzKSwgbC5maWxsU3R5bGUgPSAiYmxhY2siLCBsLmZpbGxSZWN0KDAsIDAsIHIsIHMpLCBuKSB7CiAgICBjb25zdCB7IHg6IGcsIHk6IF8sIGRyYXdXOiBGLCBkcmF3SDogSSB9ID0gQ2UoCiAgICAgIG4ud2lkdGgsCiAgICAgIG4uaGVpZ2h0LAogICAgICByLAogICAgICBzLAogICAgICB4CiAgICApOwogICAgbC5maWx0ZXIgPSBgYnJpZ2h0bmVzcygke299KSBibHVyKDhweClgLCBsLmRyYXdJbWFnZShuLCBnLCBfLCBGLCBJKSwgbC5maWx0ZXIgPSAibm9uZSI7CiAgfQogIGwuZHJhd0ltYWdlKGUsIHAsIGMsIGYsIGQpOwogIGNvbnN0IGIgPSBMZShpLCBtLCByLCBzKTsKICBsLmNsZWFyUmVjdCgwLCAwLCByLCBzKSwgbC5maWxsU3R5bGUgPSAiYmxhY2siLCBsLmZpbGxSZWN0KDAsIDAsIHIsIHMpLCBsLmZpbHRlciA9IGBicmlnaHRuZXNzKCR7b30pIGJsdXIoOHB4KWAsIGwuZHJhd0ltYWdlKGUsIHAsIGMsIGYsIGQpLCBsLmZpbHRlciA9ICJub25lIjsKICBjb25zdCB5ID0gTGUoaSwgbSwgciwgcyk7CiAgbC5jbGVhclJlY3QoMCwgMCwgciwgcyksIGwuZmlsbFN0eWxlID0gImJsYWNrIiwgbC5maWxsUmVjdCgwLCAwLCByLCBzKSwgbC5maWxsU3R5bGUgPSAid2hpdGUiLCBsLmZpbGxSZWN0KE1hdGgubWF4KDAsIHApLCBNYXRoLm1heCgwLCBjKSwgTWF0aC5taW4oZiwgciAtIE1hdGgubWF4KDAsIHApKSwgTWF0aC5taW4oZCwgcyAtIE1hdGgubWF4KDAsIGMpKSk7CiAgY29uc3QgRCA9IExlKGksIG0sIHIsIHMpOwogIHJldHVybiB7CiAgICBiYWNrZ3JvdW5kVGV4OiBiLAogICAgYmFja2dyb3VuZFZpZXc6IGIuY3JlYXRlVmlldygpLAogICAgb2JzdGFjbGVUZXg6IHksCiAgICBvYnN0YWNsZVZpZXc6IHkuY3JlYXRlVmlldygpLAogICAgY292ZXJhZ2VUZXg6IEQsCiAgICBjb3ZlcmFnZVZpZXc6IEQuY3JlYXRlVmlldygpLAogICAgc2hhcmVkQ292ZXJhZ2U6ICExCiAgfTsKfQpmdW5jdGlvbiBMZShpLCBlLCByLCBzKSB7CiAgY29uc3QgbyA9IGkuY3JlYXRlVGV4dHVyZSh7CiAgICBzaXplOiBbciwgc10sCiAgICBmb3JtYXQ6ICJyZ2JhOHVub3JtIiwKICAgIHVzYWdlOiBHUFVUZXh0dXJlVXNhZ2UuVEVYVFVSRV9CSU5ESU5HIHwgR1BVVGV4dHVyZVVzYWdlLkNPUFlfRFNUIHwgR1BVVGV4dHVyZVVzYWdlLlJFTkRFUl9BVFRBQ0hNRU5UCiAgfSk7CiAgcmV0dXJuIGkucXVldWUuY29weUV4dGVybmFsSW1hZ2VUb1RleHR1cmUoCiAgICB7IHNvdXJjZTogZSB9LAogICAgeyB0ZXh0dXJlOiBvIH0sCiAgICBbciwgc10KICApLCBvOwp9CmFzeW5jIGZ1bmN0aW9uIFp0KGkpIHsKICBjb25zdCBlID0gYXdhaXQgZmV0Y2goaSk7CiAgaWYgKCFlLm9rKQogICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gZmV0Y2ggaW1hZ2U6ICR7aX0gKCR7ZS5zdGF0dXN9KWApOwogIGNvbnN0IHIgPSBhd2FpdCBlLmJsb2IoKTsKICByZXR1cm4gY3JlYXRlSW1hZ2VCaXRtYXAocik7Cn0KY29uc3QgbnQgPSB0eXBlb2YgcmVxdWVzdEFuaW1hdGlvbkZyYW1lIDwgInUiID8gcmVxdWVzdEFuaW1hdGlvbkZyYW1lLmJpbmQoZ2xvYmFsVGhpcykgOiAoaSkgPT4gc2V0VGltZW91dChpLCAxZTMgLyA2MCksIGVyID0gdHlwZW9mIGNhbmNlbEFuaW1hdGlvbkZyYW1lIDwgInUiID8gY2FuY2VsQW5pbWF0aW9uRnJhbWUuYmluZChnbG9iYWxUaGlzKSA6IGNsZWFyVGltZW91dCwgVmUgPSAwLjAxNiwgbHQgPSB7IHN0YW5kYXJkOiAwLCBnbGFzczogMSwgaW5rOiAyLCBhdXJvcmE6IDMsIHJpcHBsZTogNCB9Owp2YXIgY2UsIE0sIEFlLCBmZSwgRWUsIEIsIFIsIE4sIHEsIEgsIEssIEwsIFksIFAsIFVlLCB2ZSwgRGUsIFYsIFQsIG9lLCBRLCBhZSwgWCwgeGUsIHBlLCBtZSwgZGUsIGhlLCBKLCBaLCBnZSwgYmUsIFRlLCB3LCBVLCBHLCBrLCBPLCBfZSwgZWUsIEEsIHVlLCB0ZSwgaCwgQywgaiwgeWUsIFhlLCBxZSwgZnQsIFNlLCBQZSwgemUsIHJ0LCBuZSwgUmUsIHdlLCBPZSwgTWUsIGl0LCBHZSwgc3QsIEhlLCB2dCwgWWUsIHh0LCBRZSwgcHQsIGplLCBtdCwgS2UsIGR0Owpjb25zdCBvdCA9IGNsYXNzIG90IHsKICAvLyDilIDilIAgQ29uc3RydWN0b3Ig4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiAgY29uc3RydWN0b3IoZSwgciA9IHt9LCBzID0ge30sIG8pIHsKICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLy8gUHJpdmF0ZSDigJQgR1BVIGluaXRpYWxpc2F0aW9uCiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIHYodGhpcywgcWUpOwogICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAvLyBQcml2YXRlIOKAlCBzaGFyZWQgaGVscGVycwogICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICB2KHRoaXMsIFNlKTsKICAgIHYodGhpcywgemUpOwogICAgdih0aGlzLCBuZSk7CiAgICB2KHRoaXMsIHdlKTsKICAgIHYodGhpcywgTWUpOwogICAgdih0aGlzLCBHZSk7CiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8vIFByaXZhdGUg4oCUIGZyYW1lIGRpc3BhdGNoCiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIHYodGhpcywgSGUpOwogICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAvLyBQcml2YXRlIOKAlCBXZWJHUFUgc2ltdWxhdGlvbiBzdGVwCiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIHYodGhpcywgWWUpOwogICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAvLyBQcml2YXRlIOKAlCBXZWJHUFUgZGlyZWN0IHNwbGF0CiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIHYodGhpcywgUWUpOwogICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAvLyBQcml2YXRlIOKAlCBXZWJHTCBzcGxhdAogICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICB2KHRoaXMsIGplKTsKICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLy8gUHJpdmF0ZSDigJQgV2ViR0wgc2ltdWxhdGlvbiBzdGVwICh1bmNoYW5nZWQgZnJvbSBvcmlnaW5hbCkKICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgdih0aGlzLCBLZSk7CiAgICB2KHRoaXMsIGNlLCB2b2lkIDApOwogICAgLy8g4pSA4pSAIFdlYkdMIHBhdGgg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiAgICB2KHRoaXMsIE0sIG51bGwpOwogICAgdih0aGlzLCBBZSwgbnVsbCk7CiAgICB2KHRoaXMsIGZlLCBudWxsKTsKICAgIHYodGhpcywgRWUsIG51bGwpOwogICAgdih0aGlzLCBCLCBudWxsKTsKICAgIHYodGhpcywgUiwgbnVsbCk7CiAgICB2KHRoaXMsIE4sIG51bGwpOwogICAgdih0aGlzLCBxLCBudWxsKTsKICAgIHYodGhpcywgSCwgbnVsbCk7CiAgICB2KHRoaXMsIEssIG51bGwpOwogICAgdih0aGlzLCBMLCBudWxsKTsKICAgIHYodGhpcywgWSwgbnVsbCk7CiAgICAvLyDilIDilIAgV2ViR1BVIHBhdGgg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiAgICB2KHRoaXMsIFAsIG51bGwpOwogICAgdih0aGlzLCBVZSwgbnVsbCk7CiAgICB2KHRoaXMsIHZlLCBudWxsKTsKICAgIHYodGhpcywgRGUsIG51bGwpOwogICAgdih0aGlzLCBWLCBudWxsKTsKICAgIHYodGhpcywgVCwgbnVsbCk7CiAgICB2KHRoaXMsIG9lLCBudWxsKTsKICAgIHYodGhpcywgUSwgbnVsbCk7CiAgICB2KHRoaXMsIGFlLCBudWxsKTsKICAgIHYodGhpcywgWCwgbnVsbCk7CiAgICAvLyBQcmUtYWxsb2NhdGVkIHVuaWZvcm0gYnVmZmVycyAoc2l6ZXM6IHNlZSBncHUtdXRpbHMgd3JpdGVYeHggZG9jcykKICAgIC8vIFZlbG9jaXR5L2RlbnNpdHkgYWR2ZWN0aW9uIHVzZSBzZXBhcmF0ZSBidWZmZXJzIOKAlCB3cml0ZUJ1ZmZlciBpcyBhIHF1ZXVlIG9wOwogICAgLy8gYSBzZWNvbmQgd3JpdGUgdG8gdGhlIHNhbWUgYnVmZmVyIGJlZm9yZSBxdWV1ZS5zdWJtaXQoKSBhbGlhc2VzIGJvdGggcGFzc2VzLgogICAgdih0aGlzLCB4ZSwgbnVsbCk7CiAgICAvLyAxNiBieXRlcyDigJQgdmVsb2NpdHkgYWR2ZWN0aW9uCiAgICB2KHRoaXMsIHBlLCBudWxsKTsKICAgIC8vIDE2IGJ5dGVzIOKAlCBkZW5zaXR5IGFkdmVjdGlvbgogICAgdih0aGlzLCBtZSwgbnVsbCk7CiAgICAvLyAxNiBieXRlcwogICAgdih0aGlzLCBkZSwgbnVsbCk7CiAgICAvLyAxNiBieXRlcwogICAgdih0aGlzLCBoZSwgbnVsbCk7CiAgICAvLyAxNiBieXRlcwogICAgdih0aGlzLCBKLCBudWxsKTsKICAgIC8vIDQ4IGJ5dGVzIOKAlCB2ZWxvY2l0eSBzcGxhdAogICAgdih0aGlzLCBaLCBudWxsKTsKICAgIC8vIDQ4IGJ5dGVzIOKAlCBkZW5zaXR5IHNwbGF0CiAgICB2KHRoaXMsIGdlLCBudWxsKTsKICAgIC8vIDE2IGJ5dGVzCiAgICB2KHRoaXMsIGJlLCBudWxsKTsKICAgIC8vIDE2IGJ5dGVzCiAgICB2KHRoaXMsIFRlLCBudWxsKTsKICAgIC8vIDY0IGJ5dGVzCiAgICAvLyDilIDilIAgU2hhcmVkIHN0YXRlIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAogICAgdih0aGlzLCB3LCAwKTsKICAgIHYodGhpcywgVSwgMCk7CiAgICB2KHRoaXMsIEcsIDApOwogICAgdih0aGlzLCBrLCAwKTsKICAgIHYodGhpcywgTywgMSk7CiAgICB2KHRoaXMsIF9lLCAxKTsKICAgIHYodGhpcywgZWUsIDAuNSk7CiAgICB2KHRoaXMsIEEsIG51bGwpOwogICAgdih0aGlzLCB1ZSwgImNvdmVyIik7CiAgICB2KHRoaXMsIHRlLCB2b2lkIDApOwogICAgdih0aGlzLCBoLCB7IHg6IDAsIHk6IDAsIGR4OiAwLCBkeTogMCwgdGFyZ2V0WDogMCwgdGFyZ2V0WTogMCwgbW92ZWQ6ICExIH0pOwogICAgdih0aGlzLCBDLCBudWxsKTsKICAgIHYodGhpcywgaiwgbnVsbCk7CiAgICB2KHRoaXMsIHllLCAhMSk7CiAgICB2KHRoaXMsIFhlLCAhMSk7CiAgICBpZiAodSh0aGlzLCBjZSwgZSksIHUodGhpcywgX2UsIE1hdGgubWF4KDAuMSwgTWF0aC5taW4oMSwgcy5kcHIgPz8gMSkpKSwgdSh0aGlzLCBlZSwgTWF0aC5tYXgoMC4xLCBNYXRoLm1pbigxLCBzLnNpbSA/PyAwLjUpKSksIHUodGhpcywgdGUsIHl0KHIpKSwgbykKICAgICAgdSh0aGlzLCBQLCBvKSwgUyh0aGlzLCBxZSwgZnQpLmNhbGwodGhpcywgbyk7CiAgICBlbHNlIHsKICAgICAgY29uc3QgeyBnbDogYSwgZXh0OiBuIH0gPSBCdChlKTsKICAgICAgdSh0aGlzLCBNLCBhKSwgdSh0aGlzLCBBZSwgbiksIHUodGhpcywgZmUsIFB0KGEpKSwgdSh0aGlzLCBFZSwgT3QoYSkpLCBhLmNsZWFyQ29sb3IoMCwgMCwgMCwgMCk7CiAgICB9CiAgfQogIC8qKgogICAqIFdlYkdQVS1maXJzdCBmYWN0b3J5LiBUcmllcyBXZWJHUFUsIGZhbGxzIGJhY2sgdG8gV2ViR0wyIOKGkiBXZWJHTDEuCiAgICogVGhpcyBpcyB0aGUgcmVjb21tZW5kZWQgZW50cnkgcG9pbnQgd2hlbiBXZWJHUFUgc3VwcG9ydCBpcyBkZXNpcmVkLgogICAqLwogIHN0YXRpYyBhc3luYyBjcmVhdGUoZSwgciA9IHt9LCBzID0ge30sIG8gPSAhMCkgewogICAgY29uc3QgYSA9IG8gPyBhd2FpdCBWdChlKSA6IG51bGw7CiAgICByZXR1cm4gbmV3IG90KGUsIHIsIHMsIGEgPz8gdm9pZCAwKTsKICB9CiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgLy8gUHVibGljIEFQSQogIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIHNldFRleHRTb3VyY2UoZSkgewogICAgdSh0aGlzLCBDLCB7IHR5cGU6ICJ0ZXh0Iiwgb3B0czogZSB9KSwgUyh0aGlzLCBTZSwgUGUpLmNhbGwodGhpcyksIFModGhpcywgbmUsIFJlKS5jYWxsKHRoaXMpLCBTKHRoaXMsIHdlLCBPZSkuY2FsbCh0aGlzKTsKICB9CiAgYXN5bmMgc2V0SW1hZ2VTb3VyY2UoZSwgciA9IDAsIHMgPSAiY292ZXIiKSB7CiAgICBjb25zdCBvID0gYXdhaXQgWnQoZSk7CiAgICBpZiAodCh0aGlzLCBYZSkpIHsKICAgICAgby5jbG9zZSgpOwogICAgICByZXR1cm47CiAgICB9CiAgICB1KHRoaXMsIEMsIHsgdHlwZTogImltYWdlIiwgYml0bWFwOiBvLCBlZmZlY3Q6IHIsIHNpemU6IHMgfSksIFModGhpcywgU2UsIFBlKS5jYWxsKHRoaXMpLCBTKHRoaXMsIG5lLCBSZSkuY2FsbCh0aGlzKSwgUyh0aGlzLCB3ZSwgT2UpLmNhbGwodGhpcyk7CiAgfQogIHNldEltYWdlQml0bWFwKGUsIHIgPSAwLCBzID0gImNvdmVyIikgewogICAgdSh0aGlzLCBDLCB7IHR5cGU6ICJpbWFnZSIsIGJpdG1hcDogZSwgZWZmZWN0OiByLCBzaXplOiBzIH0pLCBTKHRoaXMsIFNlLCBQZSkuY2FsbCh0aGlzKSwgUyh0aGlzLCBuZSwgUmUpLmNhbGwodGhpcyksIFModGhpcywgd2UsIE9lKS5jYWxsKHRoaXMpOwogIH0KICBzZXRCYWNrZ3JvdW5kKGUsIHIgPSAiY292ZXIiKSB7CiAgICB0KHRoaXMsIEEpICYmIHQodGhpcywgQSkgIT09IGUgJiYgdCh0aGlzLCBBKS5jbG9zZSgpLCB1KHRoaXMsIEEsIGUpLCB1KHRoaXMsIHVlLCByID8/ICJjb3ZlciIpLCB0KHRoaXMsIEMpICYmIHQodGhpcywgdykgPiAwICYmIHQodGhpcywgVSkgPiAwICYmIFModGhpcywgbmUsIFJlKS5jYWxsKHRoaXMpOwogIH0KICBoYW5kbGVNb3ZlKGUsIHIsIHMgPSAxKSB7CiAgICB0KHRoaXMsIGgpLm1vdmVkID0gITAsIHQodGhpcywgaCkuZHggPSAoZSAtIHQodGhpcywgaCkudGFyZ2V0WCkgKiBzLCB0KHRoaXMsIGgpLmR5ID0gKHIgLSB0KHRoaXMsIGgpLnRhcmdldFkpICogcywgdCh0aGlzLCBoKS50YXJnZXRYID0gZSwgdCh0aGlzLCBoKS50YXJnZXRZID0gcjsKICB9CiAgLyoqCiAgICogSW1tZWRpYXRlbHkgYXBwbGllcyBvbmUgZmx1aWQgc3BsYXQgYXQgKHgsIHkpIHdpdGggZXhwbGljaXQgdmVsb2NpdHkgKHZ4LCB2eSkuCiAgICogU2FmZSB0byBjYWxsIG11bHRpcGxlIHRpbWVzIHBlciBmcmFtZSDigJQgZWFjaCBjYWxsIHdyaXRlcyBkaXJlY3RseSB0byB0aGUgRkJPcy4KICAgKiBEZXNpZ25lZCBmb3IgcHJvZ3JhbW1hdGljIHVzZSBjYXNlcyAoZS5nLiBwYXJ0aWNsZSBzeXN0ZW1zLCBhdHRyYWN0b3IgcGF0aHMpCiAgICogd2hlcmUgeW91IHdhbnQgTiBpbmRlcGVuZGVudCBpbmplY3Rpb24gcG9pbnRzIHBlciBmcmFtZSB3aXRob3V0IGZsb29kaW5nIHRoZQogICAqIG1vdXNlLXN0YXRlIG1hY2hpbmUgb3IgdGhlIHdvcmtlciBtZXNzYWdlIHF1ZXVlLgogICAqLwogIHNwbGF0KGUsIHIsIHMsIG8sIGEgPSAxKSB7CiAgICAhdCh0aGlzLCB5ZSkgfHwgdCh0aGlzLCB3KSA9PT0gMCB8fCAodCh0aGlzLCBQKSA/IFModGhpcywgUWUsIHB0KS5jYWxsKHRoaXMsIGUsIHIsIHMsIG8sIGEpIDogUyh0aGlzLCBqZSwgbXQpLmNhbGwodGhpcywgZSwgciwgcywgbywgYSkpOwogIH0KICB1cGRhdGVRdWFsaXR5KGUpIHsKICAgIGUuZHByICE9PSB2b2lkIDAgJiYgdSh0aGlzLCBfZSwgTWF0aC5tYXgoMC4xLCBNYXRoLm1pbigxLCBlLmRwcikpKSwgZS5zaW0gIT09IHZvaWQgMCAmJiB1KHRoaXMsIGVlLCBNYXRoLm1heCgwLjEsIE1hdGgubWluKDEsIGUuc2ltKSkpOwogIH0KICByZXNpemUoZSwgciwgcykgewogICAgaWYgKHMgIT09IHZvaWQgMCA/IHUodGhpcywgTywgcykgOiB0eXBlb2Ygd2luZG93IDwgInUiICYmIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvICYmIHUodGhpcywgTywgd2luZG93LmRldmljZVBpeGVsUmF0aW8pLCBlICE9PSB2b2lkIDAgJiYgZSA+IDApIHsKICAgICAgaWYgKHIgPT09IHZvaWQgMCB8fCByIDw9IDApCiAgICAgICAgcmV0dXJuOwogICAgICB1KHRoaXMsIHcsIHQodGhpcywgY2UpLndpZHRoID0gZSksIHUodGhpcywgVSwgdCh0aGlzLCBjZSkuaGVpZ2h0ID0gciksIHUodGhpcywgRywgTWF0aC5tYXgoMSwgTWF0aC5yb3VuZChlICogdCh0aGlzLCBlZSkpKSksIHUodGhpcywgaywgTWF0aC5tYXgoMSwgTWF0aC5yb3VuZChyICogdCh0aGlzLCBlZSkpKSksIFModGhpcywgemUsIHJ0KS5jYWxsKHRoaXMpOwogICAgfSBlbHNlCiAgICAgIFModGhpcywgU2UsIFBlKS5jYWxsKHRoaXMpOwogICAgdCh0aGlzLCBDKSAmJiBTKHRoaXMsIG5lLCBSZSkuY2FsbCh0aGlzKSwgUyh0aGlzLCB3ZSwgT2UpLmNhbGwodGhpcyk7CiAgfQogIHVwZGF0ZUNvbmZpZyhlKSB7CiAgICBPYmplY3QuYXNzaWduKHQodGhpcywgdGUpLCBlKTsKICB9CiAgZGVzdHJveSgpIHsKICAgIHZhciBlLCByLCBzLCBvLCBhLCBuLCB4LCBtLCBsLCBwLCBjOwogICAgaWYgKHUodGhpcywgWGUsICEwKSwgdGhpcy5zdG9wKCksIFModGhpcywgTWUsIGl0KS5jYWxsKHRoaXMpLCBTKHRoaXMsIEdlLCBzdCkuY2FsbCh0aGlzKSwgdCh0aGlzLCBBKSAmJiAodCh0aGlzLCBBKS5jbG9zZSgpLCB1KHRoaXMsIEEsIG51bGwpKSwgdCh0aGlzLCBQKSkKICAgICAgKGUgPSB0KHRoaXMsIHhlKSkgPT0gbnVsbCB8fCBlLmRlc3Ryb3koKSwgKHIgPSB0KHRoaXMsIHBlKSkgPT0gbnVsbCB8fCByLmRlc3Ryb3koKSwgKHMgPSB0KHRoaXMsIG1lKSkgPT0gbnVsbCB8fCBzLmRlc3Ryb3koKSwgKG8gPSB0KHRoaXMsIGRlKSkgPT0gbnVsbCB8fCBvLmRlc3Ryb3koKSwgKGEgPSB0KHRoaXMsIGhlKSkgPT0gbnVsbCB8fCBhLmRlc3Ryb3koKSwgKG4gPSB0KHRoaXMsIEopKSA9PSBudWxsIHx8IG4uZGVzdHJveSgpLCAoeCA9IHQodGhpcywgWikpID09IG51bGwgfHwgeC5kZXN0cm95KCksIChtID0gdCh0aGlzLCBnZSkpID09IG51bGwgfHwgbS5kZXN0cm95KCksIChsID0gdCh0aGlzLCBiZSkpID09IG51bGwgfHwgbC5kZXN0cm95KCksIChwID0gdCh0aGlzLCBUZSkpID09IG51bGwgfHwgcC5kZXN0cm95KCksIChjID0gdCh0aGlzLCB2ZSkpID09IG51bGwgfHwgYy5kZXN0cm95KCksIHQodGhpcywgUCkuZGV2aWNlLmRlc3Ryb3koKTsKICAgIGVsc2UgewogICAgICBjb25zdCBmID0gdCh0aGlzLCBNKTsKICAgICAgZm9yIChjb25zdCBiIG9mIE9iamVjdC52YWx1ZXModCh0aGlzLCBmZSkpKQogICAgICAgIGIuZGlzcG9zZSgpOwogICAgICBjb25zdCBkID0gZi5nZXRFeHRlbnNpb24oIldFQkdMX2xvc2VfY29udGV4dCIpOwogICAgICBkID09IG51bGwgfHwgZC5sb3NlQ29udGV4dCgpOwogICAgfQogIH0KICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAvLyBMb29wIGNvbnRyb2wKICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICBzdGFydCgpIHsKICAgIGlmICh0KHRoaXMsIGopICE9PSBudWxsKQogICAgICByZXR1cm47CiAgICBjb25zdCBlID0gKCkgPT4gewogICAgICBTKHRoaXMsIEhlLCB2dCkuY2FsbCh0aGlzKSwgdSh0aGlzLCBqLCBudChlKSk7CiAgICB9OwogICAgdSh0aGlzLCBqLCBudChlKSk7CiAgfQogIHN0b3AoKSB7CiAgICB0KHRoaXMsIGopICE9PSBudWxsICYmIChlcih0KHRoaXMsIGopKSwgdSh0aGlzLCBqLCBudWxsKSk7CiAgfQogIGdldCBpc1J1bm5pbmcoKSB7CiAgICByZXR1cm4gdCh0aGlzLCBqKSAhPT0gbnVsbDsKICB9Cn07CmNlID0gbmV3IFdlYWtNYXAoKSwgTSA9IG5ldyBXZWFrTWFwKCksIEFlID0gbmV3IFdlYWtNYXAoKSwgZmUgPSBuZXcgV2Vha01hcCgpLCBFZSA9IG5ldyBXZWFrTWFwKCksIEIgPSBuZXcgV2Vha01hcCgpLCBSID0gbmV3IFdlYWtNYXAoKSwgTiA9IG5ldyBXZWFrTWFwKCksIHEgPSBuZXcgV2Vha01hcCgpLCBIID0gbmV3IFdlYWtNYXAoKSwgSyA9IG5ldyBXZWFrTWFwKCksIEwgPSBuZXcgV2Vha01hcCgpLCBZID0gbmV3IFdlYWtNYXAoKSwgUCA9IG5ldyBXZWFrTWFwKCksIFVlID0gbmV3IFdlYWtNYXAoKSwgdmUgPSBuZXcgV2Vha01hcCgpLCBEZSA9IG5ldyBXZWFrTWFwKCksIFYgPSBuZXcgV2Vha01hcCgpLCBUID0gbmV3IFdlYWtNYXAoKSwgb2UgPSBuZXcgV2Vha01hcCgpLCBRID0gbmV3IFdlYWtNYXAoKSwgYWUgPSBuZXcgV2Vha01hcCgpLCBYID0gbmV3IFdlYWtNYXAoKSwgeGUgPSBuZXcgV2Vha01hcCgpLCBwZSA9IG5ldyBXZWFrTWFwKCksIG1lID0gbmV3IFdlYWtNYXAoKSwgZGUgPSBuZXcgV2Vha01hcCgpLCBoZSA9IG5ldyBXZWFrTWFwKCksIEogPSBuZXcgV2Vha01hcCgpLCBaID0gbmV3IFdlYWtNYXAoKSwgZ2UgPSBuZXcgV2Vha01hcCgpLCBiZSA9IG5ldyBXZWFrTWFwKCksIFRlID0gbmV3IFdlYWtNYXAoKSwgdyA9IG5ldyBXZWFrTWFwKCksIFUgPSBuZXcgV2Vha01hcCgpLCBHID0gbmV3IFdlYWtNYXAoKSwgayA9IG5ldyBXZWFrTWFwKCksIE8gPSBuZXcgV2Vha01hcCgpLCBfZSA9IG5ldyBXZWFrTWFwKCksIGVlID0gbmV3IFdlYWtNYXAoKSwgQSA9IG5ldyBXZWFrTWFwKCksIHVlID0gbmV3IFdlYWtNYXAoKSwgdGUgPSBuZXcgV2Vha01hcCgpLCBoID0gbmV3IFdlYWtNYXAoKSwgQyA9IG5ldyBXZWFrTWFwKCksIGogPSBuZXcgV2Vha01hcCgpLCB5ZSA9IG5ldyBXZWFrTWFwKCksIFhlID0gbmV3IFdlYWtNYXAoKSwgcWUgPSBuZXcgV2Vha1NldCgpLCBmdCA9IGZ1bmN0aW9uKGUpIHsKICBjb25zdCB7IGRldmljZTogciwgZm9ybWF0OiBzIH0gPSBlOwogIHUodGhpcywgVWUsICR0KHIsIHMpKSwgdSh0aGlzLCB2ZSwgV3QocikpLCB1KHRoaXMsIERlLCBOdChyKSksIHUodGhpcywgeGUsIFcociwgMTYpKSwgdSh0aGlzLCBwZSwgVyhyLCAxNikpLCB1KHRoaXMsIG1lLCBXKHIsIDE2KSksIHUodGhpcywgZGUsIFcociwgMTYpKSwgdSh0aGlzLCBoZSwgVyhyLCAxNikpLCB1KHRoaXMsIEosIFcociwgNDgpKSwgdSh0aGlzLCBaLCBXKHIsIDQ4KSksIHUodGhpcywgZ2UsIFcociwgMTYpKSwgdSh0aGlzLCBiZSwgVyhyLCAxNikpLCB1KHRoaXMsIFRlLCBXKHIsIDY0KSk7Cn0sIFNlID0gbmV3IFdlYWtTZXQoKSwgUGUgPSBmdW5jdGlvbigpIHsKICBjb25zdCBlID0gdCh0aGlzLCBjZSk7CiAgImNsaWVudFdpZHRoIiBpbiBlICYmIGUuY2xpZW50V2lkdGggPiAwID8gKHUodGhpcywgTywgKHR5cGVvZiB3aW5kb3cgPCAidSIgJiYgd2luZG93LmRldmljZVBpeGVsUmF0aW8gfHwgMSkgKiB0KHRoaXMsIF9lKSksIHUodGhpcywgdywgZS53aWR0aCA9IE1hdGgucm91bmQoZS5jbGllbnRXaWR0aCAqIHQodGhpcywgTykpKSwgdSh0aGlzLCBVLCBlLmhlaWdodCA9IE1hdGgucm91bmQoZS5jbGllbnRIZWlnaHQgKiB0KHRoaXMsIE8pKSkpIDogKHUodGhpcywgdywgZS53aWR0aCksIHUodGhpcywgVSwgZS5oZWlnaHQpKSwgISh0KHRoaXMsIHcpID09PSAwIHx8IHQodGhpcywgVSkgPT09IDApICYmICh1KHRoaXMsIEcsIE1hdGgubWF4KDEsIE1hdGgucm91bmQodCh0aGlzLCB3KSAqIHQodGhpcywgZWUpKSkpLCB1KHRoaXMsIGssIE1hdGgubWF4KDEsIE1hdGgucm91bmQodCh0aGlzLCBVKSAqIHQodGhpcywgZWUpKSkpLCBTKHRoaXMsIHplLCBydCkuY2FsbCh0aGlzKSk7Cn0sIHplID0gbmV3IFdlYWtTZXQoKSwgcnQgPSBmdW5jdGlvbigpIHsKICBpZiAoUyh0aGlzLCBNZSwgaXQpLmNhbGwodGhpcyksIHQodGhpcywgUCkpIHsKICAgIGNvbnN0IHsgZGV2aWNlOiBlIH0gPSB0KHRoaXMsIFApLCByID0gInJnYmExNmZsb2F0IiwgcyA9IHQodGhpcywgRyksIG8gPSB0KHRoaXMsIGspOwogICAgdSh0aGlzLCBWLCBldChlLCByLCBzLCBvKSksIHUodGhpcywgVCwgZXQoZSwgciwgcywgbykpLCB1KHRoaXMsIFEsIGV0KGUsIHIsIHMsIG8pKSwgdSh0aGlzLCBvZSwgTmUoZSwgciwgcywgbykpLCB1KHRoaXMsIGFlLCBOZShlLCByLCBzLCBvKSk7CiAgfSBlbHNlIHsKICAgIGNvbnN0IGUgPSB0KHRoaXMsIE0pLCByID0gdCh0aGlzLCBBZSksIHMgPSB0KHRoaXMsIEcpLCBvID0gdCh0aGlzLCBrKTsKICAgIHUodGhpcywgQiwgWmUoZSwgciwgcywgbykpLCB1KHRoaXMsIFIsIFplKGUsIHIsIHMsIG8pKSwgdSh0aGlzLCBxLCBaZShlLCByLCBzLCBvKSksIHUodGhpcywgTiwgJGUoZSwgciwgcywgbykpLCB1KHRoaXMsIEgsICRlKGUsIHIsIHMsIG8pKTsKICB9Cn0sIG5lID0gbmV3IFdlYWtTZXQoKSwgUmUgPSBmdW5jdGlvbigpIHsKICBpZiAoISghdCh0aGlzLCBDKSB8fCB0KHRoaXMsIHcpID09PSAwIHx8IHQodGhpcywgVSkgPT09IDApKSB7CiAgICBpZiAoUyh0aGlzLCBHZSwgc3QpLmNhbGwodGhpcyksIHQodGhpcywgUCkpIHsKICAgICAgY29uc3QgeyBkZXZpY2U6IGUgfSA9IHQodGhpcywgUCk7CiAgICAgIHQodGhpcywgQykudHlwZSA9PT0gInRleHQiID8gdSh0aGlzLCBYLCBLdCgKICAgICAgICBlLAogICAgICAgIHQodGhpcywgdyksCiAgICAgICAgdCh0aGlzLCBVKSwKICAgICAgICB0KHRoaXMsIEMpLm9wdHMsCiAgICAgICAgdCh0aGlzLCBBKSwKICAgICAgICB0KHRoaXMsIHVlKQogICAgICApKSA6IHUodGhpcywgWCwgSnQoCiAgICAgICAgZSwKICAgICAgICB0KHRoaXMsIEMpLmJpdG1hcCwKICAgICAgICB0KHRoaXMsIHcpLAogICAgICAgIHQodGhpcywgVSksCiAgICAgICAgdCh0aGlzLCBDKS5lZmZlY3QsCiAgICAgICAgdCh0aGlzLCBDKS5zaXplLAogICAgICAgIHQodGhpcywgQSksCiAgICAgICAgdCh0aGlzLCB1ZSkKICAgICAgKSk7CiAgICB9IGVsc2UgewogICAgICBjb25zdCBlID0gdCh0aGlzLCBNKTsKICAgICAgaWYgKHQodGhpcywgQykudHlwZSA9PT0gInRleHQiKSB7CiAgICAgICAgY29uc3QgeyBiYWNrZ3JvdW5kVGV4OiByLCBvYnN0YWNsZVRleDogcywgY292ZXJhZ2VUZXg6IG8gfSA9IFF0KAogICAgICAgICAgZSwKICAgICAgICAgIHQodGhpcywgdyksCiAgICAgICAgICB0KHRoaXMsIFUpLAogICAgICAgICAgdCh0aGlzLCBDKS5vcHRzLAogICAgICAgICAgdCh0aGlzLCBBKSwKICAgICAgICAgIHQodGhpcywgdWUpCiAgICAgICAgKTsKICAgICAgICB1KHRoaXMsIEssIHIpLCB1KHRoaXMsIEwsIHMpLCB1KHRoaXMsIFksIG8pOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbnN0IHsgYmFja2dyb3VuZFRleDogciwgb2JzdGFjbGVUZXg6IHMsIGNvdmVyYWdlVGV4OiBvIH0gPSBqdCgKICAgICAgICAgIGUsCiAgICAgICAgICB0KHRoaXMsIEMpLmJpdG1hcCwKICAgICAgICAgIHQodGhpcywgdyksCiAgICAgICAgICB0KHRoaXMsIFUpLAogICAgICAgICAgdCh0aGlzLCBDKS5lZmZlY3QsCiAgICAgICAgICB0KHRoaXMsIEMpLnNpemUsCiAgICAgICAgICB0KHRoaXMsIEEpLAogICAgICAgICAgdCh0aGlzLCB1ZSkKICAgICAgICApOwogICAgICAgIHUodGhpcywgSywgciksIHUodGhpcywgTCwgcyksIHUodGhpcywgWSwgbyk7CiAgICAgIH0KICAgIH0KICAgIHUodGhpcywgeWUsICEwKTsKICB9Cn0sIHdlID0gbmV3IFdlYWtTZXQoKSwgT2UgPSBmdW5jdGlvbigpIHsKICB0KHRoaXMsIHllKSAmJiAhdGhpcy5pc1J1bm5pbmcgJiYgdGhpcy5zdGFydCgpOwp9LCBNZSA9IG5ldyBXZWFrU2V0KCksIGl0ID0gZnVuY3Rpb24oKSB7CiAgdmFyIGUsIHIsIHMsIG8sIGEsIG4sIHgsIG07CiAgaWYgKHQodGhpcywgUCkpCiAgICAoZSA9IHQodGhpcywgVikpID09IG51bGwgfHwgZS5kaXNwb3NlKCksIChyID0gdCh0aGlzLCBUKSkgPT0gbnVsbCB8fCByLmRpc3Bvc2UoKSwgKHMgPSB0KHRoaXMsIFEpKSA9PSBudWxsIHx8IHMuZGlzcG9zZSgpLCAobyA9IHQodGhpcywgb2UpKSA9PSBudWxsIHx8IG8udGV4LmRlc3Ryb3koKSwgKGEgPSB0KHRoaXMsIGFlKSkgPT0gbnVsbCB8fCBhLnRleC5kZXN0cm95KCksIHUodGhpcywgViwgdSh0aGlzLCBULCB1KHRoaXMsIFEsIG51bGwpKSksIHUodGhpcywgb2UsIHUodGhpcywgYWUsIG51bGwpKTsKICBlbHNlIHsKICAgIGNvbnN0IGwgPSB0KHRoaXMsIE0pOwogICAgKG4gPSB0KHRoaXMsIEIpKSA9PSBudWxsIHx8IG4uZGlzcG9zZSgpLCAoeCA9IHQodGhpcywgUikpID09IG51bGwgfHwgeC5kaXNwb3NlKCksIChtID0gdCh0aGlzLCBxKSkgPT0gbnVsbCB8fCBtLmRpc3Bvc2UoKSwgdCh0aGlzLCBOKSAmJiAobC5kZWxldGVUZXh0dXJlKHQodGhpcywgTikudGV4KSwgbC5kZWxldGVGcmFtZWJ1ZmZlcih0KHRoaXMsIE4pLmZibykpLCB0KHRoaXMsIEgpICYmIChsLmRlbGV0ZVRleHR1cmUodCh0aGlzLCBIKS50ZXgpLCBsLmRlbGV0ZUZyYW1lYnVmZmVyKHQodGhpcywgSCkuZmJvKSksIHUodGhpcywgQiwgdSh0aGlzLCBSLCB1KHRoaXMsIHEsIHUodGhpcywgTiwgdSh0aGlzLCBILCBudWxsKSkpKSk7CiAgfQp9LCBHZSA9IG5ldyBXZWFrU2V0KCksIHN0ID0gZnVuY3Rpb24oKSB7CiAgaWYgKHQodGhpcywgUCkpCiAgICB0KHRoaXMsIFgpICYmICh0KHRoaXMsIFgpLmJhY2tncm91bmRUZXguZGVzdHJveSgpLCB0KHRoaXMsIFgpLm9ic3RhY2xlVGV4LmRlc3Ryb3koKSwgdCh0aGlzLCBYKS5zaGFyZWRDb3ZlcmFnZSB8fCB0KHRoaXMsIFgpLmNvdmVyYWdlVGV4LmRlc3Ryb3koKSwgdSh0aGlzLCBYLCBudWxsKSk7CiAgZWxzZSB7CiAgICBjb25zdCBlID0gdCh0aGlzLCBNKTsKICAgIHQodGhpcywgSykgJiYgZS5kZWxldGVUZXh0dXJlKHQodGhpcywgSykpLCB0KHRoaXMsIEwpICYmIGUuZGVsZXRlVGV4dHVyZSh0KHRoaXMsIEwpKSwgdCh0aGlzLCBZKSAmJiB0KHRoaXMsIFkpICE9PSB0KHRoaXMsIEwpICYmIGUuZGVsZXRlVGV4dHVyZSh0KHRoaXMsIFkpKSwgdSh0aGlzLCBLLCB1KHRoaXMsIEwsIHUodGhpcywgWSwgbnVsbCkpKTsKICB9Cn0sIEhlID0gbmV3IFdlYWtTZXQoKSwgdnQgPSBmdW5jdGlvbigpIHsKICAhdCh0aGlzLCB5ZSkgfHwgdCh0aGlzLCB3KSA9PT0gMCB8fCAodCh0aGlzLCBQKSA/IFModGhpcywgWWUsIHh0KS5jYWxsKHRoaXMpIDogUyh0aGlzLCBLZSwgZHQpLmNhbGwodGhpcykpOwp9LCBZZSA9IG5ldyBXZWFrU2V0KCksIHh0ID0gZnVuY3Rpb24oKSB7CiAgY29uc3QgZSA9IHQodGhpcywgUCksIHIgPSBlLmRldmljZSwgcyA9IHQodGhpcywgVWUpLCBvID0gdCh0aGlzLCB2ZSksIGEgPSB0KHRoaXMsIERlKSwgbiA9IHQodGhpcywgdGUpLCB4ID0gdCh0aGlzLCBYKTsKICBpZiAoIXQodGhpcywgVikgfHwgIXQodGhpcywgVCkpCiAgICByZXR1cm47CiAgdCh0aGlzLCBoKS54ICs9ICh0KHRoaXMsIGgpLnRhcmdldFggLSB0KHRoaXMsIGgpLngpICogMC4xNSwgdCh0aGlzLCBoKS55ICs9ICh0KHRoaXMsIGgpLnRhcmdldFkgLSB0KHRoaXMsIGgpLnkpICogMC4xNTsKICBjb25zdCBtID0gdCh0aGlzLCBHKSwgbCA9IHQodGhpcywgayksIHAgPSB0KHRoaXMsIHcpLCBjID0gdCh0aGlzLCBVKSwgZiA9IDEgLyBtLCBkID0gMSAvIGw7CiAgdXQociwgdCh0aGlzLCB4ZSksIGYsIGQsIFZlLCBuLnZlbG9jaXR5RGlzc2lwYXRpb24pLCBJZShyLCB0KHRoaXMsIG1lKSwgZiwgZCksIEllKHIsIHQodGhpcywgZGUpLCBmLCBkKSwgSWUociwgdCh0aGlzLCBoZSksIGYsIGQpLCBJZShyLCB0KHRoaXMsIGdlKSwgZiwgZCksIHF0KHIsIHQodGhpcywgYmUpLCBmLCBkLCBuLmN1cmwsIFZlKSwgSHQoCiAgICByLAogICAgdCh0aGlzLCBUZSksCiAgICAxIC8gcCwKICAgIDEgLyBjLAogICAgbi5yZWZyYWN0aW9uLAogICAgbi5zcGVjdWxhckV4cCwKICAgIG4ud2F0ZXJDb2xvciwKICAgIG4uZ2xvd0NvbG9yLAogICAgbi5zaGluZSwKICAgIG4ud2FycFN0cmVuZ3RoID8/IDAuMDE1LAogICAgbHRbbi5hbGdvcml0aG1dID8/IDAKICApOwogIGNvbnN0IGIgPSByLmNyZWF0ZUNvbW1hbmRFbmNvZGVyKCksIHkgPSAoZywgXykgPT4gci5jcmVhdGVCaW5kR3JvdXAoeyBsYXlvdXQ6IGcuZ2V0QmluZEdyb3VwTGF5b3V0KDApLCBlbnRyaWVzOiBfIH0pLCBEID0geyBiaW5kaW5nOiAxLCByZXNvdXJjZTogYSB9OwogIHsKICAgIGNvbnN0IGcgPSB5KHMuYWR2ZWN0aW9uLCBbCiAgICAgIHsgYmluZGluZzogMCwgcmVzb3VyY2U6IHsgYnVmZmVyOiB0KHRoaXMsIHhlKSB9IH0sCiAgICAgIEQsCiAgICAgIHsgYmluZGluZzogMiwgcmVzb3VyY2U6IHQodGhpcywgVCkucmVhZC52aWV3IH0sCiAgICAgIHsgYmluZGluZzogMywgcmVzb3VyY2U6IHQodGhpcywgVCkucmVhZC52aWV3IH0sCiAgICAgIHsgYmluZGluZzogNCwgcmVzb3VyY2U6IHgub2JzdGFjbGVWaWV3IH0KICAgIF0pOwogICAgeihiLCBzLmFkdmVjdGlvbiwgZywgbywgdCh0aGlzLCBUKS53cml0ZS52aWV3KTsKICB9CiAgdCh0aGlzLCBUKS5zd2FwKCk7CiAgewogICAgdXQociwgdCh0aGlzLCBwZSksIGYsIGQsIFZlLCBuLmRlbnNpdHlEaXNzaXBhdGlvbik7CiAgICBjb25zdCBnID0geShzLmFkdmVjdGlvbiwgWwogICAgICB7IGJpbmRpbmc6IDAsIHJlc291cmNlOiB7IGJ1ZmZlcjogdCh0aGlzLCBwZSkgfSB9LAogICAgICBELAogICAgICB7IGJpbmRpbmc6IDIsIHJlc291cmNlOiB0KHRoaXMsIFQpLnJlYWQudmlldyB9LAogICAgICB7IGJpbmRpbmc6IDMsIHJlc291cmNlOiB0KHRoaXMsIFYpLnJlYWQudmlldyB9LAogICAgICB7IGJpbmRpbmc6IDQsIHJlc291cmNlOiB4Lm9ic3RhY2xlVmlldyB9CiAgICBdKTsKICAgIHooYiwgcy5hZHZlY3Rpb24sIGcsIG8sIHQodGhpcywgVikud3JpdGUudmlldyk7CiAgfQogIHQodGhpcywgVikuc3dhcCgpOwogIHsKICAgIGNvbnN0IGcgPSB5KHMuY3VybCwgWwogICAgICB7IGJpbmRpbmc6IDAsIHJlc291cmNlOiB7IGJ1ZmZlcjogdCh0aGlzLCBnZSkgfSB9LAogICAgICBELAogICAgICB7IGJpbmRpbmc6IDIsIHJlc291cmNlOiB0KHRoaXMsIFQpLnJlYWQudmlldyB9CiAgICBdKTsKICAgIHooYiwgcy5jdXJsLCBnLCBvLCB0KHRoaXMsIGFlKS52aWV3KTsKICB9CiAgewogICAgY29uc3QgZyA9IHkocy52b3J0aWNpdHksIFsKICAgICAgeyBiaW5kaW5nOiAwLCByZXNvdXJjZTogeyBidWZmZXI6IHQodGhpcywgYmUpIH0gfSwKICAgICAgRCwKICAgICAgeyBiaW5kaW5nOiAyLCByZXNvdXJjZTogdCh0aGlzLCBUKS5yZWFkLnZpZXcgfSwKICAgICAgeyBiaW5kaW5nOiAzLCByZXNvdXJjZTogdCh0aGlzLCBhZSkudmlldyB9CiAgICBdKTsKICAgIHooYiwgcy52b3J0aWNpdHksIGcsIG8sIHQodGhpcywgVCkud3JpdGUudmlldyk7CiAgfQogIGlmICh0KHRoaXMsIFQpLnN3YXAoKSwgdCh0aGlzLCBoKS5tb3ZlZCkgewogICAgY29uc3QgZyA9IHQodGhpcywgaCkueCAqIHQodGhpcywgTykgLyBwLCBfID0gdCh0aGlzLCBoKS55ICogdCh0aGlzLCBPKSAvIGM7CiAgICBXZSgKICAgICAgciwKICAgICAgdCh0aGlzLCBKKSwKICAgICAgZiwKICAgICAgZCwKICAgICAgcCAvIGMsCiAgICAgIG4uc3BsYXRSYWRpdXMsCiAgICAgIHQodGhpcywgaCkuZHggKiBuLnNwbGF0Rm9yY2UsCiAgICAgIHQodGhpcywgaCkuZHkgKiBuLnNwbGF0Rm9yY2UsCiAgICAgIDAsCiAgICAgIGcsCiAgICAgIF8KICAgICk7CiAgICB7CiAgICAgIGNvbnN0IEYgPSB5KHMuc3BsYXQsIFsKICAgICAgICB7IGJpbmRpbmc6IDAsIHJlc291cmNlOiB7IGJ1ZmZlcjogdCh0aGlzLCBKKSB9IH0sCiAgICAgICAgRCwKICAgICAgICB7IGJpbmRpbmc6IDIsIHJlc291cmNlOiB0KHRoaXMsIFQpLnJlYWQudmlldyB9CiAgICAgIF0pOwogICAgICB6KGIsIHMuc3BsYXQsIEYsIG8sIHQodGhpcywgVCkud3JpdGUudmlldyk7CiAgICB9CiAgICB0KHRoaXMsIFQpLnN3YXAoKSwgV2UoCiAgICAgIHIsCiAgICAgIHQodGhpcywgWiksCiAgICAgIGYsCiAgICAgIGQsCiAgICAgIHAgLyBjLAogICAgICBuLnNwbGF0UmFkaXVzLAogICAgICAxLAogICAgICAxLAogICAgICAxLAogICAgICBnLAogICAgICBfCiAgICApOwogICAgewogICAgICBjb25zdCBGID0geShzLnNwbGF0LCBbCiAgICAgICAgeyBiaW5kaW5nOiAwLCByZXNvdXJjZTogeyBidWZmZXI6IHQodGhpcywgWikgfSB9LAogICAgICAgIEQsCiAgICAgICAgeyBiaW5kaW5nOiAyLCByZXNvdXJjZTogdCh0aGlzLCBWKS5yZWFkLnZpZXcgfQogICAgICBdKTsKICAgICAgeihiLCBzLnNwbGF0LCBGLCBvLCB0KHRoaXMsIFYpLndyaXRlLnZpZXcpOwogICAgfQogICAgdCh0aGlzLCBWKS5zd2FwKCksIHQodGhpcywgaCkubW92ZWQgPSAhMTsKICB9CiAgewogICAgY29uc3QgZyA9IHkocy5kaXZlcmdlbmNlLCBbCiAgICAgIHsgYmluZGluZzogMCwgcmVzb3VyY2U6IHsgYnVmZmVyOiB0KHRoaXMsIG1lKSB9IH0sCiAgICAgIEQsCiAgICAgIHsgYmluZGluZzogMiwgcmVzb3VyY2U6IHQodGhpcywgVCkucmVhZC52aWV3IH0sCiAgICAgIHsgYmluZGluZzogMywgcmVzb3VyY2U6IHgub2JzdGFjbGVWaWV3IH0KICAgIF0pOwogICAgeihiLCBzLmRpdmVyZ2VuY2UsIGcsIG8sIHQodGhpcywgb2UpLnZpZXcpOwogIH0KICBmb3IgKGxldCBnID0gMDsgZyA8IG4ucHJlc3N1cmVJdGVyYXRpb25zOyBnKyspIHsKICAgIGNvbnN0IF8gPSB5KHMucHJlc3N1cmUsIFsKICAgICAgeyBiaW5kaW5nOiAwLCByZXNvdXJjZTogeyBidWZmZXI6IHQodGhpcywgZGUpIH0gfSwKICAgICAgRCwKICAgICAgeyBiaW5kaW5nOiAyLCByZXNvdXJjZTogdCh0aGlzLCBRKS5yZWFkLnZpZXcgfSwKICAgICAgeyBiaW5kaW5nOiAzLCByZXNvdXJjZTogdCh0aGlzLCBvZSkudmlldyB9LAogICAgICB7IGJpbmRpbmc6IDQsIHJlc291cmNlOiB4Lm9ic3RhY2xlVmlldyB9CiAgICBdKTsKICAgIHooYiwgcy5wcmVzc3VyZSwgXywgbywgdCh0aGlzLCBRKS53cml0ZS52aWV3KSwgdCh0aGlzLCBRKS5zd2FwKCk7CiAgfQogIHsKICAgIGNvbnN0IGcgPSB5KHMuZ3JhZGllbnRTdWJ0cmFjdCwgWwogICAgICB7IGJpbmRpbmc6IDAsIHJlc291cmNlOiB7IGJ1ZmZlcjogdCh0aGlzLCBoZSkgfSB9LAogICAgICBELAogICAgICB7IGJpbmRpbmc6IDIsIHJlc291cmNlOiB0KHRoaXMsIFEpLnJlYWQudmlldyB9LAogICAgICB7IGJpbmRpbmc6IDMsIHJlc291cmNlOiB0KHRoaXMsIFQpLnJlYWQudmlldyB9LAogICAgICB7IGJpbmRpbmc6IDQsIHJlc291cmNlOiB4Lm9ic3RhY2xlVmlldyB9CiAgICBdKTsKICAgIHooYiwgcy5ncmFkaWVudFN1YnRyYWN0LCBnLCBvLCB0KHRoaXMsIFQpLndyaXRlLnZpZXcpOwogIH0KICB0KHRoaXMsIFQpLnN3YXAoKTsKICB7CiAgICBjb25zdCBnID0gZS5jb250ZXh0LmdldEN1cnJlbnRUZXh0dXJlKCkuY3JlYXRlVmlldygpLCBfID0geShzLmRpc3BsYXksIFsKICAgICAgeyBiaW5kaW5nOiAwLCByZXNvdXJjZTogeyBidWZmZXI6IHQodGhpcywgVGUpIH0gfSwKICAgICAgRCwKICAgICAgeyBiaW5kaW5nOiAyLCByZXNvdXJjZTogdCh0aGlzLCBWKS5yZWFkLnZpZXcgfSwKICAgICAgeyBiaW5kaW5nOiAzLCByZXNvdXJjZTogeC5vYnN0YWNsZVZpZXcgfSwKICAgICAgeyBiaW5kaW5nOiA0LCByZXNvdXJjZTogeC5iYWNrZ3JvdW5kVmlldyB9LAogICAgICB7IGJpbmRpbmc6IDUsIHJlc291cmNlOiB4LmNvdmVyYWdlVmlldyB9LAogICAgICB7IGJpbmRpbmc6IDYsIHJlc291cmNlOiB0KHRoaXMsIFQpLnJlYWQudmlldyB9CiAgICBdKTsKICAgIFl0KGIsIHMuZGlzcGxheSwgXywgbywgZyk7CiAgfQogIHIucXVldWUuc3VibWl0KFtiLmZpbmlzaCgpXSk7Cn0sIFFlID0gbmV3IFdlYWtTZXQoKSwgcHQgPSBmdW5jdGlvbihlLCByLCBzLCBvLCBhKSB7CiAgY29uc3QgeCA9IHQodGhpcywgUCkuZGV2aWNlLCBtID0gdCh0aGlzLCBVZSkuc3BsYXQsIGwgPSB0KHRoaXMsIHZlKSwgcCA9IHQodGhpcywgRGUpLCBjID0gdCh0aGlzLCB0ZSksIGYgPSB0KHRoaXMsIEcpLCBkID0gdCh0aGlzLCBrKSwgYiA9IDEgLyBmLCB5ID0gMSAvIGQsIEQgPSB4LmNyZWF0ZUNvbW1hbmRFbmNvZGVyKCksIGcgPSB7IGJpbmRpbmc6IDEsIHJlc291cmNlOiBwIH0sIF8gPSAoQmUpID0+IHguY3JlYXRlQmluZEdyb3VwKHsgbGF5b3V0OiBtLmdldEJpbmRHcm91cExheW91dCgwKSwgZW50cmllczogQmUgfSksIEYgPSBlICogdCh0aGlzLCBPKSAvIHQodGhpcywgdyksIEkgPSByICogdCh0aGlzLCBPKSAvIHQodGhpcywgVSk7CiAgV2UoCiAgICB4LAogICAgdCh0aGlzLCBKKSwKICAgIGIsCiAgICB5LAogICAgdCh0aGlzLCB3KSAvIHQodGhpcywgVSksCiAgICBjLnNwbGF0UmFkaXVzLAogICAgcyAqIGMuc3BsYXRGb3JjZSAqIGEsCiAgICBvICogYy5zcGxhdEZvcmNlICogYSwKICAgIDAsCiAgICBGLAogICAgSQogICk7CiAgewogICAgY29uc3QgQmUgPSBfKFsKICAgICAgeyBiaW5kaW5nOiAwLCByZXNvdXJjZTogeyBidWZmZXI6IHQodGhpcywgSikgfSB9LAogICAgICBnLAogICAgICB7IGJpbmRpbmc6IDIsIHJlc291cmNlOiB0KHRoaXMsIFQpLnJlYWQudmlldyB9CiAgICBdKTsKICAgIHooRCwgbSwgQmUsIGwsIHQodGhpcywgVCkud3JpdGUudmlldyk7CiAgfQogIHQodGhpcywgVCkuc3dhcCgpLCBXZSgKICAgIHgsCiAgICB0KHRoaXMsIFopLAogICAgYiwKICAgIHksCiAgICB0KHRoaXMsIHcpIC8gdCh0aGlzLCBVKSwKICAgIGMuc3BsYXRSYWRpdXMsCiAgICBhLAogICAgYSwKICAgIGEsCiAgICBGLAogICAgSQogICk7CiAgewogICAgY29uc3QgQmUgPSBfKFsKICAgICAgeyBiaW5kaW5nOiAwLCByZXNvdXJjZTogeyBidWZmZXI6IHQodGhpcywgWikgfSB9LAogICAgICBnLAogICAgICB7IGJpbmRpbmc6IDIsIHJlc291cmNlOiB0KHRoaXMsIFYpLnJlYWQudmlldyB9CiAgICBdKTsKICAgIHooRCwgbSwgQmUsIGwsIHQodGhpcywgVikud3JpdGUudmlldyk7CiAgfQogIHQodGhpcywgVikuc3dhcCgpLCB4LnF1ZXVlLnN1Ym1pdChbRC5maW5pc2goKV0pOwp9LCBqZSA9IG5ldyBXZWFrU2V0KCksIG10ID0gZnVuY3Rpb24oZSwgciwgcywgbywgYSkgewogIGNvbnN0IG4gPSB0KHRoaXMsIE0pLCB4ID0gdCh0aGlzLCB0ZSksIG0gPSB0KHRoaXMsIGZlKS5zcGxhdCwgbCA9IHQodGhpcywgRWUpOwogIG4udmlld3BvcnQoMCwgMCwgdCh0aGlzLCBHKSwgdCh0aGlzLCBrKSksIG0uYmluZCgpLCBuLnVuaWZvcm0xZihtLnVuaWZvcm1zLmFzcGVjdFJhdGlvLCB0KHRoaXMsIHcpIC8gdCh0aGlzLCBVKSksIG4udW5pZm9ybTJmKG0udW5pZm9ybXMucG9pbnQsIGUgKiB0KHRoaXMsIE8pIC8gdCh0aGlzLCB3KSwgMSAtIHIgKiB0KHRoaXMsIE8pIC8gdCh0aGlzLCBVKSksIG4udW5pZm9ybTFmKG0udW5pZm9ybXMucmFkaXVzLCB4LnNwbGF0UmFkaXVzKSwgbi51bmlmb3JtMWkobS51bmlmb3Jtcy51VGFyZ2V0LCAwKSwgbi5hY3RpdmVUZXh0dXJlKG4uVEVYVFVSRTApLCBuLmJpbmRUZXh0dXJlKG4uVEVYVFVSRV8yRCwgdCh0aGlzLCBSKS5yZWFkLnRleCksIG4udW5pZm9ybTNmKG0udW5pZm9ybXMuY29sb3IsIHMgKiB4LnNwbGF0Rm9yY2UgKiBhLCAtbyAqIHguc3BsYXRGb3JjZSAqIGEsIDApLCBsKHQodGhpcywgUikud3JpdGUuZmJvKSwgdCh0aGlzLCBSKS5zd2FwKCksIG4uYWN0aXZlVGV4dHVyZShuLlRFWFRVUkUwKSwgbi5iaW5kVGV4dHVyZShuLlRFWFRVUkVfMkQsIHQodGhpcywgQikucmVhZC50ZXgpLCBuLnVuaWZvcm0zZihtLnVuaWZvcm1zLmNvbG9yLCBhLCBhLCBhKSwgbCh0KHRoaXMsIEIpLndyaXRlLmZibyksIHQodGhpcywgQikuc3dhcCgpOwp9LCBLZSA9IG5ldyBXZWFrU2V0KCksIGR0ID0gZnVuY3Rpb24oKSB7CiAgaWYgKCF0KHRoaXMsIEIpIHx8ICF0KHRoaXMsIFIpKQogICAgcmV0dXJuOwogIGNvbnN0IGUgPSB0KHRoaXMsIE0pLCByID0gdCh0aGlzLCB0ZSksIHsgYWR2ZWN0aW9uOiBzLCBkaXZlcmdlbmNlOiBvLCBwcmVzc3VyZTogYSwgZ3JhZGllbnRTdWJ0cmFjdDogbiwgc3BsYXQ6IHgsIGN1cmw6IG0sIHZvcnRpY2l0eTogbCwgZGlzcGxheTogcCB9ID0gdCh0aGlzLCBmZSk7CiAgdCh0aGlzLCBoKS54ICs9ICh0KHRoaXMsIGgpLnRhcmdldFggLSB0KHRoaXMsIGgpLngpICogMC4xNSwgdCh0aGlzLCBoKS55ICs9ICh0KHRoaXMsIGgpLnRhcmdldFkgLSB0KHRoaXMsIGgpLnkpICogMC4xNTsKICBjb25zdCBjID0gdCh0aGlzLCBHKSwgZiA9IHQodGhpcywgayksIGQgPSB0KHRoaXMsIEVlKTsKICBlLnZpZXdwb3J0KDAsIDAsIGMsIGYpLCBzLmJpbmQoKSwgZS51bmlmb3JtMmYocy51bmlmb3Jtcy50ZXhlbFNpemUsIDEgLyBjLCAxIC8gZiksIGUudW5pZm9ybTFmKHMudW5pZm9ybXMuZHQsIFZlKSwgZS51bmlmb3JtMWkocy51bmlmb3Jtcy51T2JzdGFjbGUsIDApLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMCksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIEwpKSwgZS51bmlmb3JtMWYocy51bmlmb3Jtcy5kaXNzaXBhdGlvbiwgci52ZWxvY2l0eURpc3NpcGF0aW9uKSwgZS51bmlmb3JtMWkocy51bmlmb3Jtcy51VmVsb2NpdHksIDEpLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMSksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIFIpLnJlYWQudGV4KSwgZS51bmlmb3JtMWkocy51bmlmb3Jtcy51U291cmNlLCAxKSwgZCh0KHRoaXMsIFIpLndyaXRlLmZibyksIHQodGhpcywgUikuc3dhcCgpLCBlLnVuaWZvcm0xZihzLnVuaWZvcm1zLmRpc3NpcGF0aW9uLCByLmRlbnNpdHlEaXNzaXBhdGlvbiksIGUudW5pZm9ybTFpKHMudW5pZm9ybXMudVNvdXJjZSwgMiksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUyKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgQikucmVhZC50ZXgpLCBkKHQodGhpcywgQikud3JpdGUuZmJvKSwgdCh0aGlzLCBCKS5zd2FwKCksIG0uYmluZCgpLCBlLnVuaWZvcm0yZihtLnVuaWZvcm1zLnRleGVsU2l6ZSwgMSAvIGMsIDEgLyBmKSwgZS51bmlmb3JtMWkobS51bmlmb3Jtcy51VmVsb2NpdHksIDApLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMCksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIFIpLnJlYWQudGV4KSwgZCh0KHRoaXMsIEgpLmZibyksIGwuYmluZCgpLCBlLnVuaWZvcm0yZihsLnVuaWZvcm1zLnRleGVsU2l6ZSwgMSAvIGMsIDEgLyBmKSwgZS51bmlmb3JtMWYobC51bmlmb3Jtcy5jdXJsLCByLmN1cmwpLCBlLnVuaWZvcm0xZihsLnVuaWZvcm1zLmR0LCBWZSksIGUudW5pZm9ybTFpKGwudW5pZm9ybXMudVZlbG9jaXR5LCAwKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTApLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBSKS5yZWFkLnRleCksIGUudW5pZm9ybTFpKGwudW5pZm9ybXMudUN1cmwsIDEpLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMSksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIEgpLnRleCksIGQodCh0aGlzLCBSKS53cml0ZS5mYm8pLCB0KHRoaXMsIFIpLnN3YXAoKSwgdCh0aGlzLCBoKS5tb3ZlZCAmJiAoeC5iaW5kKCksIGUudW5pZm9ybTFmKHgudW5pZm9ybXMuYXNwZWN0UmF0aW8sIHQodGhpcywgdykgLyB0KHRoaXMsIFUpKSwgZS51bmlmb3JtMmYoeC51bmlmb3Jtcy5wb2ludCwgdCh0aGlzLCBoKS54ICogdCh0aGlzLCBPKSAvIHQodGhpcywgdyksIDEgLSB0KHRoaXMsIGgpLnkgKiB0KHRoaXMsIE8pIC8gdCh0aGlzLCBVKSksIGUudW5pZm9ybTFmKHgudW5pZm9ybXMucmFkaXVzLCByLnNwbGF0UmFkaXVzKSwgZS51bmlmb3JtMWkoeC51bmlmb3Jtcy51VGFyZ2V0LCAwKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTApLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBSKS5yZWFkLnRleCksIGUudW5pZm9ybTNmKHgudW5pZm9ybXMuY29sb3IsIHQodGhpcywgaCkuZHggKiByLnNwbGF0Rm9yY2UsIC10KHRoaXMsIGgpLmR5ICogci5zcGxhdEZvcmNlLCAwKSwgZCh0KHRoaXMsIFIpLndyaXRlLmZibyksIHQodGhpcywgUikuc3dhcCgpLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMCksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIEIpLnJlYWQudGV4KSwgZS51bmlmb3JtM2YoeC51bmlmb3Jtcy5jb2xvciwgMSwgMSwgMSksIGQodCh0aGlzLCBCKS53cml0ZS5mYm8pLCB0KHRoaXMsIEIpLnN3YXAoKSwgdCh0aGlzLCBoKS5tb3ZlZCA9ICExKSwgby5iaW5kKCksIGUudW5pZm9ybTJmKG8udW5pZm9ybXMudGV4ZWxTaXplLCAxIC8gYywgMSAvIGYpLCBlLnVuaWZvcm0xaShvLnVuaWZvcm1zLnVWZWxvY2l0eSwgMCksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUwKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgUikucmVhZC50ZXgpLCBlLnVuaWZvcm0xaShvLnVuaWZvcm1zLnVPYnN0YWNsZSwgMSksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUxKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgTCkpLCBkKHQodGhpcywgTikuZmJvKSwgYS5iaW5kKCksIGUudW5pZm9ybTJmKGEudW5pZm9ybXMudGV4ZWxTaXplLCAxIC8gYywgMSAvIGYpLCBlLnVuaWZvcm0xaShhLnVuaWZvcm1zLnVEaXZlcmdlbmNlLCAwKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTApLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBOKS50ZXgpLCBlLnVuaWZvcm0xaShhLnVuaWZvcm1zLnVPYnN0YWNsZSwgMSksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUxKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgTCkpOwogIGZvciAobGV0IGIgPSAwOyBiIDwgci5wcmVzc3VyZUl0ZXJhdGlvbnM7IGIrKykKICAgIGUudW5pZm9ybTFpKGEudW5pZm9ybXMudVByZXNzdXJlLCAyKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTIpLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBxKS5yZWFkLnRleCksIGQodCh0aGlzLCBxKS53cml0ZS5mYm8pLCB0KHRoaXMsIHEpLnN3YXAoKTsKICBuLmJpbmQoKSwgZS51bmlmb3JtMmYobi51bmlmb3Jtcy50ZXhlbFNpemUsIDEgLyBjLCAxIC8gZiksIGUudW5pZm9ybTFpKG4udW5pZm9ybXMudVByZXNzdXJlLCAwKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTApLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBxKS5yZWFkLnRleCksIGUudW5pZm9ybTFpKG4udW5pZm9ybXMudVZlbG9jaXR5LCAxKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTEpLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBSKS5yZWFkLnRleCksIGUudW5pZm9ybTFpKG4udW5pZm9ybXMudU9ic3RhY2xlLCAyKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTIpLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBMKSksIGQodCh0aGlzLCBSKS53cml0ZS5mYm8pLCB0KHRoaXMsIFIpLnN3YXAoKSwgZS52aWV3cG9ydCgwLCAwLCB0KHRoaXMsIHcpLCB0KHRoaXMsIFUpKSwgZS5iaW5kRnJhbWVidWZmZXIoZS5GUkFNRUJVRkZFUiwgbnVsbCksIGUuY2xlYXIoZS5DT0xPUl9CVUZGRVJfQklUKSwgcC5iaW5kKCksIGUudW5pZm9ybTJmKHAudW5pZm9ybXMudGV4ZWxTaXplLCAxIC8gdCh0aGlzLCB3KSwgMSAvIHQodGhpcywgVSkpLCBlLnVuaWZvcm0zZnYocC51bmlmb3Jtcy51V2F0ZXJDb2xvciwgci53YXRlckNvbG9yKSwgZS51bmlmb3JtM2Z2KHAudW5pZm9ybXMudUdsb3dDb2xvciwgci5nbG93Q29sb3IpLCBlLnVuaWZvcm0xZihwLnVuaWZvcm1zLnVSZWZyYWN0aW9uLCByLnJlZnJhY3Rpb24pLCBlLnVuaWZvcm0xZihwLnVuaWZvcm1zLnVTcGVjdWxhckV4cCwgci5zcGVjdWxhckV4cCksIGUudW5pZm9ybTFmKHAudW5pZm9ybXMudVNoaW5lLCByLnNoaW5lKSwgZS51bmlmb3JtMWYocC51bmlmb3Jtcy51V2FycFN0cmVuZ3RoLCByLndhcnBTdHJlbmd0aCA/PyAwLjAxNSksIGUudW5pZm9ybTFpKHAudW5pZm9ybXMudUFsZ29yaXRobSwgbHRbci5hbGdvcml0aG1dID8/IDApLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMCksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIEIpLnJlYWQudGV4KSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTEpLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBMKSksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUyKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgSykpLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMyksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIFkpKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTQpLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBSKS5yZWFkLnRleCksIGUudW5pZm9ybTFpKHAudW5pZm9ybXMudVRleHR1cmUsIDApLCBlLnVuaWZvcm0xaShwLnVuaWZvcm1zLnVPYnN0YWNsZSwgMSksIGUudW5pZm9ybTFpKHAudW5pZm9ybXMudUJhY2tncm91bmQsIDIpLCBlLnVuaWZvcm0xaShwLnVuaWZvcm1zLnVDb3ZlcmFnZSwgMyksIGUudW5pZm9ybTFpKHAudW5pZm9ybXMudVZlbG9jaXR5LCA0KSwgZChudWxsKTsKfTsKbGV0IHR0ID0gb3QsIEUgPSBudWxsLCBodDsKY29uc3QgJCA9IG5ldyBQcm9taXNlKChpKSA9PiB7CiAgaHQgPSBpOwp9KTsKc2VsZi5vbm1lc3NhZ2UgPSBhc3luYyAoaSkgPT4gewogIGNvbnN0IHsgdHlwZTogZSwgLi4uciB9ID0gaS5kYXRhOwogIHRyeSB7CiAgICBzd2l0Y2ggKGUpIHsKICAgICAgY2FzZSAiaW5pdCI6IHsKICAgICAgICBjb25zdCB7IGNhbnZhczogcywgd2lkdGg6IG8sIGhlaWdodDogYSwgY29uZmlnOiBuLCBkcHI6IHgsIHF1YWxpdHk6IG0sIHVzZVdlYkdQVTogbCB9ID0gcjsKICAgICAgICBzLndpZHRoID0gbywgcy5oZWlnaHQgPSBhLCBFID0gYXdhaXQgdHQuY3JlYXRlKHMsIG4sIG0gPz8ge30sIGwgPz8gITApLCBFLnJlc2l6ZShvLCBhLCB4IHx8IDEpLCBodCgpLCBzZWxmLnBvc3RNZXNzYWdlKHsgdHlwZTogInJlYWR5IiB9KTsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBjYXNlICJzZXRUZXh0U291cmNlIjogewogICAgICAgIGlmIChhd2FpdCAkLCAhRSkKICAgICAgICAgIHJldHVybjsKICAgICAgICBFLnNldFRleHRTb3VyY2Uoci5vcHRzKTsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBjYXNlICJzZXRJbWFnZVNvdXJjZSI6IHsKICAgICAgICBpZiAoYXdhaXQgJCwgIUUpCiAgICAgICAgICByZXR1cm47CiAgICAgICAgYXdhaXQgRS5zZXRJbWFnZVNvdXJjZSgKICAgICAgICAgIHIuc3JjLAogICAgICAgICAgci5lZmZlY3QsCiAgICAgICAgICByLnNpemUKICAgICAgICApOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGNhc2UgInNldEltYWdlQml0bWFwIjogewogICAgICAgIGlmIChhd2FpdCAkLCAhRSkKICAgICAgICAgIHJldHVybjsKICAgICAgICBFLnNldEltYWdlQml0bWFwKAogICAgICAgICAgci5iaXRtYXAsCiAgICAgICAgICByLmVmZmVjdCwKICAgICAgICAgIHIuc2l6ZQogICAgICAgICk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY2FzZSAic2V0QmFja2dyb3VuZCI6IHsKICAgICAgICBpZiAoYXdhaXQgJCwgIUUpCiAgICAgICAgICByZXR1cm47CiAgICAgICAgRS5zZXRCYWNrZ3JvdW5kKHIuYml0bWFwLCByLnNpemUpOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGNhc2UgInNwbGF0IjogewogICAgICAgIGlmIChhd2FpdCAkLCAhRSkKICAgICAgICAgIHJldHVybjsKICAgICAgICBFLnNwbGF0KAogICAgICAgICAgci54LAogICAgICAgICAgci55LAogICAgICAgICAgci52eCwKICAgICAgICAgIHIudnksCiAgICAgICAgICByLnN0cmVuZ3RoID8/IDEKICAgICAgICApOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGNhc2UgIm1vdmUiOiB7CiAgICAgICAgaWYgKGF3YWl0ICQsICFFKQogICAgICAgICAgcmV0dXJuOwogICAgICAgIEUuaGFuZGxlTW92ZShyLngsIHIueSwgci5zdHJlbmd0aCA/PyAxKTsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBjYXNlICJyZXNpemUiOiB7CiAgICAgICAgaWYgKGF3YWl0ICQsICFFKQogICAgICAgICAgcmV0dXJuOwogICAgICAgIEUucmVzaXplKHIud2lkdGgsIHIuaGVpZ2h0LCByLmRwcik7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY2FzZSAidXBkYXRlUXVhbGl0eSI6IHsKICAgICAgICBpZiAoYXdhaXQgJCwgIUUpCiAgICAgICAgICByZXR1cm47CiAgICAgICAgRS51cGRhdGVRdWFsaXR5KHIucXVhbGl0eSk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY2FzZSAidXBkYXRlQ29uZmlnIjogewogICAgICAgIGlmIChhd2FpdCAkLCAhRSkKICAgICAgICAgIHJldHVybjsKICAgICAgICBFLnVwZGF0ZUNvbmZpZyhyLmNvbmZpZyk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY2FzZSAiZGVzdHJveSI6IHsKICAgICAgICBhd2FpdCAkLCBFID09IG51bGwgfHwgRS5kZXN0cm95KCksIEUgPSBudWxsOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgY29uc29sZS53YXJuKCJbZmx1aWRpdHktanMgd29ya2VyXSBVbmtub3duIG1lc3NhZ2UgdHlwZToiLCBlKTsKICAgIH0KICB9IGNhdGNoIChzKSB7CiAgICBzZWxmLnBvc3RNZXNzYWdlKHsgdHlwZTogImVycm9yIiwgbWVzc2FnZTogKHMgPT0gbnVsbCA/IHZvaWQgMCA6IHMubWVzc2FnZSkgPz8gU3RyaW5nKHMpIH0pOwogIH0KfTsK", YI = typeof window < "u" && window.Blob && new Blob([atob(NI)], { type: "text/javascript;charset=utf-8" });
1538
- function XC() {
1564
+ let ZI = vI;
1565
+ const jI = "dmFyIFR0ID0gT2JqZWN0LmRlZmluZVByb3BlcnR5Owp2YXIgeXQgPSAoaSwgZSwgcikgPT4gZSBpbiBpID8gVHQoaSwgZSwgeyBlbnVtZXJhYmxlOiAhMCwgY29uZmlndXJhYmxlOiAhMCwgd3JpdGFibGU6ICEwLCB2YWx1ZTogciB9KSA6IGlbZV0gPSByOwp2YXIga2UgPSAoaSwgZSwgcikgPT4gKHl0KGksIHR5cGVvZiBlICE9ICJzeW1ib2wiID8gZSArICIiIDogZSwgciksIHIpLCBldCA9IChpLCBlLCByKSA9PiB7CiAgaWYgKCFlLmhhcyhpKSkKICAgIHRocm93IFR5cGVFcnJvcigiQ2Fubm90ICIgKyByKTsKfTsKdmFyIHQgPSAoaSwgZSwgcikgPT4gKGV0KGksIGUsICJyZWFkIGZyb20gcHJpdmF0ZSBmaWVsZCIpLCByID8gci5jYWxsKGkpIDogZS5nZXQoaSkpLCBmID0gKGksIGUsIHIpID0+IHsKICBpZiAoZS5oYXMoaSkpCiAgICB0aHJvdyBUeXBlRXJyb3IoIkNhbm5vdCBhZGQgdGhlIHNhbWUgcHJpdmF0ZSBtZW1iZXIgbW9yZSB0aGFuIG9uY2UiKTsKICBlIGluc3RhbmNlb2YgV2Vha1NldCA/IGUuYWRkKGkpIDogZS5zZXQoaSwgcik7Cn0sIGwgPSAoaSwgZSwgciwgcykgPT4gKGV0KGksIGUsICJ3cml0ZSB0byBwcml2YXRlIGZpZWxkIiksIHMgPyBzLmNhbGwoaSwgcikgOiBlLnNldChpLCByKSwgcik7CnZhciBTID0gKGksIGUsIHIpID0+IChldChpLCBlLCAiYWNjZXNzIHByaXZhdGUgbWV0aG9kIiksIHIpOwpjb25zdCB2dCA9IHsKICBkZW5zaXR5RGlzc2lwYXRpb246IDAuOTkyLAogIHZlbG9jaXR5RGlzc2lwYXRpb246IDAuOTMsCiAgcHJlc3N1cmVJdGVyYXRpb25zOiAxLAogIGN1cmw6IDFlLTQsCiAgc3BsYXRSYWRpdXM6IDRlLTMsCiAgc3BsYXRGb3JjZTogMC45MSwKICByZWZyYWN0aW9uOiAwLjI1LAogIHNwZWN1bGFyRXhwOiAxLjAxLAogIHNoaW5lOiAwLjAxLAogIHdhdGVyQ29sb3I6ICIjMDAwMDAwIiwKICBnbG93Q29sb3I6ICIjYjNkOWZmIiwKICBhbGdvcml0aG06ICJzdGFuZGFyZCIsCiAgd2FycFN0cmVuZ3RoOiAwLjAxNQp9OwooewogIC4uLnZ0Cn0pOwpjb25zdCBTdCA9IHsKICBjYWxtOiB7CiAgICBkZW5zaXR5RGlzc2lwYXRpb246IDAuOTk5LAogICAgdmVsb2NpdHlEaXNzaXBhdGlvbjogMC45OCwKICAgIGN1cmw6IDFlLTQsCiAgICBzcGxhdFJhZGl1czogM2UtMywKICAgIHNwbGF0Rm9yY2U6IDAuNSwKICAgIHJlZnJhY3Rpb246IDAuMTUsCiAgICBzaGluZTogNWUtMywKICAgIGdsb3dDb2xvcjogIiM5OWQ5ZmYiLAogICAgd2F0ZXJDb2xvcjogIiMwMDA1MGQiCiAgfSwKICBzYW5kOiB7CiAgICBkZW5zaXR5RGlzc2lwYXRpb246IDAuOTk3LAogICAgdmVsb2NpdHlEaXNzaXBhdGlvbjogMC45OCwKICAgIGN1cmw6IDEsCiAgICBzcGxhdFJhZGl1czogMC4wMSwKICAgIHNwbGF0Rm9yY2U6IDAuOSwKICAgIHJlZnJhY3Rpb246IDAuOCwKICAgIHNwZWN1bGFyRXhwOiAwLjEsCiAgICBzaGluZTogMC4wNSwKICAgIGdsb3dDb2xvcjogIiMwNzA3MDciLAogICAgd2F0ZXJDb2xvcjogIiM3MzU0MjAiCiAgfSwKICB3YXZlOiB7CiAgICBkZW5zaXR5RGlzc2lwYXRpb246IDAuOTk0LAogICAgdmVsb2NpdHlEaXNzaXBhdGlvbjogMC45MiwKICAgIGN1cmw6IDAuMiwKICAgIHNwbGF0UmFkaXVzOiA1ZS0zLAogICAgc3BsYXRGb3JjZTogMS4yLAogICAgcmVmcmFjdGlvbjogMC4zNSwKICAgIHNoaW5lOiAwLjAzLAogICAgZ2xvd0NvbG9yOiAiIzgwY2NmZiIsCiAgICB3YXRlckNvbG9yOiAiIzAwMDMwOCIKICB9LAogIG5lb246IHsKICAgIGRlbnNpdHlEaXNzaXBhdGlvbjogMC45ODUsCiAgICB2ZWxvY2l0eURpc3NpcGF0aW9uOiAwLjkzLAogICAgY3VybDogMC4wNSwKICAgIHNwbGF0UmFkaXVzOiA4ZS0zLAogICAgc3BsYXRGb3JjZTogMS41LAogICAgcmVmcmFjdGlvbjogMC4yNSwKICAgIHNwZWN1bGFyRXhwOiAwLjUsCiAgICBzaGluZTogMC4xNCwKICAgIGdsb3dDb2xvcjogIiNmZjMzY2MiLAogICAgd2F0ZXJDb2xvcjogIiMwZDAwMTQiCiAgfSwKICBzbW9rZTogewogICAgZGVuc2l0eURpc3NpcGF0aW9uOiAwLjk5NiwKICAgIHZlbG9jaXR5RGlzc2lwYXRpb246IDAuOTcsCiAgICBjdXJsOiAwLjA0LAogICAgc3BsYXRSYWRpdXM6IDllLTMsCiAgICBzcGxhdEZvcmNlOiAwLjgsCiAgICByZWZyYWN0aW9uOiAwLjA4LAogICAgc2hpbmU6IDAsCiAgICBnbG93Q29sb3I6ICIjODA4MDgwIiwKICAgIHdhdGVyQ29sb3I6ICIjMGYwZjBmIgogIH0KfTsKZnVuY3Rpb24gV2UoaSkgewogIGlmIChBcnJheS5pc0FycmF5KGkpKQogICAgcmV0dXJuIGk7CiAgY29uc3QgZSA9IGkuc2xpY2UoMSwgNyk7CiAgcmV0dXJuIGUubGVuZ3RoID09PSAzID8gWwogICAgcGFyc2VJbnQoZVswXSArIGVbMF0sIDE2KSAvIDI1NSwKICAgIHBhcnNlSW50KGVbMV0gKyBlWzFdLCAxNikgLyAyNTUsCiAgICBwYXJzZUludChlWzJdICsgZVsyXSwgMTYpIC8gMjU1CiAgXSA6IFsKICAgIHBhcnNlSW50KGUuc2xpY2UoMCwgMiksIDE2KSAvIDI1NSwKICAgIHBhcnNlSW50KGUuc2xpY2UoMiwgNCksIDE2KSAvIDI1NSwKICAgIHBhcnNlSW50KGUuc2xpY2UoNCwgNiksIDE2KSAvIDI1NQogIF07Cn0KZnVuY3Rpb24gd3QoaSA9IHt9LCBlLCByID0gdnQpIHsKICByZXR1cm4geyAuLi5lID8geyAuLi5yLCAuLi5TdFtlXSB9IDogciwgLi4uaSB9Owp9CmNvbnN0IHJlID0gKAogIC8qIGdsc2wgKi8KICBgCiAgcHJlY2lzaW9uIGhpZ2hwIGZsb2F0OwogIGF0dHJpYnV0ZSB2ZWMyIGFQb3NpdGlvbjsKICB2YXJ5aW5nIHZlYzIgdlV2OwogIHZhcnlpbmcgdmVjMiB2TDsgdmFyeWluZyB2ZWMyIHZSOyB2YXJ5aW5nIHZlYzIgdlQ7IHZhcnlpbmcgdmVjMiB2QjsKICB1bmlmb3JtIHZlYzIgdGV4ZWxTaXplOwogIHZvaWQgbWFpbiAoKSB7CiAgICB2VXYgPSBhUG9zaXRpb24gKiAwLjUgKyAwLjU7CiAgICB2TCA9IHZVdiAtIHZlYzIodGV4ZWxTaXplLngsIDAuMCk7CiAgICB2UiA9IHZVdiArIHZlYzIodGV4ZWxTaXplLngsIDAuMCk7CiAgICB2VCA9IHZVdiArIHZlYzIoMC4wLCB0ZXhlbFNpemUueSk7CiAgICB2QiA9IHZVdiAtIHZlYzIoMC4wLCB0ZXhlbFNpemUueSk7CiAgICBnbF9Qb3NpdGlvbiA9IHZlYzQoYVBvc2l0aW9uLCAwLjAsIDEuMCk7CiAgfQpgCiksIFJ0ID0gKAogIC8qIGdsc2wgKi8KICBgCiAgcHJlY2lzaW9uIGhpZ2hwIGZsb2F0OwogIHZhcnlpbmcgdmVjMiB2VXY7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdVZlbG9jaXR5OwogIHVuaWZvcm0gc2FtcGxlcjJEIHVTb3VyY2U7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdU9ic3RhY2xlOwogIHVuaWZvcm0gdmVjMiB0ZXhlbFNpemU7CiAgdW5pZm9ybSBmbG9hdCBkdDsKICB1bmlmb3JtIGZsb2F0IGRpc3NpcGF0aW9uOwogIHZvaWQgbWFpbiAoKSB7CiAgICBpZiAodGV4dHVyZTJEKHVPYnN0YWNsZSwgdlV2KS5yID4gMC41KSB7IGdsX0ZyYWdDb2xvciA9IHZlYzQoMC4wKTsgcmV0dXJuOyB9CiAgICB2ZWMyIGNvb3JkID0gdlV2IC0gZHQgKiB0ZXh0dXJlMkQodVZlbG9jaXR5LCB2VXYpLnh5ICogdGV4ZWxTaXplOwogICAgZ2xfRnJhZ0NvbG9yID0gZGlzc2lwYXRpb24gKiB0ZXh0dXJlMkQodVNvdXJjZSwgY29vcmQpOwogIH0KYAopLCBFdCA9ICgKICAvKiBnbHNsICovCiAgYAogIHByZWNpc2lvbiBoaWdocCBmbG9hdDsKICB2YXJ5aW5nIHZlYzIgdkw7IHZhcnlpbmcgdmVjMiB2UjsgdmFyeWluZyB2ZWMyIHZUOyB2YXJ5aW5nIHZlYzIgdkI7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdVZlbG9jaXR5OwogIHVuaWZvcm0gc2FtcGxlcjJEIHVPYnN0YWNsZTsKICB2b2lkIG1haW4gKCkgewogICAgZmxvYXQgTCA9IHRleHR1cmUyRCh1T2JzdGFjbGUsIHZMKS5yID4gMC41ID8gMC4wIDogdGV4dHVyZTJEKHVWZWxvY2l0eSwgdkwpLng7CiAgICBmbG9hdCBSID0gdGV4dHVyZTJEKHVPYnN0YWNsZSwgdlIpLnIgPiAwLjUgPyAwLjAgOiB0ZXh0dXJlMkQodVZlbG9jaXR5LCB2UikueDsKICAgIGZsb2F0IFQgPSB0ZXh0dXJlMkQodU9ic3RhY2xlLCB2VCkuciA+IDAuNSA/IDAuMCA6IHRleHR1cmUyRCh1VmVsb2NpdHksIHZUKS55OwogICAgZmxvYXQgQiA9IHRleHR1cmUyRCh1T2JzdGFjbGUsIHZCKS5yID4gMC41ID8gMC4wIDogdGV4dHVyZTJEKHVWZWxvY2l0eSwgdkIpLnk7CiAgICBnbF9GcmFnQ29sb3IgPSB2ZWM0KDAuNSAqIChSIC0gTCArIFQgLSBCKSwgMC4wLCAwLjAsIDEuMCk7CiAgfQpgCiksIFV0ID0gKAogIC8qIGdsc2wgKi8KICBgCiAgcHJlY2lzaW9uIGhpZ2hwIGZsb2F0OwogIHZhcnlpbmcgdmVjMiB2VXY7IHZhcnlpbmcgdmVjMiB2TDsgdmFyeWluZyB2ZWMyIHZSOyB2YXJ5aW5nIHZlYzIgdlQ7IHZhcnlpbmcgdmVjMiB2QjsKICB1bmlmb3JtIHNhbXBsZXIyRCB1UHJlc3N1cmU7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdURpdmVyZ2VuY2U7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdU9ic3RhY2xlOwogIHZvaWQgbWFpbiAoKSB7CiAgICBmbG9hdCBDID0gdGV4dHVyZTJEKHVQcmVzc3VyZSwgdlV2KS54OwogICAgZmxvYXQgTCA9IHRleHR1cmUyRCh1T2JzdGFjbGUsIHZMKS5yID4gMC41ID8gQyA6IHRleHR1cmUyRCh1UHJlc3N1cmUsIHZMKS54OwogICAgZmxvYXQgUiA9IHRleHR1cmUyRCh1T2JzdGFjbGUsIHZSKS5yID4gMC41ID8gQyA6IHRleHR1cmUyRCh1UHJlc3N1cmUsIHZSKS54OwogICAgZmxvYXQgVCA9IHRleHR1cmUyRCh1T2JzdGFjbGUsIHZUKS5yID4gMC41ID8gQyA6IHRleHR1cmUyRCh1UHJlc3N1cmUsIHZUKS54OwogICAgZmxvYXQgQiA9IHRleHR1cmUyRCh1T2JzdGFjbGUsIHZCKS5yID4gMC41ID8gQyA6IHRleHR1cmUyRCh1UHJlc3N1cmUsIHZCKS54OwogICAgZmxvYXQgZGl2ID0gdGV4dHVyZTJEKHVEaXZlcmdlbmNlLCB2VXYpLng7CiAgICBnbF9GcmFnQ29sb3IgPSB2ZWM0KChMICsgUiArIEIgKyBUIC0gZGl2KSAqIDAuMjUsIDAuMCwgMC4wLCAxLjApOwogIH0KYAopLCBEdCA9ICgKICAvKiBnbHNsICovCiAgYAogIHByZWNpc2lvbiBoaWdocCBmbG9hdDsKICB2YXJ5aW5nIHZlYzIgdlV2OyB2YXJ5aW5nIHZlYzIgdkw7IHZhcnlpbmcgdmVjMiB2UjsgdmFyeWluZyB2ZWMyIHZUOyB2YXJ5aW5nIHZlYzIgdkI7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdVByZXNzdXJlOwogIHVuaWZvcm0gc2FtcGxlcjJEIHVWZWxvY2l0eTsKICB1bmlmb3JtIHNhbXBsZXIyRCB1T2JzdGFjbGU7CiAgdm9pZCBtYWluICgpIHsKICAgIGlmICh0ZXh0dXJlMkQodU9ic3RhY2xlLCB2VXYpLnIgPiAwLjUpIHsgZ2xfRnJhZ0NvbG9yID0gdmVjNCgwLjApOyByZXR1cm47IH0KICAgIGZsb2F0IEwgPSB0ZXh0dXJlMkQodVByZXNzdXJlLCB2TCkueDsKICAgIGZsb2F0IFIgPSB0ZXh0dXJlMkQodVByZXNzdXJlLCB2UikueDsKICAgIGZsb2F0IFQgPSB0ZXh0dXJlMkQodVByZXNzdXJlLCB2VCkueDsKICAgIGZsb2F0IEIgPSB0ZXh0dXJlMkQodVByZXNzdXJlLCB2QikueDsKICAgIHZlYzIgdmVsID0gdGV4dHVyZTJEKHVWZWxvY2l0eSwgdlV2KS54eSAtIHZlYzIoUiAtIEwsIFQgLSBCKTsKICAgIGdsX0ZyYWdDb2xvciA9IHZlYzQodmVsLCAwLjAsIDEuMCk7CiAgfQpgCiksIF90ID0gKAogIC8qIGdsc2wgKi8KICBgCiAgcHJlY2lzaW9uIGhpZ2hwIGZsb2F0OwogIHZhcnlpbmcgdmVjMiB2VXY7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdVRhcmdldDsKICB1bmlmb3JtIGZsb2F0IGFzcGVjdFJhdGlvOwogIHVuaWZvcm0gdmVjMyBjb2xvcjsKICB1bmlmb3JtIHZlYzIgcG9pbnQ7CiAgdW5pZm9ybSBmbG9hdCByYWRpdXM7CiAgdm9pZCBtYWluICgpIHsKICAgIHZlYzIgcCA9IHZVdiAtIHBvaW50Lnh5OwogICAgcC54ICo9IGFzcGVjdFJhdGlvOwogICAgdmVjMyBzcGxhdCA9IGV4cCgtZG90KHAsIHApIC8gcmFkaXVzKSAqIGNvbG9yOwogICAgZ2xfRnJhZ0NvbG9yID0gdmVjNCh0ZXh0dXJlMkQodVRhcmdldCwgdlV2KS54eXogKyBzcGxhdCwgMS4wKTsKICB9CmAKKSwgQ3QgPSAoCiAgLyogZ2xzbCAqLwogIGAKICBwcmVjaXNpb24gaGlnaHAgZmxvYXQ7CiAgdmFyeWluZyB2ZWMyIHZMOyB2YXJ5aW5nIHZlYzIgdlI7IHZhcnlpbmcgdmVjMiB2VDsgdmFyeWluZyB2ZWMyIHZCOwogIHVuaWZvcm0gc2FtcGxlcjJEIHVWZWxvY2l0eTsKICB2b2lkIG1haW4gKCkgewogICAgZmxvYXQgTCA9IHRleHR1cmUyRCh1VmVsb2NpdHksIHZMKS55OwogICAgZmxvYXQgUiA9IHRleHR1cmUyRCh1VmVsb2NpdHksIHZSKS55OwogICAgZmxvYXQgVCA9IHRleHR1cmUyRCh1VmVsb2NpdHksIHZUKS54OwogICAgZmxvYXQgQiA9IHRleHR1cmUyRCh1VmVsb2NpdHksIHZCKS54OwogICAgZ2xfRnJhZ0NvbG9yID0gdmVjNCgwLjUgKiAoUiAtIEwgLSBUICsgQiksIDAuMCwgMC4wLCAxLjApOwogIH0KYAopLCBCdCA9ICgKICAvKiBnbHNsICovCiAgYAogIHByZWNpc2lvbiBoaWdocCBmbG9hdDsKICB2YXJ5aW5nIHZlYzIgdlV2OyB2YXJ5aW5nIHZlYzIgdkw7IHZhcnlpbmcgdmVjMiB2UjsgdmFyeWluZyB2ZWMyIHZUOyB2YXJ5aW5nIHZlYzIgdkI7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdVZlbG9jaXR5OwogIHVuaWZvcm0gc2FtcGxlcjJEIHVDdXJsOwogIHVuaWZvcm0gZmxvYXQgY3VybDsKICB1bmlmb3JtIGZsb2F0IGR0OwogIHZvaWQgbWFpbiAoKSB7CiAgICBmbG9hdCBMID0gdGV4dHVyZTJEKHVDdXJsLCB2TCkueDsKICAgIGZsb2F0IFIgPSB0ZXh0dXJlMkQodUN1cmwsIHZSKS54OwogICAgZmxvYXQgVCA9IHRleHR1cmUyRCh1Q3VybCwgdlQpLng7CiAgICBmbG9hdCBCID0gdGV4dHVyZTJEKHVDdXJsLCB2QikueDsKICAgIGZsb2F0IEMgPSB0ZXh0dXJlMkQodUN1cmwsIHZVdikueDsKICAgIHZlYzIgZm9yY2UgPSAwLjUgKiB2ZWMyKGFicyhUKSAtIGFicyhCKSwgYWJzKFIpIC0gYWJzKEwpKTsKICAgIGZvcmNlIC89IGxlbmd0aChmb3JjZSkgKyAwLjAwMDE7CiAgICBmb3JjZSAqPSBjdXJsICogMzAuMCAqIEM7CiAgICBnbF9GcmFnQ29sb3IgPSB2ZWM0KHRleHR1cmUyRCh1VmVsb2NpdHksIHZVdikueHkgKyBmb3JjZSAqIGR0LCAwLjAsIDEuMCk7CiAgfQpgCiksIFZ0ID0gKAogIC8qIGdsc2wgKi8KICBgCiAgcHJlY2lzaW9uIGhpZ2hwIGZsb2F0OwogIHZhcnlpbmcgdmVjMiB2VXY7CgogIHVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlOwogIHVuaWZvcm0gc2FtcGxlcjJEIHVPYnN0YWNsZTsKICB1bmlmb3JtIHNhbXBsZXIyRCB1QmFja2dyb3VuZDsKICB1bmlmb3JtIHNhbXBsZXIyRCB1Q292ZXJhZ2U7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdVZlbG9jaXR5OwoKICB1bmlmb3JtIHZlYzIgIHRleGVsU2l6ZTsKICB1bmlmb3JtIHZlYzMgIHVXYXRlckNvbG9yOwogIHVuaWZvcm0gdmVjMyAgdUdsb3dDb2xvcjsKICB1bmlmb3JtIGZsb2F0IHVSZWZyYWN0aW9uOwogIHVuaWZvcm0gZmxvYXQgdVNwZWN1bGFyRXhwOwogIHVuaWZvcm0gZmxvYXQgdVNoaW5lOwogIHVuaWZvcm0gZmxvYXQgdVdhcnBTdHJlbmd0aDsKICB1bmlmb3JtIGludCAgIHVBbGdvcml0aG07CiAgdW5pZm9ybSBpbnQgICB1RW5hYmxlQWxwaGE7CgogIHZvaWQgbWFpbiAoKSB7CiAgICBmbG9hdCBvYnMgICAgICA9IHRleHR1cmUyRCh1T2JzdGFjbGUsICB2VXYpLnI7CiAgICAvLyBNYXNrIGRlbnNpdHkgaW5zaWRlIG9ic3RhY2xlcyBzbyBzcGxhdHMgZG9uJ3QgZmxpY2tlciB0aGUgdGV4dC9pbWFnZSBjb250ZW50LgogICAgZmxvYXQgZGVuc2l0eSAgPSBtYXgodGV4dHVyZTJEKHVUZXh0dXJlLCB2VXYpLnIsIDAuMCkgKiAoMS4wIC0gc3RlcCgwLjUsIG9icykpOwogICAgZmxvYXQgY292ZXJhZ2UgPSB0ZXh0dXJlMkQodUNvdmVyYWdlLCAgdlV2KS5yOwoKICAgIGZsb2F0IGRMID0gbWF4KHRleHR1cmUyRCh1VGV4dHVyZSwgdlV2IC0gdmVjMih0ZXhlbFNpemUueCAqIDIuMCwgMC4wKSkuciwgMC4wKTsKICAgIGZsb2F0IGRSID0gbWF4KHRleHR1cmUyRCh1VGV4dHVyZSwgdlV2ICsgdmVjMih0ZXhlbFNpemUueCAqIDIuMCwgMC4wKSkuciwgMC4wKTsKICAgIGZsb2F0IGRUID0gbWF4KHRleHR1cmUyRCh1VGV4dHVyZSwgdlV2ICsgdmVjMigwLjAsIHRleGVsU2l6ZS55ICogMi4wKSkuciwgMC4wKTsKICAgIGZsb2F0IGRCID0gbWF4KHRleHR1cmUyRCh1VGV4dHVyZSwgdlV2IC0gdmVjMigwLjAsIHRleGVsU2l6ZS55ICogMi4wKSkuciwgMC4wKTsKCiAgICB2ZWMzICBub3JtYWwgICA9IG5vcm1hbGl6ZSh2ZWMzKGRMIC0gZFIsIGRCIC0gZFQsIDAuMikpOwogICAgdmVjMyAgbGlnaHREaXIgPSBub3JtYWxpemUodmVjMygwLjUsIDEuMCwgMC41KSk7CiAgICB2ZWMzICBoYWxmViAgICA9IG5vcm1hbGl6ZShsaWdodERpciArIHZlYzMoMC4wLCAwLjAsIDEuMCkpOwogICAgZmxvYXQgc3BlYyAgICAgPSBwb3cobWF4KGRvdChub3JtYWwsIGhhbGZWKSwgMC4wKSwgdVNwZWN1bGFyRXhwKSAqIHVTaGluZSAqIGRlbnNpdHk7CgogICAgLy8gSW4gdHJhbnNwYXJlbnQgKG5vbi1jb3ZlcmFnZSkgYXJlYXMgdGhlIGJhY2tncm91bmQgdGV4dHVyZSBpcyBlbXB0eSBibGFjayBjYW52YXMuCiAgICAvLyBSZXBsYWNlIGl0IHdpdGggdVdhdGVyQ29sb3Igc28gZmx1aWQgY29sb3VyIGlzIG5vdCBjb250YW1pbmF0ZWQgYnkgdGhhdCBibGFjaywKICAgIC8vIGFsbG93aW5nIHRoZSBDU1MgYmFja2dyb3VuZENvbG9yIHRvIHNob3cgdGhyb3VnaCBjb3JyZWN0bHkgdmlhIHByZW11bHRpcGxpZWQgYWxwaGEuCiAgICB2ZWMzIGJnUmF3ID0gdGV4dHVyZTJEKHVCYWNrZ3JvdW5kLCB2VXYpLnJnYjsKICAgIHZlYzMgYmcgICAgPSBtaXgodVdhdGVyQ29sb3IsIGJnUmF3LCBjb3ZlcmFnZSk7CiAgICB2ZWMzIGNvbG9yID0gYmc7CgogICAgaWYgKHVBbGdvcml0aG0gPT0gMSkgewogICAgICAvLyDilIDilIAgZ2xhc3Mg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiAgICAgIC8vIFN0cm9uZyBVViBkaXN0b3J0aW9uIG9ubHkuIEltYWdlIGJlbmRzIGJ1dCBubyBjb2xvdXIgb3ZlcmxheS4KICAgICAgdmVjMiByZWZyVXYgPSBjbGFtcCh2VXYgKyBub3JtYWwueHkgKiB1UmVmcmFjdGlvbiAqIGRlbnNpdHkgKiAzLjAsIDAuMCwgMS4wKTsKICAgICAgdmVjMyByZWZyQmcgPSBtaXgodVdhdGVyQ29sb3IsIHRleHR1cmUyRCh1QmFja2dyb3VuZCwgbWl4KHZVdiwgcmVmclV2LCAxLjAgLSBvYnMpKS5yZ2IsIGNvdmVyYWdlKTsKICAgICAgY29sb3IgPSByZWZyQmcgKyBzcGVjICogdUdsb3dDb2xvciAqIDIuNTsKICAgICAgY29sb3IgPSBtaXgoY29sb3IsIGJnICogMC42LCBvYnMgKiAwLjMpOwoKICAgIH0gZWxzZSBpZiAodUFsZ29yaXRobSA9PSAyKSB7CiAgICAgIC8vIOKUgOKUgCBpbmsg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiAgICAgIC8vIERlbnNlIG9wYXF1ZSBwaWdtZW50IHRoYXQgc3RhaW5zLiBTdWJ0bGUgcmVmcmFjdGlvbiB1bmRlcm5lYXRoLgogICAgICBmbG9hdCBpbmtEICA9IG1pbihkZW5zaXR5ICogNC4wLCAxLjApOwogICAgICB2ZWMyIHJlZnJVdiA9IGNsYW1wKHZVdiArIG5vcm1hbC54eSAqIHVSZWZyYWN0aW9uICogZGVuc2l0eSAqIDAuNCwgMC4wLCAxLjApOwogICAgICB2ZWMzIHJlZnJCZyA9IG1peCh1V2F0ZXJDb2xvciwgdGV4dHVyZTJEKHVCYWNrZ3JvdW5kLCBtaXgodlV2LCByZWZyVXYsIDEuMCAtIG9icykpLnJnYiwgY292ZXJhZ2UpOwogICAgICBjb2xvciA9IG1peChyZWZyQmcsIHVXYXRlckNvbG9yICsgc3BlYyAqIHVHbG93Q29sb3IsIGlua0QpOwogICAgICBjb2xvciA9IG1peChjb2xvciwgYmcgKiAwLjUsIG9icyAqIDAuMTUpOwoKICAgIH0gZWxzZSBpZiAodUFsZ29yaXRobSA9PSAzKSB7CiAgICAgIC8vIOKUgOKUgCBhdXJvcmEg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiAgICAgIC8vIFZlbG9jaXR5IGZpZWxkIHdhcnBzIGJhY2tncm91bmQgVVZzIOKAlCBsaXF1aWQgbWV0YWwgLyBsYXZhLWxhbXAgZmVlbC4KICAgICAgdmVjMiAgdmVsICAgID0gdGV4dHVyZTJEKHVWZWxvY2l0eSwgdlV2KS54eTsKICAgICAgZmxvYXQgdmVsTWFnID0gY2xhbXAobGVuZ3RoKHZlbCkgKiAyMC4wLCAwLjAsIDEuMCk7CiAgICAgIHZlYzIgIHdhcnBVdiA9IGNsYW1wKHZVdiArIHZlbCAqIHVXYXJwU3RyZW5ndGgsIDAuMCwgMS4wKTsKICAgICAgdmVjMyAgd2FycEJnID0gbWl4KHVXYXRlckNvbG9yLCB0ZXh0dXJlMkQodUJhY2tncm91bmQsIHdhcnBVdikucmdiLCBjb3ZlcmFnZSk7CiAgICAgIGNvbG9yICA9IG1peChiZywgd2FycEJnLCB2ZWxNYWcgKiAoMS4wIC0gb2JzKSk7CiAgICAgIGNvbG9yICs9IHNwZWMgKiB1R2xvd0NvbG9yICogdmVsTWFnICogMS41OwogICAgICBjb2xvciArPSB1V2F0ZXJDb2xvciAqIGRlbnNpdHkgKiAwLjM7CiAgICAgIGNvbG9yICA9IG1peChjb2xvciwgYmcgKiAwLjUsIG9icyAqIDAuMik7CgogICAgfSBlbHNlIGlmICh1QWxnb3JpdGhtID09IDQpIHsKICAgICAgLy8g4pSA4pSAIHJpcHBsZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKICAgICAgLy8gRXhhZ2dlcmF0ZWQgbm9ybWFsIHBlcnR1cmJhdGlvbiArIEZyZXNuZWwgcmltIOKAlCBjYWxtIHdhdGVyIHN1cmZhY2UuCiAgICAgIHZlYzIgIHJpcHBsZVV2ID0gY2xhbXAodlV2ICsgbm9ybWFsLnh5ICogdVJlZnJhY3Rpb24gKiBkZW5zaXR5ICogNi4wLCAwLjAsIDEuMCk7CiAgICAgIHZlYzMgIHJlZnJCZyAgID0gbWl4KHVXYXRlckNvbG9yLCB0ZXh0dXJlMkQodUJhY2tncm91bmQsIG1peCh2VXYsIHJpcHBsZVV2LCAxLjAgLSBvYnMpKS5yZ2IsIGNvdmVyYWdlKTsKICAgICAgZmxvYXQgZnJlc25lbCAgPSBwb3coY2xhbXAoMS4wIC0gZG90KG5vcm1hbCwgdmVjMygwLjAsIDAuMCwgMS4wKSksIDAuMCwgMS4wKSwgMy4wKSAqIGRlbnNpdHk7CiAgICAgIGNvbG9yICA9IHJlZnJCZzsKICAgICAgY29sb3IgKz0gZnJlc25lbCAqIHVHbG93Q29sb3IgKiAyLjA7CiAgICAgIGNvbG9yICs9IHNwZWMgKiB1R2xvd0NvbG9yICogZGVuc2l0eSAqIDIuMDsKICAgICAgY29sb3IgID0gbWl4KGNvbG9yLCBiZyAqIDAuNSwgb2JzICogMC4yKTsKCiAgICB9IGVsc2UgewogICAgICAvLyDilIDilIAgc3RhbmRhcmQgKDApIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAogICAgICAvLyBPcmlnaW5hbDogY29sb3VyIG92ZXJsYXkgYmxlbmRlZCBvdmVyIHJlZnJhY3RlZCBiYWNrZ3JvdW5kLgogICAgICB2ZWMyIHJlZnJVdiA9IHZVdiArIG5vcm1hbC54eSAqIHVSZWZyYWN0aW9uICogZGVuc2l0eTsKICAgICAgdmVjMyByZWZyQmcgPSBtaXgodVdhdGVyQ29sb3IsIHRleHR1cmUyRCh1QmFja2dyb3VuZCwgbWl4KHZVdiwgcmVmclV2LCAxLjAgLSBvYnMpKS5yZ2IsIGNvdmVyYWdlKTsKICAgICAgY29sb3IgID0gbWl4KHJlZnJCZywgdVdhdGVyQ29sb3IsIG1pbihkZW5zaXR5ICogMS41LCAwLjgpKTsKICAgICAgY29sb3IgKz0gc3BlYyAqIHVHbG93Q29sb3I7CiAgICAgIGNvbG9yICA9IG1peChjb2xvciwgYmcgKiAwLjUsIG9icyAqIDAuMik7CiAgICB9CgogICAgLy8gT3V0cHV0OiBwcmVtdWx0aXBsaWVkIGFscGhhIHdoZW4gdHJhbnNwYXJlbmN5IGlzIGVuYWJsZWQgKGxldHMgQ1NTIGJhY2tncm91bmRDb2xvcgogICAgLy8gc2hvdyB0aHJvdWdoKSwgb3Igc3RyYWlnaHQgb3BhcXVlIGNvbG91ciB3aGVuIGVuYWJsZUFscGhhIGlzIG9mZiAocGVyZiBtb2RlKS4KICAgIGZsb2F0IGFscGhhID0gY2xhbXAobWF4KGRlbnNpdHkgKiAxLjUsIGNvdmVyYWdlKSwgMC4wLCAxLjApOwogICAgaWYgKHVFbmFibGVBbHBoYSA9PSAxKSB7CiAgICAgIGdsX0ZyYWdDb2xvciA9IHZlYzQoY29sb3IgKiBhbHBoYSwgYWxwaGEpOwogICAgfSBlbHNlIHsKICAgICAgZ2xfRnJhZ0NvbG9yID0gdmVjNChjb2xvciwgMS4wKTsKICAgIH0KICB9CmAKKTsKZnVuY3Rpb24gT3QoaSwgZSA9ICEwKSB7CiAgY29uc3QgciA9IHsgYWxwaGE6IGUsIGRlcHRoOiAhMSwgc3RlbmNpbDogITEsIGFudGlhbGlhczogITAsIHByZXNlcnZlRHJhd2luZ0J1ZmZlcjogITEgfTsKICBsZXQgcyA9IGkuZ2V0Q29udGV4dCgid2ViZ2wyIiwgcik7CiAgY29uc3QgbyA9ICEhczsKICBvIHx8IChzID0gaS5nZXRDb250ZXh0KCJ3ZWJnbCIsIHIpLCBzLmdldEV4dGVuc2lvbigiRVhUX2NvbG9yX2J1ZmZlcl9oYWxmX2Zsb2F0IikpOwogIGNvbnN0IGEgPSBvID8gbnVsbCA6IHMuZ2V0RXh0ZW5zaW9uKCJPRVNfdGV4dHVyZV9oYWxmX2Zsb2F0IiksIHUgPSBvID8gcy5IQUxGX0ZMT0FUIDogYS5IQUxGX0ZMT0FUX09FUzsKICByZXR1cm4gcy5nZXRFeHRlbnNpb24oIkVYVF9jb2xvcl9idWZmZXJfZmxvYXQiKSwgcy5nZXRFeHRlbnNpb24oIk9FU190ZXh0dXJlX2hhbGZfZmxvYXRfbGluZWFyIiksIHsKICAgIHR5cGU6IG8gPyAid2ViZ2wyIiA6ICJ3ZWJnbDEiLAogICAgZ2w6IHMsCiAgICBpc1dlYkdMMjogbywKICAgIGV4dDogewogICAgICBpbnRlcm5hbEZvcm1hdDogbyA/IHMuUkdCQTE2RiA6IHMuUkdCQSwKICAgICAgZm9ybWF0OiBzLlJHQkEsCiAgICAgIHR5cGU6IHUKICAgIH0KICB9Owp9CmFzeW5jIGZ1bmN0aW9uIEZ0KGksIGUgPSAhMCkgewogIGlmICh0eXBlb2YgbmF2aWdhdG9yID4gInUiIHx8ICFuYXZpZ2F0b3IuZ3B1KQogICAgcmV0dXJuIG51bGw7CiAgdHJ5IHsKICAgIGNvbnN0IHIgPSBhd2FpdCBuYXZpZ2F0b3IuZ3B1LnJlcXVlc3RBZGFwdGVyKCk7CiAgICBpZiAoIXIpCiAgICAgIHJldHVybiBudWxsOwogICAgY29uc3QgcyA9IGF3YWl0IHIucmVxdWVzdERldmljZSgpLCBvID0gaS5nZXRDb250ZXh0KCJ3ZWJncHUiKTsKICAgIGlmICghbykKICAgICAgcmV0dXJuIG51bGw7CiAgICBjb25zdCBhID0gbmF2aWdhdG9yLmdwdS5nZXRQcmVmZXJyZWRDYW52YXNGb3JtYXQoKTsKICAgIHJldHVybiBvLmNvbmZpZ3VyZSh7IGRldmljZTogcywgZm9ybWF0OiBhLCBhbHBoYU1vZGU6IGUgPyAicHJlbXVsdGlwbGllZCIgOiAib3BhcXVlIiB9KSwgeyB0eXBlOiAid2ViZ3B1IiwgYWRhcHRlcjogciwgZGV2aWNlOiBzLCBjb250ZXh0OiBvLCBmb3JtYXQ6IGEgfTsKICB9IGNhdGNoIHsKICAgIHJldHVybiBudWxsOwogIH0KfQpjbGFzcyBpZSB7CiAgY29uc3RydWN0b3IoZSwgciwgcykgewogICAga2UodGhpcywgInByb2dyYW0iKTsKICAgIGtlKHRoaXMsICJ1bmlmb3JtcyIsIHt9KTsKICAgIGtlKHRoaXMsICJfZ2wiKTsKICAgIHRoaXMuX2dsID0gZSwgdGhpcy5wcm9ncmFtID0gZS5jcmVhdGVQcm9ncmFtKCksIGUuYXR0YWNoU2hhZGVyKHRoaXMucHJvZ3JhbSwgdGhpcy5fY29tcGlsZShlLlZFUlRFWF9TSEFERVIsIHIpKSwgZS5hdHRhY2hTaGFkZXIodGhpcy5wcm9ncmFtLCB0aGlzLl9jb21waWxlKGUuRlJBR01FTlRfU0hBREVSLCBzKSksIGUubGlua1Byb2dyYW0odGhpcy5wcm9ncmFtKTsKICAgIGNvbnN0IG8gPSBlLmdldFByb2dyYW1QYXJhbWV0ZXIodGhpcy5wcm9ncmFtLCBlLkFDVElWRV9VTklGT1JNUyk7CiAgICBmb3IgKGxldCBhID0gMDsgYSA8IG87IGErKykgewogICAgICBjb25zdCB1ID0gZS5nZXRBY3RpdmVVbmlmb3JtKHRoaXMucHJvZ3JhbSwgYSkubmFtZTsKICAgICAgdGhpcy51bmlmb3Jtc1t1XSA9IGUuZ2V0VW5pZm9ybUxvY2F0aW9uKHRoaXMucHJvZ3JhbSwgdSk7CiAgICB9CiAgfQogIF9jb21waWxlKGUsIHIpIHsKICAgIGNvbnN0IHMgPSB0aGlzLl9nbCwgbyA9IHMuY3JlYXRlU2hhZGVyKGUpOwogICAgcmV0dXJuIHMuc2hhZGVyU291cmNlKG8sIHIpLCBzLmNvbXBpbGVTaGFkZXIobyksIG87CiAgfQogIGJpbmQoKSB7CiAgICB0aGlzLl9nbC51c2VQcm9ncmFtKHRoaXMucHJvZ3JhbSk7CiAgfQogIGRpc3Bvc2UoKSB7CiAgICB0aGlzLl9nbC5kZWxldGVQcm9ncmFtKHRoaXMucHJvZ3JhbSk7CiAgfQp9CmZ1bmN0aW9uIFB0KGkpIHsKICByZXR1cm4gewogICAgYWR2ZWN0aW9uOiBuZXcgaWUoaSwgcmUsIFJ0KSwKICAgIGRpdmVyZ2VuY2U6IG5ldyBpZShpLCByZSwgRXQpLAogICAgcHJlc3N1cmU6IG5ldyBpZShpLCByZSwgVXQpLAogICAgZ3JhZGllbnRTdWJ0cmFjdDogbmV3IGllKGksIHJlLCBEdCksCiAgICBzcGxhdDogbmV3IGllKGksIHJlLCBfdCksCiAgICBjdXJsOiBuZXcgaWUoaSwgcmUsIEN0KSwKICAgIHZvcnRpY2l0eTogbmV3IGllKGksIHJlLCBCdCksCiAgICBkaXNwbGF5OiBuZXcgaWUoaSwgcmUsIFZ0KQogIH07Cn0KZnVuY3Rpb24gcWUoaSwgZSwgciwgcykgewogIGkuYWN0aXZlVGV4dHVyZShpLlRFWFRVUkUwKTsKICBjb25zdCBvID0gaS5jcmVhdGVUZXh0dXJlKCk7CiAgaS5iaW5kVGV4dHVyZShpLlRFWFRVUkVfMkQsIG8pLCBpLnRleFBhcmFtZXRlcmkoaS5URVhUVVJFXzJELCBpLlRFWFRVUkVfTUlOX0ZJTFRFUiwgaS5MSU5FQVIpLCBpLnRleFBhcmFtZXRlcmkoaS5URVhUVVJFXzJELCBpLlRFWFRVUkVfTUFHX0ZJTFRFUiwgaS5MSU5FQVIpLCBpLnRleFBhcmFtZXRlcmkoaS5URVhUVVJFXzJELCBpLlRFWFRVUkVfV1JBUF9TLCBpLkNMQU1QX1RPX0VER0UpLCBpLnRleFBhcmFtZXRlcmkoaS5URVhUVVJFXzJELCBpLlRFWFRVUkVfV1JBUF9ULCBpLkNMQU1QX1RPX0VER0UpLCBpLnRleEltYWdlMkQoaS5URVhUVVJFXzJELCAwLCBlLmludGVybmFsRm9ybWF0LCByLCBzLCAwLCBlLmZvcm1hdCwgZS50eXBlLCBudWxsKTsKICBjb25zdCBhID0gaS5jcmVhdGVGcmFtZWJ1ZmZlcigpOwogIHJldHVybiBpLmJpbmRGcmFtZWJ1ZmZlcihpLkZSQU1FQlVGRkVSLCBhKSwgaS5mcmFtZWJ1ZmZlclRleHR1cmUyRChpLkZSQU1FQlVGRkVSLCBpLkNPTE9SX0FUVEFDSE1FTlQwLCBpLlRFWFRVUkVfMkQsIG8sIDApLCB7IHRleDogbywgZmJvOiBhLCB3aWR0aDogciwgaGVpZ2h0OiBzIH07Cn0KZnVuY3Rpb24gdHQoaSwgZSwgciwgcykgewogIGxldCBvID0gcWUoaSwgZSwgciwgcyksIGEgPSBxZShpLCBlLCByLCBzKTsKICByZXR1cm4gewogICAgZ2V0IHJlYWQoKSB7CiAgICAgIHJldHVybiBvOwogICAgfSwKICAgIGdldCB3cml0ZSgpIHsKICAgICAgcmV0dXJuIGE7CiAgICB9LAogICAgc3dhcCgpIHsKICAgICAgW28sIGFdID0gW2EsIG9dOwogICAgfSwKICAgIGRpc3Bvc2UoKSB7CiAgICAgIGkuZGVsZXRlVGV4dHVyZShvLnRleCksIGkuZGVsZXRlRnJhbWVidWZmZXIoby5mYm8pLCBpLmRlbGV0ZVRleHR1cmUoYS50ZXgpLCBpLmRlbGV0ZUZyYW1lYnVmZmVyKGEuZmJvKTsKICAgIH0KICB9Owp9CmZ1bmN0aW9uIEx0KGkpIHsKICBjb25zdCBlID0gaS5jcmVhdGVCdWZmZXIoKTsKICByZXR1cm4gaS5iaW5kQnVmZmVyKGkuQVJSQVlfQlVGRkVSLCBlKSwgaS5idWZmZXJEYXRhKGkuQVJSQVlfQlVGRkVSLCBuZXcgRmxvYXQzMkFycmF5KFstMSwgLTEsIC0xLCAxLCAxLCAxLCAxLCAtMV0pLCBpLlNUQVRJQ19EUkFXKSwgaS52ZXJ0ZXhBdHRyaWJQb2ludGVyKDAsIDIsIGkuRkxPQVQsICExLCAwLCAwKSwgaS5lbmFibGVWZXJ0ZXhBdHRyaWJBcnJheSgwKSwgZnVuY3Rpb24ocykgewogICAgaS5iaW5kRnJhbWVidWZmZXIoaS5GUkFNRUJVRkZFUiwgcyksIGkuZHJhd0FycmF5cyhpLlRSSUFOR0xFX0ZBTiwgMCwgNCk7CiAgfTsKfQpjb25zdCBsZSA9ICgKICAvKiB3Z3NsICovCiAgYApzdHJ1Y3QgVlNPdXQgewogIEBidWlsdGluKHBvc2l0aW9uKSBwb3MgOiB2ZWM0ZiwKICBAbG9jYXRpb24oMCkgICAgICAgdXYgIDogdmVjMmYsCiAgQGxvY2F0aW9uKDEpICAgICAgIHZMICA6IHZlYzJmLAogIEBsb2NhdGlvbigyKSAgICAgICB2UiAgOiB2ZWMyZiwKICBAbG9jYXRpb24oMykgICAgICAgdlQgIDogdmVjMmYsCiAgQGxvY2F0aW9uKDQpICAgICAgIHZCICA6IHZlYzJmLAp9YAopLCBBdCA9ICgKICAvKiB3Z3NsICovCiAgYAoke2xlfQoKc3RydWN0IFUgewogIHRleGVsU2l6ZSAgOiB2ZWMyZiwKICBkdCAgICAgICAgIDogZjMyLAogIGRpc3NpcGF0aW9uOiBmMzIsCn0KQGdyb3VwKDApIEBiaW5kaW5nKDApIHZhcjx1bmlmb3JtPiB1ICAgICA6IFU7CkBncm91cCgwKSBAYmluZGluZygxKSB2YXIgICAgICAgICAgc2FtcCAgOiBzYW1wbGVyOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMikgdmFyICAgICAgICAgIHVWZWwgIDogdGV4dHVyZV8yZDxmMzI+OwpAZ3JvdXAoMCkgQGJpbmRpbmcoMykgdmFyICAgICAgICAgIHVTcmMgIDogdGV4dHVyZV8yZDxmMzI+OwpAZ3JvdXAoMCkgQGJpbmRpbmcoNCkgdmFyICAgICAgICAgIHVPYnMgIDogdGV4dHVyZV8yZDxmMzI+OwoKQHZlcnRleCBmbiB2cyhAbG9jYXRpb24oMCkgYTogdmVjMmYpIC0+IFZTT3V0IHsKICB2YXIgbzogVlNPdXQ7CiAgby51diA9IHZlYzJmKGEueCAqIDAuNSArIDAuNSwgMC41IC0gYS55ICogMC41KTsKICBvLnZMID0gby51diAtIHZlYzJmKHUudGV4ZWxTaXplLngsIDAuMCk7CiAgby52UiA9IG8udXYgKyB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlQgPSBvLnV2ICsgdmVjMmYoMC4wLCB1LnRleGVsU2l6ZS55KTsKICBvLnZCID0gby51diAtIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby5wb3MgPSB2ZWM0ZihhLCAwLjAsIDEuMCk7CiAgcmV0dXJuIG87Cn0KCkBmcmFnbWVudCBmbiBmcyhpOiBWU091dCkgLT4gQGxvY2F0aW9uKDApIHZlYzRmIHsKICAvLyBTYW1wbGUgYWxsIHRleHR1cmVzIGJlZm9yZSBicmFuY2hpbmcg4oCUIHRleHR1cmVTYW1wbGUgcmVxdWlyZXMgdW5pZm9ybSBjb250cm9sIGZsb3cKICBsZXQgb2JzICAgPSB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudXYpLnI7CiAgbGV0IHZlbCAgID0gdGV4dHVyZVNhbXBsZSh1VmVsLCBzYW1wLCBpLnV2KS54eTsKICBsZXQgY29vcmQgPSBpLnV2IC0gdS5kdCAqIHZlbCAqIHUudGV4ZWxTaXplOwogIGxldCBzcmMgICA9IHRleHR1cmVTYW1wbGUodVNyYywgc2FtcCwgY29vcmQpOwogIGlmIChvYnMgPiAwLjUpIHsgcmV0dXJuIHZlYzRmKDAuMCk7IH0KICByZXR1cm4gdS5kaXNzaXBhdGlvbiAqIHNyYzsKfQpgCiksIHp0ID0gKAogIC8qIHdnc2wgKi8KICBgCiR7bGV9CgpzdHJ1Y3QgVSB7IHRleGVsU2l6ZTogdmVjMmYsIF9wYWQ6IHZlYzJmIH0KQGdyb3VwKDApIEBiaW5kaW5nKDApIHZhcjx1bmlmb3JtPiB1ICAgIDogVTsKQGdyb3VwKDApIEBiaW5kaW5nKDEpIHZhciAgICAgICAgICBzYW1wIDogc2FtcGxlcjsKQGdyb3VwKDApIEBiaW5kaW5nKDIpIHZhciAgICAgICAgICB1VmVsIDogdGV4dHVyZV8yZDxmMzI+OwpAZ3JvdXAoMCkgQGJpbmRpbmcoMykgdmFyICAgICAgICAgIHVPYnMgOiB0ZXh0dXJlXzJkPGYzMj47CgpAdmVydGV4IGZuIHZzKEBsb2NhdGlvbigwKSBhOiB2ZWMyZikgLT4gVlNPdXQgewogIHZhciBvOiBWU091dDsKICBvLnV2ID0gdmVjMmYoYS54ICogMC41ICsgMC41LCAwLjUgLSBhLnkgKiAwLjUpOwogIG8udkwgPSBvLnV2IC0gdmVjMmYodS50ZXhlbFNpemUueCwgMC4wKTsKICBvLnZSID0gby51diArIHZlYzJmKHUudGV4ZWxTaXplLngsIDAuMCk7CiAgby52VCA9IG8udXYgKyB2ZWMyZigwLjAsIHUudGV4ZWxTaXplLnkpOwogIG8udkIgPSBvLnV2IC0gdmVjMmYoMC4wLCB1LnRleGVsU2l6ZS55KTsKICBvLnBvcyA9IHZlYzRmKGEsIDAuMCwgMS4wKTsKICByZXR1cm4gbzsKfQoKQGZyYWdtZW50IGZuIGZzKGk6IFZTT3V0KSAtPiBAbG9jYXRpb24oMCkgdmVjNGYgewogIGxldCBMID0gc2VsZWN0KHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS52TCkueCwgMC4wLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudkwpLnIgPiAwLjUpOwogIGxldCBSID0gc2VsZWN0KHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS52UikueCwgMC4wLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudlIpLnIgPiAwLjUpOwogIGxldCBUID0gc2VsZWN0KHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS52VCkueSwgMC4wLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudlQpLnIgPiAwLjUpOwogIGxldCBCID0gc2VsZWN0KHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS52QikueSwgMC4wLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudkIpLnIgPiAwLjUpOwogIHJldHVybiB2ZWM0ZigwLjUgKiAoUiAtIEwgKyBUIC0gQiksIDAuMCwgMC4wLCAxLjApOwp9CmAKKSwgWHQgPSAoCiAgLyogd2dzbCAqLwogIGAKJHtsZX0KCnN0cnVjdCBVIHsgdGV4ZWxTaXplOiB2ZWMyZiwgX3BhZDogdmVjMmYgfQpAZ3JvdXAoMCkgQGJpbmRpbmcoMCkgdmFyPHVuaWZvcm0+IHUgICAgOiBVOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMSkgdmFyICAgICAgICAgIHNhbXAgOiBzYW1wbGVyOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMikgdmFyICAgICAgICAgIHVQcmVzOiB0ZXh0dXJlXzJkPGYzMj47CkBncm91cCgwKSBAYmluZGluZygzKSB2YXIgICAgICAgICAgdURpdiA6IHRleHR1cmVfMmQ8ZjMyPjsKQGdyb3VwKDApIEBiaW5kaW5nKDQpIHZhciAgICAgICAgICB1T2JzIDogdGV4dHVyZV8yZDxmMzI+OwoKQHZlcnRleCBmbiB2cyhAbG9jYXRpb24oMCkgYTogdmVjMmYpIC0+IFZTT3V0IHsKICB2YXIgbzogVlNPdXQ7CiAgby51diA9IHZlYzJmKGEueCAqIDAuNSArIDAuNSwgMC41IC0gYS55ICogMC41KTsKICBvLnZMID0gby51diAtIHZlYzJmKHUudGV4ZWxTaXplLngsIDAuMCk7CiAgby52UiA9IG8udXYgKyB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlQgPSBvLnV2ICsgdmVjMmYoMC4wLCB1LnRleGVsU2l6ZS55KTsKICBvLnZCID0gby51diAtIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby5wb3MgPSB2ZWM0ZihhLCAwLjAsIDEuMCk7CiAgcmV0dXJuIG87Cn0KCkBmcmFnbWVudCBmbiBmcyhpOiBWU091dCkgLT4gQGxvY2F0aW9uKDApIHZlYzRmIHsKICBsZXQgQyAgPSB0ZXh0dXJlU2FtcGxlKHVQcmVzLCBzYW1wLCBpLnV2KS54OwogIGxldCBMICA9IHNlbGVjdCh0ZXh0dXJlU2FtcGxlKHVQcmVzLCBzYW1wLCBpLnZMKS54LCBDLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudkwpLnIgPiAwLjUpOwogIGxldCBSICA9IHNlbGVjdCh0ZXh0dXJlU2FtcGxlKHVQcmVzLCBzYW1wLCBpLnZSKS54LCBDLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudlIpLnIgPiAwLjUpOwogIGxldCBUICA9IHNlbGVjdCh0ZXh0dXJlU2FtcGxlKHVQcmVzLCBzYW1wLCBpLnZUKS54LCBDLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudlQpLnIgPiAwLjUpOwogIGxldCBCICA9IHNlbGVjdCh0ZXh0dXJlU2FtcGxlKHVQcmVzLCBzYW1wLCBpLnZCKS54LCBDLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudkIpLnIgPiAwLjUpOwogIGxldCBkdiA9IHRleHR1cmVTYW1wbGUodURpdiwgc2FtcCwgaS51dikueDsKICByZXR1cm4gdmVjNGYoKEwgKyBSICsgQiArIFQgLSBkdikgKiAwLjI1LCAwLjAsIDAuMCwgMS4wKTsKfQpgCiksIE10ID0gKAogIC8qIHdnc2wgKi8KICBgCiR7bGV9CgpzdHJ1Y3QgVSB7IHRleGVsU2l6ZTogdmVjMmYsIF9wYWQ6IHZlYzJmIH0KQGdyb3VwKDApIEBiaW5kaW5nKDApIHZhcjx1bmlmb3JtPiB1ICAgIDogVTsKQGdyb3VwKDApIEBiaW5kaW5nKDEpIHZhciAgICAgICAgICBzYW1wIDogc2FtcGxlcjsKQGdyb3VwKDApIEBiaW5kaW5nKDIpIHZhciAgICAgICAgICB1UHJlczogdGV4dHVyZV8yZDxmMzI+OwpAZ3JvdXAoMCkgQGJpbmRpbmcoMykgdmFyICAgICAgICAgIHVWZWwgOiB0ZXh0dXJlXzJkPGYzMj47CkBncm91cCgwKSBAYmluZGluZyg0KSB2YXIgICAgICAgICAgdU9icyA6IHRleHR1cmVfMmQ8ZjMyPjsKCkB2ZXJ0ZXggZm4gdnMoQGxvY2F0aW9uKDApIGE6IHZlYzJmKSAtPiBWU091dCB7CiAgdmFyIG86IFZTT3V0OwogIG8udXYgPSB2ZWMyZihhLnggKiAwLjUgKyAwLjUsIDAuNSAtIGEueSAqIDAuNSk7CiAgby52TCA9IG8udXYgLSB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlIgPSBvLnV2ICsgdmVjMmYodS50ZXhlbFNpemUueCwgMC4wKTsKICBvLnZUID0gby51diArIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby52QiA9IG8udXYgLSB2ZWMyZigwLjAsIHUudGV4ZWxTaXplLnkpOwogIG8ucG9zID0gdmVjNGYoYSwgMC4wLCAxLjApOwogIHJldHVybiBvOwp9CgpAZnJhZ21lbnQgZm4gZnMoaTogVlNPdXQpIC0+IEBsb2NhdGlvbigwKSB2ZWM0ZiB7CiAgLy8gU2FtcGxlIGFsbCB0ZXh0dXJlcyBiZWZvcmUgYnJhbmNoaW5nIOKAlCB0ZXh0dXJlU2FtcGxlIHJlcXVpcmVzIHVuaWZvcm0gY29udHJvbCBmbG93CiAgbGV0IG9icyA9IHRleHR1cmVTYW1wbGUodU9icywgc2FtcCwgaS51dikucjsKICBsZXQgTCAgID0gdGV4dHVyZVNhbXBsZSh1UHJlcywgc2FtcCwgaS52TCkueDsKICBsZXQgUiAgID0gdGV4dHVyZVNhbXBsZSh1UHJlcywgc2FtcCwgaS52UikueDsKICBsZXQgVCAgID0gdGV4dHVyZVNhbXBsZSh1UHJlcywgc2FtcCwgaS52VCkueDsKICBsZXQgQiAgID0gdGV4dHVyZVNhbXBsZSh1UHJlcywgc2FtcCwgaS52QikueDsKICBsZXQgdmVsID0gdGV4dHVyZVNhbXBsZSh1VmVsLCBzYW1wLCBpLnV2KS54eSAtIHZlYzJmKFIgLSBMLCBUIC0gQik7CiAgaWYgKG9icyA+IDAuNSkgeyByZXR1cm4gdmVjNGYoMC4wKTsgfQogIHJldHVybiB2ZWM0Zih2ZWwsIDAuMCwgMS4wKTsKfQpgCiksIEd0ID0gKAogIC8qIHdnc2wgKi8KICBgCiR7bGV9CgovLyB0ZXhlbFNpemUgb2NjdXBpZXMgYnl0ZXMgMC03IGZvciB0aGUgc2hhcmVkIHZlcnRleCBzdGFnZTsgYXNwZWN0UmF0aW8vcmFkaXVzIGZpbGwgdGhlIHJlc3QuCnN0cnVjdCBVIHsKICB0ZXhlbFNpemUgIDogdmVjMmYsCiAgYXNwZWN0UmF0aW86IGYzMiwKICByYWRpdXMgICAgIDogZjMyLAogIGNvbG9yICAgICAgOiB2ZWM0ZiwgIC8vIHh5eiA9IGNvbG91ciwgdyB1bnVzZWQKICBwb2ludCAgICAgIDogdmVjMmYsCiAgX3BhZCAgICAgICA6IHZlYzJmLAp9CkBncm91cCgwKSBAYmluZGluZygwKSB2YXI8dW5pZm9ybT4gdSAgICA6IFU7CkBncm91cCgwKSBAYmluZGluZygxKSB2YXIgICAgICAgICAgc2FtcCA6IHNhbXBsZXI7CkBncm91cCgwKSBAYmluZGluZygyKSB2YXIgICAgICAgICAgdVRndCA6IHRleHR1cmVfMmQ8ZjMyPjsKCkB2ZXJ0ZXggZm4gdnMoQGxvY2F0aW9uKDApIGE6IHZlYzJmKSAtPiBWU091dCB7CiAgdmFyIG86IFZTT3V0OwogIG8udXYgPSB2ZWMyZihhLnggKiAwLjUgKyAwLjUsIDAuNSAtIGEueSAqIDAuNSk7CiAgby52TCA9IG8udXYgLSB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlIgPSBvLnV2ICsgdmVjMmYodS50ZXhlbFNpemUueCwgMC4wKTsKICBvLnZUID0gby51diArIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby52QiA9IG8udXYgLSB2ZWMyZigwLjAsIHUudGV4ZWxTaXplLnkpOwogIG8ucG9zID0gdmVjNGYoYSwgMC4wLCAxLjApOwogIHJldHVybiBvOwp9CgpAZnJhZ21lbnQgZm4gZnMoaTogVlNPdXQpIC0+IEBsb2NhdGlvbigwKSB2ZWM0ZiB7CiAgdmFyIHAgID0gaS51diAtIHUucG9pbnQ7CiAgcC54ICAgKj0gdS5hc3BlY3RSYXRpbzsKICBsZXQgc3AgPSBleHAoLWRvdChwLCBwKSAvIHUucmFkaXVzKSAqIHUuY29sb3IueHl6OwogIHJldHVybiB2ZWM0Zih0ZXh0dXJlU2FtcGxlKHVUZ3QsIHNhbXAsIGkudXYpLnh5eiArIHNwLCAxLjApOwp9CmAKKSwgSXQgPSAoCiAgLyogd2dzbCAqLwogIGAKJHtsZX0KCnN0cnVjdCBVIHsgdGV4ZWxTaXplOiB2ZWMyZiwgX3BhZDogdmVjMmYgfQpAZ3JvdXAoMCkgQGJpbmRpbmcoMCkgdmFyPHVuaWZvcm0+IHUgICAgOiBVOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMSkgdmFyICAgICAgICAgIHNhbXAgOiBzYW1wbGVyOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMikgdmFyICAgICAgICAgIHVWZWwgOiB0ZXh0dXJlXzJkPGYzMj47CgpAdmVydGV4IGZuIHZzKEBsb2NhdGlvbigwKSBhOiB2ZWMyZikgLT4gVlNPdXQgewogIHZhciBvOiBWU091dDsKICBvLnV2ID0gdmVjMmYoYS54ICogMC41ICsgMC41LCAwLjUgLSBhLnkgKiAwLjUpOwogIG8udkwgPSBvLnV2IC0gdmVjMmYodS50ZXhlbFNpemUueCwgMC4wKTsKICBvLnZSID0gby51diArIHZlYzJmKHUudGV4ZWxTaXplLngsIDAuMCk7CiAgby52VCA9IG8udXYgKyB2ZWMyZigwLjAsIHUudGV4ZWxTaXplLnkpOwogIG8udkIgPSBvLnV2IC0gdmVjMmYoMC4wLCB1LnRleGVsU2l6ZS55KTsKICBvLnBvcyA9IHZlYzRmKGEsIDAuMCwgMS4wKTsKICByZXR1cm4gbzsKfQoKQGZyYWdtZW50IGZuIGZzKGk6IFZTT3V0KSAtPiBAbG9jYXRpb24oMCkgdmVjNGYgewogIGxldCBMID0gdGV4dHVyZVNhbXBsZSh1VmVsLCBzYW1wLCBpLnZMKS55OwogIGxldCBSID0gdGV4dHVyZVNhbXBsZSh1VmVsLCBzYW1wLCBpLnZSKS55OwogIGxldCBUID0gdGV4dHVyZVNhbXBsZSh1VmVsLCBzYW1wLCBpLnZUKS54OwogIGxldCBCID0gdGV4dHVyZVNhbXBsZSh1VmVsLCBzYW1wLCBpLnZCKS54OwogIHJldHVybiB2ZWM0ZigwLjUgKiAoUiAtIEwgLSBUICsgQiksIDAuMCwgMC4wLCAxLjApOwp9CmAKKSwga3QgPSAoCiAgLyogd2dzbCAqLwogIGAKJHtsZX0KCnN0cnVjdCBVIHsKICB0ZXhlbFNpemU6IHZlYzJmLAogIGN1cmwgICAgIDogZjMyLAogIGR0ICAgICAgIDogZjMyLAp9CkBncm91cCgwKSBAYmluZGluZygwKSB2YXI8dW5pZm9ybT4gdSAgICA6IFU7CkBncm91cCgwKSBAYmluZGluZygxKSB2YXIgICAgICAgICAgc2FtcCA6IHNhbXBsZXI7CkBncm91cCgwKSBAYmluZGluZygyKSB2YXIgICAgICAgICAgdVZlbCA6IHRleHR1cmVfMmQ8ZjMyPjsKQGdyb3VwKDApIEBiaW5kaW5nKDMpIHZhciAgICAgICAgICB1Q3JsIDogdGV4dHVyZV8yZDxmMzI+OwoKQHZlcnRleCBmbiB2cyhAbG9jYXRpb24oMCkgYTogdmVjMmYpIC0+IFZTT3V0IHsKICB2YXIgbzogVlNPdXQ7CiAgby51diA9IHZlYzJmKGEueCAqIDAuNSArIDAuNSwgMC41IC0gYS55ICogMC41KTsKICBvLnZMID0gby51diAtIHZlYzJmKHUudGV4ZWxTaXplLngsIDAuMCk7CiAgby52UiA9IG8udXYgKyB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlQgPSBvLnV2ICsgdmVjMmYoMC4wLCB1LnRleGVsU2l6ZS55KTsKICBvLnZCID0gby51diAtIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby5wb3MgPSB2ZWM0ZihhLCAwLjAsIDEuMCk7CiAgcmV0dXJuIG87Cn0KCkBmcmFnbWVudCBmbiBmcyhpOiBWU091dCkgLT4gQGxvY2F0aW9uKDApIHZlYzRmIHsKICBsZXQgTCAgICAgPSB0ZXh0dXJlU2FtcGxlKHVDcmwsIHNhbXAsIGkudkwpLng7CiAgbGV0IFIgICAgID0gdGV4dHVyZVNhbXBsZSh1Q3JsLCBzYW1wLCBpLnZSKS54OwogIGxldCBUICAgICA9IHRleHR1cmVTYW1wbGUodUNybCwgc2FtcCwgaS52VCkueDsKICBsZXQgQiAgICAgPSB0ZXh0dXJlU2FtcGxlKHVDcmwsIHNhbXAsIGkudkIpLng7CiAgbGV0IEMgICAgID0gdGV4dHVyZVNhbXBsZSh1Q3JsLCBzYW1wLCBpLnV2KS54OwogIHZhciBmb3JjZSA9IDAuNSAqIHZlYzJmKGFicyhUKSAtIGFicyhCKSwgYWJzKFIpIC0gYWJzKEwpKTsKICBmb3JjZSAgICAvPSBsZW5ndGgoZm9yY2UpICsgMC4wMDAxOwogIGZvcmNlICAgICo9IHUuY3VybCAqIDMwLjAgKiBDOwogIGxldCB2ZWwgICA9IHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS51dikueHkgKyBmb3JjZSAqIHUuZHQ7CiAgcmV0dXJuIHZlYzRmKHZlbCwgMC4wLCAxLjApOwp9CmAKKSwgV3QgPSAoCiAgLyogd2dzbCAqLwogIGAKJHtsZX0KCnN0cnVjdCBVIHsKICB0ZXhlbFNpemUgICA6IHZlYzJmLAogIHJlZnJhY3Rpb24gIDogZjMyLAogIHNwZWN1bGFyRXhwIDogZjMyLAogIHdhdGVyQ29sb3IgIDogdmVjNGYsCiAgZ2xvd0NvbG9yICAgOiB2ZWM0ZiwKICBzaGluZSAgICAgICA6IGYzMiwKICB3YXJwU3RyZW5ndGg6IGYzMiwKICBhbGdvcml0aG0gICA6IGkzMiwKICBlbmFibGVBbHBoYSA6IGkzMiwKfQpAZ3JvdXAoMCkgQGJpbmRpbmcoMCkgdmFyPHVuaWZvcm0+IHUgICAgOiBVOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMSkgdmFyICAgICAgICAgIHNhbXAgOiBzYW1wbGVyOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMikgdmFyICAgICAgICAgIHVUZXggOiB0ZXh0dXJlXzJkPGYzMj47CkBncm91cCgwKSBAYmluZGluZygzKSB2YXIgICAgICAgICAgdU9icyA6IHRleHR1cmVfMmQ8ZjMyPjsKQGdyb3VwKDApIEBiaW5kaW5nKDQpIHZhciAgICAgICAgICB1QmcgIDogdGV4dHVyZV8yZDxmMzI+OwpAZ3JvdXAoMCkgQGJpbmRpbmcoNSkgdmFyICAgICAgICAgIHVDb3YgOiB0ZXh0dXJlXzJkPGYzMj47CkBncm91cCgwKSBAYmluZGluZyg2KSB2YXIgICAgICAgICAgdVZlbCA6IHRleHR1cmVfMmQ8ZjMyPjsKCkB2ZXJ0ZXggZm4gdnMoQGxvY2F0aW9uKDApIGE6IHZlYzJmKSAtPiBWU091dCB7CiAgdmFyIG86IFZTT3V0OwogIG8udXYgPSB2ZWMyZihhLnggKiAwLjUgKyAwLjUsIDAuNSAtIGEueSAqIDAuNSk7CiAgby52TCA9IG8udXYgLSB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlIgPSBvLnV2ICsgdmVjMmYodS50ZXhlbFNpemUueCwgMC4wKTsKICBvLnZUID0gby51diArIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby52QiA9IG8udXYgLSB2ZWMyZigwLjAsIHUudGV4ZWxTaXplLnkpOwogIG8ucG9zID0gdmVjNGYoYSwgMC4wLCAxLjApOwogIHJldHVybiBvOwp9CgpAZnJhZ21lbnQgZm4gZnMoaTogVlNPdXQpIC0+IEBsb2NhdGlvbigwKSB2ZWM0ZiB7CiAgbGV0IG9icyAgICAgPSB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudXYpLnI7CiAgbGV0IGRlbnNpdHkgPSBtYXgodGV4dHVyZVNhbXBsZSh1VGV4LCBzYW1wLCBpLnV2KS5yLCAwLjApICogKDEuMCAtIHN0ZXAoMC41LCBvYnMpKTsKICBsZXQgY292ICAgICA9IHRleHR1cmVTYW1wbGUodUNvdiwgc2FtcCwgaS51dikucjsKCiAgbGV0IHRzMiA9IHUudGV4ZWxTaXplICogMi4wOwogIGxldCBkTCAgPSBtYXgodGV4dHVyZVNhbXBsZSh1VGV4LCBzYW1wLCBpLnV2IC0gdmVjMmYodHMyLngsIDAuMCkpLnIsIDAuMCk7CiAgbGV0IGRSICA9IG1heCh0ZXh0dXJlU2FtcGxlKHVUZXgsIHNhbXAsIGkudXYgKyB2ZWMyZih0czIueCwgMC4wKSkuciwgMC4wKTsKICBsZXQgZFQgID0gbWF4KHRleHR1cmVTYW1wbGUodVRleCwgc2FtcCwgaS51diArIHZlYzJmKDAuMCwgdHMyLnkpKS5yLCAwLjApOwogIGxldCBkQiAgPSBtYXgodGV4dHVyZVNhbXBsZSh1VGV4LCBzYW1wLCBpLnV2IC0gdmVjMmYoMC4wLCB0czIueSkpLnIsIDAuMCk7CgogIGxldCBub3JtICA9IG5vcm1hbGl6ZSh2ZWMzZihkTCAtIGRSLCBkQiAtIGRULCAwLjIpKTsKICBsZXQgbGRpciAgPSBub3JtYWxpemUodmVjM2YoMC41LCAxLjAsIDAuNSkpOwogIGxldCBoYWxmViA9IG5vcm1hbGl6ZShsZGlyICsgdmVjM2YoMC4wLCAwLjAsIDEuMCkpOwogIGxldCBzcGVjICA9IHBvdyhtYXgoZG90KG5vcm0sIGhhbGZWKSwgMC4wKSwgdS5zcGVjdWxhckV4cCkgKiB1LnNoaW5lICogZGVuc2l0eTsKCiAgbGV0IGJnUmF3ID0gdGV4dHVyZVNhbXBsZSh1QmcsIHNhbXAsIGkudXYpLnJnYjsKICBsZXQgd2MgICAgPSB1LndhdGVyQ29sb3IucmdiOwogIGxldCBnYyAgICA9IHUuZ2xvd0NvbG9yLnJnYjsKICBsZXQgYmcgICAgPSBtaXgod2MsIGJnUmF3LCBjb3YpOwogIHZhciBjb2xvciA9IGJnOwoKICBpZiAodS5hbGdvcml0aG0gPT0gMSkgewogICAgbGV0IHJ1diA9IGNsYW1wKGkudXYgKyBub3JtLnh5ICogdS5yZWZyYWN0aW9uICogZGVuc2l0eSAqIDMuMCwgdmVjMmYoMC4wKSwgdmVjMmYoMS4wKSk7CiAgICBsZXQgcmJnID0gbWl4KHdjLCB0ZXh0dXJlU2FtcGxlKHVCZywgc2FtcCwgbWl4KGkudXYsIHJ1diwgMS4wIC0gb2JzKSkucmdiLCBjb3YpOwogICAgY29sb3IgICA9IHJiZyArIHNwZWMgKiBnYyAqIDIuNTsKICAgIGNvbG9yICAgPSBtaXgoY29sb3IsIGJnICogMC42LCBvYnMgKiAwLjMpOwogIH0gZWxzZSBpZiAodS5hbGdvcml0aG0gPT0gMikgewogICAgbGV0IGlua0QgPSBtaW4oZGVuc2l0eSAqIDQuMCwgMS4wKTsKICAgIGxldCBydXYgID0gY2xhbXAoaS51diArIG5vcm0ueHkgKiB1LnJlZnJhY3Rpb24gKiBkZW5zaXR5ICogMC40LCB2ZWMyZigwLjApLCB2ZWMyZigxLjApKTsKICAgIGxldCByYmcgID0gbWl4KHdjLCB0ZXh0dXJlU2FtcGxlKHVCZywgc2FtcCwgbWl4KGkudXYsIHJ1diwgMS4wIC0gb2JzKSkucmdiLCBjb3YpOwogICAgY29sb3IgICAgPSBtaXgocmJnLCB3YyArIHNwZWMgKiBnYywgaW5rRCk7CiAgICBjb2xvciAgICA9IG1peChjb2xvciwgYmcgKiAwLjUsIG9icyAqIDAuMTUpOwogIH0gZWxzZSBpZiAodS5hbGdvcml0aG0gPT0gMykgewogICAgbGV0IHZlbCAgICA9IHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS51dikueHk7CiAgICBsZXQgdmVsTWFnID0gY2xhbXAobGVuZ3RoKHZlbCkgKiAyMC4wLCAwLjAsIDEuMCk7CiAgICBsZXQgd3V2ICAgID0gY2xhbXAoaS51diArIHZlbCAqIHUud2FycFN0cmVuZ3RoLCB2ZWMyZigwLjApLCB2ZWMyZigxLjApKTsKICAgIGxldCB3YmcgICAgPSBtaXgod2MsIHRleHR1cmVTYW1wbGUodUJnLCBzYW1wLCB3dXYpLnJnYiwgY292KTsKICAgIGNvbG9yICAgICAgPSBtaXgoYmcsIHdiZywgdmVsTWFnICogKDEuMCAtIG9icykpOwogICAgY29sb3IgICAgICs9IHNwZWMgKiBnYyAqIHZlbE1hZyAqIDEuNTsKICAgIGNvbG9yICAgICArPSB3YyAqIGRlbnNpdHkgKiAwLjM7CiAgICBjb2xvciAgICAgID0gbWl4KGNvbG9yLCBiZyAqIDAuNSwgb2JzICogMC4yKTsKICB9IGVsc2UgaWYgKHUuYWxnb3JpdGhtID09IDQpIHsKICAgIGxldCBydXYgICA9IGNsYW1wKGkudXYgKyBub3JtLnh5ICogdS5yZWZyYWN0aW9uICogZGVuc2l0eSAqIDYuMCwgdmVjMmYoMC4wKSwgdmVjMmYoMS4wKSk7CiAgICBsZXQgcmJnICAgPSBtaXgod2MsIHRleHR1cmVTYW1wbGUodUJnLCBzYW1wLCBtaXgoaS51diwgcnV2LCAxLjAgLSBvYnMpKS5yZ2IsIGNvdik7CiAgICBsZXQgZnJlcyAgPSBwb3coY2xhbXAoMS4wIC0gZG90KG5vcm0sIHZlYzNmKDAuMCwgMC4wLCAxLjApKSwgMC4wLCAxLjApLCAzLjApICogZGVuc2l0eTsKICAgIGNvbG9yICAgICA9IHJiZzsKICAgIGNvbG9yICAgICs9IGZyZXMgKiBnYyAqIDIuMDsKICAgIGNvbG9yICAgICs9IHNwZWMgKiBnYyAqIGRlbnNpdHkgKiAyLjA7CiAgICBjb2xvciAgICAgPSBtaXgoY29sb3IsIGJnICogMC41LCBvYnMgKiAwLjIpOwogIH0gZWxzZSB7CiAgICBsZXQgcnV2ID0gaS51diArIG5vcm0ueHkgKiB1LnJlZnJhY3Rpb24gKiBkZW5zaXR5OwogICAgbGV0IHJiZyA9IG1peCh3YywgdGV4dHVyZVNhbXBsZSh1QmcsIHNhbXAsIG1peChpLnV2LCBydXYsIDEuMCAtIG9icykpLnJnYiwgY292KTsKICAgIGNvbG9yICAgPSBtaXgocmJnLCB3YywgbWluKGRlbnNpdHkgKiAxLjUsIDAuOCkpOwogICAgY29sb3IgICs9IHNwZWMgKiBnYzsKICAgIGNvbG9yICAgPSBtaXgoY29sb3IsIGJnICogMC41LCBvYnMgKiAwLjIpOwogIH0KCiAgbGV0IGFscGhhID0gY2xhbXAobWF4KGRlbnNpdHkgKiAxLjUsIGNvdiksIDAuMCwgMS4wKTsKICBpZiAodS5lbmFibGVBbHBoYSA9PSAxKSB7CiAgICByZXR1cm4gdmVjNGYoY29sb3IgKiBhbHBoYSwgYWxwaGEpOwogIH0KICByZXR1cm4gdmVjNGYoY29sb3IsIDEuMCk7Cn0KYAopLCBOdCA9IHsKICBhcnJheVN0cmlkZTogOCwKICBhdHRyaWJ1dGVzOiBbeyBzaGFkZXJMb2NhdGlvbjogMCwgb2Zmc2V0OiAwLCBmb3JtYXQ6ICJmbG9hdDMyeDIiIH1dCn0sIG50ID0gbmV3IEZsb2F0MzJBcnJheShbCiAgLTEsCiAgLTEsCiAgLTEsCiAgMSwKICAxLAogIC0xLAogIDEsCiAgLTEsCiAgLTEsCiAgMSwKICAxLAogIDEKXSk7CmZ1bmN0aW9uICR0KGkpIHsKICBjb25zdCBlID0gaS5jcmVhdGVCdWZmZXIoeyBzaXplOiBudC5ieXRlTGVuZ3RoLCB1c2FnZTogR1BVQnVmZmVyVXNhZ2UuVkVSVEVYIHwgR1BVQnVmZmVyVXNhZ2UuQ09QWV9EU1QgfSk7CiAgcmV0dXJuIGkucXVldWUud3JpdGVCdWZmZXIoZSwgMCwgbnQpLCBlOwp9CmZ1bmN0aW9uIEhlKGksIGUsIHIsIHMpIHsKICBjb25zdCBvID0gaS5jcmVhdGVUZXh0dXJlKHsKICAgIHNpemU6IFtyLCBzXSwKICAgIGZvcm1hdDogZSwKICAgIHVzYWdlOiBHUFVUZXh0dXJlVXNhZ2UuVEVYVFVSRV9CSU5ESU5HIHwgR1BVVGV4dHVyZVVzYWdlLlJFTkRFUl9BVFRBQ0hNRU5UIHwgR1BVVGV4dHVyZVVzYWdlLkNPUFlfU1JDCiAgfSk7CiAgcmV0dXJuIHsgdGV4OiBvLCB2aWV3OiBvLmNyZWF0ZVZpZXcoKSwgd2lkdGg6IHIsIGhlaWdodDogcyB9Owp9CmZ1bmN0aW9uIHJ0KGksIGUsIHIsIHMpIHsKICBsZXQgbyA9IEhlKGksIGUsIHIsIHMpLCBhID0gSGUoaSwgZSwgciwgcyk7CiAgcmV0dXJuIHsKICAgIGdldCByZWFkKCkgewogICAgICByZXR1cm4gbzsKICAgIH0sCiAgICBnZXQgd3JpdGUoKSB7CiAgICAgIHJldHVybiBhOwogICAgfSwKICAgIHN3YXAoKSB7CiAgICAgIFtvLCBhXSA9IFthLCBvXTsKICAgIH0sCiAgICBkaXNwb3NlKCkgewogICAgICBvLnRleC5kZXN0cm95KCksIGEudGV4LmRlc3Ryb3koKTsKICAgIH0KICB9Owp9CmZ1bmN0aW9uIHNlKGksIGUsIHIsIHMpIHsKICBjb25zdCBvID0gaS5jcmVhdGVTaGFkZXJNb2R1bGUoeyBjb2RlOiBlIH0pOwogIHJldHVybiBpLmNyZWF0ZVJlbmRlclBpcGVsaW5lKHsKICAgIGxheW91dDogImF1dG8iLAogICAgdmVydGV4OiB7IG1vZHVsZTogbywgZW50cnlQb2ludDogInZzIiwgYnVmZmVyczogW050XSB9LAogICAgZnJhZ21lbnQ6IHsgbW9kdWxlOiBvLCBlbnRyeVBvaW50OiAiZnMiLCB0YXJnZXRzOiBbeyBmb3JtYXQ6IHIsIC4uLnMgPyB7IGJsZW5kOiBzIH0gOiB7fSB9XSB9LAogICAgcHJpbWl0aXZlOiB7IHRvcG9sb2d5OiAidHJpYW5nbGUtbGlzdCIgfQogIH0pOwp9CmNvbnN0IHF0ID0gewogIGNvbG9yOiB7IG9wZXJhdGlvbjogImFkZCIsIHNyY0ZhY3RvcjogIm9uZSIsIGRzdEZhY3RvcjogInplcm8iIH0sCiAgYWxwaGE6IHsgb3BlcmF0aW9uOiAiYWRkIiwgc3JjRmFjdG9yOiAib25lIiwgZHN0RmFjdG9yOiAiemVybyIgfQp9OwpmdW5jdGlvbiBIdChpLCBlLCByID0gITApIHsKICBjb25zdCBzID0gInJnYmExNmZsb2F0IjsKICByZXR1cm4gewogICAgYWR2ZWN0aW9uOiBzZShpLCBBdCwgcyksCiAgICBkaXZlcmdlbmNlOiBzZShpLCB6dCwgcyksCiAgICBwcmVzc3VyZTogc2UoaSwgWHQsIHMpLAogICAgZ3JhZGllbnRTdWJ0cmFjdDogc2UoaSwgTXQsIHMpLAogICAgc3BsYXQ6IHNlKGksIEd0LCBzKSwKICAgIGN1cmw6IHNlKGksIEl0LCBzKSwKICAgIHZvcnRpY2l0eTogc2UoaSwga3QsIHMpLAogICAgZGlzcGxheTogc2UoaSwgV3QsIGUsIHIgPyB2b2lkIDAgOiBxdCkKICB9Owp9CmZ1bmN0aW9uIFl0KGkpIHsKICByZXR1cm4gaS5jcmVhdGVTYW1wbGVyKHsgbWFnRmlsdGVyOiAibGluZWFyIiwgbWluRmlsdGVyOiAibGluZWFyIiwgYWRkcmVzc01vZGVVOiAiY2xhbXAtdG8tZWRnZSIsIGFkZHJlc3NNb2RlVjogImNsYW1wLXRvLWVkZ2UiIH0pOwp9CmZ1bmN0aW9uIFcoaSwgZSkgewogIHJldHVybiBpLmNyZWF0ZUJ1ZmZlcih7IHNpemU6IGUsIHVzYWdlOiBHUFVCdWZmZXJVc2FnZS5VTklGT1JNIHwgR1BVQnVmZmVyVXNhZ2UuQ09QWV9EU1QgfSk7Cn0KZnVuY3Rpb24gbHQoaSwgZSwgciwgcywgbywgYSkgewogIGNvbnN0IHUgPSBuZXcgRmxvYXQzMkFycmF5KFtyLCBzLCBvLCBhXSk7CiAgaS5xdWV1ZS53cml0ZUJ1ZmZlcihlLCAwLCB1KTsKfQpmdW5jdGlvbiBOZShpLCBlLCByLCBzKSB7CiAgY29uc3QgbyA9IG5ldyBGbG9hdDMyQXJyYXkoW3IsIHMsIDAsIDBdKTsKICBpLnF1ZXVlLndyaXRlQnVmZmVyKGUsIDAsIG8pOwp9CmZ1bmN0aW9uIFF0KGksIGUsIHIsIHMsIG8sIGEpIHsKICBjb25zdCB1ID0gbmV3IEZsb2F0MzJBcnJheShbciwgcywgbywgYV0pOwogIGkucXVldWUud3JpdGVCdWZmZXIoZSwgMCwgdSk7Cn0KZnVuY3Rpb24gJGUoaSwgZSwgciwgcywgbywgYSwgdSwgdiwgbSwgYywgeCkgewogIGNvbnN0IHAgPSBuZXcgRmxvYXQzMkFycmF5KDEyKTsKICBwWzBdID0gciwgcFsxXSA9IHMsIHBbMl0gPSBvLCBwWzNdID0gYSwgcFs0XSA9IHUsIHBbNV0gPSB2LCBwWzZdID0gbSwgcFs3XSA9IDAsIHBbOF0gPSBjLCBwWzldID0geCwgcFsxMF0gPSAwLCBwWzExXSA9IDAsIGkucXVldWUud3JpdGVCdWZmZXIoZSwgMCwgcCk7Cn0KZnVuY3Rpb24ganQoaSwgZSwgciwgcywgbywgYSwgdSwgdiwgbSwgYywgeCwgcCkgewogIGNvbnN0IG4gPSBuZXcgRmxvYXQzMkFycmF5KDE2KSwgZCA9IG5ldyBJbnQzMkFycmF5KG4uYnVmZmVyKTsKICBuWzBdID0gciwgblsxXSA9IHMsIG5bMl0gPSBvLCBuWzNdID0gYSwgbls0XSA9IHVbMF0sIG5bNV0gPSB1WzFdLCBuWzZdID0gdVsyXSwgbls3XSA9IDAsIG5bOF0gPSB2WzBdLCBuWzldID0gdlsxXSwgblsxMF0gPSB2WzJdLCBuWzExXSA9IDAsIG5bMTJdID0gbSwgblsxM10gPSBjLCBkWzE0XSA9IHgsIGRbMTVdID0gcCA/IDEgOiAwLCBpLnF1ZXVlLndyaXRlQnVmZmVyKGUsIDAsIG4pOwp9CmZ1bmN0aW9uIFgoaSwgZSwgciwgcywgbykgewogIGNvbnN0IGEgPSBpLmJlZ2luUmVuZGVyUGFzcyh7CiAgICBjb2xvckF0dGFjaG1lbnRzOiBbewogICAgICB2aWV3OiBvLAogICAgICBjbGVhclZhbHVlOiBbMCwgMCwgMCwgMF0sCiAgICAgIGxvYWRPcDogImNsZWFyIiwKICAgICAgc3RvcmVPcDogInN0b3JlIgogICAgfV0KICB9KTsKICBhLnNldFBpcGVsaW5lKGUpLCBhLnNldEJpbmRHcm91cCgwLCByKSwgYS5zZXRWZXJ0ZXhCdWZmZXIoMCwgcyksIGEuZHJhdyg2KSwgYS5lbmQoKTsKfQpmdW5jdGlvbiBLdChpLCBlLCByLCBzLCBvKSB7CiAgY29uc3QgYSA9IGkuYmVnaW5SZW5kZXJQYXNzKHsKICAgIGNvbG9yQXR0YWNobWVudHM6IFt7CiAgICAgIHZpZXc6IG8sCiAgICAgIGNsZWFyVmFsdWU6IFswLCAwLCAwLCAwXSwKICAgICAgbG9hZE9wOiAiY2xlYXIiLAogICAgICBzdG9yZU9wOiAic3RvcmUiCiAgICB9XQogIH0pOwogIGEuc2V0UGlwZWxpbmUoZSksIGEuc2V0QmluZEdyb3VwKDAsIHIpLCBhLnNldFZlcnRleEJ1ZmZlcigwLCBzKSwgYS5kcmF3KDYpLCBhLmVuZCgpOwp9CmZ1bmN0aW9uIEJlKGksIGUsIHIsIHMsIG8gPSAiY292ZXIiKSB7CiAgbGV0IGE7CiAgbyA9PT0gImNvdmVyIiA/IGEgPSBNYXRoLm1heChyIC8gaSwgcyAvIGUpIDogbyA9PT0gImNvbnRhaW4iID8gYSA9IE1hdGgubWluKHIgLyBpLCBzIC8gZSkgOiB0eXBlb2YgbyA9PSAic3RyaW5nIiAmJiBvLmVuZHNXaXRoKCIlIikgPyBhID0gTWF0aC5taW4ociAvIGksIHMgLyBlKSAqIChwYXJzZUZsb2F0KG8pIC8gMTAwKSA6IHR5cGVvZiBvID09ICJzdHJpbmciICYmIG8uZW5kc1dpdGgoInB4IikgPyBhID0gcGFyc2VGbG9hdChvKSAvIE1hdGgubWF4KGksIGUpIDogdHlwZW9mIG8gPT0gIm51bWJlciIgPyBhID0gbyA6IGEgPSBNYXRoLm1heChyIC8gaSwgcyAvIGUpOwogIGNvbnN0IHUgPSBpICogYSwgdiA9IGUgKiBhOwogIHJldHVybiB7IHg6IChyIC0gdSkgLyAyLCB5OiAocyAtIHYpIC8gMiwgZHJhd1c6IHUsIGRyYXdIOiB2IH07Cn0KZnVuY3Rpb24gSnQoaSwgZSwgciwgcywgbyA9IG51bGwsIGEgPSAiY292ZXIiKSB7CiAgY29uc3QgeyB0ZXh0OiB1LCBmb250U2l6ZTogdiwgY29sb3I6IG0sIGZvbnRGYW1pbHk6IGMgPSAic2Fucy1zZXJpZiIsIGZvbnRXZWlnaHQ6IHggPSA5MDAgfSA9IHMsIHAgPSBuZXcgT2Zmc2NyZWVuQ2FudmFzKGUsIHIpLCBuID0gcC5nZXRDb250ZXh0KCIyZCIpOwogICgoRCkgPT4gewogICAgaWYgKG8pIHsKICAgICAgbi5jbGVhclJlY3QoMCwgMCwgZSwgciksIG4uZmlsbFN0eWxlID0gImJsYWNrIiwgbi5maWxsUmVjdCgwLCAwLCBlLCByKTsKICAgICAgY29uc3QgeyB4OiBnLCB5OiBfLCBkcmF3VzogUCwgZHJhd0g6IGsgfSA9IEJlKAogICAgICAgIG8ud2lkdGgsCiAgICAgICAgby5oZWlnaHQsCiAgICAgICAgZSwKICAgICAgICByLAogICAgICAgIGEKICAgICAgKTsKICAgICAgbi5kcmF3SW1hZ2UobywgZywgXywgUCwgayk7CiAgICB9IGVsc2UKICAgICAgbi5maWxsU3R5bGUgPSAiYmxhY2siLCBuLmZpbGxSZWN0KDAsIDAsIGUsIHIpOwogICAgbi5maWxsU3R5bGUgPSBELCBuLmZvbnQgPSBgJHt4fSAke3Z9cHggJHtjfWAsIG4udGV4dEFsaWduID0gImNlbnRlciIsIG4udGV4dEJhc2VsaW5lID0gIm1pZGRsZSIsIG4uZmlsbFRleHQodSwgZSAvIDIsIHIgLyAyKTsKICB9KShtKTsKICBjb25zdCBiID0gTGUoaSwgcCk7CiAgbi5maWxsU3R5bGUgPSAiYmxhY2siLCBuLmZpbGxSZWN0KDAsIDAsIGUsIHIpLCBuLmZpbGxTdHlsZSA9ICJ3aGl0ZSIsIG4uZm9udCA9IGAke3h9ICR7dn1weCAke2N9YCwgbi50ZXh0QWxpZ24gPSAiY2VudGVyIiwgbi50ZXh0QmFzZWxpbmUgPSAibWlkZGxlIiwgbi5maWxsVGV4dCh1LCBlIC8gMiwgciAvIDIpOwogIGNvbnN0IHkgPSBMZShpLCBwKTsKICByZXR1cm4geyBiYWNrZ3JvdW5kVGV4OiBiLCBvYnN0YWNsZVRleDogeSwgY292ZXJhZ2VUZXg6IHkgfTsKfQpmdW5jdGlvbiBadChpLCBlLCByLCBzLCBvID0gMCwgYSA9ICJjb3ZlciIsIHUgPSBudWxsLCB2ID0gImNvdmVyIikgewogIGNvbnN0IG0gPSBuZXcgT2Zmc2NyZWVuQ2FudmFzKHIsIHMpLCBjID0gbS5nZXRDb250ZXh0KCIyZCIpLCB7IHgsIHk6IHAsIGRyYXdXOiBuLCBkcmF3SDogZCB9ID0gQmUoZS53aWR0aCwgZS5oZWlnaHQsIHIsIHMsIGEpOwogIGlmIChjLmNsZWFyUmVjdCgwLCAwLCByLCBzKSwgYy5maWxsU3R5bGUgPSAiYmxhY2siLCBjLmZpbGxSZWN0KDAsIDAsIHIsIHMpLCB1KSB7CiAgICBjb25zdCB7CiAgICAgIHg6IGcsCiAgICAgIHk6IF8sCiAgICAgIGRyYXdXOiBQLAogICAgICBkcmF3SDogawogICAgfSA9IEJlKHUud2lkdGgsIHUuaGVpZ2h0LCByLCBzLCB2KTsKICAgIGMuZmlsdGVyID0gYGJyaWdodG5lc3MoJHtvfSkgYmx1cig4cHgpYCwgYy5kcmF3SW1hZ2UodSwgZywgXywgUCwgayksIGMuZmlsdGVyID0gIm5vbmUiOwogIH0KICBjLmRyYXdJbWFnZShlLCB4LCBwLCBuLCBkKTsKICBjb25zdCBiID0gTGUoaSwgbSk7CiAgYy5jbGVhclJlY3QoMCwgMCwgciwgcyksIGMuZmlsbFN0eWxlID0gImJsYWNrIiwgYy5maWxsUmVjdCgwLCAwLCByLCBzKSwgYy5maWx0ZXIgPSBgYnJpZ2h0bmVzcygke299KSBibHVyKDhweClgLCBjLmRyYXdJbWFnZShlLCB4LCBwLCBuLCBkKSwgYy5maWx0ZXIgPSAibm9uZSI7CiAgY29uc3QgeSA9IExlKGksIG0pOwogIGMuY2xlYXJSZWN0KDAsIDAsIHIsIHMpLCBjLmZpbGxTdHlsZSA9ICJibGFjayIsIGMuZmlsbFJlY3QoMCwgMCwgciwgcyksIGMuZmlsbFN0eWxlID0gIndoaXRlIiwgYy5maWxsUmVjdCgKICAgIE1hdGgubWF4KDAsIHgpLAogICAgTWF0aC5tYXgoMCwgcCksCiAgICBNYXRoLm1pbihuLCByIC0gTWF0aC5tYXgoMCwgeCkpLAogICAgTWF0aC5taW4oZCwgcyAtIE1hdGgubWF4KDAsIHApKQogICk7CiAgY29uc3QgRCA9IExlKGksIG0pOwogIHJldHVybiB7IGJhY2tncm91bmRUZXg6IGIsIG9ic3RhY2xlVGV4OiB5LCBjb3ZlcmFnZVRleDogRCB9Owp9CmZ1bmN0aW9uIExlKGksIGUpIHsKICBjb25zdCByID0gaS5jcmVhdGVUZXh0dXJlKCk7CiAgcmV0dXJuIGkuYmluZFRleHR1cmUoaS5URVhUVVJFXzJELCByKSwgaS5waXhlbFN0b3JlaShpLlVOUEFDS19GTElQX1lfV0VCR0wsICEwKSwgaS50ZXhJbWFnZTJEKGkuVEVYVFVSRV8yRCwgMCwgaS5SR0JBLCBpLlJHQkEsIGkuVU5TSUdORURfQllURSwgZSksIGkudGV4UGFyYW1ldGVyaShpLlRFWFRVUkVfMkQsIGkuVEVYVFVSRV9NSU5fRklMVEVSLCBpLkxJTkVBUiksIGkudGV4UGFyYW1ldGVyaShpLlRFWFRVUkVfMkQsIGkuVEVYVFVSRV9NQUdfRklMVEVSLCBpLkxJTkVBUiksIGkudGV4UGFyYW1ldGVyaShpLlRFWFRVUkVfMkQsIGkuVEVYVFVSRV9XUkFQX1MsIGkuQ0xBTVBfVE9fRURHRSksIGkudGV4UGFyYW1ldGVyaShpLlRFWFRVUkVfMkQsIGkuVEVYVFVSRV9XUkFQX1QsIGkuQ0xBTVBfVE9fRURHRSksIHI7Cn0KZnVuY3Rpb24gZXIoaSwgZSwgciwgcywgbyA9IG51bGwsIGEgPSAiY292ZXIiKSB7CiAgY29uc3QgeyB0ZXh0OiB1LCBmb250U2l6ZTogdiwgY29sb3I6IG0sIGZvbnRGYW1pbHk6IGMgPSAic2Fucy1zZXJpZiIsIGZvbnRXZWlnaHQ6IHggPSA5MDAgfSA9IHMsIHAgPSBuZXcgT2Zmc2NyZWVuQ2FudmFzKGUsIHIpLCBuID0gcC5nZXRDb250ZXh0KCIyZCIpOwogICgoRCkgPT4gewogICAgaWYgKG8pIHsKICAgICAgbi5jbGVhclJlY3QoMCwgMCwgZSwgciksIG4uZmlsbFN0eWxlID0gImJsYWNrIiwgbi5maWxsUmVjdCgwLCAwLCBlLCByKTsKICAgICAgY29uc3QgeyB4OiBnLCB5OiBfLCBkcmF3VzogUCwgZHJhd0g6IGsgfSA9IEJlKAogICAgICAgIG8ud2lkdGgsCiAgICAgICAgby5oZWlnaHQsCiAgICAgICAgZSwKICAgICAgICByLAogICAgICAgIGEKICAgICAgKTsKICAgICAgbi5kcmF3SW1hZ2UobywgZywgXywgUCwgayk7CiAgICB9IGVsc2UKICAgICAgbi5maWxsU3R5bGUgPSAiYmxhY2siLCBuLmZpbGxSZWN0KDAsIDAsIGUsIHIpOwogICAgbi5maWxsU3R5bGUgPSBELCBuLmZvbnQgPSBgJHt4fSAke3Z9cHggJHtjfWAsIG4udGV4dEFsaWduID0gImNlbnRlciIsIG4udGV4dEJhc2VsaW5lID0gIm1pZGRsZSIsIG4uZmlsbFRleHQodSwgZSAvIDIsIHIgLyAyKTsKICB9KShtKTsKICBjb25zdCBiID0gQWUoaSwgcCwgZSwgcik7CiAgbi5maWxsU3R5bGUgPSAiYmxhY2siLCBuLmZpbGxSZWN0KDAsIDAsIGUsIHIpLCBuLmZpbGxTdHlsZSA9ICJ3aGl0ZSIsIG4uZm9udCA9IGAke3h9ICR7dn1weCAke2N9YCwgbi50ZXh0QWxpZ24gPSAiY2VudGVyIiwgbi50ZXh0QmFzZWxpbmUgPSAibWlkZGxlIiwgbi5maWxsVGV4dCh1LCBlIC8gMiwgciAvIDIpOwogIGNvbnN0IHkgPSBBZShpLCBwLCBlLCByKTsKICByZXR1cm4gewogICAgYmFja2dyb3VuZFRleDogYiwKICAgIGJhY2tncm91bmRWaWV3OiBiLmNyZWF0ZVZpZXcoKSwKICAgIG9ic3RhY2xlVGV4OiB5LAogICAgb2JzdGFjbGVWaWV3OiB5LmNyZWF0ZVZpZXcoKSwKICAgIGNvdmVyYWdlVGV4OiB5LAogICAgY292ZXJhZ2VWaWV3OiB5LmNyZWF0ZVZpZXcoKSwKICAgIHNoYXJlZENvdmVyYWdlOiAhMAogIH07Cn0KZnVuY3Rpb24gdHIoaSwgZSwgciwgcywgbyA9IDAsIGEgPSAiY292ZXIiLCB1ID0gbnVsbCwgdiA9ICJjb3ZlciIpIHsKICBjb25zdCBtID0gbmV3IE9mZnNjcmVlbkNhbnZhcyhyLCBzKSwgYyA9IG0uZ2V0Q29udGV4dCgiMmQiKSwgeyB4LCB5OiBwLCBkcmF3VzogbiwgZHJhd0g6IGQgfSA9IEJlKGUud2lkdGgsIGUuaGVpZ2h0LCByLCBzLCBhKTsKICBpZiAoYy5jbGVhclJlY3QoMCwgMCwgciwgcyksIGMuZmlsbFN0eWxlID0gImJsYWNrIiwgYy5maWxsUmVjdCgwLCAwLCByLCBzKSwgdSkgewogICAgY29uc3QgeyB4OiBnLCB5OiBfLCBkcmF3VzogUCwgZHJhd0g6IGsgfSA9IEJlKAogICAgICB1LndpZHRoLAogICAgICB1LmhlaWdodCwKICAgICAgciwKICAgICAgcywKICAgICAgdgogICAgKTsKICAgIGMuZmlsdGVyID0gYGJyaWdodG5lc3MoJHtvfSkgYmx1cig4cHgpYCwgYy5kcmF3SW1hZ2UodSwgZywgXywgUCwgayksIGMuZmlsdGVyID0gIm5vbmUiOwogIH0KICBjLmRyYXdJbWFnZShlLCB4LCBwLCBuLCBkKTsKICBjb25zdCBiID0gQWUoaSwgbSwgciwgcyk7CiAgYy5jbGVhclJlY3QoMCwgMCwgciwgcyksIGMuZmlsbFN0eWxlID0gImJsYWNrIiwgYy5maWxsUmVjdCgwLCAwLCByLCBzKSwgYy5maWx0ZXIgPSBgYnJpZ2h0bmVzcygke299KSBibHVyKDhweClgLCBjLmRyYXdJbWFnZShlLCB4LCBwLCBuLCBkKSwgYy5maWx0ZXIgPSAibm9uZSI7CiAgY29uc3QgeSA9IEFlKGksIG0sIHIsIHMpOwogIGMuY2xlYXJSZWN0KDAsIDAsIHIsIHMpLCBjLmZpbGxTdHlsZSA9ICJibGFjayIsIGMuZmlsbFJlY3QoMCwgMCwgciwgcyksIGMuZmlsbFN0eWxlID0gIndoaXRlIiwgYy5maWxsUmVjdChNYXRoLm1heCgwLCB4KSwgTWF0aC5tYXgoMCwgcCksIE1hdGgubWluKG4sIHIgLSBNYXRoLm1heCgwLCB4KSksIE1hdGgubWluKGQsIHMgLSBNYXRoLm1heCgwLCBwKSkpOwogIGNvbnN0IEQgPSBBZShpLCBtLCByLCBzKTsKICByZXR1cm4gewogICAgYmFja2dyb3VuZFRleDogYiwKICAgIGJhY2tncm91bmRWaWV3OiBiLmNyZWF0ZVZpZXcoKSwKICAgIG9ic3RhY2xlVGV4OiB5LAogICAgb2JzdGFjbGVWaWV3OiB5LmNyZWF0ZVZpZXcoKSwKICAgIGNvdmVyYWdlVGV4OiBELAogICAgY292ZXJhZ2VWaWV3OiBELmNyZWF0ZVZpZXcoKSwKICAgIHNoYXJlZENvdmVyYWdlOiAhMQogIH07Cn0KZnVuY3Rpb24gQWUoaSwgZSwgciwgcykgewogIGNvbnN0IG8gPSBpLmNyZWF0ZVRleHR1cmUoewogICAgc2l6ZTogW3IsIHNdLAogICAgZm9ybWF0OiAicmdiYTh1bm9ybSIsCiAgICB1c2FnZTogR1BVVGV4dHVyZVVzYWdlLlRFWFRVUkVfQklORElORyB8IEdQVVRleHR1cmVVc2FnZS5DT1BZX0RTVCB8IEdQVVRleHR1cmVVc2FnZS5SRU5ERVJfQVRUQUNITUVOVAogIH0pOwogIHJldHVybiBpLnF1ZXVlLmNvcHlFeHRlcm5hbEltYWdlVG9UZXh0dXJlKAogICAgeyBzb3VyY2U6IGUgfSwKICAgIHsgdGV4dHVyZTogbyB9LAogICAgW3IsIHNdCiAgKSwgbzsKfQphc3luYyBmdW5jdGlvbiBycihpKSB7CiAgY29uc3QgZSA9IGF3YWl0IGZldGNoKGkpOwogIGlmICghZS5vaykKICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGZldGNoIGltYWdlOiAke2l9ICgke2Uuc3RhdHVzfSlgKTsKICBjb25zdCByID0gYXdhaXQgZS5ibG9iKCk7CiAgcmV0dXJuIGNyZWF0ZUltYWdlQml0bWFwKHIpOwp9CmNvbnN0IGN0ID0gdHlwZW9mIHJlcXVlc3RBbmltYXRpb25GcmFtZSA8ICJ1IiA/IHJlcXVlc3RBbmltYXRpb25GcmFtZS5iaW5kKGdsb2JhbFRoaXMpIDogKGkpID0+IHNldFRpbWVvdXQoaSwgMWUzIC8gNjApLCBpciA9IHR5cGVvZiBjYW5jZWxBbmltYXRpb25GcmFtZSA8ICJ1IiA/IGNhbmNlbEFuaW1hdGlvbkZyYW1lLmJpbmQoZ2xvYmFsVGhpcykgOiBjbGVhclRpbWVvdXQsIE9lID0gMC4wMTYsIGZ0ID0geyBzdGFuZGFyZDogMCwgZ2xhc3M6IDEsIGluazogMiwgYXVyb3JhOiAzLCByaXBwbGU6IDQgfTsKdmFyIGNlLCBNLCB6ZSwgZmUsIFVlLCBCLCBSLCAkLCBxLCBILCBLLCBMLCBZLCBPLCBEZSwgdmUsIF9lLCBWLCBULCBvZSwgUSwgYWUsIHosIHBlLCB4ZSwgbWUsIGRlLCBoZSwgSiwgWiwgZ2UsIGJlLCBUZSwgdywgVSwgRywgSSwgRiwgQ2UsIGVlLCBBLCB1ZSwgdGUsIGgsIEMsIGosIHllLCBYZSwgU2UsIFllLCBwdCwgd2UsIEZlLCBNZSwgc3QsIG5lLCBFZSwgUmUsIFBlLCBHZSwgb3QsIEllLCBhdCwgUWUsIHh0LCBqZSwgbXQsIEtlLCBkdCwgSmUsIGh0LCBaZSwgZ3Q7CmNvbnN0IHV0ID0gY2xhc3MgdXQgewogIC8vIOKUgOKUgCBDb25zdHJ1Y3RvciDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKICBjb25zdHJ1Y3RvcihlLCByID0ge30sIHMgPSB7fSwgbywgYSA9ICEwKSB7CiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8vIFByaXZhdGUg4oCUIEdQVSBpbml0aWFsaXNhdGlvbgogICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBmKHRoaXMsIFllKTsKICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLy8gUHJpdmF0ZSDigJQgc2hhcmVkIGhlbHBlcnMKICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgZih0aGlzLCB3ZSk7CiAgICBmKHRoaXMsIE1lKTsKICAgIGYodGhpcywgbmUpOwogICAgZih0aGlzLCBSZSk7CiAgICBmKHRoaXMsIEdlKTsKICAgIGYodGhpcywgSWUpOwogICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAvLyBQcml2YXRlIOKAlCBmcmFtZSBkaXNwYXRjaAogICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBmKHRoaXMsIFFlKTsKICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLy8gUHJpdmF0ZSDigJQgV2ViR1BVIHNpbXVsYXRpb24gc3RlcAogICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBmKHRoaXMsIGplKTsKICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLy8gUHJpdmF0ZSDigJQgV2ViR1BVIGRpcmVjdCBzcGxhdAogICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBmKHRoaXMsIEtlKTsKICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLy8gUHJpdmF0ZSDigJQgV2ViR0wgc3BsYXQKICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgZih0aGlzLCBKZSk7CiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8vIFByaXZhdGUg4oCUIFdlYkdMIHNpbXVsYXRpb24gc3RlcCAodW5jaGFuZ2VkIGZyb20gb3JpZ2luYWwpCiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIGYodGhpcywgWmUpOwogICAgZih0aGlzLCBjZSwgdm9pZCAwKTsKICAgIC8vIOKUgOKUgCBXZWJHTCBwYXRoIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAogICAgZih0aGlzLCBNLCBudWxsKTsKICAgIGYodGhpcywgemUsIG51bGwpOwogICAgZih0aGlzLCBmZSwgbnVsbCk7CiAgICBmKHRoaXMsIFVlLCBudWxsKTsKICAgIGYodGhpcywgQiwgbnVsbCk7CiAgICBmKHRoaXMsIFIsIG51bGwpOwogICAgZih0aGlzLCAkLCBudWxsKTsKICAgIGYodGhpcywgcSwgbnVsbCk7CiAgICBmKHRoaXMsIEgsIG51bGwpOwogICAgZih0aGlzLCBLLCBudWxsKTsKICAgIGYodGhpcywgTCwgbnVsbCk7CiAgICBmKHRoaXMsIFksIG51bGwpOwogICAgLy8g4pSA4pSAIFdlYkdQVSBwYXRoIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAogICAgZih0aGlzLCBPLCBudWxsKTsKICAgIGYodGhpcywgRGUsIG51bGwpOwogICAgZih0aGlzLCB2ZSwgbnVsbCk7CiAgICBmKHRoaXMsIF9lLCBudWxsKTsKICAgIGYodGhpcywgViwgbnVsbCk7CiAgICBmKHRoaXMsIFQsIG51bGwpOwogICAgZih0aGlzLCBvZSwgbnVsbCk7CiAgICBmKHRoaXMsIFEsIG51bGwpOwogICAgZih0aGlzLCBhZSwgbnVsbCk7CiAgICBmKHRoaXMsIHosIG51bGwpOwogICAgLy8gUHJlLWFsbG9jYXRlZCB1bmlmb3JtIGJ1ZmZlcnMgKHNpemVzOiBzZWUgZ3B1LXV0aWxzIHdyaXRlWHh4IGRvY3MpCiAgICAvLyBWZWxvY2l0eS9kZW5zaXR5IGFkdmVjdGlvbiB1c2Ugc2VwYXJhdGUgYnVmZmVycyDigJQgd3JpdGVCdWZmZXIgaXMgYSBxdWV1ZSBvcDsKICAgIC8vIGEgc2Vjb25kIHdyaXRlIHRvIHRoZSBzYW1lIGJ1ZmZlciBiZWZvcmUgcXVldWUuc3VibWl0KCkgYWxpYXNlcyBib3RoIHBhc3Nlcy4KICAgIGYodGhpcywgcGUsIG51bGwpOwogICAgLy8gMTYgYnl0ZXMg4oCUIHZlbG9jaXR5IGFkdmVjdGlvbgogICAgZih0aGlzLCB4ZSwgbnVsbCk7CiAgICAvLyAxNiBieXRlcyDigJQgZGVuc2l0eSBhZHZlY3Rpb24KICAgIGYodGhpcywgbWUsIG51bGwpOwogICAgLy8gMTYgYnl0ZXMKICAgIGYodGhpcywgZGUsIG51bGwpOwogICAgLy8gMTYgYnl0ZXMKICAgIGYodGhpcywgaGUsIG51bGwpOwogICAgLy8gMTYgYnl0ZXMKICAgIGYodGhpcywgSiwgbnVsbCk7CiAgICAvLyA0OCBieXRlcyDigJQgdmVsb2NpdHkgc3BsYXQKICAgIGYodGhpcywgWiwgbnVsbCk7CiAgICAvLyA0OCBieXRlcyDigJQgZGVuc2l0eSBzcGxhdAogICAgZih0aGlzLCBnZSwgbnVsbCk7CiAgICAvLyAxNiBieXRlcwogICAgZih0aGlzLCBiZSwgbnVsbCk7CiAgICAvLyAxNiBieXRlcwogICAgZih0aGlzLCBUZSwgbnVsbCk7CiAgICAvLyA2NCBieXRlcwogICAgLy8g4pSA4pSAIFNoYXJlZCBzdGF0ZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKICAgIGYodGhpcywgdywgMCk7CiAgICBmKHRoaXMsIFUsIDApOwogICAgZih0aGlzLCBHLCAwKTsKICAgIGYodGhpcywgSSwgMCk7CiAgICBmKHRoaXMsIEYsIDEpOwogICAgZih0aGlzLCBDZSwgMSk7CiAgICBmKHRoaXMsIGVlLCAwLjUpOwogICAgZih0aGlzLCBBLCBudWxsKTsKICAgIGYodGhpcywgdWUsICJjb3ZlciIpOwogICAgZih0aGlzLCB0ZSwgdm9pZCAwKTsKICAgIGYodGhpcywgaCwgeyB4OiAwLCB5OiAwLCBkeDogMCwgZHk6IDAsIHRhcmdldFg6IDAsIHRhcmdldFk6IDAsIG1vdmVkOiAhMSB9KTsKICAgIGYodGhpcywgQywgbnVsbCk7CiAgICBmKHRoaXMsIGosIG51bGwpOwogICAgZih0aGlzLCB5ZSwgITEpOwogICAgZih0aGlzLCBYZSwgITEpOwogICAgZih0aGlzLCBTZSwgITApOwogICAgaWYgKGwodGhpcywgY2UsIGUpLCBsKHRoaXMsIENlLCBNYXRoLm1heCgwLjEsIE1hdGgubWluKDEsIHMuZHByID8/IDEpKSksIGwodGhpcywgZWUsIE1hdGgubWF4KDAuMSwgTWF0aC5taW4oMSwgcy5zaW0gPz8gMC41KSkpLCBsKHRoaXMsIHRlLCB3dChyKSksIGwodGhpcywgU2UsIGEpLCBvKQogICAgICBsKHRoaXMsIE8sIG8pLCBTKHRoaXMsIFllLCBwdCkuY2FsbCh0aGlzLCBvKTsKICAgIGVsc2UgewogICAgICBjb25zdCB7IGdsOiB1LCBleHQ6IHYgfSA9IE90KGUsIGEpOwogICAgICBsKHRoaXMsIE0sIHUpLCBsKHRoaXMsIHplLCB2KSwgbCh0aGlzLCBmZSwgUHQodSkpLCBsKHRoaXMsIFVlLCBMdCh1KSksIHUuY2xlYXJDb2xvcigwLCAwLCAwLCBhID8gMCA6IDEpOwogICAgfQogIH0KICAvKioKICAgKiBXZWJHUFUtZmlyc3QgZmFjdG9yeS4gVHJpZXMgV2ViR1BVLCBmYWxscyBiYWNrIHRvIFdlYkdMMiDihpIgV2ViR0wxLgogICAqIFRoaXMgaXMgdGhlIHJlY29tbWVuZGVkIGVudHJ5IHBvaW50IHdoZW4gV2ViR1BVIHN1cHBvcnQgaXMgZGVzaXJlZC4KICAgKi8KICBzdGF0aWMgYXN5bmMgY3JlYXRlKGUsIHIgPSB7fSwgcyA9IHt9LCBvID0gITAsIGEgPSAhMCkgewogICAgY29uc3QgdSA9IG8gPyBhd2FpdCBGdChlLCBhKSA6IG51bGw7CiAgICByZXR1cm4gbmV3IHV0KGUsIHIsIHMsIHUgPz8gdm9pZCAwLCBhKTsKICB9CiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgLy8gUHVibGljIEFQSQogIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIHNldFRleHRTb3VyY2UoZSkgewogICAgbCh0aGlzLCBDLCB7IHR5cGU6ICJ0ZXh0Iiwgb3B0czogZSB9KSwgUyh0aGlzLCB3ZSwgRmUpLmNhbGwodGhpcyksIFModGhpcywgbmUsIEVlKS5jYWxsKHRoaXMpLCBTKHRoaXMsIFJlLCBQZSkuY2FsbCh0aGlzKTsKICB9CiAgYXN5bmMgc2V0SW1hZ2VTb3VyY2UoZSwgciA9IDAsIHMgPSAiY292ZXIiKSB7CiAgICBjb25zdCBvID0gYXdhaXQgcnIoZSk7CiAgICBpZiAodCh0aGlzLCBYZSkpIHsKICAgICAgby5jbG9zZSgpOwogICAgICByZXR1cm47CiAgICB9CiAgICBsKHRoaXMsIEMsIHsgdHlwZTogImltYWdlIiwgYml0bWFwOiBvLCBlZmZlY3Q6IHIsIHNpemU6IHMgfSksIFModGhpcywgd2UsIEZlKS5jYWxsKHRoaXMpLCBTKHRoaXMsIG5lLCBFZSkuY2FsbCh0aGlzKSwgUyh0aGlzLCBSZSwgUGUpLmNhbGwodGhpcyk7CiAgfQogIHNldEltYWdlQml0bWFwKGUsIHIgPSAwLCBzID0gImNvdmVyIikgewogICAgbCh0aGlzLCBDLCB7IHR5cGU6ICJpbWFnZSIsIGJpdG1hcDogZSwgZWZmZWN0OiByLCBzaXplOiBzIH0pLCBTKHRoaXMsIHdlLCBGZSkuY2FsbCh0aGlzKSwgUyh0aGlzLCBuZSwgRWUpLmNhbGwodGhpcyksIFModGhpcywgUmUsIFBlKS5jYWxsKHRoaXMpOwogIH0KICBzZXRCYWNrZ3JvdW5kKGUsIHIgPSAiY292ZXIiKSB7CiAgICB0KHRoaXMsIEEpICYmIHQodGhpcywgQSkgIT09IGUgJiYgdCh0aGlzLCBBKS5jbG9zZSgpLCBsKHRoaXMsIEEsIGUpLCBsKHRoaXMsIHVlLCByID8/ICJjb3ZlciIpLCB0KHRoaXMsIEMpICYmIHQodGhpcywgdykgPiAwICYmIHQodGhpcywgVSkgPiAwICYmIFModGhpcywgbmUsIEVlKS5jYWxsKHRoaXMpOwogIH0KICBoYW5kbGVNb3ZlKGUsIHIsIHMgPSAxKSB7CiAgICB0KHRoaXMsIGgpLm1vdmVkID0gITAsIHQodGhpcywgaCkuZHggPSAoZSAtIHQodGhpcywgaCkudGFyZ2V0WCkgKiBzLCB0KHRoaXMsIGgpLmR5ID0gKHIgLSB0KHRoaXMsIGgpLnRhcmdldFkpICogcywgdCh0aGlzLCBoKS50YXJnZXRYID0gZSwgdCh0aGlzLCBoKS50YXJnZXRZID0gcjsKICB9CiAgLyoqCiAgICogSW1tZWRpYXRlbHkgYXBwbGllcyBvbmUgZmx1aWQgc3BsYXQgYXQgKHgsIHkpIHdpdGggZXhwbGljaXQgdmVsb2NpdHkgKHZ4LCB2eSkuCiAgICogU2FmZSB0byBjYWxsIG11bHRpcGxlIHRpbWVzIHBlciBmcmFtZSDigJQgZWFjaCBjYWxsIHdyaXRlcyBkaXJlY3RseSB0byB0aGUgRkJPcy4KICAgKiBEZXNpZ25lZCBmb3IgcHJvZ3JhbW1hdGljIHVzZSBjYXNlcyAoZS5nLiBwYXJ0aWNsZSBzeXN0ZW1zLCBhdHRyYWN0b3IgcGF0aHMpCiAgICogd2hlcmUgeW91IHdhbnQgTiBpbmRlcGVuZGVudCBpbmplY3Rpb24gcG9pbnRzIHBlciBmcmFtZSB3aXRob3V0IGZsb29kaW5nIHRoZQogICAqIG1vdXNlLXN0YXRlIG1hY2hpbmUgb3IgdGhlIHdvcmtlciBtZXNzYWdlIHF1ZXVlLgogICAqLwogIHNwbGF0KGUsIHIsIHMsIG8sIGEgPSAxKSB7CiAgICAhdCh0aGlzLCB5ZSkgfHwgdCh0aGlzLCB3KSA9PT0gMCB8fCAodCh0aGlzLCBPKSA/IFModGhpcywgS2UsIGR0KS5jYWxsKHRoaXMsIGUsIHIsIHMsIG8sIGEpIDogUyh0aGlzLCBKZSwgaHQpLmNhbGwodGhpcywgZSwgciwgcywgbywgYSkpOwogIH0KICB1cGRhdGVRdWFsaXR5KGUpIHsKICAgIGUuZHByICE9PSB2b2lkIDAgJiYgbCh0aGlzLCBDZSwgTWF0aC5tYXgoMC4xLCBNYXRoLm1pbigxLCBlLmRwcikpKSwgZS5zaW0gIT09IHZvaWQgMCAmJiBsKHRoaXMsIGVlLCBNYXRoLm1heCgwLjEsIE1hdGgubWluKDEsIGUuc2ltKSkpOwogIH0KICByZXNpemUoZSwgciwgcykgewogICAgaWYgKHMgIT09IHZvaWQgMCA/IGwodGhpcywgRiwgcykgOiB0eXBlb2Ygd2luZG93IDwgInUiICYmIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvICYmIGwodGhpcywgRiwgd2luZG93LmRldmljZVBpeGVsUmF0aW8pLCBlICE9PSB2b2lkIDAgJiYgZSA+IDApIHsKICAgICAgaWYgKHIgPT09IHZvaWQgMCB8fCByIDw9IDApCiAgICAgICAgcmV0dXJuOwogICAgICBsKHRoaXMsIHcsIHQodGhpcywgY2UpLndpZHRoID0gZSksIGwodGhpcywgVSwgdCh0aGlzLCBjZSkuaGVpZ2h0ID0gciksIGwodGhpcywgRywgTWF0aC5tYXgoMSwgTWF0aC5yb3VuZChlICogdCh0aGlzLCBlZSkpKSksIGwodGhpcywgSSwgTWF0aC5tYXgoMSwgTWF0aC5yb3VuZChyICogdCh0aGlzLCBlZSkpKSksIFModGhpcywgTWUsIHN0KS5jYWxsKHRoaXMpOwogICAgfSBlbHNlCiAgICAgIFModGhpcywgd2UsIEZlKS5jYWxsKHRoaXMpOwogICAgdCh0aGlzLCBDKSAmJiBTKHRoaXMsIG5lLCBFZSkuY2FsbCh0aGlzKSwgUyh0aGlzLCBSZSwgUGUpLmNhbGwodGhpcyk7CiAgfQogIHVwZGF0ZUNvbmZpZyhlKSB7CiAgICBPYmplY3QuYXNzaWduKHQodGhpcywgdGUpLCBlKTsKICB9CiAgZGVzdHJveSgpIHsKICAgIHZhciBlLCByLCBzLCBvLCBhLCB1LCB2LCBtLCBjLCB4LCBwOwogICAgaWYgKGwodGhpcywgWGUsICEwKSwgdGhpcy5zdG9wKCksIFModGhpcywgR2UsIG90KS5jYWxsKHRoaXMpLCBTKHRoaXMsIEllLCBhdCkuY2FsbCh0aGlzKSwgdCh0aGlzLCBBKSAmJiAodCh0aGlzLCBBKS5jbG9zZSgpLCBsKHRoaXMsIEEsIG51bGwpKSwgdCh0aGlzLCBPKSkKICAgICAgKGUgPSB0KHRoaXMsIHBlKSkgPT0gbnVsbCB8fCBlLmRlc3Ryb3koKSwgKHIgPSB0KHRoaXMsIHhlKSkgPT0gbnVsbCB8fCByLmRlc3Ryb3koKSwgKHMgPSB0KHRoaXMsIG1lKSkgPT0gbnVsbCB8fCBzLmRlc3Ryb3koKSwgKG8gPSB0KHRoaXMsIGRlKSkgPT0gbnVsbCB8fCBvLmRlc3Ryb3koKSwgKGEgPSB0KHRoaXMsIGhlKSkgPT0gbnVsbCB8fCBhLmRlc3Ryb3koKSwgKHUgPSB0KHRoaXMsIEopKSA9PSBudWxsIHx8IHUuZGVzdHJveSgpLCAodiA9IHQodGhpcywgWikpID09IG51bGwgfHwgdi5kZXN0cm95KCksIChtID0gdCh0aGlzLCBnZSkpID09IG51bGwgfHwgbS5kZXN0cm95KCksIChjID0gdCh0aGlzLCBiZSkpID09IG51bGwgfHwgYy5kZXN0cm95KCksICh4ID0gdCh0aGlzLCBUZSkpID09IG51bGwgfHwgeC5kZXN0cm95KCksIChwID0gdCh0aGlzLCB2ZSkpID09IG51bGwgfHwgcC5kZXN0cm95KCksIHQodGhpcywgTykuZGV2aWNlLmRlc3Ryb3koKTsKICAgIGVsc2UgewogICAgICBjb25zdCBuID0gdCh0aGlzLCBNKTsKICAgICAgZm9yIChjb25zdCBiIG9mIE9iamVjdC52YWx1ZXModCh0aGlzLCBmZSkpKQogICAgICAgIGIuZGlzcG9zZSgpOwogICAgICBjb25zdCBkID0gbi5nZXRFeHRlbnNpb24oIldFQkdMX2xvc2VfY29udGV4dCIpOwogICAgICBkID09IG51bGwgfHwgZC5sb3NlQ29udGV4dCgpOwogICAgfQogIH0KICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAvLyBMb29wIGNvbnRyb2wKICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICBzdGFydCgpIHsKICAgIGlmICh0KHRoaXMsIGopICE9PSBudWxsKQogICAgICByZXR1cm47CiAgICBjb25zdCBlID0gKCkgPT4gewogICAgICBTKHRoaXMsIFFlLCB4dCkuY2FsbCh0aGlzKSwgbCh0aGlzLCBqLCBjdChlKSk7CiAgICB9OwogICAgbCh0aGlzLCBqLCBjdChlKSk7CiAgfQogIHN0b3AoKSB7CiAgICB0KHRoaXMsIGopICE9PSBudWxsICYmIChpcih0KHRoaXMsIGopKSwgbCh0aGlzLCBqLCBudWxsKSk7CiAgfQogIGdldCBpc1J1bm5pbmcoKSB7CiAgICByZXR1cm4gdCh0aGlzLCBqKSAhPT0gbnVsbDsKICB9Cn07CmNlID0gbmV3IFdlYWtNYXAoKSwgTSA9IG5ldyBXZWFrTWFwKCksIHplID0gbmV3IFdlYWtNYXAoKSwgZmUgPSBuZXcgV2Vha01hcCgpLCBVZSA9IG5ldyBXZWFrTWFwKCksIEIgPSBuZXcgV2Vha01hcCgpLCBSID0gbmV3IFdlYWtNYXAoKSwgJCA9IG5ldyBXZWFrTWFwKCksIHEgPSBuZXcgV2Vha01hcCgpLCBIID0gbmV3IFdlYWtNYXAoKSwgSyA9IG5ldyBXZWFrTWFwKCksIEwgPSBuZXcgV2Vha01hcCgpLCBZID0gbmV3IFdlYWtNYXAoKSwgTyA9IG5ldyBXZWFrTWFwKCksIERlID0gbmV3IFdlYWtNYXAoKSwgdmUgPSBuZXcgV2Vha01hcCgpLCBfZSA9IG5ldyBXZWFrTWFwKCksIFYgPSBuZXcgV2Vha01hcCgpLCBUID0gbmV3IFdlYWtNYXAoKSwgb2UgPSBuZXcgV2Vha01hcCgpLCBRID0gbmV3IFdlYWtNYXAoKSwgYWUgPSBuZXcgV2Vha01hcCgpLCB6ID0gbmV3IFdlYWtNYXAoKSwgcGUgPSBuZXcgV2Vha01hcCgpLCB4ZSA9IG5ldyBXZWFrTWFwKCksIG1lID0gbmV3IFdlYWtNYXAoKSwgZGUgPSBuZXcgV2Vha01hcCgpLCBoZSA9IG5ldyBXZWFrTWFwKCksIEogPSBuZXcgV2Vha01hcCgpLCBaID0gbmV3IFdlYWtNYXAoKSwgZ2UgPSBuZXcgV2Vha01hcCgpLCBiZSA9IG5ldyBXZWFrTWFwKCksIFRlID0gbmV3IFdlYWtNYXAoKSwgdyA9IG5ldyBXZWFrTWFwKCksIFUgPSBuZXcgV2Vha01hcCgpLCBHID0gbmV3IFdlYWtNYXAoKSwgSSA9IG5ldyBXZWFrTWFwKCksIEYgPSBuZXcgV2Vha01hcCgpLCBDZSA9IG5ldyBXZWFrTWFwKCksIGVlID0gbmV3IFdlYWtNYXAoKSwgQSA9IG5ldyBXZWFrTWFwKCksIHVlID0gbmV3IFdlYWtNYXAoKSwgdGUgPSBuZXcgV2Vha01hcCgpLCBoID0gbmV3IFdlYWtNYXAoKSwgQyA9IG5ldyBXZWFrTWFwKCksIGogPSBuZXcgV2Vha01hcCgpLCB5ZSA9IG5ldyBXZWFrTWFwKCksIFhlID0gbmV3IFdlYWtNYXAoKSwgU2UgPSBuZXcgV2Vha01hcCgpLCBZZSA9IG5ldyBXZWFrU2V0KCksIHB0ID0gZnVuY3Rpb24oZSkgewogIGNvbnN0IHsgZGV2aWNlOiByLCBmb3JtYXQ6IHMgfSA9IGU7CiAgbCh0aGlzLCBEZSwgSHQociwgcywgdCh0aGlzLCBTZSkpKSwgbCh0aGlzLCB2ZSwgJHQocikpLCBsKHRoaXMsIF9lLCBZdChyKSksIGwodGhpcywgcGUsIFcociwgMTYpKSwgbCh0aGlzLCB4ZSwgVyhyLCAxNikpLCBsKHRoaXMsIG1lLCBXKHIsIDE2KSksIGwodGhpcywgZGUsIFcociwgMTYpKSwgbCh0aGlzLCBoZSwgVyhyLCAxNikpLCBsKHRoaXMsIEosIFcociwgNDgpKSwgbCh0aGlzLCBaLCBXKHIsIDQ4KSksIGwodGhpcywgZ2UsIFcociwgMTYpKSwgbCh0aGlzLCBiZSwgVyhyLCAxNikpLCBsKHRoaXMsIFRlLCBXKHIsIDY0KSk7Cn0sIHdlID0gbmV3IFdlYWtTZXQoKSwgRmUgPSBmdW5jdGlvbigpIHsKICBjb25zdCBlID0gdCh0aGlzLCBjZSk7CiAgImNsaWVudFdpZHRoIiBpbiBlICYmIGUuY2xpZW50V2lkdGggPiAwID8gKGwodGhpcywgRiwgKHR5cGVvZiB3aW5kb3cgPCAidSIgJiYgd2luZG93LmRldmljZVBpeGVsUmF0aW8gfHwgMSkgKiB0KHRoaXMsIENlKSksIGwodGhpcywgdywgZS53aWR0aCA9IE1hdGgucm91bmQoZS5jbGllbnRXaWR0aCAqIHQodGhpcywgRikpKSwgbCh0aGlzLCBVLCBlLmhlaWdodCA9IE1hdGgucm91bmQoZS5jbGllbnRIZWlnaHQgKiB0KHRoaXMsIEYpKSkpIDogKGwodGhpcywgdywgZS53aWR0aCksIGwodGhpcywgVSwgZS5oZWlnaHQpKSwgISh0KHRoaXMsIHcpID09PSAwIHx8IHQodGhpcywgVSkgPT09IDApICYmIChsKHRoaXMsIEcsIE1hdGgubWF4KDEsIE1hdGgucm91bmQodCh0aGlzLCB3KSAqIHQodGhpcywgZWUpKSkpLCBsKHRoaXMsIEksIE1hdGgubWF4KDEsIE1hdGgucm91bmQodCh0aGlzLCBVKSAqIHQodGhpcywgZWUpKSkpLCBTKHRoaXMsIE1lLCBzdCkuY2FsbCh0aGlzKSk7Cn0sIE1lID0gbmV3IFdlYWtTZXQoKSwgc3QgPSBmdW5jdGlvbigpIHsKICBpZiAoUyh0aGlzLCBHZSwgb3QpLmNhbGwodGhpcyksIHQodGhpcywgTykpIHsKICAgIGNvbnN0IHsgZGV2aWNlOiBlIH0gPSB0KHRoaXMsIE8pLCByID0gInJnYmExNmZsb2F0IiwgcyA9IHQodGhpcywgRyksIG8gPSB0KHRoaXMsIEkpOwogICAgbCh0aGlzLCBWLCBydChlLCByLCBzLCBvKSksIGwodGhpcywgVCwgcnQoZSwgciwgcywgbykpLCBsKHRoaXMsIFEsIHJ0KGUsIHIsIHMsIG8pKSwgbCh0aGlzLCBvZSwgSGUoZSwgciwgcywgbykpLCBsKHRoaXMsIGFlLCBIZShlLCByLCBzLCBvKSk7CiAgfSBlbHNlIHsKICAgIGNvbnN0IGUgPSB0KHRoaXMsIE0pLCByID0gdCh0aGlzLCB6ZSksIHMgPSB0KHRoaXMsIEcpLCBvID0gdCh0aGlzLCBJKTsKICAgIGwodGhpcywgQiwgdHQoZSwgciwgcywgbykpLCBsKHRoaXMsIFIsIHR0KGUsIHIsIHMsIG8pKSwgbCh0aGlzLCBxLCB0dChlLCByLCBzLCBvKSksIGwodGhpcywgJCwgcWUoZSwgciwgcywgbykpLCBsKHRoaXMsIEgsIHFlKGUsIHIsIHMsIG8pKTsKICB9Cn0sIG5lID0gbmV3IFdlYWtTZXQoKSwgRWUgPSBmdW5jdGlvbigpIHsKICBpZiAoISghdCh0aGlzLCBDKSB8fCB0KHRoaXMsIHcpID09PSAwIHx8IHQodGhpcywgVSkgPT09IDApKSB7CiAgICBpZiAoUyh0aGlzLCBJZSwgYXQpLmNhbGwodGhpcyksIHQodGhpcywgTykpIHsKICAgICAgY29uc3QgeyBkZXZpY2U6IGUgfSA9IHQodGhpcywgTyk7CiAgICAgIHQodGhpcywgQykudHlwZSA9PT0gInRleHQiID8gbCh0aGlzLCB6LCBlcigKICAgICAgICBlLAogICAgICAgIHQodGhpcywgdyksCiAgICAgICAgdCh0aGlzLCBVKSwKICAgICAgICB0KHRoaXMsIEMpLm9wdHMsCiAgICAgICAgdCh0aGlzLCBBKSwKICAgICAgICB0KHRoaXMsIHVlKQogICAgICApKSA6IGwodGhpcywgeiwgdHIoCiAgICAgICAgZSwKICAgICAgICB0KHRoaXMsIEMpLmJpdG1hcCwKICAgICAgICB0KHRoaXMsIHcpLAogICAgICAgIHQodGhpcywgVSksCiAgICAgICAgdCh0aGlzLCBDKS5lZmZlY3QsCiAgICAgICAgdCh0aGlzLCBDKS5zaXplLAogICAgICAgIHQodGhpcywgQSksCiAgICAgICAgdCh0aGlzLCB1ZSkKICAgICAgKSk7CiAgICB9IGVsc2UgewogICAgICBjb25zdCBlID0gdCh0aGlzLCBNKTsKICAgICAgaWYgKHQodGhpcywgQykudHlwZSA9PT0gInRleHQiKSB7CiAgICAgICAgY29uc3QgeyBiYWNrZ3JvdW5kVGV4OiByLCBvYnN0YWNsZVRleDogcywgY292ZXJhZ2VUZXg6IG8gfSA9IEp0KAogICAgICAgICAgZSwKICAgICAgICAgIHQodGhpcywgdyksCiAgICAgICAgICB0KHRoaXMsIFUpLAogICAgICAgICAgdCh0aGlzLCBDKS5vcHRzLAogICAgICAgICAgdCh0aGlzLCBBKSwKICAgICAgICAgIHQodGhpcywgdWUpCiAgICAgICAgKTsKICAgICAgICBsKHRoaXMsIEssIHIpLCBsKHRoaXMsIEwsIHMpLCBsKHRoaXMsIFksIG8pOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbnN0IHsgYmFja2dyb3VuZFRleDogciwgb2JzdGFjbGVUZXg6IHMsIGNvdmVyYWdlVGV4OiBvIH0gPSBadCgKICAgICAgICAgIGUsCiAgICAgICAgICB0KHRoaXMsIEMpLmJpdG1hcCwKICAgICAgICAgIHQodGhpcywgdyksCiAgICAgICAgICB0KHRoaXMsIFUpLAogICAgICAgICAgdCh0aGlzLCBDKS5lZmZlY3QsCiAgICAgICAgICB0KHRoaXMsIEMpLnNpemUsCiAgICAgICAgICB0KHRoaXMsIEEpLAogICAgICAgICAgdCh0aGlzLCB1ZSkKICAgICAgICApOwogICAgICAgIGwodGhpcywgSywgciksIGwodGhpcywgTCwgcyksIGwodGhpcywgWSwgbyk7CiAgICAgIH0KICAgIH0KICAgIGwodGhpcywgeWUsICEwKTsKICB9Cn0sIFJlID0gbmV3IFdlYWtTZXQoKSwgUGUgPSBmdW5jdGlvbigpIHsKICB0KHRoaXMsIHllKSAmJiAhdGhpcy5pc1J1bm5pbmcgJiYgdGhpcy5zdGFydCgpOwp9LCBHZSA9IG5ldyBXZWFrU2V0KCksIG90ID0gZnVuY3Rpb24oKSB7CiAgdmFyIGUsIHIsIHMsIG8sIGEsIHUsIHYsIG07CiAgaWYgKHQodGhpcywgTykpCiAgICAoZSA9IHQodGhpcywgVikpID09IG51bGwgfHwgZS5kaXNwb3NlKCksIChyID0gdCh0aGlzLCBUKSkgPT0gbnVsbCB8fCByLmRpc3Bvc2UoKSwgKHMgPSB0KHRoaXMsIFEpKSA9PSBudWxsIHx8IHMuZGlzcG9zZSgpLCAobyA9IHQodGhpcywgb2UpKSA9PSBudWxsIHx8IG8udGV4LmRlc3Ryb3koKSwgKGEgPSB0KHRoaXMsIGFlKSkgPT0gbnVsbCB8fCBhLnRleC5kZXN0cm95KCksIGwodGhpcywgViwgbCh0aGlzLCBULCBsKHRoaXMsIFEsIG51bGwpKSksIGwodGhpcywgb2UsIGwodGhpcywgYWUsIG51bGwpKTsKICBlbHNlIHsKICAgIGNvbnN0IGMgPSB0KHRoaXMsIE0pOwogICAgKHUgPSB0KHRoaXMsIEIpKSA9PSBudWxsIHx8IHUuZGlzcG9zZSgpLCAodiA9IHQodGhpcywgUikpID09IG51bGwgfHwgdi5kaXNwb3NlKCksIChtID0gdCh0aGlzLCBxKSkgPT0gbnVsbCB8fCBtLmRpc3Bvc2UoKSwgdCh0aGlzLCAkKSAmJiAoYy5kZWxldGVUZXh0dXJlKHQodGhpcywgJCkudGV4KSwgYy5kZWxldGVGcmFtZWJ1ZmZlcih0KHRoaXMsICQpLmZibykpLCB0KHRoaXMsIEgpICYmIChjLmRlbGV0ZVRleHR1cmUodCh0aGlzLCBIKS50ZXgpLCBjLmRlbGV0ZUZyYW1lYnVmZmVyKHQodGhpcywgSCkuZmJvKSksIGwodGhpcywgQiwgbCh0aGlzLCBSLCBsKHRoaXMsIHEsIGwodGhpcywgJCwgbCh0aGlzLCBILCBudWxsKSkpKSk7CiAgfQp9LCBJZSA9IG5ldyBXZWFrU2V0KCksIGF0ID0gZnVuY3Rpb24oKSB7CiAgaWYgKHQodGhpcywgTykpCiAgICB0KHRoaXMsIHopICYmICh0KHRoaXMsIHopLmJhY2tncm91bmRUZXguZGVzdHJveSgpLCB0KHRoaXMsIHopLm9ic3RhY2xlVGV4LmRlc3Ryb3koKSwgdCh0aGlzLCB6KS5zaGFyZWRDb3ZlcmFnZSB8fCB0KHRoaXMsIHopLmNvdmVyYWdlVGV4LmRlc3Ryb3koKSwgbCh0aGlzLCB6LCBudWxsKSk7CiAgZWxzZSB7CiAgICBjb25zdCBlID0gdCh0aGlzLCBNKTsKICAgIHQodGhpcywgSykgJiYgZS5kZWxldGVUZXh0dXJlKHQodGhpcywgSykpLCB0KHRoaXMsIEwpICYmIGUuZGVsZXRlVGV4dHVyZSh0KHRoaXMsIEwpKSwgdCh0aGlzLCBZKSAmJiB0KHRoaXMsIFkpICE9PSB0KHRoaXMsIEwpICYmIGUuZGVsZXRlVGV4dHVyZSh0KHRoaXMsIFkpKSwgbCh0aGlzLCBLLCBsKHRoaXMsIEwsIGwodGhpcywgWSwgbnVsbCkpKTsKICB9Cn0sIFFlID0gbmV3IFdlYWtTZXQoKSwgeHQgPSBmdW5jdGlvbigpIHsKICAhdCh0aGlzLCB5ZSkgfHwgdCh0aGlzLCB3KSA9PT0gMCB8fCAodCh0aGlzLCBPKSA/IFModGhpcywgamUsIG10KS5jYWxsKHRoaXMpIDogUyh0aGlzLCBaZSwgZ3QpLmNhbGwodGhpcykpOwp9LCBqZSA9IG5ldyBXZWFrU2V0KCksIG10ID0gZnVuY3Rpb24oKSB7CiAgY29uc3QgZSA9IHQodGhpcywgTyksIHIgPSBlLmRldmljZSwgcyA9IHQodGhpcywgRGUpLCBvID0gdCh0aGlzLCB2ZSksIGEgPSB0KHRoaXMsIF9lKSwgdSA9IHQodGhpcywgdGUpLCB2ID0gdCh0aGlzLCB6KTsKICBpZiAoIXQodGhpcywgVikgfHwgIXQodGhpcywgVCkpCiAgICByZXR1cm47CiAgdCh0aGlzLCBoKS54ICs9ICh0KHRoaXMsIGgpLnRhcmdldFggLSB0KHRoaXMsIGgpLngpICogMC4xNSwgdCh0aGlzLCBoKS55ICs9ICh0KHRoaXMsIGgpLnRhcmdldFkgLSB0KHRoaXMsIGgpLnkpICogMC4xNTsKICBjb25zdCBtID0gdCh0aGlzLCBHKSwgYyA9IHQodGhpcywgSSksIHggPSB0KHRoaXMsIHcpLCBwID0gdCh0aGlzLCBVKSwgbiA9IDEgLyBtLCBkID0gMSAvIGM7CiAgbHQociwgdCh0aGlzLCBwZSksIG4sIGQsIE9lLCB1LnZlbG9jaXR5RGlzc2lwYXRpb24pLCBOZShyLCB0KHRoaXMsIG1lKSwgbiwgZCksIE5lKHIsIHQodGhpcywgZGUpLCBuLCBkKSwgTmUociwgdCh0aGlzLCBoZSksIG4sIGQpLCBOZShyLCB0KHRoaXMsIGdlKSwgbiwgZCksIFF0KHIsIHQodGhpcywgYmUpLCBuLCBkLCB1LmN1cmwsIE9lKSwganQoCiAgICByLAogICAgdCh0aGlzLCBUZSksCiAgICAxIC8geCwKICAgIDEgLyBwLAogICAgdS5yZWZyYWN0aW9uLAogICAgdS5zcGVjdWxhckV4cCwKICAgIFdlKHUud2F0ZXJDb2xvciksCiAgICBXZSh1Lmdsb3dDb2xvciksCiAgICB1LnNoaW5lLAogICAgdS53YXJwU3RyZW5ndGggPz8gMC4wMTUsCiAgICBmdFt1LmFsZ29yaXRobV0gPz8gMCwKICAgIHQodGhpcywgU2UpCiAgKTsKICBjb25zdCBiID0gci5jcmVhdGVDb21tYW5kRW5jb2RlcigpLCB5ID0gKGcsIF8pID0+IHIuY3JlYXRlQmluZEdyb3VwKHsgbGF5b3V0OiBnLmdldEJpbmRHcm91cExheW91dCgwKSwgZW50cmllczogXyB9KSwgRCA9IHsgYmluZGluZzogMSwgcmVzb3VyY2U6IGEgfTsKICB7CiAgICBjb25zdCBnID0geShzLmFkdmVjdGlvbiwgWwogICAgICB7IGJpbmRpbmc6IDAsIHJlc291cmNlOiB7IGJ1ZmZlcjogdCh0aGlzLCBwZSkgfSB9LAogICAgICBELAogICAgICB7IGJpbmRpbmc6IDIsIHJlc291cmNlOiB0KHRoaXMsIFQpLnJlYWQudmlldyB9LAogICAgICB7IGJpbmRpbmc6IDMsIHJlc291cmNlOiB0KHRoaXMsIFQpLnJlYWQudmlldyB9LAogICAgICB7IGJpbmRpbmc6IDQsIHJlc291cmNlOiB2Lm9ic3RhY2xlVmlldyB9CiAgICBdKTsKICAgIFgoYiwgcy5hZHZlY3Rpb24sIGcsIG8sIHQodGhpcywgVCkud3JpdGUudmlldyk7CiAgfQogIHQodGhpcywgVCkuc3dhcCgpOwogIHsKICAgIGx0KHIsIHQodGhpcywgeGUpLCBuLCBkLCBPZSwgdS5kZW5zaXR5RGlzc2lwYXRpb24pOwogICAgY29uc3QgZyA9IHkocy5hZHZlY3Rpb24sIFsKICAgICAgeyBiaW5kaW5nOiAwLCByZXNvdXJjZTogeyBidWZmZXI6IHQodGhpcywgeGUpIH0gfSwKICAgICAgRCwKICAgICAgeyBiaW5kaW5nOiAyLCByZXNvdXJjZTogdCh0aGlzLCBUKS5yZWFkLnZpZXcgfSwKICAgICAgeyBiaW5kaW5nOiAzLCByZXNvdXJjZTogdCh0aGlzLCBWKS5yZWFkLnZpZXcgfSwKICAgICAgeyBiaW5kaW5nOiA0LCByZXNvdXJjZTogdi5vYnN0YWNsZVZpZXcgfQogICAgXSk7CiAgICBYKGIsIHMuYWR2ZWN0aW9uLCBnLCBvLCB0KHRoaXMsIFYpLndyaXRlLnZpZXcpOwogIH0KICB0KHRoaXMsIFYpLnN3YXAoKTsKICB7CiAgICBjb25zdCBnID0geShzLmN1cmwsIFsKICAgICAgeyBiaW5kaW5nOiAwLCByZXNvdXJjZTogeyBidWZmZXI6IHQodGhpcywgZ2UpIH0gfSwKICAgICAgRCwKICAgICAgeyBiaW5kaW5nOiAyLCByZXNvdXJjZTogdCh0aGlzLCBUKS5yZWFkLnZpZXcgfQogICAgXSk7CiAgICBYKGIsIHMuY3VybCwgZywgbywgdCh0aGlzLCBhZSkudmlldyk7CiAgfQogIHsKICAgIGNvbnN0IGcgPSB5KHMudm9ydGljaXR5LCBbCiAgICAgIHsgYmluZGluZzogMCwgcmVzb3VyY2U6IHsgYnVmZmVyOiB0KHRoaXMsIGJlKSB9IH0sCiAgICAgIEQsCiAgICAgIHsgYmluZGluZzogMiwgcmVzb3VyY2U6IHQodGhpcywgVCkucmVhZC52aWV3IH0sCiAgICAgIHsgYmluZGluZzogMywgcmVzb3VyY2U6IHQodGhpcywgYWUpLnZpZXcgfQogICAgXSk7CiAgICBYKGIsIHMudm9ydGljaXR5LCBnLCBvLCB0KHRoaXMsIFQpLndyaXRlLnZpZXcpOwogIH0KICBpZiAodCh0aGlzLCBUKS5zd2FwKCksIHQodGhpcywgaCkubW92ZWQpIHsKICAgIGNvbnN0IGcgPSB0KHRoaXMsIGgpLnggKiB0KHRoaXMsIEYpIC8geCwgXyA9IHQodGhpcywgaCkueSAqIHQodGhpcywgRikgLyBwOwogICAgJGUoCiAgICAgIHIsCiAgICAgIHQodGhpcywgSiksCiAgICAgIG4sCiAgICAgIGQsCiAgICAgIHggLyBwLAogICAgICB1LnNwbGF0UmFkaXVzLAogICAgICB0KHRoaXMsIGgpLmR4ICogdS5zcGxhdEZvcmNlLAogICAgICB0KHRoaXMsIGgpLmR5ICogdS5zcGxhdEZvcmNlLAogICAgICAwLAogICAgICBnLAogICAgICBfCiAgICApOwogICAgewogICAgICBjb25zdCBQID0geShzLnNwbGF0LCBbCiAgICAgICAgeyBiaW5kaW5nOiAwLCByZXNvdXJjZTogeyBidWZmZXI6IHQodGhpcywgSikgfSB9LAogICAgICAgIEQsCiAgICAgICAgeyBiaW5kaW5nOiAyLCByZXNvdXJjZTogdCh0aGlzLCBUKS5yZWFkLnZpZXcgfQogICAgICBdKTsKICAgICAgWChiLCBzLnNwbGF0LCBQLCBvLCB0KHRoaXMsIFQpLndyaXRlLnZpZXcpOwogICAgfQogICAgdCh0aGlzLCBUKS5zd2FwKCksICRlKAogICAgICByLAogICAgICB0KHRoaXMsIFopLAogICAgICBuLAogICAgICBkLAogICAgICB4IC8gcCwKICAgICAgdS5zcGxhdFJhZGl1cywKICAgICAgMSwKICAgICAgMSwKICAgICAgMSwKICAgICAgZywKICAgICAgXwogICAgKTsKICAgIHsKICAgICAgY29uc3QgUCA9IHkocy5zcGxhdCwgWwogICAgICAgIHsgYmluZGluZzogMCwgcmVzb3VyY2U6IHsgYnVmZmVyOiB0KHRoaXMsIFopIH0gfSwKICAgICAgICBELAogICAgICAgIHsgYmluZGluZzogMiwgcmVzb3VyY2U6IHQodGhpcywgVikucmVhZC52aWV3IH0KICAgICAgXSk7CiAgICAgIFgoYiwgcy5zcGxhdCwgUCwgbywgdCh0aGlzLCBWKS53cml0ZS52aWV3KTsKICAgIH0KICAgIHQodGhpcywgVikuc3dhcCgpLCB0KHRoaXMsIGgpLm1vdmVkID0gITE7CiAgfQogIHsKICAgIGNvbnN0IGcgPSB5KHMuZGl2ZXJnZW5jZSwgWwogICAgICB7IGJpbmRpbmc6IDAsIHJlc291cmNlOiB7IGJ1ZmZlcjogdCh0aGlzLCBtZSkgfSB9LAogICAgICBELAogICAgICB7IGJpbmRpbmc6IDIsIHJlc291cmNlOiB0KHRoaXMsIFQpLnJlYWQudmlldyB9LAogICAgICB7IGJpbmRpbmc6IDMsIHJlc291cmNlOiB2Lm9ic3RhY2xlVmlldyB9CiAgICBdKTsKICAgIFgoYiwgcy5kaXZlcmdlbmNlLCBnLCBvLCB0KHRoaXMsIG9lKS52aWV3KTsKICB9CiAgZm9yIChsZXQgZyA9IDA7IGcgPCB1LnByZXNzdXJlSXRlcmF0aW9uczsgZysrKSB7CiAgICBjb25zdCBfID0geShzLnByZXNzdXJlLCBbCiAgICAgIHsgYmluZGluZzogMCwgcmVzb3VyY2U6IHsgYnVmZmVyOiB0KHRoaXMsIGRlKSB9IH0sCiAgICAgIEQsCiAgICAgIHsgYmluZGluZzogMiwgcmVzb3VyY2U6IHQodGhpcywgUSkucmVhZC52aWV3IH0sCiAgICAgIHsgYmluZGluZzogMywgcmVzb3VyY2U6IHQodGhpcywgb2UpLnZpZXcgfSwKICAgICAgeyBiaW5kaW5nOiA0LCByZXNvdXJjZTogdi5vYnN0YWNsZVZpZXcgfQogICAgXSk7CiAgICBYKGIsIHMucHJlc3N1cmUsIF8sIG8sIHQodGhpcywgUSkud3JpdGUudmlldyksIHQodGhpcywgUSkuc3dhcCgpOwogIH0KICB7CiAgICBjb25zdCBnID0geShzLmdyYWRpZW50U3VidHJhY3QsIFsKICAgICAgeyBiaW5kaW5nOiAwLCByZXNvdXJjZTogeyBidWZmZXI6IHQodGhpcywgaGUpIH0gfSwKICAgICAgRCwKICAgICAgeyBiaW5kaW5nOiAyLCByZXNvdXJjZTogdCh0aGlzLCBRKS5yZWFkLnZpZXcgfSwKICAgICAgeyBiaW5kaW5nOiAzLCByZXNvdXJjZTogdCh0aGlzLCBUKS5yZWFkLnZpZXcgfSwKICAgICAgeyBiaW5kaW5nOiA0LCByZXNvdXJjZTogdi5vYnN0YWNsZVZpZXcgfQogICAgXSk7CiAgICBYKGIsIHMuZ3JhZGllbnRTdWJ0cmFjdCwgZywgbywgdCh0aGlzLCBUKS53cml0ZS52aWV3KTsKICB9CiAgdCh0aGlzLCBUKS5zd2FwKCk7CiAgewogICAgY29uc3QgZyA9IGUuY29udGV4dC5nZXRDdXJyZW50VGV4dHVyZSgpLmNyZWF0ZVZpZXcoKSwgXyA9IHkocy5kaXNwbGF5LCBbCiAgICAgIHsgYmluZGluZzogMCwgcmVzb3VyY2U6IHsgYnVmZmVyOiB0KHRoaXMsIFRlKSB9IH0sCiAgICAgIEQsCiAgICAgIHsgYmluZGluZzogMiwgcmVzb3VyY2U6IHQodGhpcywgVikucmVhZC52aWV3IH0sCiAgICAgIHsgYmluZGluZzogMywgcmVzb3VyY2U6IHYub2JzdGFjbGVWaWV3IH0sCiAgICAgIHsgYmluZGluZzogNCwgcmVzb3VyY2U6IHYuYmFja2dyb3VuZFZpZXcgfSwKICAgICAgeyBiaW5kaW5nOiA1LCByZXNvdXJjZTogdi5jb3ZlcmFnZVZpZXcgfSwKICAgICAgeyBiaW5kaW5nOiA2LCByZXNvdXJjZTogdCh0aGlzLCBUKS5yZWFkLnZpZXcgfQogICAgXSk7CiAgICBLdChiLCBzLmRpc3BsYXksIF8sIG8sIGcpOwogIH0KICByLnF1ZXVlLnN1Ym1pdChbYi5maW5pc2goKV0pOwp9LCBLZSA9IG5ldyBXZWFrU2V0KCksIGR0ID0gZnVuY3Rpb24oZSwgciwgcywgbywgYSkgewogIGNvbnN0IHYgPSB0KHRoaXMsIE8pLmRldmljZSwgbSA9IHQodGhpcywgRGUpLnNwbGF0LCBjID0gdCh0aGlzLCB2ZSksIHggPSB0KHRoaXMsIF9lKSwgcCA9IHQodGhpcywgdGUpLCBuID0gdCh0aGlzLCBHKSwgZCA9IHQodGhpcywgSSksIGIgPSAxIC8gbiwgeSA9IDEgLyBkLCBEID0gdi5jcmVhdGVDb21tYW5kRW5jb2RlcigpLCBnID0geyBiaW5kaW5nOiAxLCByZXNvdXJjZTogeCB9LCBfID0gKFZlKSA9PiB2LmNyZWF0ZUJpbmRHcm91cCh7IGxheW91dDogbS5nZXRCaW5kR3JvdXBMYXlvdXQoMCksIGVudHJpZXM6IFZlIH0pLCBQID0gZSAqIHQodGhpcywgRikgLyB0KHRoaXMsIHcpLCBrID0gciAqIHQodGhpcywgRikgLyB0KHRoaXMsIFUpOwogICRlKAogICAgdiwKICAgIHQodGhpcywgSiksCiAgICBiLAogICAgeSwKICAgIHQodGhpcywgdykgLyB0KHRoaXMsIFUpLAogICAgcC5zcGxhdFJhZGl1cywKICAgIHMgKiBwLnNwbGF0Rm9yY2UgKiBhLAogICAgbyAqIHAuc3BsYXRGb3JjZSAqIGEsCiAgICAwLAogICAgUCwKICAgIGsKICApOwogIHsKICAgIGNvbnN0IFZlID0gXyhbCiAgICAgIHsgYmluZGluZzogMCwgcmVzb3VyY2U6IHsgYnVmZmVyOiB0KHRoaXMsIEopIH0gfSwKICAgICAgZywKICAgICAgeyBiaW5kaW5nOiAyLCByZXNvdXJjZTogdCh0aGlzLCBUKS5yZWFkLnZpZXcgfQogICAgXSk7CiAgICBYKEQsIG0sIFZlLCBjLCB0KHRoaXMsIFQpLndyaXRlLnZpZXcpOwogIH0KICB0KHRoaXMsIFQpLnN3YXAoKSwgJGUoCiAgICB2LAogICAgdCh0aGlzLCBaKSwKICAgIGIsCiAgICB5LAogICAgdCh0aGlzLCB3KSAvIHQodGhpcywgVSksCiAgICBwLnNwbGF0UmFkaXVzLAogICAgYSwKICAgIGEsCiAgICBhLAogICAgUCwKICAgIGsKICApOwogIHsKICAgIGNvbnN0IFZlID0gXyhbCiAgICAgIHsgYmluZGluZzogMCwgcmVzb3VyY2U6IHsgYnVmZmVyOiB0KHRoaXMsIFopIH0gfSwKICAgICAgZywKICAgICAgeyBiaW5kaW5nOiAyLCByZXNvdXJjZTogdCh0aGlzLCBWKS5yZWFkLnZpZXcgfQogICAgXSk7CiAgICBYKEQsIG0sIFZlLCBjLCB0KHRoaXMsIFYpLndyaXRlLnZpZXcpOwogIH0KICB0KHRoaXMsIFYpLnN3YXAoKSwgdi5xdWV1ZS5zdWJtaXQoW0QuZmluaXNoKCldKTsKfSwgSmUgPSBuZXcgV2Vha1NldCgpLCBodCA9IGZ1bmN0aW9uKGUsIHIsIHMsIG8sIGEpIHsKICBjb25zdCB1ID0gdCh0aGlzLCBNKSwgdiA9IHQodGhpcywgdGUpLCBtID0gdCh0aGlzLCBmZSkuc3BsYXQsIGMgPSB0KHRoaXMsIFVlKTsKICB1LnZpZXdwb3J0KDAsIDAsIHQodGhpcywgRyksIHQodGhpcywgSSkpLCBtLmJpbmQoKSwgdS51bmlmb3JtMWYobS51bmlmb3Jtcy5hc3BlY3RSYXRpbywgdCh0aGlzLCB3KSAvIHQodGhpcywgVSkpLCB1LnVuaWZvcm0yZihtLnVuaWZvcm1zLnBvaW50LCBlICogdCh0aGlzLCBGKSAvIHQodGhpcywgdyksIDEgLSByICogdCh0aGlzLCBGKSAvIHQodGhpcywgVSkpLCB1LnVuaWZvcm0xZihtLnVuaWZvcm1zLnJhZGl1cywgdi5zcGxhdFJhZGl1cyksIHUudW5pZm9ybTFpKG0udW5pZm9ybXMudVRhcmdldCwgMCksIHUuYWN0aXZlVGV4dHVyZSh1LlRFWFRVUkUwKSwgdS5iaW5kVGV4dHVyZSh1LlRFWFRVUkVfMkQsIHQodGhpcywgUikucmVhZC50ZXgpLCB1LnVuaWZvcm0zZihtLnVuaWZvcm1zLmNvbG9yLCBzICogdi5zcGxhdEZvcmNlICogYSwgLW8gKiB2LnNwbGF0Rm9yY2UgKiBhLCAwKSwgYyh0KHRoaXMsIFIpLndyaXRlLmZibyksIHQodGhpcywgUikuc3dhcCgpLCB1LmFjdGl2ZVRleHR1cmUodS5URVhUVVJFMCksIHUuYmluZFRleHR1cmUodS5URVhUVVJFXzJELCB0KHRoaXMsIEIpLnJlYWQudGV4KSwgdS51bmlmb3JtM2YobS51bmlmb3Jtcy5jb2xvciwgYSwgYSwgYSksIGModCh0aGlzLCBCKS53cml0ZS5mYm8pLCB0KHRoaXMsIEIpLnN3YXAoKTsKfSwgWmUgPSBuZXcgV2Vha1NldCgpLCBndCA9IGZ1bmN0aW9uKCkgewogIGlmICghdCh0aGlzLCBCKSB8fCAhdCh0aGlzLCBSKSkKICAgIHJldHVybjsKICBjb25zdCBlID0gdCh0aGlzLCBNKSwgciA9IHQodGhpcywgdGUpLCB7IGFkdmVjdGlvbjogcywgZGl2ZXJnZW5jZTogbywgcHJlc3N1cmU6IGEsIGdyYWRpZW50U3VidHJhY3Q6IHUsIHNwbGF0OiB2LCBjdXJsOiBtLCB2b3J0aWNpdHk6IGMsIGRpc3BsYXk6IHggfSA9IHQodGhpcywgZmUpOwogIHQodGhpcywgaCkueCArPSAodCh0aGlzLCBoKS50YXJnZXRYIC0gdCh0aGlzLCBoKS54KSAqIDAuMTUsIHQodGhpcywgaCkueSArPSAodCh0aGlzLCBoKS50YXJnZXRZIC0gdCh0aGlzLCBoKS55KSAqIDAuMTU7CiAgY29uc3QgcCA9IHQodGhpcywgRyksIG4gPSB0KHRoaXMsIEkpLCBkID0gdCh0aGlzLCBVZSk7CiAgZS52aWV3cG9ydCgwLCAwLCBwLCBuKSwgcy5iaW5kKCksIGUudW5pZm9ybTJmKHMudW5pZm9ybXMudGV4ZWxTaXplLCAxIC8gcCwgMSAvIG4pLCBlLnVuaWZvcm0xZihzLnVuaWZvcm1zLmR0LCBPZSksIGUudW5pZm9ybTFpKHMudW5pZm9ybXMudU9ic3RhY2xlLCAwKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTApLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBMKSksIGUudW5pZm9ybTFmKHMudW5pZm9ybXMuZGlzc2lwYXRpb24sIHIudmVsb2NpdHlEaXNzaXBhdGlvbiksIGUudW5pZm9ybTFpKHMudW5pZm9ybXMudVZlbG9jaXR5LCAxKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTEpLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBSKS5yZWFkLnRleCksIGUudW5pZm9ybTFpKHMudW5pZm9ybXMudVNvdXJjZSwgMSksIGQodCh0aGlzLCBSKS53cml0ZS5mYm8pLCB0KHRoaXMsIFIpLnN3YXAoKSwgZS51bmlmb3JtMWYocy51bmlmb3Jtcy5kaXNzaXBhdGlvbiwgci5kZW5zaXR5RGlzc2lwYXRpb24pLCBlLnVuaWZvcm0xaShzLnVuaWZvcm1zLnVTb3VyY2UsIDIpLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMiksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIEIpLnJlYWQudGV4KSwgZCh0KHRoaXMsIEIpLndyaXRlLmZibyksIHQodGhpcywgQikuc3dhcCgpLCBtLmJpbmQoKSwgZS51bmlmb3JtMmYobS51bmlmb3Jtcy50ZXhlbFNpemUsIDEgLyBwLCAxIC8gbiksIGUudW5pZm9ybTFpKG0udW5pZm9ybXMudVZlbG9jaXR5LCAwKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTApLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBSKS5yZWFkLnRleCksIGQodCh0aGlzLCBIKS5mYm8pLCBjLmJpbmQoKSwgZS51bmlmb3JtMmYoYy51bmlmb3Jtcy50ZXhlbFNpemUsIDEgLyBwLCAxIC8gbiksIGUudW5pZm9ybTFmKGMudW5pZm9ybXMuY3VybCwgci5jdXJsKSwgZS51bmlmb3JtMWYoYy51bmlmb3Jtcy5kdCwgT2UpLCBlLnVuaWZvcm0xaShjLnVuaWZvcm1zLnVWZWxvY2l0eSwgMCksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUwKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgUikucmVhZC50ZXgpLCBlLnVuaWZvcm0xaShjLnVuaWZvcm1zLnVDdXJsLCAxKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTEpLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBIKS50ZXgpLCBkKHQodGhpcywgUikud3JpdGUuZmJvKSwgdCh0aGlzLCBSKS5zd2FwKCksIHQodGhpcywgaCkubW92ZWQgJiYgKHYuYmluZCgpLCBlLnVuaWZvcm0xZih2LnVuaWZvcm1zLmFzcGVjdFJhdGlvLCB0KHRoaXMsIHcpIC8gdCh0aGlzLCBVKSksIGUudW5pZm9ybTJmKHYudW5pZm9ybXMucG9pbnQsIHQodGhpcywgaCkueCAqIHQodGhpcywgRikgLyB0KHRoaXMsIHcpLCAxIC0gdCh0aGlzLCBoKS55ICogdCh0aGlzLCBGKSAvIHQodGhpcywgVSkpLCBlLnVuaWZvcm0xZih2LnVuaWZvcm1zLnJhZGl1cywgci5zcGxhdFJhZGl1cyksIGUudW5pZm9ybTFpKHYudW5pZm9ybXMudVRhcmdldCwgMCksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUwKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgUikucmVhZC50ZXgpLCBlLnVuaWZvcm0zZih2LnVuaWZvcm1zLmNvbG9yLCB0KHRoaXMsIGgpLmR4ICogci5zcGxhdEZvcmNlLCAtdCh0aGlzLCBoKS5keSAqIHIuc3BsYXRGb3JjZSwgMCksIGQodCh0aGlzLCBSKS53cml0ZS5mYm8pLCB0KHRoaXMsIFIpLnN3YXAoKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTApLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBCKS5yZWFkLnRleCksIGUudW5pZm9ybTNmKHYudW5pZm9ybXMuY29sb3IsIDEsIDEsIDEpLCBkKHQodGhpcywgQikud3JpdGUuZmJvKSwgdCh0aGlzLCBCKS5zd2FwKCksIHQodGhpcywgaCkubW92ZWQgPSAhMSksIG8uYmluZCgpLCBlLnVuaWZvcm0yZihvLnVuaWZvcm1zLnRleGVsU2l6ZSwgMSAvIHAsIDEgLyBuKSwgZS51bmlmb3JtMWkoby51bmlmb3Jtcy51VmVsb2NpdHksIDApLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMCksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIFIpLnJlYWQudGV4KSwgZS51bmlmb3JtMWkoby51bmlmb3Jtcy51T2JzdGFjbGUsIDEpLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMSksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIEwpKSwgZCh0KHRoaXMsICQpLmZibyksIGEuYmluZCgpLCBlLnVuaWZvcm0yZihhLnVuaWZvcm1zLnRleGVsU2l6ZSwgMSAvIHAsIDEgLyBuKSwgZS51bmlmb3JtMWkoYS51bmlmb3Jtcy51RGl2ZXJnZW5jZSwgMCksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUwKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgJCkudGV4KSwgZS51bmlmb3JtMWkoYS51bmlmb3Jtcy51T2JzdGFjbGUsIDEpLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMSksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIEwpKTsKICBmb3IgKGxldCBiID0gMDsgYiA8IHIucHJlc3N1cmVJdGVyYXRpb25zOyBiKyspCiAgICBlLnVuaWZvcm0xaShhLnVuaWZvcm1zLnVQcmVzc3VyZSwgMiksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUyKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgcSkucmVhZC50ZXgpLCBkKHQodGhpcywgcSkud3JpdGUuZmJvKSwgdCh0aGlzLCBxKS5zd2FwKCk7CiAgdS5iaW5kKCksIGUudW5pZm9ybTJmKHUudW5pZm9ybXMudGV4ZWxTaXplLCAxIC8gcCwgMSAvIG4pLCBlLnVuaWZvcm0xaSh1LnVuaWZvcm1zLnVQcmVzc3VyZSwgMCksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUwKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgcSkucmVhZC50ZXgpLCBlLnVuaWZvcm0xaSh1LnVuaWZvcm1zLnVWZWxvY2l0eSwgMSksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUxKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgUikucmVhZC50ZXgpLCBlLnVuaWZvcm0xaSh1LnVuaWZvcm1zLnVPYnN0YWNsZSwgMiksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUyKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgTCkpLCBkKHQodGhpcywgUikud3JpdGUuZmJvKSwgdCh0aGlzLCBSKS5zd2FwKCksIGUudmlld3BvcnQoMCwgMCwgdCh0aGlzLCB3KSwgdCh0aGlzLCBVKSksIGUuYmluZEZyYW1lYnVmZmVyKGUuRlJBTUVCVUZGRVIsIG51bGwpLCBlLmNsZWFyKGUuQ09MT1JfQlVGRkVSX0JJVCksIHguYmluZCgpLCBlLnVuaWZvcm0yZih4LnVuaWZvcm1zLnRleGVsU2l6ZSwgMSAvIHQodGhpcywgdyksIDEgLyB0KHRoaXMsIFUpKSwgZS51bmlmb3JtM2Z2KHgudW5pZm9ybXMudVdhdGVyQ29sb3IsIFdlKHIud2F0ZXJDb2xvcikpLCBlLnVuaWZvcm0zZnYoeC51bmlmb3Jtcy51R2xvd0NvbG9yLCBXZShyLmdsb3dDb2xvcikpLCBlLnVuaWZvcm0xZih4LnVuaWZvcm1zLnVSZWZyYWN0aW9uLCByLnJlZnJhY3Rpb24pLCBlLnVuaWZvcm0xZih4LnVuaWZvcm1zLnVTcGVjdWxhckV4cCwgci5zcGVjdWxhckV4cCksIGUudW5pZm9ybTFmKHgudW5pZm9ybXMudVNoaW5lLCByLnNoaW5lKSwgZS51bmlmb3JtMWYoeC51bmlmb3Jtcy51V2FycFN0cmVuZ3RoLCByLndhcnBTdHJlbmd0aCA/PyAwLjAxNSksIGUudW5pZm9ybTFpKHgudW5pZm9ybXMudUFsZ29yaXRobSwgZnRbci5hbGdvcml0aG1dID8/IDApLCBlLnVuaWZvcm0xaSh4LnVuaWZvcm1zLnVFbmFibGVBbHBoYSwgdCh0aGlzLCBTZSkgPyAxIDogMCksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUwKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgQikucmVhZC50ZXgpLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMSksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIEwpKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTIpLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBLKSksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUzKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgWSkpLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFNCksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIFIpLnJlYWQudGV4KSwgZS51bmlmb3JtMWkoeC51bmlmb3Jtcy51VGV4dHVyZSwgMCksIGUudW5pZm9ybTFpKHgudW5pZm9ybXMudU9ic3RhY2xlLCAxKSwgZS51bmlmb3JtMWkoeC51bmlmb3Jtcy51QmFja2dyb3VuZCwgMiksIGUudW5pZm9ybTFpKHgudW5pZm9ybXMudUNvdmVyYWdlLCAzKSwgZS51bmlmb3JtMWkoeC51bmlmb3Jtcy51VmVsb2NpdHksIDQpLCBkKG51bGwpOwp9OwpsZXQgaXQgPSB1dCwgRSA9IG51bGwsIGJ0Owpjb25zdCBOID0gbmV3IFByb21pc2UoKGkpID0+IHsKICBidCA9IGk7Cn0pOwpzZWxmLm9ubWVzc2FnZSA9IGFzeW5jIChpKSA9PiB7CiAgY29uc3QgeyB0eXBlOiBlLCAuLi5yIH0gPSBpLmRhdGE7CiAgdHJ5IHsKICAgIHN3aXRjaCAoZSkgewogICAgICBjYXNlICJpbml0IjogewogICAgICAgIGNvbnN0IHsgY2FudmFzOiBzLCB3aWR0aDogbywgaGVpZ2h0OiBhLCBjb25maWc6IHUsIGRwcjogdiwgcXVhbGl0eTogbSwgdXNlV2ViR1BVOiBjLCBlbmFibGVBbHBoYTogeCB9ID0gcjsKICAgICAgICBzLndpZHRoID0gbywgcy5oZWlnaHQgPSBhLCBFID0gYXdhaXQgaXQuY3JlYXRlKHMsIHUsIG0gPz8ge30sIGMgPz8gITAsIHggPz8gITApLCBFLnJlc2l6ZShvLCBhLCB2IHx8IDEpLCBidCgpLCBzZWxmLnBvc3RNZXNzYWdlKHsgdHlwZTogInJlYWR5IiB9KTsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBjYXNlICJzZXRUZXh0U291cmNlIjogewogICAgICAgIGlmIChhd2FpdCBOLCAhRSkKICAgICAgICAgIHJldHVybjsKICAgICAgICBFLnNldFRleHRTb3VyY2Uoci5vcHRzKTsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBjYXNlICJzZXRJbWFnZVNvdXJjZSI6IHsKICAgICAgICBpZiAoYXdhaXQgTiwgIUUpCiAgICAgICAgICByZXR1cm47CiAgICAgICAgYXdhaXQgRS5zZXRJbWFnZVNvdXJjZSgKICAgICAgICAgIHIuc3JjLAogICAgICAgICAgci5lZmZlY3QsCiAgICAgICAgICByLnNpemUKICAgICAgICApOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGNhc2UgInNldEltYWdlQml0bWFwIjogewogICAgICAgIGlmIChhd2FpdCBOLCAhRSkKICAgICAgICAgIHJldHVybjsKICAgICAgICBFLnNldEltYWdlQml0bWFwKAogICAgICAgICAgci5iaXRtYXAsCiAgICAgICAgICByLmVmZmVjdCwKICAgICAgICAgIHIuc2l6ZQogICAgICAgICk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY2FzZSAic2V0QmFja2dyb3VuZCI6IHsKICAgICAgICBpZiAoYXdhaXQgTiwgIUUpCiAgICAgICAgICByZXR1cm47CiAgICAgICAgRS5zZXRCYWNrZ3JvdW5kKHIuYml0bWFwLCByLnNpemUpOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGNhc2UgInNwbGF0IjogewogICAgICAgIGlmIChhd2FpdCBOLCAhRSkKICAgICAgICAgIHJldHVybjsKICAgICAgICBFLnNwbGF0KAogICAgICAgICAgci54LAogICAgICAgICAgci55LAogICAgICAgICAgci52eCwKICAgICAgICAgIHIudnksCiAgICAgICAgICByLnN0cmVuZ3RoID8/IDEKICAgICAgICApOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGNhc2UgIm1vdmUiOiB7CiAgICAgICAgaWYgKGF3YWl0IE4sICFFKQogICAgICAgICAgcmV0dXJuOwogICAgICAgIEUuaGFuZGxlTW92ZShyLngsIHIueSwgci5zdHJlbmd0aCA/PyAxKTsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBjYXNlICJyZXNpemUiOiB7CiAgICAgICAgaWYgKGF3YWl0IE4sICFFKQogICAgICAgICAgcmV0dXJuOwogICAgICAgIEUucmVzaXplKHIud2lkdGgsIHIuaGVpZ2h0LCByLmRwcik7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY2FzZSAidXBkYXRlUXVhbGl0eSI6IHsKICAgICAgICBpZiAoYXdhaXQgTiwgIUUpCiAgICAgICAgICByZXR1cm47CiAgICAgICAgRS51cGRhdGVRdWFsaXR5KHIucXVhbGl0eSk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY2FzZSAidXBkYXRlQ29uZmlnIjogewogICAgICAgIGlmIChhd2FpdCBOLCAhRSkKICAgICAgICAgIHJldHVybjsKICAgICAgICBFLnVwZGF0ZUNvbmZpZyhyLmNvbmZpZyk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY2FzZSAiZGVzdHJveSI6IHsKICAgICAgICBhd2FpdCBOLCBFID09IG51bGwgfHwgRS5kZXN0cm95KCksIEUgPSBudWxsOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgY29uc29sZS53YXJuKCJbZmx1aWRpdHktanMgd29ya2VyXSBVbmtub3duIG1lc3NhZ2UgdHlwZToiLCBlKTsKICAgIH0KICB9IGNhdGNoIChzKSB7CiAgICBzZWxmLnBvc3RNZXNzYWdlKHsgdHlwZTogImVycm9yIiwgbWVzc2FnZTogKHMgPT0gbnVsbCA/IHZvaWQgMCA6IHMubWVzc2FnZSkgPz8gU3RyaW5nKHMpIH0pOwogIH0KfTsK", fI = typeof window < "u" && window.Blob && new Blob([atob(jI)], { type: "text/javascript;charset=utf-8" });
1566
+ function YC() {
1539
1567
  let e;
1540
1568
  try {
1541
- if (e = YI && (window.URL || window.webkitURL).createObjectURL(YI), !e)
1569
+ if (e = fI && (window.URL || window.webkitURL).createObjectURL(fI), !e)
1542
1570
  throw "";
1543
1571
  return new Worker(e);
1544
1572
  } catch {
1545
- return new Worker("data:application/javascript;base64," + NI, { type: "module" });
1573
+ return new Worker("data:application/javascript;base64," + jI, { type: "module" });
1546
1574
  } finally {
1547
1575
  e && (window.URL || window.webkitURL).revokeObjectURL(e);
1548
1576
  }
1549
1577
  }
1550
- const RC = typeof Worker < "u" && typeof OffscreenCanvas < "u";
1551
- var v, M, zg, Ng, j, dg, rg, Lg, eI, hI, ZI, QI;
1552
- class vC {
1578
+ const kC = typeof Worker < "u" && typeof OffscreenCanvas < "u";
1579
+ var R, x, Og, Eg, Fg, P, dg, wg, Lg, tI, HI, rI, PI;
1580
+ class MC {
1553
1581
  constructor(g, {
1554
1582
  isWorkerEnabled: C = !0,
1555
1583
  useWebGPU: i = !0,
1556
- quality: s = {},
1584
+ enableAlpha: s = !0,
1585
+ quality: l = {},
1557
1586
  config: t = {}
1558
1587
  } = {}) {
1559
1588
  // ---------------------------------------------------------------------------
@@ -1569,39 +1598,40 @@ class vC {
1569
1598
  * this is the common path in jsdom/test environments and keeps the
1570
1599
  * constructor behaviour synchronous where possible.
1571
1600
  */
1572
- S(this, eI);
1573
- S(this, ZI);
1574
- S(this, v, null);
1575
- S(this, M, null);
1576
- S(this, zg, void 0);
1577
- S(this, Ng, void 0);
1578
- S(this, j, void 0);
1579
- S(this, dg, void 0);
1601
+ d(this, tI);
1602
+ d(this, rI);
1603
+ d(this, R, null);
1604
+ d(this, x, null);
1605
+ d(this, Og, void 0);
1606
+ d(this, Eg, void 0);
1607
+ d(this, Fg, void 0);
1608
+ d(this, P, void 0);
1609
+ d(this, dg, void 0);
1580
1610
  // Pending source calls queued while WebGPU async init is in progress (main-thread only)
1581
- S(this, rg, null);
1582
- S(this, Lg, null);
1583
- l(this, j, Math.max(0.1, Math.min(1, s.dpr ?? 1))), l(this, dg, Math.max(0.1, Math.min(1, s.sim ?? 0.5))), l(this, Ng, i), l(this, zg, C && RC), I(this, zg) ? h(this, ZI, QI).call(this, g, t) : h(this, eI, hI).call(this, g, t);
1611
+ d(this, wg, null);
1612
+ d(this, Lg, null);
1613
+ o(this, P, Math.max(0.1, Math.min(1, l.dpr ?? 1))), o(this, dg, Math.max(0.1, Math.min(1, l.sim ?? 0.5))), o(this, Eg, i), o(this, Fg, s), o(this, Og, C && kC), I(this, Og) ? h(this, rI, PI).call(this, g, t) : h(this, tI, HI).call(this, g, t);
1584
1614
  }
1585
1615
  // ---------------------------------------------------------------------------
1586
1616
  // Source setters
1587
1617
  // ---------------------------------------------------------------------------
1588
1618
  setTextSource(g) {
1589
- I(this, v) ? I(this, v).postMessage({ type: "setTextSource", opts: g }) : I(this, M) ? I(this, M).setTextSource(g) : (l(this, rg, g), l(this, Lg, null));
1619
+ I(this, R) ? I(this, R).postMessage({ type: "setTextSource", opts: g }) : I(this, x) ? I(this, x).setTextSource(g) : (o(this, wg, g), o(this, Lg, null));
1590
1620
  }
1591
- setImageSource(g, C = Bg.effect, i = Bg.imageSize) {
1592
- if (I(this, v)) {
1621
+ setImageSource(g, C = ng.effect, i = ng.imageSize) {
1622
+ if (I(this, R)) {
1593
1623
  const s = new URL(g, location.href).href;
1594
- I(this, v).postMessage({ type: "setImageSource", src: s, effect: C, size: i });
1624
+ I(this, R).postMessage({ type: "setImageSource", src: s, effect: C, size: i });
1595
1625
  } else
1596
- I(this, M) ? I(this, M).setImageSource(g, C, i) : (l(this, Lg, { src: g, effect: C, size: i }), l(this, rg, null));
1626
+ I(this, x) ? I(this, x).setImageSource(g, C, i) : (o(this, Lg, { src: g, effect: C, size: i }), o(this, wg, null));
1597
1627
  }
1598
1628
  setBackground(g, C = "cover") {
1599
1629
  var i;
1600
- if (I(this, v)) {
1630
+ if (I(this, R)) {
1601
1631
  const s = g ? [g] : [];
1602
- I(this, v).postMessage({ type: "setBackground", bitmap: g ?? null, size: C }, s);
1632
+ I(this, R).postMessage({ type: "setBackground", bitmap: g ?? null, size: C }, s);
1603
1633
  } else
1604
- (i = I(this, M)) == null || i.setBackground(g ?? null, C);
1634
+ (i = I(this, x)) == null || i.setBackground(g ?? null, C);
1605
1635
  }
1606
1636
  // ---------------------------------------------------------------------------
1607
1637
  // Interaction
@@ -1610,336 +1640,348 @@ class vC {
1610
1640
  * Immediately injects one splat at (x, y) with explicit velocity (vx, vy).
1611
1641
  * Safe to call multiple times per frame. See FluidSimulation.splat for details.
1612
1642
  */
1613
- splat(g, C, i, s, t = 1) {
1614
- I(this, v) ? I(this, v).postMessage({ type: "splat", x: g, y: C, vx: i, vy: s, strength: t }) : I(this, M).splat(g, C, i, s, t);
1643
+ splat(g, C, i, s, l = 1) {
1644
+ I(this, R) ? I(this, R).postMessage({ type: "splat", x: g, y: C, vx: i, vy: s, strength: l }) : I(this, x).splat(g, C, i, s, l);
1615
1645
  }
1616
1646
  handleMove(g, C, i = 1) {
1617
- I(this, v) ? I(this, v).postMessage({ type: "move", x: g, y: C, strength: i }) : I(this, M).handleMove(g, C, i);
1647
+ I(this, R) ? I(this, R).postMessage({ type: "move", x: g, y: C, strength: i }) : I(this, x).handleMove(g, C, i);
1618
1648
  }
1619
1649
  // ---------------------------------------------------------------------------
1620
1650
  // Config + control
1621
1651
  // ---------------------------------------------------------------------------
1622
1652
  updateQuality(g) {
1623
- l(this, j, Math.max(0.1, Math.min(1, g.dpr ?? I(this, j)))), l(this, dg, Math.max(0.1, Math.min(1, g.sim ?? I(this, dg)))), I(this, v) ? I(this, v).postMessage({ type: "updateQuality", quality: { dpr: I(this, j), sim: I(this, dg) } }) : I(this, M).updateQuality(g);
1653
+ o(this, P, Math.max(0.1, Math.min(1, g.dpr ?? I(this, P)))), o(this, dg, Math.max(0.1, Math.min(1, g.sim ?? I(this, dg)))), I(this, R) ? I(this, R).postMessage({ type: "updateQuality", quality: { dpr: I(this, P), sim: I(this, dg) } }) : I(this, x).updateQuality(g);
1624
1654
  }
1625
1655
  updateConfig(g) {
1626
- I(this, v) ? I(this, v).postMessage({ type: "updateConfig", config: g }) : I(this, M).updateConfig(g);
1656
+ I(this, R) ? I(this, R).postMessage({ type: "updateConfig", config: g }) : I(this, x).updateConfig(g);
1627
1657
  }
1628
1658
  resize(g, C) {
1629
- const i = (typeof window < "u" && window.devicePixelRatio || 1) * I(this, j);
1630
- I(this, v) ? I(this, v).postMessage({ type: "resize", width: g, height: C, dpr: i }) : I(this, M).resize(g, C, i);
1659
+ const i = (typeof window < "u" && window.devicePixelRatio || 1) * I(this, P);
1660
+ I(this, R) ? I(this, R).postMessage({ type: "resize", width: g, height: C, dpr: i }) : I(this, x).resize(g, C, i);
1631
1661
  }
1632
1662
  destroy() {
1633
1663
  var g;
1634
- if (I(this, v)) {
1635
- const C = I(this, v);
1636
- l(this, v, null), C.postMessage({ type: "destroy" }), setTimeout(() => C.terminate(), 50);
1664
+ if (I(this, R)) {
1665
+ const C = I(this, R);
1666
+ o(this, R, null), C.postMessage({ type: "destroy" }), setTimeout(() => C.terminate(), 50);
1637
1667
  } else
1638
- (g = I(this, M)) == null || g.destroy(), l(this, M, null);
1668
+ (g = I(this, x)) == null || g.destroy(), o(this, x, null);
1639
1669
  }
1640
1670
  }
1641
- v = new WeakMap(), M = new WeakMap(), zg = new WeakMap(), Ng = new WeakMap(), j = new WeakMap(), dg = new WeakMap(), rg = new WeakMap(), Lg = new WeakMap(), eI = new WeakSet(), hI = function(g, C) {
1642
- const i = { dpr: I(this, j), sim: I(this, dg) };
1643
- I(this, Ng) && typeof navigator < "u" && !!navigator.gpu ? dI.create(g, C, i, !0).then((t) => {
1644
- if (l(this, M, t), I(this, rg))
1645
- t.setTextSource(I(this, rg)), l(this, rg, null);
1671
+ R = new WeakMap(), x = new WeakMap(), Og = new WeakMap(), Eg = new WeakMap(), Fg = new WeakMap(), P = new WeakMap(), dg = new WeakMap(), wg = new WeakMap(), Lg = new WeakMap(), tI = new WeakSet(), HI = function(g, C) {
1672
+ const i = { dpr: I(this, P), sim: I(this, dg) };
1673
+ I(this, Eg) && typeof navigator < "u" && !!navigator.gpu ? ZI.create(g, C, i, !0, I(this, Fg)).then((l) => {
1674
+ if (o(this, x, l), I(this, wg))
1675
+ l.setTextSource(I(this, wg)), o(this, wg, null);
1646
1676
  else if (I(this, Lg)) {
1647
- const { src: o, effect: a, size: u } = I(this, Lg);
1648
- t.setImageSource(o, a, u), l(this, Lg, null);
1677
+ const { src: t, effect: a, size: u } = I(this, Lg);
1678
+ l.setImageSource(t, a, u), o(this, Lg, null);
1649
1679
  }
1650
- }).catch((t) => {
1651
- console.error("[fluidity-js] Renderer init failed:", t);
1652
- }) : l(this, M, new dI(g, C, i));
1653
- }, ZI = new WeakSet(), QI = function(g, C) {
1654
- const i = (typeof window < "u" && window.devicePixelRatio || 1) * I(this, j), s = Math.round(g.clientWidth * i), t = Math.round(g.clientHeight * i);
1655
- g.width = s, g.height = t;
1656
- let o;
1680
+ }).catch((l) => {
1681
+ console.error("[fluidity-js] Renderer init failed:", l);
1682
+ }) : o(this, x, new ZI(g, C, i, void 0, I(this, Fg)));
1683
+ }, rI = new WeakSet(), PI = function(g, C) {
1684
+ const i = (typeof window < "u" && window.devicePixelRatio || 1) * I(this, P), s = Math.round(g.clientWidth * i), l = Math.round(g.clientHeight * i);
1685
+ g.width = s, g.height = l;
1686
+ let t;
1657
1687
  try {
1658
- o = g.transferControlToOffscreen();
1688
+ t = g.transferControlToOffscreen();
1659
1689
  } catch {
1660
1690
  console.warn(
1661
1691
  "[fluidity-js] OffscreenCanvas transfer failed — falling back to main-thread mode. This is expected in React StrictMode development."
1662
- ), l(this, zg, !1), h(this, eI, hI).call(this, g, C);
1692
+ ), o(this, Og, !1), h(this, tI, HI).call(this, g, C);
1663
1693
  return;
1664
1694
  }
1665
- const a = l(this, v, new XC());
1695
+ const a = o(this, R, new YC());
1666
1696
  a.onerror = (u) => {
1667
1697
  console.error("[fluidity-js] Worker error:", u.message);
1668
1698
  }, a.onmessage = (u) => {
1669
1699
  u.data.type === "error" && console.error("[fluidity-js] Simulation error:", u.data.message);
1670
1700
  }, a.postMessage(
1671
- { type: "init", canvas: o, width: s, height: t, config: C, dpr: i, quality: { dpr: I(this, j), sim: I(this, dg) }, useWebGPU: I(this, Ng) },
1672
- [o]
1701
+ { type: "init", canvas: t, width: s, height: l, config: C, dpr: i, quality: { dpr: I(this, P), sim: I(this, dg) }, useWebGPU: I(this, Eg), enableAlpha: I(this, Fg) },
1702
+ [t]
1673
1703
  );
1674
1704
  };
1675
- function OI(e, {
1705
+ function _I(e, {
1676
1706
  isWorkerEnabled: g = !0,
1677
1707
  useWebGPU: C = !0,
1678
- quality: i = {},
1679
- config: s = {}
1708
+ enableAlpha: i = !0,
1709
+ quality: s = {},
1710
+ config: l = {}
1680
1711
  } = {}) {
1681
- const t = Mg(null), o = Mg({ isWorkerEnabled: g, quality: i, config: s }), a = Mg(Math.max(0.1, Math.min(1, i.dpr ?? 1))), u = Mg({
1682
- dpr: i.dpr,
1683
- sim: i.sim
1712
+ const t = Tg(null), a = Tg({ isWorkerEnabled: g, quality: s, config: l }), u = Tg(Math.max(0.1, Math.min(1, s.dpr ?? 1))), c = Tg({
1713
+ dpr: s.dpr,
1714
+ sim: s.sim
1684
1715
  });
1685
- return eg(() => {
1686
- const A = e.current;
1687
- if (!A)
1716
+ return sg(() => {
1717
+ const Z = e.current;
1718
+ if (!Z)
1688
1719
  return;
1689
- const p = document.createElement("canvas");
1690
- p.id = `fluid_canvas_${Date.now()}`, p.style.cssText = "position:absolute;inset:0;width:100%;height:100%;display:block;", A.appendChild(p);
1691
- const { isWorkerEnabled: c, quality: d, config: Z } = o.current, m = (window.devicePixelRatio || 1) * a.current, w = A.getBoundingClientRect(), b = Math.round((w.width || A.clientWidth) * m) || 0, n = Math.round((w.height || A.clientHeight) * m) || 0;
1692
- b > 0 && (p.width = b, p.height = n), n === 0 && console.warn(
1720
+ const S = document.createElement("canvas");
1721
+ S.id = `fluid_canvas_${Date.now()}`, S.style.cssText = "position:absolute;inset:0;width:100%;height:100%;display:block;", Z.appendChild(S);
1722
+ const { isWorkerEnabled: A, quality: B, config: m } = a.current, r = (window.devicePixelRatio || 1) * u.current, L = Z.getBoundingClientRect(), G = Math.round((L.width || Z.clientWidth) * r) || 0, K = Math.round((L.height || Z.clientHeight) * r) || 0;
1723
+ G > 0 && (S.width = G, S.height = K), K === 0 && console.warn(
1693
1724
  "[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."
1694
1725
  );
1695
- const r = new vC(p, { isWorkerEnabled: c, useWebGPU: C, quality: d, config: Z });
1696
- t.current = r;
1697
- const R = new ResizeObserver((B) => {
1698
- for (const W of B) {
1699
- const G = (window.devicePixelRatio || 1) * a.current, { inlineSize: K, blockSize: U } = W.contentBoxSize[0];
1700
- r.resize(Math.round(K * G), Math.round(U * G));
1726
+ const b = new MC(S, {
1727
+ isWorkerEnabled: A,
1728
+ useWebGPU: C,
1729
+ enableAlpha: i,
1730
+ quality: B,
1731
+ config: m
1732
+ });
1733
+ t.current = b;
1734
+ const Y = new ResizeObserver((n) => {
1735
+ for (const F of n) {
1736
+ const p = (window.devicePixelRatio || 1) * u.current, { inlineSize: V, blockSize: W } = F.contentBoxSize[0];
1737
+ b.resize(Math.round(V * p), Math.round(W * p));
1701
1738
  }
1702
1739
  });
1703
- return R.observe(A), () => {
1704
- R.disconnect(), r.destroy(), p.remove(), t.current = null;
1740
+ return Y.observe(Z), () => {
1741
+ Y.disconnect(), b.destroy(), S.remove(), t.current = null;
1705
1742
  };
1706
- }, [C]), eg(() => {
1707
- a.current = Math.max(0.1, Math.min(1, i.dpr ?? 1));
1708
- const A = u.current;
1709
- u.current = { dpr: i.dpr, sim: i.sim };
1710
- const p = t.current, c = e.current;
1711
- if (!p || !c || A.dpr === i.dpr && A.sim === i.sim)
1743
+ }, [C, i]), sg(() => {
1744
+ u.current = Math.max(0.1, Math.min(1, s.dpr ?? 1));
1745
+ const Z = c.current;
1746
+ c.current = { dpr: s.dpr, sim: s.sim };
1747
+ const S = t.current, A = e.current;
1748
+ if (!S || !A || Z.dpr === s.dpr && Z.sim === s.sim)
1712
1749
  return;
1713
- p.updateQuality(i);
1714
- const d = (window.devicePixelRatio || 1) * a.current, Z = c.clientWidth, m = c.clientHeight;
1715
- Z > 0 && m > 0 && p.resize(Math.round(Z * d), Math.round(m * d));
1716
- }, [i.dpr, i.sim, C]), t;
1750
+ S.updateQuality(s);
1751
+ const B = (window.devicePixelRatio || 1) * u.current, m = A.clientWidth, r = A.clientHeight;
1752
+ m > 0 && r > 0 && S.resize(Math.round(m * B), Math.round(r * B));
1753
+ }, [s.dpr, s.sim, C, i]), t;
1717
1754
  }
1718
- const kC = kI(function({
1755
+ const DC = FI(function({
1719
1756
  text: g,
1720
- fontSize: C = Sg.fontSize,
1721
- color: i = Sg.color,
1722
- fontFamily: s = Sg.fontFamily,
1723
- fontWeight: t = Sg.fontWeight,
1724
- className: o,
1757
+ fontSize: C = ag.fontSize,
1758
+ color: i = ag.color,
1759
+ fontFamily: s = ag.fontFamily,
1760
+ fontWeight: l = ag.fontWeight,
1761
+ className: t,
1725
1762
  style: a,
1726
1763
  config: u,
1727
- preset: A,
1728
- algorithm: p,
1729
- backgroundColor: c = Sg.backgroundColor,
1730
- backgroundSrc: d,
1731
- backgroundSize: Z = Sg.backgroundSize,
1732
- isMouseEnabled: m = Sg.isMouseEnabled,
1733
- isWorkerEnabled: w = Sg.isWorkerEnabled,
1734
- useWebGPU: b = !0,
1735
- quality: n = mI.quality
1736
- }, r) {
1737
- const R = Mg(null), B = OI(R, {
1738
- isWorkerEnabled: w,
1739
- useWebGPU: b,
1740
- quality: n,
1741
- config: qg({ ...u, ...p ? { algorithm: p } : {} }, A, HI)
1764
+ preset: c,
1765
+ algorithm: Z,
1766
+ backgroundColor: S = ag.backgroundColor,
1767
+ backgroundSrc: A,
1768
+ backgroundSize: B = ag.backgroundSize,
1769
+ isMouseEnabled: m = ag.isMouseEnabled,
1770
+ isWorkerEnabled: r = ag.isWorkerEnabled,
1771
+ useWebGPU: L = !0,
1772
+ enableAlpha: G = !0,
1773
+ quality: K = wI.quality
1774
+ }, b) {
1775
+ const Y = Tg(null), n = _I(Y, {
1776
+ isWorkerEnabled: r,
1777
+ useWebGPU: L,
1778
+ enableAlpha: G,
1779
+ quality: K,
1780
+ config: II({ ...u, ...Z ? { algorithm: Z } : {} }, c, UI)
1742
1781
  });
1743
- xI(
1744
- r,
1782
+ DI(
1783
+ b,
1745
1784
  () => ({
1746
1785
  reset() {
1747
- var G;
1748
- (G = B.current) == null || G.setTextSource({ text: g, fontSize: C, color: i, fontFamily: s, fontWeight: t });
1786
+ var p;
1787
+ (p = n.current) == null || p.setTextSource({ text: g, fontSize: C, color: i, fontFamily: s, fontWeight: l });
1749
1788
  },
1750
- move(G, K, U = 1) {
1751
- var Y;
1752
- (Y = B.current) == null || Y.handleMove(G, K, U);
1789
+ move(p, V, W = 1) {
1790
+ var U;
1791
+ (U = n.current) == null || U.handleMove(p, V, W);
1753
1792
  },
1754
- splat(G, K, U, Y, P = 1) {
1755
- var cg;
1756
- (cg = B.current) == null || cg.splat(G, K, U, Y, P);
1793
+ splat(p, V, W, U, _ = 1) {
1794
+ var Sg;
1795
+ (Sg = n.current) == null || Sg.splat(p, V, W, U, _);
1757
1796
  },
1758
- updateConfig(G) {
1759
- var K;
1760
- (K = B.current) == null || K.updateConfig(G);
1797
+ updateConfig(p) {
1798
+ var V;
1799
+ (V = n.current) == null || V.updateConfig(p);
1761
1800
  }
1762
1801
  }),
1763
- [g, C, i, s, t]
1764
- ), eg(() => {
1765
- var G;
1766
- (G = B.current) == null || G.setTextSource({ text: g, fontSize: C, color: i, fontFamily: s, fontWeight: t });
1767
- }, [g, C, i, s, t, b]);
1768
- const W = JSON.stringify(u);
1769
- return eg(() => {
1770
- var G;
1771
- (G = B.current) == null || G.updateConfig(
1772
- qg({ ...u, ...p !== void 0 ? { algorithm: p } : {} }, A, HI)
1802
+ [g, C, i, s, l]
1803
+ ), sg(() => {
1804
+ var p;
1805
+ (p = n.current) == null || p.setTextSource({ text: g, fontSize: C, color: i, fontFamily: s, fontWeight: l });
1806
+ }, [g, C, i, s, l, L, G]);
1807
+ const F = JSON.stringify(u);
1808
+ return sg(() => {
1809
+ var p;
1810
+ (p = n.current) == null || p.updateConfig(
1811
+ II({ ...u, ...Z !== void 0 ? { algorithm: Z } : {} }, c, UI)
1773
1812
  );
1774
- }, [A, p, W, b]), eg(() => {
1775
- var K;
1776
- if (!d) {
1777
- (K = B.current) == null || K.setBackground(null);
1813
+ }, [c, Z, F, L, G]), sg(() => {
1814
+ var V;
1815
+ if (!A) {
1816
+ (V = n.current) == null || V.setBackground(null);
1778
1817
  return;
1779
1818
  }
1780
- let G = !1;
1781
- return KI(d).then((U) => {
1782
- var Y;
1783
- if (G) {
1784
- U.close();
1819
+ let p = !1;
1820
+ return XI(A).then((W) => {
1821
+ var U;
1822
+ if (p) {
1823
+ W.close();
1785
1824
  return;
1786
1825
  }
1787
- (Y = B.current) == null || Y.setBackground(U, Z);
1788
- }).catch((U) => console.error("[fluidity-js] backgroundSrc load failed:", U)), () => {
1789
- G = !0;
1826
+ (U = n.current) == null || U.setBackground(W, B);
1827
+ }).catch((W) => console.error("[fluidity-js] backgroundSrc load failed:", W)), () => {
1828
+ p = !0;
1790
1829
  };
1791
- }, [d, Z, b]), eg(() => {
1830
+ }, [A, B, L, G]), sg(() => {
1792
1831
  if (!m)
1793
1832
  return;
1794
- const G = R.current;
1795
- if (!G)
1833
+ const p = Y.current;
1834
+ if (!p)
1796
1835
  return;
1797
- const K = (Y) => {
1798
- var cg;
1799
- const P = G.getBoundingClientRect();
1800
- (cg = B.current) == null || cg.handleMove(Y.clientX - P.left, Y.clientY - P.top, 2);
1801
- }, U = (Y) => {
1802
- var VI;
1803
- Y.preventDefault();
1804
- const P = G.getBoundingClientRect(), cg = Y.touches[0];
1805
- (VI = B.current) == null || VI.handleMove(cg.clientX - P.left, cg.clientY - P.top, 1);
1836
+ const V = (U) => {
1837
+ var Sg;
1838
+ const _ = p.getBoundingClientRect();
1839
+ (Sg = n.current) == null || Sg.handleMove(U.clientX - _.left, U.clientY - _.top, 2);
1840
+ }, W = (U) => {
1841
+ var RI;
1842
+ U.preventDefault();
1843
+ const _ = p.getBoundingClientRect(), Sg = U.touches[0];
1844
+ (RI = n.current) == null || RI.handleMove(Sg.clientX - _.left, Sg.clientY - _.top, 1);
1806
1845
  };
1807
- return G.addEventListener("mousemove", K), G.addEventListener("touchmove", U, { passive: !1 }), () => {
1808
- G.removeEventListener("mousemove", K), G.removeEventListener("touchmove", U);
1846
+ return p.addEventListener("mousemove", V), p.addEventListener("touchmove", W, { passive: !1 }), () => {
1847
+ p.removeEventListener("mousemove", V), p.removeEventListener("touchmove", W);
1809
1848
  };
1810
- }, [m]), /* @__PURE__ */ UI(
1849
+ }, [m]), /* @__PURE__ */ xI(
1811
1850
  "div",
1812
1851
  {
1813
- ref: R,
1814
- className: o,
1852
+ ref: Y,
1853
+ className: t,
1815
1854
  style: {
1816
1855
  position: "relative",
1817
1856
  display: "block",
1818
1857
  width: "100%",
1819
1858
  height: "100%",
1820
- background: c,
1859
+ background: S,
1821
1860
  ...a
1822
1861
  }
1823
1862
  }
1824
1863
  );
1825
- }), xC = kI(function({
1864
+ }), TC = FI(function({
1826
1865
  src: g,
1827
- effect: C = Bg.effect,
1828
- imageSize: i = Bg.imageSize,
1866
+ effect: C = ng.effect,
1867
+ imageSize: i = ng.imageSize,
1829
1868
  className: s,
1830
- style: t,
1831
- config: o,
1869
+ style: l,
1870
+ config: t,
1832
1871
  preset: a,
1833
1872
  algorithm: u,
1834
- backgroundColor: A = Bg.backgroundColor,
1835
- backgroundSrc: p,
1836
- backgroundSize: c = Bg.backgroundSize,
1837
- isMouseEnabled: d = Bg.isMouseEnabled,
1838
- isWorkerEnabled: Z = Bg.isWorkerEnabled,
1873
+ backgroundColor: c = ng.backgroundColor,
1874
+ backgroundSrc: Z,
1875
+ backgroundSize: S = ng.backgroundSize,
1876
+ isMouseEnabled: A = ng.isMouseEnabled,
1877
+ isWorkerEnabled: B = ng.isWorkerEnabled,
1839
1878
  useWebGPU: m = !0,
1840
- quality: w = mI.quality
1841
- }, b) {
1842
- const n = Mg(null), r = OI(n, {
1843
- isWorkerEnabled: Z,
1879
+ enableAlpha: r = !0,
1880
+ quality: L = wI.quality
1881
+ }, G) {
1882
+ const K = Tg(null), b = _I(K, {
1883
+ isWorkerEnabled: B,
1844
1884
  useWebGPU: m,
1845
- quality: w,
1846
- config: qg({ ...o, ...u ? { algorithm: u } : {} }, a)
1885
+ enableAlpha: r,
1886
+ quality: L,
1887
+ config: II({ ...t, ...u ? { algorithm: u } : {} }, a)
1847
1888
  });
1848
- xI(
1849
- b,
1889
+ DI(
1890
+ G,
1850
1891
  () => ({
1851
1892
  reset() {
1852
- var B;
1853
- g && ((B = r.current) == null || B.setImageSource(g, C, i));
1893
+ var n;
1894
+ g && ((n = b.current) == null || n.setImageSource(g, C, i));
1854
1895
  },
1855
- move(B, W, G = 1) {
1856
- var K;
1857
- (K = r.current) == null || K.handleMove(B, W, G);
1896
+ move(n, F, p = 1) {
1897
+ var V;
1898
+ (V = b.current) == null || V.handleMove(n, F, p);
1858
1899
  },
1859
- splat(B, W, G, K, U = 1) {
1860
- var Y;
1861
- (Y = r.current) == null || Y.splat(B, W, G, K, U);
1900
+ splat(n, F, p, V, W = 1) {
1901
+ var U;
1902
+ (U = b.current) == null || U.splat(n, F, p, V, W);
1862
1903
  },
1863
- updateConfig(B) {
1864
- var W;
1865
- (W = r.current) == null || W.updateConfig(B);
1904
+ updateConfig(n) {
1905
+ var F;
1906
+ (F = b.current) == null || F.updateConfig(n);
1866
1907
  }
1867
1908
  }),
1868
1909
  [g, C, i]
1869
- ), eg(() => {
1870
- var B;
1871
- g && ((B = r.current) == null || B.setImageSource(g, C, i));
1872
- }, [g, C, i, m]);
1873
- const R = JSON.stringify(o);
1874
- return eg(() => {
1875
- var B;
1876
- (B = r.current) == null || B.updateConfig(
1877
- qg({ ...o, ...u !== void 0 ? { algorithm: u } : {} }, a)
1910
+ ), sg(() => {
1911
+ var n;
1912
+ g && ((n = b.current) == null || n.setImageSource(g, C, i));
1913
+ }, [g, C, i, m, r]);
1914
+ const Y = JSON.stringify(t);
1915
+ return sg(() => {
1916
+ var n;
1917
+ (n = b.current) == null || n.updateConfig(
1918
+ II({ ...t, ...u !== void 0 ? { algorithm: u } : {} }, a)
1878
1919
  );
1879
- }, [a, u, R, m]), eg(() => {
1880
- var W;
1881
- if (!p) {
1882
- (W = r.current) == null || W.setBackground(null);
1920
+ }, [a, u, Y, m, r]), sg(() => {
1921
+ var F;
1922
+ if (!Z) {
1923
+ (F = b.current) == null || F.setBackground(null);
1883
1924
  return;
1884
1925
  }
1885
- let B = !1;
1886
- return KI(p).then((G) => {
1887
- var K;
1888
- if (B) {
1889
- G.close();
1926
+ let n = !1;
1927
+ return XI(Z).then((p) => {
1928
+ var V;
1929
+ if (n) {
1930
+ p.close();
1890
1931
  return;
1891
1932
  }
1892
- (K = r.current) == null || K.setBackground(G, c);
1893
- }).catch((G) => console.error("[fluidity-js] backgroundSrc load failed:", G)), () => {
1894
- B = !0;
1933
+ (V = b.current) == null || V.setBackground(p, S);
1934
+ }).catch((p) => console.error("[fluidity-js] backgroundSrc load failed:", p)), () => {
1935
+ n = !0;
1895
1936
  };
1896
- }, [p, c, m]), eg(() => {
1897
- if (!d)
1937
+ }, [Z, S, m, r]), sg(() => {
1938
+ if (!A)
1898
1939
  return;
1899
- const B = n.current;
1900
- if (!B)
1940
+ const n = K.current;
1941
+ if (!n)
1901
1942
  return;
1902
- const W = (K) => {
1903
- var Y;
1904
- const U = B.getBoundingClientRect();
1905
- (Y = r.current) == null || Y.handleMove(K.clientX - U.left, K.clientY - U.top, 2);
1906
- }, G = (K) => {
1907
- var P;
1908
- K.preventDefault();
1909
- const U = B.getBoundingClientRect(), Y = K.touches[0];
1910
- (P = r.current) == null || P.handleMove(Y.clientX - U.left, Y.clientY - U.top, 1);
1943
+ const F = (V) => {
1944
+ var U;
1945
+ const W = n.getBoundingClientRect();
1946
+ (U = b.current) == null || U.handleMove(V.clientX - W.left, V.clientY - W.top, 2);
1947
+ }, p = (V) => {
1948
+ var _;
1949
+ V.preventDefault();
1950
+ const W = n.getBoundingClientRect(), U = V.touches[0];
1951
+ (_ = b.current) == null || _.handleMove(U.clientX - W.left, U.clientY - W.top, 1);
1911
1952
  };
1912
- return B.addEventListener("mousemove", W), B.addEventListener("touchmove", G, { passive: !1 }), () => {
1913
- B.removeEventListener("mousemove", W), B.removeEventListener("touchmove", G);
1953
+ return n.addEventListener("mousemove", F), n.addEventListener("touchmove", p, { passive: !1 }), () => {
1954
+ n.removeEventListener("mousemove", F), n.removeEventListener("touchmove", p);
1914
1955
  };
1915
- }, [d]), /* @__PURE__ */ UI(
1956
+ }, [A]), /* @__PURE__ */ xI(
1916
1957
  "div",
1917
1958
  {
1918
- ref: n,
1959
+ ref: K,
1919
1960
  className: s,
1920
1961
  style: {
1921
1962
  position: "relative",
1922
1963
  display: "block",
1923
1964
  width: "100%",
1924
1965
  height: "100%",
1925
- background: A,
1926
- ...t
1966
+ background: c,
1967
+ ...l
1927
1968
  }
1928
1969
  }
1929
1970
  );
1930
1971
  });
1931
1972
  export {
1932
- fI as DEFAULT_CONFIG,
1933
- HI as DEFAULT_CONFIG_TEXT,
1934
- Bg as DEFAULT_PROPS_IMAGE,
1935
- mI as DEFAULT_PROPS_SHARED,
1936
- Sg as DEFAULT_PROPS_TEXT,
1937
- vC as FluidController,
1938
- xC as FluidImage,
1939
- dI as FluidSimulation,
1940
- kC as FluidText,
1941
- _I as PRESETS,
1942
- KI as loadImageBitmap,
1943
- qg as mergeConfig,
1944
- OI as useFluid
1973
+ TI as DEFAULT_CONFIG,
1974
+ UI as DEFAULT_CONFIG_TEXT,
1975
+ ng as DEFAULT_PROPS_IMAGE,
1976
+ wI as DEFAULT_PROPS_SHARED,
1977
+ ag as DEFAULT_PROPS_TEXT,
1978
+ MC as FluidController,
1979
+ TC as FluidImage,
1980
+ ZI as FluidSimulation,
1981
+ DC as FluidText,
1982
+ IC as PRESETS,
1983
+ XI as loadImageBitmap,
1984
+ II as mergeConfig,
1985
+ AI as parseColor,
1986
+ _I as useFluid
1945
1987
  };