peeksafe 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/CHANGELOG.md +325 -0
  2. package/LICENSE +190 -0
  3. package/NOTICE +78 -0
  4. package/README.md +490 -2
  5. package/RESEARCH-NOTES.md +274 -0
  6. package/dist/baseline.d.ts +45 -0
  7. package/dist/baseline.d.ts.map +1 -0
  8. package/dist/baseline.js +49 -0
  9. package/dist/baseline.js.map +1 -0
  10. package/dist/check.d.ts +64 -0
  11. package/dist/check.d.ts.map +1 -0
  12. package/dist/check.js +172 -0
  13. package/dist/check.js.map +1 -0
  14. package/dist/cluster.d.ts +328 -0
  15. package/dist/cluster.d.ts.map +1 -0
  16. package/dist/cluster.js +606 -0
  17. package/dist/cluster.js.map +1 -0
  18. package/dist/errors.d.ts +108 -0
  19. package/dist/errors.d.ts.map +1 -0
  20. package/dist/errors.js +192 -0
  21. package/dist/errors.js.map +1 -0
  22. package/dist/evidence.d.ts +15 -0
  23. package/dist/evidence.d.ts.map +1 -0
  24. package/dist/evidence.js +30 -0
  25. package/dist/evidence.js.map +1 -0
  26. package/dist/frontier.d.ts +271 -0
  27. package/dist/frontier.d.ts.map +1 -0
  28. package/dist/frontier.js +505 -0
  29. package/dist/frontier.js.map +1 -0
  30. package/dist/gate.d.ts +175 -0
  31. package/dist/gate.d.ts.map +1 -0
  32. package/dist/gate.js +200 -0
  33. package/dist/gate.js.map +1 -0
  34. package/dist/index.d.ts +60 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +79 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/plan.d.ts +280 -0
  39. package/dist/plan.d.ts.map +1 -0
  40. package/dist/plan.js +626 -0
  41. package/dist/plan.js.map +1 -0
  42. package/dist/rand.d.ts +17 -0
  43. package/dist/rand.d.ts.map +1 -0
  44. package/dist/rand.js +104 -0
  45. package/dist/rand.js.map +1 -0
  46. package/dist/stats.d.ts +401 -0
  47. package/dist/stats.d.ts.map +1 -0
  48. package/dist/stats.js +1304 -0
  49. package/dist/stats.js.map +1 -0
  50. package/dist/stop.d.ts +164 -0
  51. package/dist/stop.d.ts.map +1 -0
  52. package/dist/stop.js +270 -0
  53. package/dist/stop.js.map +1 -0
  54. package/package.json +62 -3
  55. package/src/baseline.ts +72 -0
  56. package/src/check.ts +238 -0
  57. package/src/cluster.ts +842 -0
  58. package/src/errors.ts +275 -0
  59. package/src/evidence.ts +62 -0
  60. package/src/frontier.ts +837 -0
  61. package/src/gate.ts +363 -0
  62. package/src/index.ts +206 -0
  63. package/src/plan.ts +968 -0
  64. package/src/rand.ts +137 -0
  65. package/src/stats.ts +1663 -0
  66. package/src/stop.ts +464 -0
