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.
- package/CHANGELOG.md +325 -0
- package/LICENSE +190 -0
- package/NOTICE +78 -0
- package/README.md +490 -2
- package/RESEARCH-NOTES.md +274 -0
- package/dist/baseline.d.ts +45 -0
- package/dist/baseline.d.ts.map +1 -0
- package/dist/baseline.js +49 -0
- package/dist/baseline.js.map +1 -0
- package/dist/check.d.ts +64 -0
- package/dist/check.d.ts.map +1 -0
- package/dist/check.js +172 -0
- package/dist/check.js.map +1 -0
- package/dist/cluster.d.ts +328 -0
- package/dist/cluster.d.ts.map +1 -0
- package/dist/cluster.js +606 -0
- package/dist/cluster.js.map +1 -0
- package/dist/errors.d.ts +108 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +192 -0
- package/dist/errors.js.map +1 -0
- package/dist/evidence.d.ts +15 -0
- package/dist/evidence.d.ts.map +1 -0
- package/dist/evidence.js +30 -0
- package/dist/evidence.js.map +1 -0
- package/dist/frontier.d.ts +271 -0
- package/dist/frontier.d.ts.map +1 -0
- package/dist/frontier.js +505 -0
- package/dist/frontier.js.map +1 -0
- package/dist/gate.d.ts +175 -0
- package/dist/gate.d.ts.map +1 -0
- package/dist/gate.js +200 -0
- package/dist/gate.js.map +1 -0
- package/dist/index.d.ts +60 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +79 -0
- package/dist/index.js.map +1 -0
- package/dist/plan.d.ts +280 -0
- package/dist/plan.d.ts.map +1 -0
- package/dist/plan.js +626 -0
- package/dist/plan.js.map +1 -0
- package/dist/rand.d.ts +17 -0
- package/dist/rand.d.ts.map +1 -0
- package/dist/rand.js +104 -0
- package/dist/rand.js.map +1 -0
- package/dist/stats.d.ts +401 -0
- package/dist/stats.d.ts.map +1 -0
- package/dist/stats.js +1304 -0
- package/dist/stats.js.map +1 -0
- package/dist/stop.d.ts +164 -0
- package/dist/stop.d.ts.map +1 -0
- package/dist/stop.js +270 -0
- package/dist/stop.js.map +1 -0
- package/package.json +62 -3
- package/src/baseline.ts +72 -0
- package/src/check.ts +238 -0
- package/src/cluster.ts +842 -0
- package/src/errors.ts +275 -0
- package/src/evidence.ts +62 -0
- package/src/frontier.ts +837 -0
- package/src/gate.ts +363 -0
- package/src/index.ts +206 -0
- package/src/plan.ts +968 -0
- package/src/rand.ts +137 -0
- package/src/stats.ts +1663 -0
- package/src/stop.ts +464 -0
package/dist/cluster.js
ADDED
|
@@ -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"}
|