@@ -0,0 +1,606 @@
1
+ /**
2
+ * cluster.ts: the suite-level effect, with the cases treated as what they are.
3
+ *
4
+ * ## The bug this module exists to fix
5
+ *
6
+ * The obvious summary of a suite effect is an ordinary normal interval over the
7
+ * per-case differences:
8
+ *
9
+ * mean ± 1.96 · sd / √n with n = 200 cases
10
+ *
11
+ * That formula is only correct if the 200 numbers are 200 independent draws.
12
+ * They usually are not. A suite of **40 case files, each expanded into 5
13
+ * variants**, is typical: `extract.pricing#saas` and `extract.pricing#api`
14
+ * share a prompt template, a grader, an expectation shape and a failure mode.
15
+ * When one moves, its four siblings move with it. The effective number of
16
+ * independent observations is closer to 40 than to 200, the true standard error
17
+ * is larger than √(s²/200), and the reported interval is **too narrow**.
18
+ *
19
+ * A too-narrow interval on the headline number is the exact failure this whole
20
+ * package exists to prevent, so it gets a proper estimator rather than a fudge
21
+ * factor.
22
+ *
23
+ * ## What is estimated here, and what is not
24
+ *
25
+ * Clustering touches **only the suite-level (and family-level) summary**.
26
+ * Specifically:
27
+ *
28
+ * affected the across-case mean difference and its interval
29
+ * (`clusteredEffect`), plus any family-level roll-up.
30
+ *
31
+ * NOT affected every per-case quantity. Each case's e-value is its own
32
+ * self-contained test on that case's own runs; nothing about
33
+ * case *A* enters case *B*'s likelihood ratio. And the
34
+ * multiplicity correction is **e-BH**, which controls FDR under
35
+ * *arbitrary* dependence between the tested hypotheses, that
36
+ * is the whole reason it was chosen over BH. So `gate`'s
37
+ * verdict, its regressed cases and its thresholds are all
38
+ * bit-for-bit identical whether or not the cases cluster.
39
+ *
40
+ * In other words: clustering makes the *description* honest. It does not, and
41
+ * must not, move the *decision*.
42
+ *
43
+ * ## Two estimators, because they fail in different directions
44
+ *
45
+ * **CR2 (the headline).** A cluster-robust sandwich with the Bell-McCaffrey
46
+ * bias reduction. For the intercept-only model that a mean is, the hat matrix
47
+ * is H = J/n, so each cluster's leverage block is (I − J_{n_g}/n) and the CR2
48
+ * adjustment `A_g = (I − H_gg)^{-1/2}` collapses to a scalar on the cluster's
49
+ * residual sum:
50
+ *
51
+ * Var̂(ȳ) = (1/n²) · Σ_g (Σ_{i∈g} ê_i)² / (1 − n_g/n)
52
+ *
53
+ * Assumption-light: it needs the *families* to be independent of each other and
54
+ * nothing at all about the correlation structure *inside* a family. It does not
55
+ * assume the family effects are normal, or exchangeable, or even
56
+ * identically distributed. Paired with Bell-McCaffrey/Satterthwaite degrees of
57
+ * freedom (which, for equal-sized families, reduce exactly to G − 1; see the
58
+ * derivation in the comment above `dfRaw` below) it is the estimator you want
59
+ * when there are 40 clusters rather than 4,000.
60
+ *
61
+ * **Random effects (the cross-check).** The one-way model
62
+ * y_gi = μ + u_g + e_gi with the ANOVA (Swamy-Arora) estimators for τ² and σ².
63
+ * More efficient *if* its assumptions hold, and it yields the number that
64
+ * actually explains the width change: the intra-class correlation
65
+ * ρ = τ²/(τ² + σ²). If the two estimators disagree materially, that is itself
66
+ * information, and `compareEstimators` says so rather than picking a winner.
67
+ *
68
+ * ## The design effect
69
+ *
70
+ * `designEffect` = (clustered SE / naive iid SE)². It is the factor by which
71
+ * the naive analysis overstated its own information, "these 200 cases carry
72
+ * the information of 200/DEFF independent ones". For roughly equal families of
73
+ * size k it tracks the textbook 1 + (k − 1)ρ, which is the sanity check the
74
+ * tests assert.
75
+ */
76
+ import { PeeksafeError } from "./errors.js";
77
+ import { normalQuantile, tQuantile } from "./stats.js";
78
+ /* ────────────────────────── the clustering key ───────────────────────── */
79
+ /**
80
+ * The cluster a case belongs to: its **case file**.
81
+ *
82
+ * Variant ids are expected as `<fileId>#<variant>`, so everything before
83
+ * the first `#` is the file, and the file is the unit an author actually wrote.
84
+ * A case with no `#` is its own family of one, which is correct, not a
85
+ * degenerate case: an unexpanded case file shares its template with nobody.
86
+ */
87
+ export function caseFamily(caseId) {
88
+ const i = caseId.indexOf("#");
89
+ return i < 0 ? caseId : caseId.slice(0, i);
90
+ }
91
+ /**
92
+ * The cluster key for a case: the one it **declares**, or its case file.
93
+ *
94
+ * `caseFamily` sees exactly one reason two cases correlate, that they were
95
+ * minted from the same file, and is blind to every other: a shared grader, a
96
+ * shared fixture directory, one flaky tool that six unrelated cases happen to
97
+ * call. Those cases are correlated too, and the interval will be too narrow
98
+ * again for a reason the id cannot express. So a case may declare its own key.
99
+ *
100
+ * A wrong key is worse than no key, which is why `clusterKeyDiagnostic` ships
101
+ * alongside: declaring two genuinely independent cases into one family throws
102
+ * away real information and widens the interval for nothing, and the only way
103
+ * to know is to look at the ICC the declared grouping actually exhibits.
104
+ */
105
+ export const clusterKey = (c) => {
106
+ // Trimmed, so `cluster: " "` is not a distinct family that silently merges
107
+ // every case that has one. An all-whitespace key is no key.
108
+ const declared = c.cluster?.trim();
109
+ return declared ? declared : caseFamily(c.id);
110
+ };
111
+ // Called before the early returns, which never reach a quantile, so every suite refuses the same level.
112
+ function requireLevel(level, where) {
113
+ if (!(level > 0 && level < 1)) {
114
+ throw new PeeksafeError("PEEKSAFE_E_STAT_DOMAIN", `${where}: level must be in (0,1), got ${level}`, {
115
+ detail: { level },
116
+ hint: "a two-sided confidence level such as 0.95, not a percentage and not an error budget",
117
+ });
118
+ }
119
+ }
120
+ /** Group observations by cluster, preserving first-seen order. */
121
+ export function groupByCluster(obs) {
122
+ const m = new Map();
123
+ for (const o of obs) {
124
+ if (!Number.isFinite(o.value)) {
125
+ throw new PeeksafeError("PEEKSAFE_E_STAT_DOMAIN", `clustered mean: value for cluster "${o.cluster}" is not finite`, {
126
+ detail: { cluster: o.cluster, value: o.value },
127
+ });
128
+ }
129
+ const xs = m.get(o.cluster);
130
+ if (xs)
131
+ xs.push(o.value);
132
+ else
133
+ m.set(o.cluster, [o.value]);
134
+ }
135
+ return m;
136
+ }
137
+ /** The naive iid interval, kept so the two can be printed side by side. */
138
+ export function iidMean(values, level = 0.95) {
139
+ requireLevel(level, "iidMean");
140
+ // groupByCluster refused these for the other estimators, so the same data was an error there and a NaN interval here.
141
+ for (let i = 0; i < values.length; i++) {
142
+ if (!Number.isFinite(values[i])) {
143
+ throw new PeeksafeError("PEEKSAFE_E_STAT_DOMAIN", `iidMean: value at index ${i} is not finite`, {
144
+ detail: { index: i, value: values[i] },
145
+ });
146
+ }
147
+ }
148
+ const n = values.length;
149
+ if (n === 0)
150
+ return { low: -1, high: 1, point: 0, observations: 0 };
151
+ const mean = values.reduce((a, b) => a + b, 0) / n;
152
+ const sd = n > 1 ? Math.sqrt(values.reduce((a, x) => a + (x - mean) ** 2, 0) / (n - 1)) : 0;
153
+ const z = normalQuantile(1 - (1 - level) / 2);
154
+ const half = (z * sd) / Math.sqrt(n);
155
+ return { low: mean - half, high: mean + half, point: mean, observations: n };
156
+ }
157
+ /**
158
+ * CR2 cluster-robust interval for a mean, with Bell-McCaffrey degrees of
159
+ * freedom. See the module header for the derivation; the short version is that
160
+ * for an intercept-only design the whole apparatus collapses to
161
+ *
162
+ * Var̂ = (1/n²) Σ_g (Σ_{i∈g} ê_i)² / (1 − n_g/n)
163
+ *
164
+ * and the Satterthwaite df to a closed form in the cluster sizes alone.
165
+ */
166
+ export function clusterRobustMean(obs, level = 0.95) {
167
+ requireLevel(level, "clusterRobustMean");
168
+ const groups = groupByCluster(obs);
169
+ const n = obs.length;
170
+ const G = groups.size;
171
+ const sizes = [...groups.values()].map((xs) => xs.length);
172
+ const naive = iidMean(obs.map((o) => o.value), level);
173
+ const naiveSe = n > 1 ? Math.sqrt(obs.reduce((a, o) => a + (o.value - naive.point) ** 2, 0) / (n - 1) / n) : 0;
174
+ const base = {
175
+ point: naive.point,
176
+ observations: n,
177
+ clusters: G,
178
+ largestCluster: sizes.length ? Math.max(...sizes) : 0,
179
+ meanClusterSize: G > 0 ? n / G : 0,
180
+ naiveSe,
181
+ method: "CR2",
182
+ };
183
+ // One cluster is one observation. There is nothing to average over, so there
184
+ // is no standard error, and saying "±0.4 points" here would be exactly the
185
+ // fabricated-precision failure this module was written to remove.
186
+ if (n === 0 || G < 2) {
187
+ return {
188
+ ...base,
189
+ low: -1,
190
+ high: 1,
191
+ se: Infinity,
192
+ designEffect: Infinity,
193
+ widthRatio: Infinity,
194
+ df: 0,
195
+ tCritical: Infinity,
196
+ effectiveSampleSize: G,
197
+ degenerate: n === 0
198
+ ? "no cases contributed an estimate"
199
+ : `all ${n} cases belong to one family ("${[...groups.keys()][0]}"), a single cluster carries no ` +
200
+ "information about between-family variation, so no interval is estimable",
201
+ };
202
+ }
203
+ const mean = base.point;
204
+ let meat = 0;
205
+ for (const xs of groups.values()) {
206
+ const sumRes = xs.reduce((a, x) => a + (x - mean), 0);
207
+ const leverage = 1 - xs.length / n; // > 0 because G ≥ 2
208
+ meat += (sumRes * sumRes) / leverage;
209
+ }
210
+ const variance = meat / (n * n);
211
+ const se = Math.sqrt(variance);
212
+ // Bell-McCaffrey / Satterthwaite df. With g_g = M b_g the closed forms are
213
+ // tr(G) = Σ n_g/n² = 1/n
214
+ // tr(G²) = Σ_g (n_g/n²)² + Σ_{g≠h} (n_g n_h)² / (n⁶ (1−n_g/n)(1−n_h/n))
215
+ // and df = tr(G)² / tr(G²). For equal cluster sizes this is exactly G − 1.
216
+ const n2 = n * n;
217
+ let trG2 = 0;
218
+ for (let i = 0; i < G; i++) {
219
+ const ni = sizes[i];
220
+ trG2 += (ni / n2) ** 2;
221
+ for (let j = 0; j < G; j++) {
222
+ if (i === j)
223
+ continue;
224
+ const nj = sizes[j];
225
+ const denom = (1 - ni / n) * (1 - nj / n);
226
+ trG2 += (ni * nj) ** 2 / (n2 * n2 * n2 * denom);
227
+ }
228
+ }
229
+ const trG = 1 / n;
230
+ const dfRaw = trG2 > 0 ? (trG * trG) / trG2 : G - 1;
231
+ const df = Math.min(n - 1, Math.max(1, dfRaw));
232
+ const t = tQuantile(1 - (1 - level) / 2, df);
233
+ const half = t * se;
234
+ const z = normalQuantile(1 - (1 - level) / 2);
235
+ const naiveHalf = z * naiveSe;
236
+ return {
237
+ ...base,
238
+ low: mean - half,
239
+ high: mean + half,
240
+ se,
241
+ designEffect: naiveSe > 0 ? (se / naiveSe) ** 2 : se > 0 ? Infinity : 1,
242
+ widthRatio: naiveHalf > 0 ? half / naiveHalf : half > 0 ? Infinity : 1,
243
+ df,
244
+ tCritical: t,
245
+ // n / DEFF, **capped at n**. When the families happen to disagree less than
246
+ // the cases within them, the CR2 standard error lands below the iid one and
247
+ // DEFF comes out under 1, a finite-sample fact about this sample, not
248
+ // information the clustering created. Uncapped, this read "worth
249
+ // 222 independent cases / 200", which claims a suite of 200 carries more
250
+ // than 200 cases' worth of evidence. It does not. The design effect itself
251
+ // is reported unclamped, because *that* number is the estimate.
252
+ effectiveSampleSize: naiveSe > 0 ? Math.min(n, n / Math.max(1e-12, (se / naiveSe) ** 2)) : n,
253
+ degenerate: null,
254
+ };
255
+ }
256
+ /**
257
+ * One-way random-effects (hierarchical) estimate of the same mean.
258
+ *
259
+ * y_gi = μ + u_g + e_gi, u_g ~ (0, τ²), e_gi ~ (0, σ²)
260
+ *
261
+ * τ² and σ² come from the ANOVA decomposition (the Swamy-Arora estimator,
262
+ * unbiased and closed-form, and it does not need the normality that REML would
263
+ * lean on). μ̂ is the GLS weighted mean of the family means with
264
+ * w_g = 1/(τ² + σ²/n_g), so its variance is 1/Σw_g.
265
+ *
266
+ * Two properties worth knowing before trusting it:
267
+ * - at τ̂² = 0 it degenerates **exactly** to the naive iid interval, which is
268
+ * the correct behaviour: no between-family variance means the cases really
269
+ * were exchangeable;
270
+ * - it weights families by information rather than by size, so unlike the
271
+ * unweighted mean it is not the same point estimate as CR2 when families
272
+ * differ in size. That difference is a feature and it is reported.
273
+ */
274
+ export function randomEffectsMean(obs, level = 0.95) {
275
+ requireLevel(level, "randomEffectsMean");
276
+ const groups = groupByCluster(obs);
277
+ const n = obs.length;
278
+ const G = groups.size;
279
+ const grand = n > 0 ? obs.reduce((a, o) => a + o.value, 0) / n : 0;
280
+ const shell = {
281
+ observations: n,
282
+ clusters: G,
283
+ method: "random-effects",
284
+ };
285
+ if (n === 0 || G < 2) {
286
+ return {
287
+ ...shell,
288
+ point: grand,
289
+ low: -1,
290
+ high: 1,
291
+ tauSquared: 0,
292
+ sigmaSquared: 0,
293
+ icc: 0,
294
+ se: Infinity,
295
+ df: 0,
296
+ degenerate: n === 0 ? "no cases contributed an estimate" : "a single family cannot separate τ² from σ²",
297
+ };
298
+ }
299
+ const entries = [...groups.entries()].map(([k, xs]) => ({
300
+ key: k,
301
+ size: xs.length,
302
+ mean: xs.reduce((a, x) => a + x, 0) / xs.length,
303
+ values: xs,
304
+ }));
305
+ let ssw = 0;
306
+ let ssb = 0;
307
+ for (const g of entries) {
308
+ for (const x of g.values)
309
+ ssw += (x - g.mean) ** 2;
310
+ ssb += g.size * (g.mean - grand) ** 2;
311
+ }
312
+ const dfW = n - G;
313
+ const dfB = G - 1;
314
+ // Every family has exactly one member: there is no within-family replication,
315
+ // so σ² is not identified, and there is also no clustering left to correct
316
+ // for. The iid interval is then the right answer, not an approximation.
317
+ if (dfW === 0) {
318
+ const iid = iidMean(obs.map((o) => o.value), level);
319
+ return {
320
+ ...shell,
321
+ point: iid.point,
322
+ low: iid.low,
323
+ high: iid.high,
324
+ tauSquared: dfB > 0 ? ssb / dfB : 0,
325
+ sigmaSquared: 0,
326
+ icc: 1,
327
+ se: dfB > 0 ? Math.sqrt(ssb / dfB / n) : 0,
328
+ df: dfB,
329
+ degenerate: "every family has exactly one case, no within-family replication, so σ² is not identified " +
330
+ "and the observations are already independent",
331
+ };
332
+ }
333
+ const msw = ssw / dfW;
334
+ const msb = ssb / dfB;
335
+ // k₀: the "average" cluster size the ANOVA estimator divides by. Equals the
336
+ // common size when families are balanced.
337
+ const sumSq = entries.reduce((a, g) => a + g.size * g.size, 0);
338
+ const k0 = (n - sumSq / n) / dfB;
339
+ const sigmaSquared = msw;
340
+ const tauSquared = k0 > 0 ? Math.max(0, (msb - msw) / k0) : 0;
341
+ // Neither variance component is positive, so every case took the same value.
342
+ // The GLS weight 1/(τ² + σ²/n_g) is then 1/0 for every family, the total
343
+ // weight is Infinity, and the weighted mean came out Infinity/Infinity, i.e.
344
+ // NaN, with `degenerate` left null, which says the estimate was formed. A
345
+ // pull request that moved nothing produces exactly this: every per-case
346
+ // difference is zero. CR2 and the iid interval both answer the grand mean
347
+ // with a zero-width interval here, and so does this.
348
+ if (!(tauSquared + sigmaSquared > 0)) {
349
+ return {
350
+ ...shell,
351
+ point: grand,
352
+ low: grand,
353
+ high: grand,
354
+ tauSquared: 0,
355
+ sigmaSquared: 0,
356
+ icc: 0,
357
+ se: 0,
358
+ df: dfB,
359
+ degenerate: null,
360
+ };
361
+ }
362
+ let sumW = 0;
363
+ let sumWY = 0;
364
+ for (const g of entries) {
365
+ const w = 1 / (tauSquared + sigmaSquared / g.size);
366
+ sumW += w;
367
+ sumWY += w * g.mean;
368
+ }
369
+ const point = sumW > 0 ? sumWY / sumW : grand;
370
+ const se = sumW > 0 ? Math.sqrt(1 / sumW) : Infinity;
371
+ const df = dfB;
372
+ const t = tQuantile(1 - (1 - level) / 2, df);
373
+ return {
374
+ ...shell,
375
+ point,
376
+ low: point - t * se,
377
+ high: point + t * se,
378
+ se,
379
+ tauSquared,
380
+ sigmaSquared,
381
+ icc: tauSquared + sigmaSquared > 0 ? tauSquared / (tauSquared + sigmaSquared) : 0,
382
+ df,
383
+ degenerate: null,
384
+ };
385
+ }
386
+ const fmtPts = (x) => `${x >= 0 ? "+" : ""}${(x * 100).toFixed(1)}`;
387
+ /**
388
+ * The whole suite-level story in one object: the honest interval, the naive one
389
+ * it replaces, the factor between them, and whether swapping them changes what
390
+ * a reader would conclude.
391
+ */
392
+ export function clusteredEffect(obs, level = 0.95) {
393
+ const cr2 = clusterRobustMean(obs, level);
394
+ const re = randomEffectsMean(obs, level);
395
+ const naive = iidMean(obs.map((o) => o.value), level);
396
+ const groups = groupByCluster(obs);
397
+ const families = [...groups.entries()]
398
+ .map(([family, xs]) => {
399
+ const m = xs.reduce((a, x) => a + x, 0) / xs.length;
400
+ const sd = xs.length > 1 ? Math.sqrt(xs.reduce((a, x) => a + (x - m) ** 2, 0) / (xs.length - 1)) : 0;
401
+ return { family, cases: xs.length, point: m, sd, min: Math.min(...xs), max: Math.max(...xs) };
402
+ })
403
+ .sort((a, b) => a.point - b.point || (a.family < b.family ? -1 : 1));
404
+ const excludesZero = (i) => i.low > 0 || i.high < 0;
405
+ const signFlippedByClustering = excludesZero(naive) && !excludesZero(cr2);
406
+ const headline = cr2.degenerate
407
+ ? `suite effect ${fmtPts(cr2.point)}pts, no interval: ${cr2.degenerate}`
408
+ : `suite effect ${fmtPts(cr2.point)}pts [${fmtPts(cr2.low)}, ${fmtPts(cr2.high)}] ` +
409
+ `over ${cr2.clusters} case families (${cr2.observations} cases); ` +
410
+ `clustering widens the interval ${cr2.widthRatio.toFixed(2)}× (design effect ${cr2.designEffect.toFixed(2)}, ` +
411
+ `ICC ${re.icc.toFixed(2)}), so the suite is worth ~${Math.round(cr2.effectiveSampleSize)} independent cases, not ${cr2.observations}` +
412
+ (signFlippedByClustering
413
+ ? ". The naive interval excluded zero and this one does not, the apparent suite-level move does not survive the correction."
414
+ : "");
415
+ return {
416
+ cr2,
417
+ randomEffects: re,
418
+ naive,
419
+ designEffect: cr2.designEffect,
420
+ widthRatio: cr2.widthRatio,
421
+ icc: re.icc,
422
+ clusters: cr2.clusters,
423
+ observations: cr2.observations,
424
+ families,
425
+ signFlippedByClustering,
426
+ headline,
427
+ };
428
+ }
429
+ /**
430
+ * Do the two estimators tell the same story? They rest on different
431
+ * assumptions, so agreement is evidence and disagreement is a warning worth
432
+ * printing rather than resolving by fiat.
433
+ */
434
+ export function compareEstimators(e) {
435
+ if (e.cr2.degenerate || e.randomEffects.degenerate) {
436
+ return { agree: true, seRatio: 1, note: e.cr2.degenerate ?? e.randomEffects.degenerate ?? "" };
437
+ }
438
+ // Two estimators that both report a standard error of zero agree; it is only
439
+ // a zero model-based SE under a positive robust one that is an infinite
440
+ // ratio. Reading every zero as Infinity made the note say "the family effects
441
+ // are not behaving like independent draws from one distribution, so trust CR2
442
+ // and not the hierarchical fit" about a suite with no variance at all, where
443
+ // the two estimators had produced the same number. Same shape as
444
+ // `designEffect` in `clusterRobustMean`, for the same reason.
445
+ const seRatio = e.randomEffects.se > 0 ? e.cr2.se / e.randomEffects.se : e.cr2.se > 0 ? Infinity : 1;
446
+ const agree = seRatio > 0.7 && seRatio < 1.45;
447
+ return {
448
+ agree,
449
+ seRatio,
450
+ note: agree
451
+ ? `CR2 and the random-effects model agree to within ${(Math.abs(seRatio - 1) * 100).toFixed(0)}% on the standard error`
452
+ : seRatio > 1
453
+ ? `the robust SE is ${seRatio.toFixed(2)}× the model-based one, the family effects are not behaving like ` +
454
+ "independent draws from one distribution, so trust CR2 and not the hierarchical fit"
455
+ : `the robust SE is only ${seRatio.toFixed(2)}× the model-based one, with this few families CR2 can be ` +
456
+ "optimistic; report the wider of the two",
457
+ };
458
+ }
459
+ /**
460
+ * Below this many clusters, a cluster-robust standard error is optimistic even
461
+ * with small-cluster degrees of freedom. Standard practice; `compareEstimators`
462
+ * says the same thing from the other direction.
463
+ */
464
+ export const MIN_TRUSTWORTHY_CLUSTERS = 20;
465
+ const summarise = (key, obs) => {
466
+ const cr2 = clusterRobustMean(obs);
467
+ const re = randomEffectsMean(obs);
468
+ return {
469
+ key,
470
+ // Only CR2 decides whether this grouping has an interval, which is what
471
+ // `degenerate` documents. The random-effects fit degenerating is a
472
+ // different fact about a different estimator: with one case per family σ²
473
+ // is not identified, so there is no ICC to report, but the cluster-robust
474
+ // interval is estimable and is in fact the iid one. Folding the two
475
+ // together made `clusterKeyDiagnostic` answer "no suite-level interval is
476
+ // estimable ... it is no claim at all" about a grouping whose standard
477
+ // error it had just computed, in a sentence reading "collapses 8 case-file
478
+ // groups into 80".
479
+ degenerate: cr2.degenerate,
480
+ clusters: cr2.clusters,
481
+ meanClusterSize: cr2.meanClusterSize,
482
+ icc: re.icc,
483
+ designEffect: cr2.designEffect,
484
+ widthRatio: cr2.widthRatio,
485
+ se: cr2.se,
486
+ effectiveSampleSize: cr2.effectiveSampleSize,
487
+ iccEstimable: re.degenerate === null,
488
+ };
489
+ };
490
+ /**
491
+ * Does a user-declared cluster key carry anything?
492
+ *
493
+ * The honest answer is a comparison, not a number: the same observations are
494
+ * grouped both ways and the intra-class correlation of each grouping is
495
+ * reported. A declared key that merges cases which do not in fact move together
496
+ * shows an ICC near zero while having *fewer, larger* clusters than the
497
+ * fallback, it has thrown away real information and widened the interval to
498
+ * pay for it. A declared key that finds correlation the case ids could not see
499
+ * shows a higher ICC and a larger design effect, and is doing its job. A
500
+ * declared key that is *finer* than the fallback, splitting apart files whose
501
+ * variants do move together, narrows the interval instead, and that is the
502
+ * dangerous direction rather than the merely wasteful one.
503
+ *
504
+ * Neither outcome is corrected automatically. A cluster key is a claim about
505
+ * the world and only the person who made it can say whether it is true; this
506
+ * says what the data thinks of it.
507
+ */
508
+ export function clusterKeyDiagnostic(declared, fallback) {
509
+ if (declared.length !== fallback.length) {
510
+ throw new PeeksafeError("PEEKSAFE_E_STAT_DOMAIN", `clusterKeyDiagnostic: the two groupings must cover the same observations (${declared.length} vs ${fallback.length})`, {
511
+ detail: { declared: declared.length, fallback: fallback.length },
512
+ hint: "group the same value array twice; do not filter one of them",
513
+ });
514
+ }
515
+ const d = summarise("declared", declared);
516
+ const f = summarise("case-id", fallback);
517
+ // A grouping with fewer than two clusters has no estimable between-family
518
+ // variance, so its design effect is Infinity and its ICC is meaningless.
519
+ // Comparing those against the fallback produces a verdict full of `Infinity×`
520
+ // that reads like a very large finding and is really an absence of one.
521
+ if (d.degenerate !== null) {
522
+ return {
523
+ declared: d,
524
+ fallback: f,
525
+ mergesUncorrelatedCases: true,
526
+ narrowsOnTooFewClusters: false,
527
+ narrowsBySplitting: false,
528
+ findsHiddenCorrelation: false,
529
+ verdict: `the declared key collapses ${f.clusters} case-file groups into ${d.clusters}, ${d.degenerate}. ` +
530
+ "No suite-level interval is estimable under this grouping, so it is not a tighter claim " +
531
+ "than the default; it is no claim at all",
532
+ };
533
+ }
534
+ // "Materially positive" rather than "> 0": the ANOVA ICC estimator is noisy
535
+ // and routinely lands slightly above zero on independent data, so a test at
536
+ // exactly zero would call every grouping useful.
537
+ const ICC_FLOOR = 0.05;
538
+ const coarser = d.clusters < f.clusters;
539
+ const mergesUncorrelatedCases = coarser && d.iccEstimable && d.icc < ICC_FLOOR;
540
+ const narrowsOnTooFewClusters = mergesUncorrelatedCases && d.widthRatio < f.widthRatio && d.clusters < MIN_TRUSTWORTHY_CLUSTERS;
541
+ // The other direction. Both flags above require `coarser`, so a key that
542
+ // *splits* the case files apart fell through every branch to "it is not
543
+ // changing the answer either way", on a grouping that had just taken the
544
+ // interval from 3.90× the iid one to 1.02×. Gated on the fallback showing
545
+ // real correlation: when the case files do not move together anyway,
546
+ // splitting them costs nothing and there is nothing to warn about.
547
+ //
548
+ // Sharing ICC_FLOOR with `mergesUncorrelatedCases` also shares its noise. On
549
+ // 8 families of 10 this fires on every seed where the families really move
550
+ // and on 0.195 of the seeds where they do not; `cluster.test.ts` costs both
551
+ // out. That asymmetry is the one to have: the flag errs toward asking an
552
+ // operator to look again at an interval that got narrower, which is the
553
+ // question this module exists to make people ask.
554
+ const narrowsBySplitting = d.clusters > f.clusters && f.iccEstimable && f.icc >= ICC_FLOOR && d.widthRatio < f.widthRatio;
555
+ // `iccEstimable` first: a grouping of singletons reports ICC exactly 1 as an
556
+ // artifact of σ̂² = 0, which sailed past this floor and could announce that a
557
+ // one-case-per-cluster key had "found correlation the case ids could not
558
+ // see". One case per cluster is the absence of within-cluster correlation.
559
+ const findsHiddenCorrelation = d.iccEstimable && d.icc >= ICC_FLOOR && d.designEffect > f.designEffect * 1.1;
560
+ // Quote the *interval width*, not the design effect. They do not move
561
+ // together: a coarse grouping with near-zero ICC can have a design effect
562
+ // below 1 and still produce a much wider interval, because 4 clusters buy 3
563
+ // degrees of freedom and a t-critical to match. The first draft of this line
564
+ // said "widening the interval (0.11× vs 0.91×)", which reads as narrowing.
565
+ const widths = `its interval is ${d.widthRatio.toFixed(2)}× the iid one against ${f.widthRatio.toFixed(2)}× for the case-file default`;
566
+ // "ICC 1.00" is what a singleton grouping prints, and it says the cases are
567
+ // perfectly correlated when the grouping is the statement that they are not
568
+ // correlated at all. Say the number is missing rather than inventing one.
569
+ const icc = (g) => (g.iccEstimable ? g.icc.toFixed(2) : "not identified");
570
+ const verdict = narrowsOnTooFewClusters
571
+ ? `the declared key merges ${f.clusters} case-file groups into ${d.clusters}, and those ${d.clusters} show ` +
572
+ `ICC ${icc(d)}, they do not move together, so ${widths}. That is the wrong direction: ` +
573
+ `a cluster-robust interval over fewer than ${MIN_TRUSTWORTHY_CLUSTERS} clusters is optimistic, and this key has ` +
574
+ `made the suite-level claim *tighter* than the default on cases that share nothing`
575
+ : mergesUncorrelatedCases
576
+ ? `the declared key merges ${f.clusters} case-file groups into ${d.clusters}, and those ${d.clusters} show ` +
577
+ `ICC ${icc(d)}, they do not move together, so ${widths}, and the extra width is ` +
578
+ `buying no information`
579
+ : narrowsBySplitting
580
+ ? `the declared key splits ${f.clusters} case-file groups into ${d.clusters}, but those ${f.clusters} files ` +
581
+ `show ICC ${icc(f)}, they do move together, so ${widths}. The split is a claim that the suite is worth ` +
582
+ `~${Math.round(d.effectiveSampleSize)} independent cases rather than ~${Math.round(f.effectiveSampleSize)}, ` +
583
+ "and it buys a narrower suite-level interval than the default with nothing behind it"
584
+ : findsHiddenCorrelation
585
+ ? `the declared key finds correlation the case ids could not see: design effect ` +
586
+ `${d.designEffect.toFixed(2)} against ${f.designEffect.toFixed(2)} over ${d.clusters} groups rather than ` +
587
+ `${f.clusters} (ICC ${icc(d)} within the declared groups, ${icc(f)} within case files). ` +
588
+ `The suite is worth ~${Math.round(d.effectiveSampleSize)} independent cases, not ${Math.round(f.effectiveSampleSize)}` +
589
+ (d.clusters < MIN_TRUSTWORTHY_CLUSTERS
590
+ ? `. Treat the interval as a lower bound on the width: ${d.clusters} clusters is below the ${MIN_TRUSTWORTHY_CLUSTERS} ` +
591
+ "a cluster-robust estimator needs to be trusted"
592
+ : "")
593
+ : `the declared key and the case-file default agree to within ` +
594
+ `${((Math.abs(d.designEffect - f.designEffect) / Math.max(1e-9, f.designEffect)) * 100).toFixed(0)}% on the design effect ` +
595
+ `(ICC ${icc(d)} vs ${icc(f)}), it is not changing the answer either way`;
596
+ return {
597
+ declared: d,
598
+ fallback: f,
599
+ mergesUncorrelatedCases,
600
+ narrowsOnTooFewClusters,
601
+ narrowsBySplitting,
602
+ findsHiddenCorrelation,
603
+ verdict,
604
+ };
605
+ }
606
+ //# sourceMappingURL=cluster.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cluster.js","sourceRoot":"","sources":["../src/cluster.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0EG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAiB,cAAc,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEtE,6EAA6E;AAE7E;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC9B,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAmC,EAAU,EAAE;IACxE,4EAA4E;IAC5E,4DAA4D;IAC5D,MAAM,QAAQ,GAAG,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC;IACnC,OAAO,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAChD,CAAC,CAAC;AAQF,wGAAwG;AACxG,SAAS,YAAY,CAAC,KAAa,EAAE,KAAa;IAChD,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,aAAa,CACrB,wBAAwB,EACxB,GAAG,KAAK,iCAAiC,KAAK,EAAE,EAChD;YACE,MAAM,EAAE,EAAE,KAAK,EAAE;YACjB,IAAI,EAAE,qFAAqF;SAC5F,CACF,CAAC;IACJ,CAAC;AACH,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,cAAc,CAAC,GAAyB;IACtD,MAAM,CAAC,GAAG,IAAI,GAAG,EAAoB,CAAC;IACtC,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;QACpB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,aAAa,CACrB,wBAAwB,EACxB,sCAAsC,CAAC,CAAC,OAAO,iBAAiB,EAChE;gBACE,MAAM,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE;aAC/C,CACF,CAAC;QACJ,CAAC;QACD,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC5B,IAAI,EAAE;YAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;;YACpB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAkCD,2EAA2E;AAC3E,MAAM,UAAU,OAAO,CAAC,MAAgB,EAAE,KAAK,GAAG,IAAI;IACpD,YAAY,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAC/B,sHAAsH;IACtH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,aAAa,CACrB,wBAAwB,EACxB,2BAA2B,CAAC,gBAAgB,EAC5C;gBACE,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE;aACvC,CACF,CAAC;QACJ,CAAC;IACH,CAAC;IACD,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;IACxB,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC;IACpE,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;IACnD,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5F,MAAM,CAAC,GAAG,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACrC,OAAO,EAAE,GAAG,EAAE,IAAI,GAAG,IAAI,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC;AAC/E,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAyB,EAAE,KAAK,GAAG,IAAI;IACvE,YAAY,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACnC,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC;IACrB,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC;IACtB,MAAM,KAAK,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;IAC1D,MAAM,KAAK,GAAG,OAAO,CACnB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EACvB,KAAK,CACN,CAAC;IACF,MAAM,OAAO,GACX,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjG,MAAM,IAAI,GAAG;QACX,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,YAAY,EAAE,CAAC;QACf,QAAQ,EAAE,CAAC;QACX,cAAc,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,eAAe,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAClC,OAAO;QACP,MAAM,EAAE,KAAc;KACvB,CAAC;IAEF,6EAA6E;IAC7E,2EAA2E;IAC3E,kEAAkE;IAClE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO;YACL,GAAG,IAAI;YACP,GAAG,EAAE,CAAC,CAAC;YACP,IAAI,EAAE,CAAC;YACP,EAAE,EAAE,QAAQ;YACZ,YAAY,EAAE,QAAQ;YACtB,UAAU,EAAE,QAAQ;YACpB,EAAE,EAAE,CAAC;YACL,SAAS,EAAE,QAAQ;YACnB,mBAAmB,EAAE,CAAC;YACtB,UAAU,EACR,CAAC,KAAK,CAAC;gBACL,CAAC,CAAC,kCAAkC;gBACpC,CAAC,CAAC,OAAO,CAAC,iCAAiC,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,kCAAkC;oBAChG,yEAAyE;SAChF,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;IACxB,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,MAAM,EAAE,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QACtD,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,oBAAoB;QACxD,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,QAAQ,CAAC;IACvC,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAChC,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAE/B,2EAA2E;IAC3E,4BAA4B;IAC5B,0EAA0E;IAC1E,2EAA2E;IAC3E,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IACjB,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;QACrB,IAAI,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,IAAI,CAAC,KAAK,CAAC;gBAAE,SAAS;YACtB,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;YACrB,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;YAC1C,IAAI,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IACD,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IAClB,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACpD,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;IAE/C,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;IAC7C,MAAM,IAAI,GAAG,CAAC,GAAG,EAAE,CAAC;IACpB,MAAM,CAAC,GAAG,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,CAAC,GAAG,OAAO,CAAC;IAE9B,OAAO;QACL,GAAG,IAAI;QACP,GAAG,EAAE,IAAI,GAAG,IAAI;QAChB,IAAI,EAAE,IAAI,GAAG,IAAI;QACjB,EAAE;QACF,YAAY,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QACvE,UAAU,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QACtE,EAAE;QACF,SAAS,EAAE,CAAC;QACZ,4EAA4E;QAC5E,4EAA4E;QAC5E,sEAAsE;QACtE,iEAAiE;QACjE,yEAAyE;QACzE,2EAA2E;QAC3E,gEAAgE;QAChE,mBAAmB,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5F,UAAU,EAAE,IAAI;KACjB,CAAC;AACJ,CAAC;AAmBD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAyB,EAAE,KAAK,GAAG,IAAI;IACvE,YAAY,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACnC,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC;IACrB,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC;IACtB,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACnE,MAAM,KAAK,GAAG;QACZ,YAAY,EAAE,CAAC;QACf,QAAQ,EAAE,CAAC;QACX,MAAM,EAAE,gBAAyB;KAClC,CAAC;IACF,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO;YACL,GAAG,KAAK;YACR,KAAK,EAAE,KAAK;YACZ,GAAG,EAAE,CAAC,CAAC;YACP,IAAI,EAAE,CAAC;YACP,UAAU,EAAE,CAAC;YACb,YAAY,EAAE,CAAC;YACf,GAAG,EAAE,CAAC;YACN,EAAE,EAAE,QAAQ;YACZ,EAAE,EAAE,CAAC;YACL,UAAU,EACR,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,kCAAkC,CAAC,CAAC,CAAC,4CAA4C;SAC9F,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACtD,GAAG,EAAE,CAAC;QACN,IAAI,EAAE,EAAE,CAAC,MAAM;QACf,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM;QAC/C,MAAM,EAAE,EAAE;KACX,CAAC,CAAC,CAAC;IAEJ,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM;YAAE,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnD,GAAG,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;IACD,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IAClB,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IAElB,8EAA8E;IAC9E,2EAA2E;IAC3E,wEAAwE;IACxE,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC;QACd,MAAM,GAAG,GAAG,OAAO,CACjB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EACvB,KAAK,CACN,CAAC;QACF,OAAO;YACL,GAAG,KAAK;YACR,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,GAAG,EAAE,GAAG,CAAC,GAAG;YACZ,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,UAAU,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;YACnC,YAAY,EAAE,CAAC;YACf,GAAG,EAAE,CAAC;YACN,EAAE,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1C,EAAE,EAAE,GAAG;YACP,UAAU,EACR,2FAA2F;gBAC3F,8CAA8C;SACjD,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IACtB,MAAM,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IACtB,4EAA4E;IAC5E,0CAA0C;IAC1C,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC/D,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;IACjC,MAAM,YAAY,GAAG,GAAG,CAAC;IACzB,MAAM,UAAU,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAE9D,6EAA6E;IAC7E,yEAAyE;IACzE,6EAA6E;IAC7E,0EAA0E;IAC1E,wEAAwE;IACxE,0EAA0E;IAC1E,qDAAqD;IACrD,IAAI,CAAC,CAAC,UAAU,GAAG,YAAY,GAAG,CAAC,CAAC,EAAE,CAAC;QACrC,OAAO;YACL,GAAG,KAAK;YACR,KAAK,EAAE,KAAK;YACZ,GAAG,EAAE,KAAK;YACV,IAAI,EAAE,KAAK;YACX,UAAU,EAAE,CAAC;YACb,YAAY,EAAE,CAAC;YACf,GAAG,EAAE,CAAC;YACN,EAAE,EAAE,CAAC;YACL,EAAE,EAAE,GAAG;YACP,UAAU,EAAE,IAAI;SACjB,CAAC;IACJ,CAAC;IAED,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,GAAG,YAAY,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;QACnD,IAAI,IAAI,CAAC,CAAC;QACV,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;IACtB,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;IAC9C,MAAM,EAAE,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IACrD,MAAM,EAAE,GAAG,GAAG,CAAC;IACf,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;IAE7C,OAAO;QACL,GAAG,KAAK;QACR,KAAK;QACL,GAAG,EAAE,KAAK,GAAG,CAAC,GAAG,EAAE;QACnB,IAAI,EAAE,KAAK,GAAG,CAAC,GAAG,EAAE;QACpB,EAAE;QACF,UAAU;QACV,YAAY;QACZ,GAAG,EAAE,UAAU,GAAG,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,UAAU,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,EAAE;QACF,UAAU,EAAE,IAAI;KACjB,CAAC;AACJ,CAAC;AA8CD,MAAM,MAAM,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;AAE5E;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,GAAyB,EAAE,KAAK,GAAG,IAAI;IACrE,MAAM,GAAG,GAAG,iBAAiB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC1C,MAAM,EAAE,GAAG,iBAAiB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,OAAO,CACnB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EACvB,KAAK,CACN,CAAC;IAEF,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACnC,MAAM,QAAQ,GAAmB,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;SACnD,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,EAAE;QACpB,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC;QACpD,MAAM,EAAE,GACN,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5F,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC;IAChG,CAAC,CAAC;SACD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAEvE,MAAM,YAAY,GAAG,CAAC,CAAW,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;IAC9D,MAAM,uBAAuB,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IAE1E,MAAM,QAAQ,GAAG,GAAG,CAAC,UAAU;QAC7B,CAAC,CAAC,gBAAgB,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,qBAAqB,GAAG,CAAC,UAAU,EAAE;QACxE,CAAC,CAAC,gBAAgB,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI;YACjF,QAAQ,GAAG,CAAC,QAAQ,mBAAmB,GAAG,CAAC,YAAY,WAAW;YAClE,kCAAkC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,oBAAoB,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;YAC9G,OAAO,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,6BAA6B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,2BAA2B,GAAG,CAAC,YAAY,EAAE;YACrI,CAAC,uBAAuB;gBACtB,CAAC,CAAC,0HAA0H;gBAC5H,CAAC,CAAC,EAAE,CAAC,CAAC;IAEZ,OAAO;QACL,GAAG;QACH,aAAa,EAAE,EAAE;QACjB,KAAK;QACL,YAAY,EAAE,GAAG,CAAC,YAAY;QAC9B,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,GAAG,EAAE,EAAE,CAAC,GAAG;QACX,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,YAAY,EAAE,GAAG,CAAC,YAAY;QAC9B,QAAQ;QACR,uBAAuB;QACvB,QAAQ;KACT,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,CAAkB;IAMlD,IAAI,CAAC,CAAC,GAAG,CAAC,UAAU,IAAI,CAAC,CAAC,aAAa,CAAC,UAAU,EAAE,CAAC;QACnD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,IAAI,CAAC,CAAC,aAAa,CAAC,UAAU,IAAI,EAAE,EAAE,CAAC;IACjG,CAAC;IACD,6EAA6E;IAC7E,wEAAwE;IACxE,8EAA8E;IAC9E,8EAA8E;IAC9E,6EAA6E;IAC7E,iEAAiE;IACjE,8DAA8D;IAC9D,MAAM,OAAO,GACX,CAAC,CAAC,aAAa,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACvF,MAAM,KAAK,GAAG,OAAO,GAAG,GAAG,IAAI,OAAO,GAAG,IAAI,CAAC;IAC9C,OAAO;QACL,KAAK;QACL,OAAO;QACP,IAAI,EAAE,KAAK;YACT,CAAC,CAAC,oDAAoD,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,yBAAyB;YACvH,CAAC,CAAC,OAAO,GAAG,CAAC;gBACX,CAAC,CAAC,oBAAoB,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,kEAAkE;oBACxG,oFAAoF;gBACtF,CAAC,CAAC,yBAAyB,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,2DAA2D;oBACtG,yCAAyC;KAChD,CAAC;AACJ,CAAC;AAmED;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,CAAC;AAE3C,MAAM,SAAS,GAAG,CAAC,GAAW,EAAE,GAAyB,EAAmB,EAAE;IAC5E,MAAM,GAAG,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;IACnC,MAAM,EAAE,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;IAClC,OAAO;QACL,GAAG;QACH,wEAAwE;QACxE,mEAAmE;QACnE,0EAA0E;QAC1E,0EAA0E;QAC1E,oEAAoE;QACpE,0EAA0E;QAC1E,uEAAuE;QACvE,2EAA2E;QAC3E,mBAAmB;QACnB,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,eAAe,EAAE,GAAG,CAAC,eAAe;QACpC,GAAG,EAAE,EAAE,CAAC,GAAG;QACX,YAAY,EAAE,GAAG,CAAC,YAAY;QAC9B,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,mBAAmB,EAAE,GAAG,CAAC,mBAAmB;QAC5C,YAAY,EAAE,EAAE,CAAC,UAAU,KAAK,IAAI;KACrC,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,oBAAoB,CAClC,QAA8B,EAC9B,QAA8B;IAE9B,IAAI,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;QACxC,MAAM,IAAI,aAAa,CACrB,wBAAwB,EACxB,6EAA6E,QAAQ,CAAC,MAAM,OAAO,QAAQ,CAAC,MAAM,GAAG,EACrH;YACE,MAAM,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,EAAE;YAChE,IAAI,EAAE,6DAA6D;SACpE,CACF,CAAC;IACJ,CAAC;IACD,MAAM,CAAC,GAAG,SAAS,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAC1C,MAAM,CAAC,GAAG,SAAS,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAEzC,0EAA0E;IAC1E,yEAAyE;IACzE,8EAA8E;IAC9E,wEAAwE;IACxE,IAAI,CAAC,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;QAC1B,OAAO;YACL,QAAQ,EAAE,CAAC;YACX,QAAQ,EAAE,CAAC;YACX,uBAAuB,EAAE,IAAI;YAC7B,uBAAuB,EAAE,KAAK;YAC9B,kBAAkB,EAAE,KAAK;YACzB,sBAAsB,EAAE,KAAK;YAC7B,OAAO,EACL,8BAA8B,CAAC,CAAC,QAAQ,0BAA0B,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,UAAU,IAAI;gBACjG,yFAAyF;gBACzF,yCAAyC;SAC5C,CAAC;IACJ,CAAC;IAED,4EAA4E;IAC5E,4EAA4E;IAC5E,iDAAiD;IACjD,MAAM,SAAS,GAAG,IAAI,CAAC;IACvB,MAAM,OAAO,GAAG,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC;IACxC,MAAM,uBAAuB,GAAG,OAAO,IAAI,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,GAAG,GAAG,SAAS,CAAC;IAC/E,MAAM,uBAAuB,GAC3B,uBAAuB,IAAI,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,QAAQ,GAAG,wBAAwB,CAAC;IAClG,yEAAyE;IACzE,wEAAwE;IACxE,yEAAyE;IACzE,0EAA0E;IAC1E,qEAAqE;IACrE,mEAAmE;IACnE,EAAE;IACF,6EAA6E;IAC7E,2EAA2E;IAC3E,4EAA4E;IAC5E,yEAAyE;IACzE,wEAAwE;IACxE,kDAAkD;IAClD,MAAM,kBAAkB,GACtB,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,GAAG,IAAI,SAAS,IAAI,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC;IACjG,6EAA6E;IAC7E,8EAA8E;IAC9E,yEAAyE;IACzE,2EAA2E;IAC3E,MAAM,sBAAsB,GAC1B,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,GAAG,IAAI,SAAS,IAAI,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,YAAY,GAAG,GAAG,CAAC;IAEhF,sEAAsE;IACtE,0EAA0E;IAC1E,4EAA4E;IAC5E,6EAA6E;IAC7E,2EAA2E;IAC3E,MAAM,MAAM,GAAG,mBAAmB,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,6BAA6B,CAAC;IACvI,4EAA4E;IAC5E,4EAA4E;IAC5E,0EAA0E;IAC1E,MAAM,GAAG,GAAG,CAAC,CAAkB,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;IAC3F,MAAM,OAAO,GAAG,uBAAuB;QACrC,CAAC,CAAC,2BAA2B,CAAC,CAAC,QAAQ,0BAA0B,CAAC,CAAC,QAAQ,eAAe,CAAC,CAAC,QAAQ,QAAQ;YAC1G,OAAO,GAAG,CAAC,CAAC,CAAC,mCAAmC,MAAM,iCAAiC;YACvF,6CAA6C,wBAAwB,4CAA4C;YACjH,mFAAmF;QACrF,CAAC,CAAC,uBAAuB;YACvB,CAAC,CAAC,2BAA2B,CAAC,CAAC,QAAQ,0BAA0B,CAAC,CAAC,QAAQ,eAAe,CAAC,CAAC,QAAQ,QAAQ;gBAC1G,OAAO,GAAG,CAAC,CAAC,CAAC,mCAAmC,MAAM,2BAA2B;gBACjF,uBAAuB;YACzB,CAAC,CAAC,kBAAkB;gBAClB,CAAC,CAAC,2BAA2B,CAAC,CAAC,QAAQ,0BAA0B,CAAC,CAAC,QAAQ,eAAe,CAAC,CAAC,QAAQ,SAAS;oBAC3G,YAAY,GAAG,CAAC,CAAC,CAAC,+BAA+B,MAAM,iDAAiD;oBACxG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,mBAAmB,CAAC,mCAAmC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,mBAAmB,CAAC,IAAI;oBAC7G,qFAAqF;gBACvF,CAAC,CAAC,sBAAsB;oBACtB,CAAC,CAAC,+EAA+E;wBAC/E,GAAG,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,QAAQ,sBAAsB;wBAC1G,GAAG,CAAC,CAAC,QAAQ,SAAS,GAAG,CAAC,CAAC,CAAC,gCAAgC,GAAG,CAAC,CAAC,CAAC,uBAAuB;wBACzF,uBAAuB,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,mBAAmB,CAAC,2BAA2B,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,mBAAmB,CAAC,EAAE;wBACtH,CAAC,CAAC,CAAC,QAAQ,GAAG,wBAAwB;4BACpC,CAAC,CAAC,uDAAuD,CAAC,CAAC,QAAQ,0BAA0B,wBAAwB,GAAG;gCACtH,gDAAgD;4BAClD,CAAC,CAAC,EAAE,CAAC;oBACT,CAAC,CAAC,6DAA6D;wBAC7D,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,yBAAyB;wBAC3H,QAAQ,GAAG,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,6CAA6C,CAAC;IAEnF,OAAO;QACL,QAAQ,EAAE,CAAC;QACX,QAAQ,EAAE,CAAC;QACX,uBAAuB;QACvB,uBAAuB;QACvB,kBAAkB;QAClB,sBAAsB;QACtB,OAAO;KACR,CAAC;AACJ,CAAC"}