@mark1russell7/rigor-statistics 0.1.3 → 0.1.5
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/README.md +3 -1
- package/build/index.d.ts +26 -4
- package/build/index.d.ts.map +1 -1
- package/build/index.js +77 -2
- package/build/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -27,13 +27,14 @@ A promotion reads `gains` against `drops` and `effect`. A sign test alone is not
|
|
|
27
27
|
| Function | What it gives |
|
|
28
28
|
| --- | --- |
|
|
29
29
|
| `mean`, `sd`, `median`, `summarize` | The descriptive statistics. `sd` is the sample standard deviation. |
|
|
30
|
-
| `quantile(values, p, method)`, `quantileSorted` | The `p` quantile, with the `"linear"` method (type 7, the default)
|
|
30
|
+
| `quantile(values, p, method)`, `quantileSorted` | The `p` quantile, with the `"linear"` method (type 7, the default), the `"nearest-rank"` method (type 1) or the `"higher"` method (`sorted[Math.ceil(p * (n - 1))]`, as NumPy). |
|
|
31
31
|
| `bootstrap(data, statistic, options)` | A percentile bootstrap interval of any statistic. The options are `runs`, `level` or `ends`, `seed` and `method`. |
|
|
32
32
|
| `bootstrapMedian`, `bootstrapClusters` | The interval of the median, and a bootstrap that draws whole clusters (boards, seeds, sites). |
|
|
33
33
|
| `bootstrapTwo(a, b, statistic, options)` | A bootstrap interval of a statistic of two independent samples, for example two arms of a benchmark. Each run draws all of `a`, then all of `b`. |
|
|
34
34
|
| `bootstrapMedianRatio(numerator, denominator, options)` | The interval of `median(numerator) / median(denominator)`. It is the uncertainty of the ratio, not the spread of the samples. |
|
|
35
35
|
| `leastSquares(x, y, { intercept })` | The ordinary least-squares fit of `y` on the rows of `x`, with a QR decomposition. It gives the coefficients, `residualSd`, `r2`, `n` and `k`. A singular design gives NaN coefficients. |
|
|
36
36
|
| `bootstrapLeastSquares(x, y, options)` | One bootstrap interval for each coefficient of `leastSquares`, from the same draws of whole rows. A singular draw does not count. |
|
|
37
|
+
| `ridgeSolve(gram, moment, lambda, { free })` | The ridge coefficients from the normal equations `X'X` and `X'y`, with a Cholesky factorization. The `free` coefficients have no penalty. A matrix that is not positive definite gives NaN coefficients. |
|
|
37
38
|
| `signTest(better, worse, sides)`, `signTestPower(n, level)` | The sign test, and the fewest wins out of `n` that the test calls significant. |
|
|
38
39
|
| `pairedPermutation(candidate, baseline, options)` | The paired permutation test (random sign flips). It uses the size of each difference. |
|
|
39
40
|
| `wilson(k, n, z)` | The Wilson interval of a proportion. |
|
|
@@ -55,6 +56,7 @@ The tests prove that these functions give the same numbers as the copies in the
|
|
|
55
56
|
| `quantile` of highways, packing and layout-contract (`quantileOf`) | `quantile(values, p)` |
|
|
56
57
|
| `quantile` of lag and lag-hud, `percentile` of lag (with `p / 100`) | `quantile(values, p, "nearest-rank")` |
|
|
57
58
|
| `median` of coeval, lag, crawler and packing | `median(values)` |
|
|
59
|
+
| The upper median `sorted[Math.floor(n / 2)]` of highways | `quantile(values, 0.5, "higher")` |
|
|
58
60
|
| `bootstrapMedian` of packing | `bootstrapMedian(sortedValues, { runs, level, seed })`. Give the values sorted, because packing draws from the sorted list. |
|
|
59
61
|
| `bootstrapMedian` of highways | `bootstrap(values, (s) => quantile(s, 0.5), { runs, level, seed })` |
|
|
60
62
|
| `bootstrap` of layout-contract | `bootstrapClusters(rows, (r) => r.cluster, statistic, { runs, seed, ends: [0.025, 0.975] })` |
|
package/build/index.d.ts
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* Each function throws a RangeError for an empty list or for a value that is NaN. Thus a missing value cannot make a
|
|
4
4
|
* quiet NaN in a record.
|
|
5
5
|
*/
|
|
6
|
-
/** The
|
|
7
|
-
type QuantileMethod = "linear" | "nearest-rank";
|
|
6
|
+
/** The definitions of a quantile that the engines use (Hyndman and Fan, 1996, and the names of NumPy). */
|
|
7
|
+
type QuantileMethod = "linear" | "nearest-rank" | "higher";
|
|
8
8
|
/** A new list with the values from the smallest to the largest. */
|
|
9
9
|
export declare function sorted(values: readonly number[]): number[];
|
|
10
10
|
export declare function mean(values: readonly number[]): number;
|
|
@@ -13,7 +13,8 @@ export declare function sd(values: readonly number[]): number;
|
|
|
13
13
|
/**
|
|
14
14
|
* The `p` quantile of a list that is already sorted. Use it when you take several quantiles of one list.
|
|
15
15
|
* The linear method gives the same numbers as the copies in highways, packing and layout-contract. The
|
|
16
|
-
* nearest-rank method gives the same numbers as the copies in lag, lag-hud and the backtest of highways.
|
|
16
|
+
* nearest-rank method gives the same numbers as the copies in lag, lag-hud and the backtest of highways. The
|
|
17
|
+
* higher method gives the upper median of the copies in highways with `p = 0.5`.
|
|
17
18
|
*/
|
|
18
19
|
export declare function quantileSorted(sortedValues: readonly number[], p: number, method?: QuantileMethod): number;
|
|
19
20
|
/** The `p` quantile of a list. */
|
|
@@ -136,6 +137,27 @@ export declare function bootstrapMedian(values: readonly number[], options?: Boo
|
|
|
136
137
|
* are in the order of their first row.
|
|
137
138
|
*/
|
|
138
139
|
export declare function bootstrapClusters<T>(rows: readonly T[], cluster: (row: T) => string, statistic: (rows: readonly T[]) => number, options?: BootstrapOptions): Interval;
|
|
140
|
+
/**
|
|
141
|
+
* The ridge solve of a least-squares problem from its normal equations. The caller gives the matrix `X'X` and the
|
|
142
|
+
* vector `X'y`. Thus it can make them from sparse rows. It can also remove the sums of one fold of a cross-validation.
|
|
143
|
+
* The solve uses a Cholesky factorization of `X'X + lambda * P`. The matrix `P` is the identity, with 0 on the
|
|
144
|
+
* diagonal for each free coefficient, for example an intercept.
|
|
145
|
+
*/
|
|
146
|
+
interface RidgeOptions {
|
|
147
|
+
/** The indexes of the coefficients with no penalty, for example 0 for an intercept. The default is none. */
|
|
148
|
+
readonly free?: readonly number[];
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* This function gives the coefficients `beta` that solve `(gram + lambda * P) beta = moment`.
|
|
152
|
+
* - `gram` is the symmetric matrix `X'X` of size `k`, in row order. The function reads only its lower triangle.
|
|
153
|
+
* - `moment` is the vector `X'y` of length `k`.
|
|
154
|
+
* - With `lambda` 0, the result is the ordinary least-squares fit.
|
|
155
|
+
*
|
|
156
|
+
* The function does not change `gram` or `moment`. When the matrix is not positive definite, each coefficient is
|
|
157
|
+
* NaN, as in `leastSquares`. The function throws a RangeError when `gram` does not have `k * k` values, and when
|
|
158
|
+
* `k` is 0. It also throws for a value that is not finite, for a `lambda` below 0, and for a bad free index.
|
|
159
|
+
*/
|
|
160
|
+
export declare function ridgeSolve(gram: ArrayLike<number>, moment: ArrayLike<number>, lambda: number, options?: RidgeOptions): number[];
|
|
139
161
|
/**
|
|
140
162
|
* The sign test of paired results: `better` inputs where the candidate wins and `worse` where it loses. The ties
|
|
141
163
|
* do not count. One-sided (the default), it is the p of `better` wins or more if the two are equal. Two-sided, it is
|
|
@@ -323,5 +345,5 @@ interface CalibrationLevel {
|
|
|
323
345
|
}
|
|
324
346
|
/** The hit rate of each stated level, from the lowest level. */
|
|
325
347
|
export declare function calibration(forecasts: readonly Forecast[]): CalibrationLevel[];
|
|
326
|
-
export type { BootstrapOptions, CalibrationLevel, CompareOptions, Comparison, Corrected, CountInterval, Effect, Forecast, Interval, LeastSquaresFit, LeastSquaresOptions, MedianInterval, NoiseOptions, PermutationOptions, PermutationResult, Proportion, QuantileMethod, Summary };
|
|
348
|
+
export type { BootstrapOptions, CalibrationLevel, CompareOptions, Comparison, Corrected, CountInterval, Effect, Forecast, Interval, LeastSquaresFit, LeastSquaresOptions, MedianInterval, NoiseOptions, PermutationOptions, PermutationResult, Proportion, QuantileMethod, RidgeOptions, Summary };
|
|
327
349
|
//# sourceMappingURL=index.d.ts.map
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/describe.ts","../src/regression.ts","../src/bootstrap.ts","../src/tests.ts","../src/rank.ts","../src/discrete.ts","../src/compare.ts"],"mappings":";;;;;;KAOY;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/describe.ts","../src/regression.ts","../src/bootstrap.ts","../src/ridge.ts","../src/tests.ts","../src/rank.ts","../src/discrete.ts","../src/compare.ts"],"mappings":";;;;;;KAOY;;wBAmBI,OAAO;wBAIP,KAAK;;wBAQL,GAAG;;;;;;;wBAeH,eAAe,iCAAiC,WAAW,SAAQ;;wBAkBnE,SAAS,2BAA2B,WAAW,SAAQ;;;;;wBASvD,OAAO;;UAQN;WACN;WACA;;WAEA;WACA;;WAEA;WACA;;WAEA;WACA;;WAEA;;wBAGK,UAAU,4BAA4B;;;;;;UClGrC;;WAEN;;UAGM;;WAEN;;WAEA;;;;;WAKA;;WAEA;;WAEA;;;;;;;;;;;wBAkBK,aAAa,mCAAmC,sBAAsB,UAAS,sBAA2B;UC/BzG;;WAEN;;WAEA;;WAEA;;WAEA,SAAS;;;;;;WAMT;;UAGM;;WAEN;WACA;WACA;WACA;WACA;;WAEA;;WAEA;;;;;;wBAOK,UAAU,GAAG,eAAe,KAAK,YAAY,iBAAiB,gBAAgB,UAAS,mBAAwB;;;;;;;;wBAsB/G,aAAa,GAAG,GAC9B,YAAY,KACZ,YAAY,KACZ,YAAY,YAAY,KAAK,YAAY,gBACzC,UAAS,mBACR;;;;;;wBAwBa,qBAAqB,8BAA8B,gCAAgC,UAAS,mBAAwB;;;;;;;wBAUpH,sBACd,mCACA,sBACA,UAAS,mBAAmB,sBAC3B;;wBAmFa,gBAAgB,2BAA2B,UAAS,mBAAwB;;;;;;wBAS5E,kBAAkB,GAChC,eAAe,KACf,UAAU,KAAK,cACf,YAAY,eAAe,gBAC3B,UAAS,mBACR;;;;;;;UCxMc;;WAEN;;;;;;;;;;;;wBAoBK,WAAW,MAAM,mBAAmB,QAAQ,mBAAmB,gBAAgB,UAAS;;;;;;wBCQxF,SAAS,gBAAgB,eAAe;;;;;wBAaxC,cAAc,WAAW,gBAAc;;qBAO1C;;UAGI;WACN;WACA;;;;;;wBAOK,OAAO,WAAW,WAAW,aAAkB;;UAc9C;;WAEN;;WAEA;;WAEA;;;;;;;wBAQK,KAAK,4BAA4B,iBAAe;UAa/C;;WAEN;;WAEA;;WAEA,aAAa;;UAGP;;WAEN;;WAEA;WACA;;;;;;wBAOK,kBAAkB,8BAA8B,6BAA6B,UAAS,qBAA0B;;wBCtHhH,MAAM;;;;;wBAgBN,SAAS,sBAAsB;;qBAmBlC;;;;;;wBAQG,WAAW,sBAAsB,sBAAsB;;UC1BtD;WACN;WACA;;WAEA;;WAEA;;;;;;;;;;wBAWK,eAAe,2BAA2B,iBAAe;;UAqBxD;WACN;WACA;;WAEA;;;;;;;wBAQK,iBAAiB,WAAW,WAAW,iBAAe;;;;;;wBA2BtD,yBAAyB,mBAAmB,WAAW,iBAAe;UClGrE;;WAEN;;WAEA;;;;;;wBAOK,WAAW,2BAA2B,UAAS;UAM9C;;WAEN;;WAEA;;WAEA;;;UAIM;WACN;WACA;;WAEA;;WAEA;;UAGM;;WAEN;WACA;;WAEA;;WAEA;;WAEA;;WAEA,QAAQ;;WAER;;WAEA;;WAEA;WACA,cAAc;;WAEd;WACA,cAAc;;;;;;;;wBAST,cAAc,2BAA2B,UAAS,iBAAsB;;UA6CvE;WACN;WACA;;;wBASK,MAAM,oBAAoB;;UAQzB;WACN;WACA;WACA;;WAEA;;WAEA,UAAU;;;wBAIL,YAAY,oBAAoB,aAAa"}
|
package/build/index.js
CHANGED
|
@@ -26,13 +26,15 @@ function sd(values) {
|
|
|
26
26
|
/**
|
|
27
27
|
* The `p` quantile of a list that is already sorted. Use it when you take several quantiles of one list.
|
|
28
28
|
* The linear method gives the same numbers as the copies in highways, packing and layout-contract. The
|
|
29
|
-
* nearest-rank method gives the same numbers as the copies in lag, lag-hud and the backtest of highways.
|
|
29
|
+
* nearest-rank method gives the same numbers as the copies in lag, lag-hud and the backtest of highways. The
|
|
30
|
+
* higher method gives the upper median of the copies in highways with `p = 0.5`.
|
|
30
31
|
*/
|
|
31
32
|
function quantileSorted(sortedValues, p, method = "linear") {
|
|
32
33
|
checked("quantile", sortedValues);
|
|
33
34
|
if (!(p >= 0 && p <= 1)) throw new RangeError(`quantile: p is from 0 to 1, not ${p}.`);
|
|
34
35
|
const n = sortedValues.length;
|
|
35
36
|
if (method === "nearest-rank") return sortedValues[Math.min(n - 1, Math.max(0, Math.ceil(p * n) - 1))];
|
|
37
|
+
if (method === "higher") return sortedValues[Math.ceil(Math.round(p * (n - 1) * 1e9) / 1e9)];
|
|
36
38
|
const at = (n - 1) * p;
|
|
37
39
|
const low = Math.floor(at);
|
|
38
40
|
const part = at - low;
|
|
@@ -353,6 +355,79 @@ function bootstrapClusters(rows, cluster, statistic, options = {}) {
|
|
|
353
355
|
estimate
|
|
354
356
|
};
|
|
355
357
|
}
|
|
358
|
+
// src/ridge.ts
|
|
359
|
+
/**
|
|
360
|
+
* The relative tolerance of the Cholesky pivots. A pivot is the squared length of the part of a column that is
|
|
361
|
+
* orthogonal to the columns before it. The rounding error of a pivot is approximately 1e-16 times its diagonal value.
|
|
362
|
+
* Thus a pivot of a dependent column is not exactly 0, and the tolerance is larger than that error.
|
|
363
|
+
*/
|
|
364
|
+
const PIVOT_TOLERANCE = 1e-12;
|
|
365
|
+
/**
|
|
366
|
+
* This function gives the coefficients `beta` that solve `(gram + lambda * P) beta = moment`.
|
|
367
|
+
* - `gram` is the symmetric matrix `X'X` of size `k`, in row order. The function reads only its lower triangle.
|
|
368
|
+
* - `moment` is the vector `X'y` of length `k`.
|
|
369
|
+
* - With `lambda` 0, the result is the ordinary least-squares fit.
|
|
370
|
+
*
|
|
371
|
+
* The function does not change `gram` or `moment`. When the matrix is not positive definite, each coefficient is
|
|
372
|
+
* NaN, as in `leastSquares`. The function throws a RangeError when `gram` does not have `k * k` values, and when
|
|
373
|
+
* `k` is 0. It also throws for a value that is not finite, for a `lambda` below 0, and for a bad free index.
|
|
374
|
+
*/
|
|
375
|
+
function ridgeSolve(gram, moment, lambda, options = {}) {
|
|
376
|
+
const k = moment.length;
|
|
377
|
+
if (k === 0) throw new RangeError("ridgeSolve: the moment is empty.");
|
|
378
|
+
if (gram.length !== k * k) throw new RangeError(`ridgeSolve: the gram has ${gram.length} values, and a moment of length ${k} needs ${k * k}.`);
|
|
379
|
+
if (!(lambda >= 0 && Number.isFinite(lambda))) throw new RangeError(`ridgeSolve: lambda is a finite number of 0 or more, not ${lambda}.`);
|
|
380
|
+
const penalty = new Float64Array(k).fill(lambda);
|
|
381
|
+
for (const i of options.free ?? []) {
|
|
382
|
+
if (!Number.isSafeInteger(i) || i < 0 || i >= k) throw new RangeError(`ridgeSolve: a free index is a whole number from 0 to ${k - 1}, not ${i}.`);
|
|
383
|
+
penalty[i] = 0;
|
|
384
|
+
}
|
|
385
|
+
const a = new Float64Array(k * k);
|
|
386
|
+
for (let i = 0; i < k * k; i++) {
|
|
387
|
+
const v = gram[i];
|
|
388
|
+
if (!Number.isFinite(v)) throw new RangeError(`ridgeSolve: the gram value ${i} is not finite.`);
|
|
389
|
+
a[i] = v;
|
|
390
|
+
}
|
|
391
|
+
const x = new Float64Array(k);
|
|
392
|
+
for (let i = 0; i < k; i++) {
|
|
393
|
+
const v = moment[i];
|
|
394
|
+
if (!Number.isFinite(v)) throw new RangeError(`ridgeSolve: the moment value ${i} is not finite.`);
|
|
395
|
+
x[i] = v;
|
|
396
|
+
a[i * k + i] = a[i * k + i] + penalty[i];
|
|
397
|
+
}
|
|
398
|
+
if (!factor(a, k)) return new Array(k).fill(NaN);
|
|
399
|
+
for (let i = 0; i < k; i++) {
|
|
400
|
+
let s = x[i];
|
|
401
|
+
for (let j = 0; j < i; j++) s -= a[i * k + j] * x[j];
|
|
402
|
+
x[i] = s / a[i * k + i];
|
|
403
|
+
}
|
|
404
|
+
for (let i = k - 1; i >= 0; i--) {
|
|
405
|
+
let s = x[i];
|
|
406
|
+
for (let j = i + 1; j < k; j++) s -= a[j * k + i] * x[j];
|
|
407
|
+
x[i] = s / a[i * k + i];
|
|
408
|
+
}
|
|
409
|
+
return Array.from(x);
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* This function writes the Cholesky factor `L` of `a` into its lower triangle, with `a = L L'`. It returns false when
|
|
413
|
+
* a pivot is not more than the tolerance times the diagonal value of its column.
|
|
414
|
+
*/
|
|
415
|
+
function factor(a, k) {
|
|
416
|
+
for (let j = 0; j < k; j++) {
|
|
417
|
+
const diagonal = a[j * k + j];
|
|
418
|
+
let d = diagonal;
|
|
419
|
+
for (let m = 0; m < j; m++) d -= a[j * k + m] ** 2;
|
|
420
|
+
if (!(d > PIVOT_TOLERANCE * Math.abs(diagonal)) || !(d > 0)) return false;
|
|
421
|
+
const l = Math.sqrt(d);
|
|
422
|
+
a[j * k + j] = l;
|
|
423
|
+
for (let i = j + 1; i < k; i++) {
|
|
424
|
+
let s = a[i * k + j];
|
|
425
|
+
for (let m = 0; m < j; m++) s -= a[i * k + m] * a[j * k + m];
|
|
426
|
+
a[i * k + j] = s / l;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
return true;
|
|
430
|
+
}
|
|
356
431
|
// src/tests.ts
|
|
357
432
|
/**
|
|
358
433
|
* The tests of a difference: the sign test, the paired permutation test, the Wilson interval of a proportion and
|
|
@@ -774,6 +849,6 @@ function calibration(forecasts) {
|
|
|
774
849
|
interval: wilson(hits, n)
|
|
775
850
|
}));
|
|
776
851
|
}
|
|
777
|
-
export { KENDALL_EXACT, Z95, binomialInterval, bootstrap, bootstrapClusters, bootstrapLeastSquares, bootstrapMedian, bootstrapMedianRatio, bootstrapTwo, brier, calibration, compareRatios, holm, kendallTau, leastSquares, mean, median, medianInterval, negativeBinomialInterval, noiseFloor, pairedPermutation, quantile, quantileSorted, ranks, sd, signTest, signTestPower, sorted, spearman, summarize, wilson };
|
|
852
|
+
export { KENDALL_EXACT, Z95, binomialInterval, bootstrap, bootstrapClusters, bootstrapLeastSquares, bootstrapMedian, bootstrapMedianRatio, bootstrapTwo, brier, calibration, compareRatios, holm, kendallTau, leastSquares, mean, median, medianInterval, negativeBinomialInterval, noiseFloor, pairedPermutation, quantile, quantileSorted, ranks, ridgeSolve, sd, signTest, signTestPower, sorted, spearman, summarize, wilson };
|
|
778
853
|
|
|
779
854
|
//# sourceMappingURL=index.js.map
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["whole"],"sources":["../src/describe.ts","../src/regression.ts","../src/bootstrap.ts","../src/tests.ts","../src/rank.ts","../src/discrete.ts","../src/compare.ts"],"sourcesContent":["/**\n * The descriptive statistics: the mean, the standard deviation, the median, the quantiles and a summary of a list.\n * Each function throws a RangeError for an empty list or for a value that is NaN. Thus a missing value cannot make a\n * quiet NaN in a record.\n */\n\n/** The two definitions of a quantile that the engines use (Hyndman and Fan, 1996). */\nexport type QuantileMethod =\n /** Type 7: a linear step between the two nearest ranks. The default of R and NumPy. */\n | \"linear\"\n /** Type 1: the smallest value with at least the share `p` of the values at or below it. */\n | \"nearest-rank\";\n\nfunction checked(name: string, values: readonly number[]): void {\n if (values.length === 0) throw new RangeError(`${name}: the list is empty.`);\n for (const v of values) if (Number.isNaN(v)) throw new RangeError(`${name}: the list has a NaN.`);\n}\n\n/** A new list with the values from the smallest to the largest. */\nexport function sorted(values: readonly number[]): number[] {\n return [...values].sort((a, b) => a - b);\n}\n\nexport function mean(values: readonly number[]): number {\n checked(\"mean\", values);\n let sum = 0;\n for (const v of values) sum += v;\n return sum / values.length;\n}\n\n/** The sample standard deviation (the divisor is n - 1). It needs 2 values or more. */\nexport function sd(values: readonly number[]): number {\n checked(\"sd\", values);\n if (values.length < 2) throw new RangeError(\"sd: the list needs 2 values or more.\");\n const m = mean(values);\n let sum = 0;\n for (const v of values) sum += (v - m) ** 2;\n return Math.sqrt(sum / (values.length - 1));\n}\n\n/**\n * The `p` quantile of a list that is already sorted. Use it when you take several quantiles of one list.\n * The linear method gives the same numbers as the copies in highways, packing and layout-contract. The\n * nearest-rank method gives the same numbers as the copies in lag, lag-hud and the backtest of highways.\n */\nexport function quantileSorted(sortedValues: readonly number[], p: number, method: QuantileMethod = \"linear\"): number {\n checked(\"quantile\", sortedValues);\n if (!(p >= 0 && p <= 1)) throw new RangeError(`quantile: p is from 0 to 1, not ${p}.`);\n const n = sortedValues.length;\n if (method === \"nearest-rank\") return sortedValues[Math.min(n - 1, Math.max(0, Math.ceil(p * n) - 1))] as number;\n const at = (n - 1) * p;\n const low = Math.floor(at);\n const part = at - low;\n const a = sortedValues[low] as number;\n if (part === 0) return a;\n const b = sortedValues[low + 1] as number;\n if (a === b) return a;\n return a + part * (b - a);\n}\n\n/** The `p` quantile of a list. */\nexport function quantile(values: readonly number[], p: number, method: QuantileMethod = \"linear\"): number {\n checked(\"quantile\", values);\n return quantileSorted(sorted(values), p, method);\n}\n\n/**\n * The median: the middle value, or the midpoint `(a + b) / 2` of the two middle values. The midpoint is correctly\n * rounded. `quantile(values, 0.5)` computes `a + 0.5 * (b - a)`, which can differ from it in the last bit.\n */\nexport function median(values: readonly number[]): number {\n checked(\"median\", values);\n const s = sorted(values);\n const middle = Math.floor(s.length / 2);\n return s.length % 2 === 1 ? (s[middle] as number) : ((s[middle - 1] as number) + (s[middle] as number)) / 2;\n}\n\n/** The summary of a list. The quartiles use the linear method. */\nexport interface Summary {\n readonly n: number;\n readonly mean: number;\n /** The sample standard deviation, or NaN for one value. */\n readonly sd: number;\n readonly min: number;\n /** The 0.25 quantile. */\n readonly q1: number;\n readonly median: number;\n /** The 0.75 quantile. */\n readonly q3: number;\n readonly max: number;\n /** The interquartile range: q3 - q1. */\n readonly iqr: number;\n}\n\nexport function summarize(values: readonly number[]): Summary {\n checked(\"summarize\", values);\n const s = sorted(values);\n const q1 = quantileSorted(s, 0.25);\n const q3 = quantileSorted(s, 0.75);\n return {\n n: s.length,\n // The mean and sd of the list in its own order, so that they are equal to mean(values) and sd(values).\n mean: mean(values),\n sd: s.length < 2 ? Number.NaN : sd(values),\n min: s[0] as number,\n q1,\n median: median(s),\n q3,\n max: s[s.length - 1] as number,\n iqr: q3 - q1,\n };\n}\n","/**\n * Ordinary least squares with a Householder QR decomposition. The QR decomposition does not square the condition\n * number of the design, as the normal equations do. A design without full rank gives NaN coefficients and does not\n * throw. Thus a bootstrap run with a singular draw is not finite, and it does not count.\n */\n\nexport interface LeastSquaresOptions {\n /** When true, the fit adds an intercept as coefficient 0. The default is true. */\n readonly intercept?: boolean;\n}\n\nexport interface LeastSquaresFit {\n /** The coefficients. With an intercept, coefficient 0 is the intercept and coefficient `j + 1` is predictor `j`. */\n readonly coefficients: number[];\n /** The residual standard deviation: the square root of the residual sum of squares divided by `n - k`. */\n readonly residualSd: number;\n /**\n * The coefficient of determination: 1 minus the residual sum of squares divided by the total sum of squares. With\n * an intercept, the total sum uses the distances from the mean of `y`. Without an intercept, it uses the values.\n */\n readonly r2: number;\n /** The number of rows. */\n readonly n: number;\n /** The number of coefficients, with the intercept. */\n readonly k: number;\n}\n\n/**\n * The relative tolerance of the rank test. A column is dependent when the part of it that is orthogonal to the\n * columns before it is shorter than this share of its length.\n */\nconst RANK_TOLERANCE = 1e-10;\n\n/**\n * The ordinary least-squares fit of `y` on the rows of `x`, with `k` coefficients. Each row has the same number of\n * predictors. The fit solves the problem with a Householder QR decomposition. When the design does not have full\n * rank, or when `n <= k`, the coefficients, `residualSd` and `r2` are NaN. When the total sum of squares is 0,\n * `r2` is NaN.\n *\n * This function throws a RangeError for an empty `x` and for rows of different lengths. It also throws\n * for `x` and `y` of different lengths, for a value that is not finite, and for a fit with no coefficient.\n */\nexport function leastSquares(x: readonly (readonly number[])[], y: readonly number[], options: LeastSquaresOptions = {}): LeastSquaresFit {\n const intercept = options.intercept ?? true;\n const k = checkedShape(\"leastSquares\", x, y, intercept);\n return fitRows(x, y, intercept, k);\n}\n\n/**\n * This function examines the shape and the values of a least-squares problem, and gives the number of\n * coefficients. It throws a RangeError for each fault.\n */\nexport function checkedShape(name: string, x: readonly (readonly number[])[], y: readonly number[], intercept: boolean): number {\n if (x.length === 0) throw new RangeError(`${name}: x is empty.`);\n if (x.length !== y.length) throw new RangeError(`${name}: x has ${x.length} rows and y has ${y.length} values. The two lengths must be equal.`);\n const p = (x[0] as readonly number[]).length;\n for (let i = 0; i < x.length; i++) {\n const row = x[i] as readonly number[];\n if (row.length !== p) throw new RangeError(`${name}: row ${i} of x has ${row.length} values, and row 0 has ${p}. Each row must have the same length.`);\n for (const v of row) if (!Number.isFinite(v)) throw new RangeError(`${name}: row ${i} of x has a value that is not finite.`);\n if (!Number.isFinite(y[i] as number)) throw new RangeError(`${name}: value ${i} of y is not finite.`);\n }\n const k = p + (intercept ? 1 : 0);\n if (k === 0) throw new RangeError(`${name}: the fit has no coefficient. Give a predictor or an intercept.`);\n return k;\n}\n\n/**\n * The fit of rows with a known shape. The caller examined the shape with `checkedShape`. The design is a matrix of\n * `n` rows and `k` columns, kept by column.\n */\nexport function fitRows(x: readonly (readonly number[])[], y: readonly number[], intercept: boolean, k: number): LeastSquaresFit {\n const n = x.length;\n const failed = (): LeastSquaresFit => ({ coefficients: new Array<number>(k).fill(Number.NaN), residualSd: Number.NaN, r2: Number.NaN, n, k });\n if (n <= k) return failed();\n const offset = intercept ? 1 : 0;\n const a = new Float64Array(n * k);\n for (let i = 0; i < n; i++) {\n const row = x[i] as readonly number[];\n if (intercept) a[i] = 1;\n for (let j = offset; j < k; j++) a[j * n + i] = row[j - offset] as number;\n }\n const qty = Float64Array.from(y);\n const diagonal = new Float64Array(k);\n for (let j = 0; j < k; j++) {\n const c = j * n;\n // A reflection keeps the length of a column. Thus the length of column j is the length of its first form.\n let head = 0;\n for (let i = 0; i < j; i++) head += (a[c + i] as number) ** 2;\n let tail2 = 0;\n for (let i = j; i < n; i++) tail2 += (a[c + i] as number) ** 2;\n // The tail is the part of column j that is orthogonal to the columns before it.\n const tail = Math.sqrt(tail2);\n if (!(tail > RANK_TOLERANCE * Math.sqrt(head + tail2))) return failed();\n const alpha = (a[c + j] as number) > 0 ? -tail : tail;\n // The Householder vector v is the tail of column j minus alpha times the first unit vector. It is kept in place.\n a[c + j] = (a[c + j] as number) - alpha;\n let vv = 0;\n for (let i = j; i < n; i++) vv += (a[c + i] as number) ** 2;\n const reflect = (target: Float64Array, start: number): void => {\n let dot = 0;\n for (let i = j; i < n; i++) dot += (a[c + i] as number) * (target[start + i] as number);\n const f = (2 * dot) / vv;\n for (let i = j; i < n; i++) target[start + i] = (target[start + i] as number) - f * (a[c + i] as number);\n };\n for (let m = j + 1; m < k; m++) reflect(a, m * n);\n reflect(qty, 0);\n diagonal[j] = alpha;\n }\n // The back substitution of R b = Q'y. Above the diagonal, R is in the columns of a.\n const b = new Array<number>(k).fill(0);\n for (let j = k - 1; j >= 0; j--) {\n let s = qty[j] as number;\n for (let m = j + 1; m < k; m++) s -= (a[m * n + j] as number) * (b[m] as number);\n b[j] = s / (diagonal[j] as number);\n }\n let center = 0;\n if (intercept) {\n for (const v of y) center += v;\n center /= n;\n }\n let rss = 0;\n let tss = 0;\n for (let i = 0; i < n; i++) {\n const row = x[i] as readonly number[];\n let fitted = intercept ? (b[0] as number) : 0;\n for (let j = offset; j < k; j++) fitted += (b[j] as number) * (row[j - offset] as number);\n rss += ((y[i] as number) - fitted) ** 2;\n tss += ((y[i] as number) - center) ** 2;\n }\n return { coefficients: b, residualSd: Math.sqrt(rss / (n - k)), r2: tss > 0 ? 1 - rss / tss : Number.NaN, n, k };\n}\n","/**\n * The percentile bootstrap. Each run draws n items with replacement (`below(n)` of rigor-generators, which is\n * `floor(next() * n)`), and computes the statistic of the sample. The interval is two quantiles of the statistics.\n * With the same seed, the draws are equal to the draws of the copies in highways, packing and layout-contract.\n * `bootstrapTwo` draws two independent samples in each run: first the items of `a`, then the items of `b`.\n * `bootstrapLeastSquares` draws whole rows, and gives one interval for each coefficient from the same draws.\n */\nimport { type Random, random } from \"@mark1russell7/rigor-generators\";\nimport { type QuantileMethod, median, quantileSorted, sorted } from \"./describe.ts\";\nimport { type LeastSquaresOptions, checkedShape, fitRows } from \"./regression.ts\";\n\nexport interface BootstrapOptions {\n /** The number of samples. The default is 10 000. */\n readonly runs?: number;\n /** The level of the interval. The default is 0.95. */\n readonly level?: number;\n /** The seed of the draws. The default is 1. */\n readonly seed?: number | string;\n /** The quantile method of the two ends of the interval. The default is linear. */\n readonly method?: QuantileMethod;\n /**\n * The quantiles of the two ends, in place of `level`, for example [0.025, 0.975] or an interval with one side.\n * The default is from the level: (1 - level) / 2 and 1 - (1 - level) / 2. In floating point, (1 - 0.95) / 2 is\n * not 0.025, so a copy that writes 0.025 needs this option to give the same numbers.\n */\n readonly ends?: readonly [number, number];\n}\n\nexport interface Interval {\n /** The statistic of all the data. */\n readonly estimate: number;\n readonly low: number;\n readonly high: number;\n readonly level: number;\n readonly runs: number;\n /** The number of runs whose statistic is a finite number. Only these runs make the interval. */\n readonly finite: number;\n /** The seed as a 32-bit number. */\n readonly seed: number;\n}\n\n/**\n * A percentile bootstrap interval of `statistic` over `data`. A run whose statistic is not finite (NaN or an\n * infinity) does not count. When no run is finite, low and high are equal to the estimate.\n */\nexport function bootstrap<T>(data: readonly T[], statistic: (sample: readonly T[]) => number, options: BootstrapOptions = {}): Interval {\n if (data.length === 0) throw new RangeError(\"bootstrap: the data is empty.\");\n const n = data.length;\n const sample = new Array<T>(n);\n return percentile(\n \"bootstrap\",\n options,\n (r) => {\n for (let i = 0; i < n; i++) sample[i] = data[r.below(n)] as T;\n return statistic(sample);\n },\n () => statistic(data),\n );\n}\n\n/**\n * A percentile bootstrap interval of `statistic` over two independent samples `a` and `b`. Use it when the two\n * samples are not paired, for example two arms of a benchmark. Each run draws `a.length` items of `a` with\n * replacement, and then `b.length` items of `b` with replacement. All the draws come from one stream of\n * `random(seed)`. The statistic reads the two drawn samples. The estimate is the statistic of all of `a` and `b`. A\n * run whose statistic is not finite does not count. When no run is finite, low and high are equal to the estimate.\n */\nexport function bootstrapTwo<A, B>(\n a: readonly A[],\n b: readonly B[],\n statistic: (a: readonly A[], b: readonly B[]) => number,\n options: BootstrapOptions = {},\n): Interval {\n if (a.length === 0) throw new RangeError(\"bootstrapTwo: the first sample is empty.\");\n if (b.length === 0) throw new RangeError(\"bootstrapTwo: the second sample is empty.\");\n const na = a.length;\n const nb = b.length;\n const sampleA = new Array<A>(na);\n const sampleB = new Array<B>(nb);\n return percentile(\n \"bootstrapTwo\",\n options,\n (r) => {\n for (let i = 0; i < na; i++) sampleA[i] = a[r.below(na)] as A;\n for (let i = 0; i < nb; i++) sampleB[i] = b[r.below(nb)] as B;\n return statistic(sampleA, sampleB);\n },\n () => statistic(a, b),\n );\n}\n\n/**\n * A bootstrap interval of the ratio `median(numerator) / median(denominator)` of two independent samples. The\n * interval is the uncertainty of the ratio of the two medians. It is not the spread of the samples. A run whose\n * denominator median is 0 is not finite, so it does not count.\n */\nexport function bootstrapMedianRatio(numerator: readonly number[], denominator: readonly number[], options: BootstrapOptions = {}): Interval {\n return bootstrapTwo(numerator, denominator, (a, b) => median(a) / median(b), options);\n}\n\n/**\n * A percentile bootstrap interval of each coefficient of the least-squares fit of `y` on the rows of `x`. Each run\n * draws `n` row indexes with replacement, and fits the drawn rows and their `y` values. All the intervals come from\n * the same draws. The estimate of each interval is the coefficient of the fit of all the data. A run with a singular\n * design gives NaN coefficients, so it does not count. The shape errors are the errors of `leastSquares`.\n */\nexport function bootstrapLeastSquares(\n x: readonly (readonly number[])[],\n y: readonly number[],\n options: BootstrapOptions & LeastSquaresOptions = {},\n): Interval[] {\n const intercept = options.intercept ?? true;\n const k = checkedShape(\"bootstrapLeastSquares\", x, y, intercept);\n const n = x.length;\n const sampleX = new Array<readonly number[]>(n);\n const sampleY = new Array<number>(n);\n return percentiles(\n \"bootstrapLeastSquares\",\n options,\n k,\n (r) => {\n for (let i = 0; i < n; i++) {\n const row = r.below(n);\n sampleX[i] = x[row] as readonly number[];\n sampleY[i] = y[row] as number;\n }\n return fitRows(sampleX, sampleY, intercept, k).coefficients;\n },\n () => fitRows(x, y, intercept, k).coefficients,\n );\n}\n\ninterface Settings {\n readonly runs: number;\n readonly lowEnd: number;\n readonly highEnd: number;\n readonly level: number;\n readonly method: QuantileMethod;\n}\n\n/** This function examines the options of a bootstrap, and gives the defaults. It throws a RangeError for each fault. */\nfunction settings(name: string, options: BootstrapOptions): Settings {\n const runs = options.runs ?? 10_000;\n if (!Number.isSafeInteger(runs) || runs < 1) throw new RangeError(`${name}: runs is a whole number of 1 or more, not ${runs}.`);\n const tail = (1 - (options.level ?? 0.95)) / 2;\n const [lowEnd, highEnd] = options.ends ?? [tail, 1 - tail];\n if (!(lowEnd >= 0 && lowEnd < highEnd && highEnd <= 1)) throw new RangeError(`${name}: the ends are 0 <= low < high <= 1, not ${lowEnd} and ${highEnd}.`);\n const level = options.ends ? highEnd - lowEnd : (options.level ?? 0.95);\n if (!(level > 0 && level < 1)) throw new RangeError(`${name}: level is more than 0 and less than 1, not ${level}.`);\n return { runs, lowEnd, highEnd, level, method: options.method ?? \"linear\" };\n}\n\n/** The interval of the finite statistics of the runs. When no run is finite, low and high are equal to the estimate. */\nfunction ends(values: number[], estimate: number, s: Settings, seed: number): Interval {\n const { runs, level } = s;\n if (values.length === 0) return { estimate, low: estimate, high: estimate, level, runs, finite: 0, seed };\n const v = sorted(values);\n return { estimate, low: quantileSorted(v, s.lowEnd, s.method), high: quantileSorted(v, s.highEnd, s.method), level, runs, finite: v.length, seed };\n}\n\n/**\n * The shared part of each percentile bootstrap. It examines the options, and starts one stream of `random(seed)`.\n * Each run gives the stream to `run`, which draws the samples and returns their statistic. Then `all` gives the\n * estimate. The order of the draws is the order in `run`.\n */\nfunction percentile(name: string, options: BootstrapOptions, run: (r: Random) => number, all: () => number): Interval {\n const s = settings(name, options);\n const r = random(options.seed ?? 1);\n const values: number[] = [];\n for (let i = 0; i < s.runs; i++) {\n const v = run(r);\n if (Number.isFinite(v)) values.push(v);\n }\n return ends(values, all(), s, r.seed);\n}\n\n/**\n * The percentile bootstrap of `k` statistics from the same draws. Each run gives `k` statistics. Each statistic\n * has its own count of finite runs.\n */\nfunction percentiles(name: string, options: BootstrapOptions, k: number, run: (r: Random) => readonly number[], all: () => readonly number[]): Interval[] {\n const s = settings(name, options);\n const r = random(options.seed ?? 1);\n const values = Array.from({ length: k }, (): number[] => []);\n for (let i = 0; i < s.runs; i++) {\n const v = run(r);\n for (let j = 0; j < k; j++) if (Number.isFinite(v[j])) (values[j] as number[]).push(v[j] as number);\n }\n const estimate = all();\n return values.map((list, j) => ends(list, estimate[j] as number, s, r.seed));\n}\n\n/** A bootstrap interval of the median. */\nexport function bootstrapMedian(values: readonly number[], options: BootstrapOptions = {}): Interval {\n return bootstrap(values, median, options);\n}\n\n/**\n * A cluster bootstrap: each run draws whole clusters with replacement, and the statistic reads the rows of the drawn\n * clusters. Use it when the rows of one cluster (one board, one seed, one site) are not independent. The clusters\n * are in the order of their first row.\n */\nexport function bootstrapClusters<T>(\n rows: readonly T[],\n cluster: (row: T) => string,\n statistic: (rows: readonly T[]) => number,\n options: BootstrapOptions = {},\n): Interval {\n const groups = new Map<string, T[]>();\n for (const row of rows) {\n const key = cluster(row);\n const list = groups.get(key);\n if (list) list.push(row);\n else groups.set(key, [row]);\n }\n const clusters = [...groups.values()];\n const result = bootstrap(clusters, (drawn) => statistic(drawn.flat()), options);\n // The estimate of all the rows in their own order, not in the order of the clusters.\n const estimate = statistic(rows);\n return result.finite === 0 ? { ...result, estimate, low: estimate, high: estimate } : { ...result, estimate };\n}\n","/**\n * The tests of a difference: the sign test, the paired permutation test, the Wilson interval of a proportion and\n * the Holm correction for several tests.\n */\nimport { random } from \"@mark1russell7/rigor-generators\";\nimport { mean } from \"./describe.ts\";\n\nfunction whole(name: string, value: number): void {\n if (!Number.isSafeInteger(value) || value < 0) throw new RangeError(`${name}: ${value} is not a whole number of 0 or more.`);\n}\n\n/** The log of each binomial term C(n, k) / 2^n, for each k from 0 to n. */\nfunction halfBinomialLogs(n: number): number[] {\n const logs: number[] = [];\n let logChoose = 0;\n for (let i = 0; i <= n; i++) {\n if (i > 0) logChoose += Math.log((n - i + 1) / i);\n logs.push(logChoose - n * Math.LN2);\n }\n return logs;\n}\n\n/** P(X >= k) for X ~ Binomial(n, 1/2), summed from the largest term so that a small tail keeps its digits. */\nfunction upperTail(k: number, n: number): number {\n if (k <= 0) return 1;\n if (k > n) return 0;\n const logs = halfBinomialLogs(n).slice(k);\n const top = Math.max(...logs);\n const sum = logs.reduce((s, l) => s + Math.exp(l - top), 0);\n return Math.min(1, Math.exp(top) * sum);\n}\n\n/**\n * The sign test of paired results: `better` inputs where the candidate wins and `worse` where it loses. The ties\n * do not count. One-sided (the default), it is the p of `better` wins or more if the two are equal. Two-sided, it is\n * two times the tail of the larger count, at most 1. The one-sided p is equal to `signTestP` of packing.\n */\nexport function signTest(better: number, worse: number, sides: 1 | 2 = 1): number {\n whole(\"signTest\", better);\n whole(\"signTest\", worse);\n const n = better + worse;\n if (n === 0) return 1;\n if (sides === 1) return upperTail(better, n);\n return Math.min(1, 2 * upperTail(Math.max(better, worse), n));\n}\n\n/**\n * The smallest number of wins out of `n` that the sign test calls significant at `level`. It is undefined when even\n * n wins out of n are not enough. Use it before a run, to know how many inputs a claim needs.\n */\nexport function signTestPower(n: number, level = 0.05, sides: 1 | 2 = 2): number | undefined {\n whole(\"signTestPower\", n);\n for (let k = Math.ceil(n / 2); k <= n; k++) if (signTest(k, n - k, sides) < level) return k;\n return undefined;\n}\n\n/** The z of a two-sided 95% interval. */\nexport const Z95 = 1.959963984540054;\n\n/** An interval of a proportion. */\nexport interface Proportion {\n readonly low: number;\n readonly high: number;\n}\n\n/**\n * The Wilson score interval of `k` successes in `n` trials (Wilson, 1927). It keeps its level for a small n and for\n * a proportion near 0 or 1, where the normal interval does not. For n = 0 the interval is 0 to 1.\n */\nexport function wilson(k: number, n: number, z: number = Z95): Proportion {\n whole(\"wilson\", k);\n whole(\"wilson\", n);\n if (k > n) throw new RangeError(`wilson: k ${k} is more than n ${n}.`);\n if (n === 0) return { low: 0, high: 1 };\n const p = k / n;\n const z2 = z * z;\n const denominator = 1 + z2 / n;\n const center = (p + z2 / (2 * n)) / denominator;\n const half = (z / denominator) * Math.sqrt((p * (1 - p)) / n + z2 / (4 * n * n));\n return { low: Math.max(0, center - half), high: Math.min(1, center + half) };\n}\n\n/** One test after the Holm correction. */\nexport interface Corrected {\n /** The p of the test. */\n readonly p: number;\n /** The p after the correction: compare it with the level of the whole family. */\n readonly adjusted: number;\n /** The adjusted p is less than the level. */\n readonly reject: boolean;\n}\n\n/**\n * The Holm step-down correction of a family of tests (Holm, 1979). It keeps the chance of one false claim or more\n * in the family at most `level`. It has no condition on how the tests depend on each other. The result is in the\n * order of the input.\n */\nexport function holm(pValues: readonly number[], level = 0.05): Corrected[] {\n for (const p of pValues) if (!(p >= 0 && p <= 1)) throw new RangeError(`holm: each p is from 0 to 1, not ${p}.`);\n const m = pValues.length;\n const order = pValues.map((p, i) => ({ p, i })).sort((a, b) => a.p - b.p || a.i - b.i);\n const adjusted = new Array<number>(m);\n let running = 0;\n order.forEach(({ p, i }, rank) => {\n running = Math.max(running, Math.min(1, (m - rank) * p));\n adjusted[i] = running;\n });\n return pValues.map((p, i) => ({ p, adjusted: adjusted[i] as number, reject: (adjusted[i] as number) < level }));\n}\n\nexport interface PermutationOptions {\n /** The number of random sign flips. The default is 10 000. */\n readonly runs?: number;\n /** The default is 1. */\n readonly seed?: number | string;\n /** The statistic of the differences. The default is the mean. */\n readonly statistic?: (differences: readonly number[]) => number;\n}\n\nexport interface PermutationResult {\n /** The statistic of the observed differences `candidate[i] - baseline[i]`. */\n readonly observed: number;\n /** The two-sided p: (1 + the flips with a statistic as far from 0 or farther) / (1 + runs). */\n readonly p: number;\n readonly runs: number;\n}\n\n/**\n * The paired permutation test (a random sign flip of each difference). It needs no normal distribution and uses\n * the size of each difference, which the sign test does not. A pair with a difference of 0 adds nothing.\n */\nexport function pairedPermutation(candidate: readonly number[], baseline: readonly number[], options: PermutationOptions = {}): PermutationResult {\n if (candidate.length !== baseline.length) throw new RangeError(`pairedPermutation: the lists have ${candidate.length} and ${baseline.length} values.`);\n const differences = candidate.map((c, i) => c - (baseline[i] as number));\n const statistic = options.statistic ?? mean;\n const runs = options.runs ?? 10_000;\n if (!Number.isSafeInteger(runs) || runs < 1) throw new RangeError(`pairedPermutation: runs is a whole number of 1 or more, not ${runs}.`);\n const observed = statistic(differences);\n const r = random(options.seed ?? 1);\n const flipped = new Array<number>(differences.length);\n let extreme = 0;\n for (let run = 0; run < runs; run++) {\n for (let i = 0; i < differences.length; i++) flipped[i] = r.next() < 0.5 ? -(differences[i] as number) : (differences[i] as number);\n // A small tolerance, so that a flip with the same statistic up to rounding counts as extreme.\n if (Math.abs(statistic(flipped)) >= Math.abs(observed) * (1 - 1e-12)) extreme++;\n }\n return { observed, p: (1 + extreme) / (1 + runs), runs };\n}\n","/**\n * Rank correlation: do two measures put the same items in the same order? Use it to test that a cheap proxy (a\n * predicted cost, a fast measure) orders the items as the real measure does.\n */\nimport { random } from \"@mark1russell7/rigor-generators\";\n\nfunction samePairs(name: string, a: readonly number[], b: readonly number[]): void {\n if (a.length !== b.length) throw new RangeError(`${name}: the lists have ${a.length} and ${b.length} values.`);\n for (const v of a) if (Number.isNaN(v)) throw new RangeError(`${name}: the first list has a NaN.`);\n for (const v of b) if (Number.isNaN(v)) throw new RangeError(`${name}: the second list has a NaN.`);\n}\n\n/** The ranks of the values, from 1. Equal values get the mean of their ranks. */\nexport function ranks(values: readonly number[]): number[] {\n const order = values.map((x, i) => [x, i] as const).sort((p, q) => p[0] - q[0]);\n const out = new Array<number>(values.length);\n for (let i = 0; i < order.length; ) {\n let j = i;\n while (j + 1 < order.length && (order[j + 1] as readonly [number, number])[0] === (order[i] as readonly [number, number])[0]) j++;\n for (let k = i; k <= j; k++) out[(order[k] as readonly [number, number])[1]] = (i + j) / 2 + 1;\n i = j + 1;\n }\n return out;\n}\n\n/**\n * The Spearman rank correlation: the Pearson correlation of the ranks, with mean ranks for ties. The value is from\n * -1 to 1. When one list has no spread, the value is 0. It is equal to the copy in the backtest of highways.\n */\nexport function spearman(a: readonly number[], b: readonly number[]): number {\n samePairs(\"spearman\", a, b);\n const ra = ranks(a);\n const rb = ranks(b);\n const mean = (xs: readonly number[]): number => xs.reduce((s, x) => s + x, 0) / xs.length;\n const ma = mean(ra);\n const mb = mean(rb);\n let num = 0;\n let da = 0;\n let db = 0;\n for (let i = 0; i < ra.length; i++) {\n num += ((ra[i] as number) - ma) * ((rb[i] as number) - mb);\n da += ((ra[i] as number) - ma) ** 2;\n db += ((rb[i] as number) - mb) ** 2;\n }\n return da === 0 || db === 0 ? 0 : num / Math.sqrt(da * db);\n}\n\n/** The largest number of values for which `kendallTau` examines each pair. Above it, a seeded sample of pairs. */\nexport const KENDALL_EXACT = 1500;\nconst KENDALL_SAMPLE = 200_000;\n\n/**\n * The Kendall tau-b of two lists (Kendall, 1938). The value is from -1 to 1. A pair with a tie in both lists does\n * not count. When the lists have fewer than 2 values, or no pair counts, the value is 1. Above `KENDALL_EXACT`\n * values, a seeded sample of 200 000 pairs gives an estimate. It is equal to the copy in highways.\n */\nexport function kendallTau(a: readonly number[], b: readonly number[], seed: number | string = 1): number {\n samePairs(\"kendallTau\", a, b);\n const n = a.length;\n if (n < 2) return 1;\n let concordant = 0;\n let discordant = 0;\n let tieA = 0;\n let tieB = 0;\n const visit = (i: number, j: number): void => {\n const da = Math.sign((a[i] as number) - (a[j] as number));\n const db = Math.sign((b[i] as number) - (b[j] as number));\n if (da === 0 && db === 0) return;\n if (da === 0) tieA++;\n else if (db === 0) tieB++;\n else if (da === db) concordant++;\n else discordant++;\n };\n if (n <= KENDALL_EXACT) {\n for (let i = 0; i < n; i++) for (let j = i + 1; j < n; j++) visit(i, j);\n } else {\n const r = random(seed);\n for (let k = 0; k < KENDALL_SAMPLE; k++) {\n const i = r.below(n);\n const j = r.below(n);\n if (i !== j) visit(i, j);\n }\n }\n const den = Math.sqrt((concordant + discordant + tieA) * (concordant + discordant + tieB));\n return den === 0 ? 1 : (concordant - discordant) / den;\n}\n","/**\n * The intervals that come from a discrete distribution. The interval of a median comes from the order statistics.\n * The central interval of a count comes from a binomial or a negative binomial distribution.\n */\nimport { sorted } from \"./describe.ts\";\n\nfunction whole(name: string, value: number): void {\n if (!Number.isSafeInteger(value) || value < 0) throw new RangeError(`${name}: ${value} is not a whole number of 0 or more.`);\n}\n\nfunction levelOf(name: string, level: number): number {\n if (!(level > 0 && level < 1)) throw new RangeError(`${name}: the level is more than 0 and less than 1, not ${level}.`);\n return (1 - level) / 2;\n}\n\n/** The chance of each count k from 0 to n of X ~ Binomial(n, p), from the logs of the terms. */\nfunction binomialTerms(n: number, p: number): number[] {\n if (p === 0) return Array.from({ length: n + 1 }, (_, k) => (k === 0 ? 1 : 0));\n if (p === 1) return Array.from({ length: n + 1 }, (_, k) => (k === n ? 1 : 0));\n const [logP, logQ] = [Math.log(p), Math.log1p(-p)];\n const terms: number[] = [];\n let logChoose = 0;\n for (let k = 0; k <= n; k++) {\n if (k > 0) logChoose += Math.log((n - k + 1) / k);\n terms.push(Math.exp(logChoose + k * logP + (n - k) * logQ));\n }\n return terms;\n}\n\n/** The distribution-free interval of a median, from two order statistics of the sample. */\nexport interface MedianInterval {\n readonly low: number;\n readonly high: number;\n /** The rank k of `low`, from 1. The interval is from x_(k) to x_(n + 1 - k) of the sorted values. */\n readonly rank: number;\n /** The chance that the interval holds the median of the population: 1 - 2 P(X <= k - 1), for X ~ Binomial(n, 1/2). */\n readonly coverage: number;\n}\n\n/**\n * The distribution-free interval of the median of a sample. It needs no assumption about the shape of the\n * distribution. It is x_(k) to x_(n + 1 - k), for the largest k whose two tails each hold (1 - level) / 2 or less.\n * For 11 values at the level 0.95, it is x_(2) to x_(10), with the coverage 0.988.\n *\n * A sample of 5 values or fewer has no rank with that coverage. Then the interval is the full range, and `coverage`\n * is less than `level`.\n */\nexport function medianInterval(values: readonly number[], level = 0.95): MedianInterval {\n if (values.length === 0) throw new RangeError(\"medianInterval: the list is empty.\");\n for (const v of values) if (Number.isNaN(v)) throw new RangeError(\"medianInterval: the list has a NaN.\");\n const tail = levelOf(\"medianInterval\", level);\n const s = sorted(values);\n const n = s.length;\n const terms = binomialTerms(n, 0.5);\n // The rank k + 1 is possible if P(X <= k), the tail that it leaves out on each side, is the tail or less.\n let k = 0;\n let below = terms[0] as number;\n while (k + 1 <= n / 2 && below <= tail) {\n k += 1;\n below += terms[k] as number;\n }\n const rank = Math.max(1, k);\n let left = 0;\n for (let i = 0; i < rank; i++) left += terms[i] as number;\n return { low: s[rank - 1] as number, high: s[n - rank] as number, rank, coverage: Math.max(0, 1 - 2 * left) };\n}\n\n/** A central interval of a count, from `low` to `high`, both included. */\nexport interface CountInterval {\n readonly low: number;\n readonly high: number;\n /** The chance of a count from `low` to `high`. It is `level` or more. */\n readonly coverage: number;\n}\n\n/**\n * The central interval of a count X ~ Binomial(n, p). `low` is the smallest k with P(X <= k) > (1 - level) / 2.\n * `high` is the largest k with P(X >= k) > (1 - level) / 2. Each tail outside the interval holds (1 - level) / 2\n * or less. The two tails are separate sums, so that a small upper tail keeps its digits.\n */\nexport function binomialInterval(n: number, p: number, level = 0.95): CountInterval {\n whole(\"binomialInterval\", n);\n if (!(p >= 0 && p <= 1)) throw new RangeError(`binomialInterval: p is from 0 to 1, not ${p}.`);\n const tail = levelOf(\"binomialInterval\", level);\n const terms = binomialTerms(n, p);\n let low = 0;\n let below = terms[0] as number;\n while (low < n && below <= tail) {\n low += 1;\n below += terms[low] as number;\n }\n let high = n;\n let above = terms[n] as number;\n while (high > 0 && above <= tail) {\n high -= 1;\n above += terms[high] as number;\n }\n let coverage = 0;\n for (let k = low; k <= high; k++) coverage += terms[k] as number;\n return { low, high, coverage: Math.min(1, coverage) };\n}\n\n/**\n * The central interval of a negative binomial count. X is the count of failures before `successes` successes, and\n * `p` is the chance of a success at each try. `low` is the smallest k with P(X <= k) > (1 - level) / 2.\n * `high` is the smallest k with P(X <= k) >= 1 - (1 - level) / 2.\n */\nexport function negativeBinomialInterval(successes: number, p: number, level = 0.95): CountInterval {\n whole(\"negativeBinomialInterval\", successes);\n if (!(p > 0 && p <= 1)) throw new RangeError(`negativeBinomialInterval: p is more than 0 and 1 or less, not ${p}.`);\n const tail = levelOf(\"negativeBinomialInterval\", level);\n const logQ = Math.log1p(-p);\n let logChance = successes * Math.log(p);\n let below = 0;\n let low = 0;\n for (let k = 0; ; k += 1) {\n const chance = Math.exp(logChance);\n if (below <= tail) low = k;\n if (below + chance >= 1 - tail) {\n let coverage = 0;\n let at = successes * Math.log(p);\n for (let i = 0; i <= k; i++) {\n if (i >= low) coverage += Math.exp(at);\n at += Math.log((i + successes) / (i + 1)) + logQ;\n }\n return { low, high: k, coverage: Math.min(1, coverage) };\n }\n below += chance;\n logChance += Math.log((k + successes) / (k + 1)) + logQ;\n }\n}\n","/**\n * The comparison of a candidate with a baseline, and the calibration of predictions. These functions make two fleet\n * rules into code. First, a change of a default is judged against the current default. The measure is the inputs that\n * gain and the inputs that lose beyond the noise, with the effect size. A sign test alone is not enough. Second, each\n * prediction states a probability, and the Brier score measures how good the stated probabilities were.\n */\nimport { median, quantileSorted, sd, sorted } from \"./describe.ts\";\nimport { type Proportion, signTest, wilson } from \"./tests.ts\";\n\nexport interface NoiseOptions {\n /** The number of standard deviations. The default is 2. */\n readonly k?: number;\n /** The fewest values (seeds or folds) that give a floor. The default is 5, the 5-seed rule. */\n readonly minimum?: number;\n}\n\n/**\n * The noise floor of a measure: k sample standard deviations of its value over independent seeds or folds. A\n * difference smaller than the floor is not a result.\n */\nexport function noiseFloor(values: readonly number[], options: NoiseOptions = {}): number {\n const minimum = options.minimum ?? 5;\n if (values.length < minimum) throw new RangeError(`noiseFloor: ${values.length} values; the rule needs ${minimum} or more seeds or folds.`);\n return (options.k ?? 2) * sd(values);\n}\n\nexport interface CompareOptions {\n /** \"higher\" (the default): a ratio above 1 is a gain. \"lower\": a ratio below 1 is a gain, as for a time or a cost. */\n readonly better?: \"higher\" | \"lower\";\n /** A ratio at this distance from 1 or nearer is a tie. The default is 0: only a ratio of exactly 1 is a tie. */\n readonly tie?: number;\n /** A gain or a loss counts only beyond this distance from 1. The default is 0. Use noiseFloor. */\n readonly noise?: number;\n}\n\n/** The effect on the inputs that are not ties. */\nexport interface Effect {\n readonly n: number;\n readonly median: number;\n /** The 0.1 quantile (linear). */\n readonly p10: number;\n /** The 0.9 quantile (linear). */\n readonly p90: number;\n}\n\nexport interface Comparison {\n /** The number of inputs. */\n readonly n: number;\n readonly ties: number;\n /** The inputs where the candidate is better, by any amount. */\n readonly wins: number;\n /** The inputs where the candidate is worse, by any amount. */\n readonly losses: number;\n /** The one-sided sign test of wins against losses. */\n readonly signP: number;\n /** The ratios of the inputs that are not ties, or undefined when each input is a tie. */\n readonly effect: Effect | undefined;\n /** The inputs that gain beyond the noise. */\n readonly gains: number;\n /** The inputs that lose beyond the noise. */\n readonly drops: number;\n /** gains / n, with its Wilson interval. */\n readonly gainShare: number;\n readonly gainInterval: Proportion;\n /** drops / n, with its Wilson interval. */\n readonly dropShare: number;\n readonly dropInterval: Proportion;\n}\n\n/**\n * The comparison of a candidate with a baseline, from the ratio candidate / baseline of each input. It answers the\n * three questions of a promotion. How often is the candidate better? By how much? How often is it worse beyond the\n * noise? A promotion reads `gains` against `drops` and `effect`, not `signP` alone, because a sign test counts a\n * win of any size.\n */\nexport function compareRatios(ratios: readonly number[], options: CompareOptions = {}): Comparison {\n if (ratios.length === 0) throw new RangeError(\"compareRatios: the list is empty.\");\n const sign = (options.better ?? \"higher\") === \"higher\" ? 1 : -1;\n const tie = options.tie ?? 0;\n const noise = options.noise ?? 0;\n if (!(tie >= 0) || !(noise >= 0)) throw new RangeError(\"compareRatios: tie and noise are 0 or more.\");\n let ties = 0;\n let wins = 0;\n let losses = 0;\n let gains = 0;\n let drops = 0;\n const changed: number[] = [];\n for (const ratio of ratios) {\n if (!Number.isFinite(ratio)) throw new RangeError(`compareRatios: each ratio is a finite number, not ${ratio}.`);\n const d = sign * (ratio - 1);\n if (Math.abs(ratio - 1) <= tie) {\n ties++;\n continue;\n }\n changed.push(ratio);\n if (d > 0) wins++;\n else losses++;\n if (d > noise) gains++;\n else if (-d > noise) drops++;\n }\n const n = ratios.length;\n const s = sorted(changed);\n const effect = s.length === 0 ? undefined : { n: s.length, median: median(s), p10: quantileSorted(s, 0.1), p90: quantileSorted(s, 0.9) };\n return {\n n,\n ties,\n wins,\n losses,\n signP: signTest(wins, losses),\n effect,\n gains,\n drops,\n gainShare: gains / n,\n gainInterval: wilson(gains, n),\n dropShare: drops / n,\n dropInterval: wilson(drops, n),\n };\n}\n\n/** A prediction: the stated probability that the claim holds, and if it held. */\nexport interface Forecast {\n readonly p: number;\n readonly hit: boolean;\n}\n\nfunction checkedForecasts(name: string, forecasts: readonly Forecast[]): void {\n if (forecasts.length === 0) throw new RangeError(`${name}: the list is empty.`);\n for (const f of forecasts) if (!(f.p >= 0 && f.p <= 1)) throw new RangeError(`${name}: each p is from 0 to 1, not ${f.p}.`);\n}\n\n/** The Brier score: the mean of (p - outcome)^2. 0 is perfect, and 0.25 is a constant 0.5. Lower is better. */\nexport function brier(forecasts: readonly Forecast[]): number {\n checkedForecasts(\"brier\", forecasts);\n let sum = 0;\n for (const f of forecasts) sum += (f.p - (f.hit ? 1 : 0)) ** 2;\n return sum / forecasts.length;\n}\n\n/** The predictions of one stated level. */\nexport interface CalibrationLevel {\n readonly stated: number;\n readonly n: number;\n readonly hits: number;\n /** hits / n. A calibrated level has a rate near `stated`. */\n readonly rate: number;\n /** The Wilson interval of the rate. A level is overconfident when `stated` is above it. */\n readonly interval: Proportion;\n}\n\n/** The hit rate of each stated level, from the lowest level. */\nexport function calibration(forecasts: readonly Forecast[]): CalibrationLevel[] {\n checkedForecasts(\"calibration\", forecasts);\n const levels = new Map<number, { n: number; hits: number }>();\n for (const f of forecasts) {\n const level = levels.get(f.p) ?? { n: 0, hits: 0 };\n level.n++;\n if (f.hit) level.hits++;\n levels.set(f.p, level);\n }\n return [...levels]\n .sort((a, b) => a[0] - b[0])\n .map(([stated, { n, hits }]) => ({ stated, n, hits, rate: hits / n, interval: wilson(hits, n) }));\n}\n"],"mappings":";;AAaA,SAAS,QAAQ,MAAc,QAAiC;CAC9D,IAAI,OAAO,WAAW,GAAG,MAAM,IAAI,WAAW,GAAG,KAAK,qBAAqB;CAC3E,KAAK,MAAM,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,GAAG,MAAM,IAAI,WAAW,GAAG,KAAK,sBAAsB;AAClG;;AAGA,SAAgB,OAAO,QAAqC;CAC1D,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC;AACzC;AAEA,SAAgB,KAAK,QAAmC;CACtD,QAAQ,QAAQ,MAAM;CACtB,IAAI,MAAM;CACV,KAAK,MAAM,KAAK,QAAQ,OAAO;CAC/B,OAAO,MAAM,OAAO;AACtB;;AAGA,SAAgB,GAAG,QAAmC;CACpD,QAAQ,MAAM,MAAM;CACpB,IAAI,OAAO,SAAS,GAAG,MAAM,IAAI,WAAW,sCAAsC;CAClF,MAAM,IAAI,KAAK,MAAM;CACrB,IAAI,MAAM;CACV,KAAK,MAAM,KAAK,QAAQ,QAAQ,IAAI,MAAM;CAC1C,OAAO,KAAK,KAAK,OAAO,OAAO,SAAS,EAAE;AAC5C;;;;;;AAOA,SAAgB,eAAe,cAAiC,GAAW,SAAyB,UAAkB;CACpH,QAAQ,YAAY,YAAY;CAChC,IAAI,EAAE,KAAK,KAAK,KAAK,IAAI,MAAM,IAAI,WAAW,mCAAmC,EAAE,EAAE;CACrF,MAAM,IAAI,aAAa;CACvB,IAAI,WAAW,gBAAgB,OAAO,aAAa,KAAK,IAAI,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC;CACpG,MAAM,MAAM,IAAI,KAAK;CACrB,MAAM,MAAM,KAAK,MAAM,EAAE;CACzB,MAAM,OAAO,KAAK;CAClB,MAAM,IAAI,aAAa;CACvB,IAAI,SAAS,GAAG,OAAO;CACvB,MAAM,IAAI,aAAa,MAAM;CAC7B,IAAI,MAAM,GAAG,OAAO;CACpB,OAAO,IAAI,QAAQ,IAAI;AACzB;;AAGA,SAAgB,SAAS,QAA2B,GAAW,SAAyB,UAAkB;CACxG,QAAQ,YAAY,MAAM;CAC1B,OAAO,eAAe,OAAO,MAAM,GAAG,GAAG,MAAM;AACjD;;;;;AAMA,SAAgB,OAAO,QAAmC;CACxD,QAAQ,UAAU,MAAM;CACxB,MAAM,IAAI,OAAO,MAAM;CACvB,MAAM,SAAS,KAAK,MAAM,EAAE,SAAS,CAAC;CACtC,OAAO,EAAE,SAAS,MAAM,IAAK,EAAE,WAAuB,EAAE,SAAS,KAAiB,EAAE,WAAsB;AAC5G;AAmBA,SAAgB,UAAU,QAAoC;CAC5D,QAAQ,aAAa,MAAM;CAC3B,MAAM,IAAI,OAAO,MAAM;CACvB,MAAM,KAAK,eAAe,GAAG,GAAI;CACjC,MAAM,KAAK,eAAe,GAAG,GAAI;CACjC,OAAO;EACL,GAAG,EAAE;EAEL,MAAM,KAAK,MAAM;EACjB,IAAI,EAAE,SAAS,IAAI,MAAa,GAAG,MAAM;EACzC,KAAK,EAAE;EACP;EACA,QAAQ,OAAO,CAAC;EAChB;EACA,KAAK,EAAE,EAAE,SAAS;EAClB,KAAK,KAAK;CACZ;AACF;;;;;;AChFA,MAAM,iBAAiB;;;;;;;;;;AAWvB,SAAgB,aAAa,GAAmC,GAAsB,UAA+B,CAAC,GAAoB;CACxI,MAAM,YAAY,QAAQ,aAAa;CAEvC,OAAO,QAAQ,GAAG,GAAG,WADX,aAAa,gBAAgB,GAAG,GAAG,SACb,CAAC;AACnC;;;;;AAMA,SAAgB,aAAa,MAAc,GAAmC,GAAsB,WAA4B;CAC9H,IAAI,EAAE,WAAW,GAAG,MAAM,IAAI,WAAW,GAAG,KAAK,cAAc;CAC/D,IAAI,EAAE,WAAW,EAAE,QAAQ,MAAM,IAAI,WAAW,GAAG,KAAK,UAAU,EAAE,OAAO,kBAAkB,EAAE,OAAO,wCAAwC;CAC9I,MAAM,IAAK,EAAE,EAAE,CAAuB;CACtC,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;EACjC,MAAM,MAAM,EAAE;EACd,IAAI,IAAI,WAAW,GAAG,MAAM,IAAI,WAAW,GAAG,KAAK,QAAQ,EAAE,YAAY,IAAI,OAAO,yBAAyB,EAAE,sCAAsC;EACrJ,KAAK,MAAM,KAAK,KAAK,IAAI,CAAC,OAAO,SAAS,CAAC,GAAG,MAAM,IAAI,WAAW,GAAG,KAAK,QAAQ,EAAE,sCAAsC;EAC3H,IAAI,CAAC,OAAO,SAAS,EAAE,EAAY,GAAG,MAAM,IAAI,WAAW,GAAG,KAAK,UAAU,EAAE,qBAAqB;CACtG;CACA,MAAM,IAAI,KAAK,YAAY,IAAI;CAC/B,IAAI,MAAM,GAAG,MAAM,IAAI,WAAW,GAAG,KAAK,gEAAgE;CAC1G,OAAO;AACT;;;;;AAMA,SAAgB,QAAQ,GAAmC,GAAsB,WAAoB,GAA4B;CAC/H,MAAM,IAAI,EAAE;CACZ,MAAM,gBAAiC;EAAE,cAAc,IAAI,MAAc,CAAC,CAAC,CAAC,KAAK,GAAU;EAAG,YAAY;EAAY,IAAI;EAAY;EAAG;CAAE;CAC3I,IAAI,KAAK,GAAG,OAAO,OAAO;CAC1B,MAAM,SAAS,YAAY,IAAI;CAC/B,MAAM,IAAI,IAAI,aAAa,IAAI,CAAC;CAChC,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;EAC1B,MAAM,MAAM,EAAE;EACd,IAAI,WAAW,EAAE,KAAK;EACtB,KAAK,IAAI,IAAI,QAAQ,IAAI,GAAG,KAAK,EAAE,IAAI,IAAI,KAAK,IAAI,IAAI;CAC1D;CACA,MAAM,MAAM,aAAa,KAAK,CAAC;CAC/B,MAAM,WAAW,IAAI,aAAa,CAAC;CACnC,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;EAC1B,MAAM,IAAI,IAAI;EAEd,IAAI,OAAO;EACX,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,QAAS,EAAE,IAAI,MAAiB;EAC5D,IAAI,QAAQ;EACZ,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,SAAU,EAAE,IAAI,MAAiB;EAE7D,MAAM,OAAO,KAAK,KAAK,KAAK;EAC5B,IAAI,EAAE,OAAO,iBAAiB,KAAK,KAAK,OAAO,KAAK,IAAI,OAAO,OAAO;EACtE,MAAM,QAAS,EAAE,IAAI,KAAgB,IAAI,CAAC,OAAO;EAEjD,EAAE,IAAI,KAAM,EAAE,IAAI,KAAgB;EAClC,IAAI,KAAK;EACT,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,MAAO,EAAE,IAAI,MAAiB;EAC1D,MAAM,WAAW,QAAsB,UAAwB;GAC7D,IAAI,MAAM;GACV,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,OAAQ,EAAE,IAAI,KAAiB,OAAO,QAAQ;GAC1E,MAAM,IAAK,IAAI,MAAO;GACtB,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,OAAO,QAAQ,KAAM,OAAO,QAAQ,KAAgB,IAAK,EAAE,IAAI;EAC7F;EACA,KAAK,IAAI,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,QAAQ,GAAG,IAAI,CAAC;EAChD,QAAQ,KAAK,CAAC;EACd,SAAS,KAAK;CAChB;CAEA,MAAM,IAAI,IAAI,MAAc,CAAC,CAAC,CAAC,KAAK,CAAC;CACrC,KAAK,IAAI,IAAI,IAAI,GAAG,KAAK,GAAG,KAAK;EAC/B,IAAI,IAAI,IAAI;EACZ,KAAK,IAAI,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,KAAM,EAAE,IAAI,IAAI,KAAiB,EAAE;EACnE,EAAE,KAAK,IAAK,SAAS;CACvB;CACA,IAAI,SAAS;CACb,IAAI,WAAW;EACb,KAAK,MAAM,KAAK,GAAG,UAAU;EAC7B,UAAU;CACZ;CACA,IAAI,MAAM;CACV,IAAI,MAAM;CACV,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;EAC1B,MAAM,MAAM,EAAE;EACd,IAAI,SAAS,YAAa,EAAE,KAAgB;EAC5C,KAAK,IAAI,IAAI,QAAQ,IAAI,GAAG,KAAK,UAAW,EAAE,KAAiB,IAAI,IAAI;EACvE,QAAS,EAAE,KAAgB,WAAW;EACtC,QAAS,EAAE,KAAgB,WAAW;CACxC;CACA,OAAO;EAAE,cAAc;EAAG,YAAY,KAAK,KAAK,OAAO,IAAI,EAAE;EAAG,IAAI,MAAM,IAAI,IAAI,MAAM,MAAM;EAAY;EAAG;CAAE;AACjH;;;;;;;;;;;;;ACtFA,SAAgB,UAAa,MAAoB,WAA6C,UAA4B,CAAC,GAAa;CACtI,IAAI,KAAK,WAAW,GAAG,MAAM,IAAI,WAAW,+BAA+B;CAC3E,MAAM,IAAI,KAAK;CACf,MAAM,SAAS,IAAI,MAAS,CAAC;CAC7B,OAAO,WACL,aACA,UACC,MAAM;EACL,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,OAAO,KAAK,KAAK,EAAE,MAAM,CAAC;EACtD,OAAO,UAAU,MAAM;CACzB,SACM,UAAU,IAAI,CACtB;AACF;;;;;;;;AASA,SAAgB,aACd,GACA,GACA,WACA,UAA4B,CAAC,GACnB;CACV,IAAI,EAAE,WAAW,GAAG,MAAM,IAAI,WAAW,0CAA0C;CACnF,IAAI,EAAE,WAAW,GAAG,MAAM,IAAI,WAAW,2CAA2C;CACpF,MAAM,KAAK,EAAE;CACb,MAAM,KAAK,EAAE;CACb,MAAM,UAAU,IAAI,MAAS,EAAE;CAC/B,MAAM,UAAU,IAAI,MAAS,EAAE;CAC/B,OAAO,WACL,gBACA,UACC,MAAM;EACL,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK,QAAQ,KAAK,EAAE,EAAE,MAAM,EAAE;EACtD,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK,QAAQ,KAAK,EAAE,EAAE,MAAM,EAAE;EACtD,OAAO,UAAU,SAAS,OAAO;CACnC,SACM,UAAU,GAAG,CAAC,CACtB;AACF;;;;;;AAOA,SAAgB,qBAAqB,WAA8B,aAAgC,UAA4B,CAAC,GAAa;CAC3I,OAAO,aAAa,WAAW,cAAc,GAAG,MAAM,OAAO,CAAC,IAAI,OAAO,CAAC,GAAG,OAAO;AACtF;;;;;;;AAQA,SAAgB,sBACd,GACA,GACA,UAAkD,CAAC,GACvC;CACZ,MAAM,YAAY,QAAQ,aAAa;CACvC,MAAM,IAAI,aAAa,yBAAyB,GAAG,GAAG,SAAS;CAC/D,MAAM,IAAI,EAAE;CACZ,MAAM,UAAU,IAAI,MAAyB,CAAC;CAC9C,MAAM,UAAU,IAAI,MAAc,CAAC;CACnC,OAAO,YACL,yBACA,SACA,IACC,MAAM;EACL,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;GAC1B,MAAM,MAAM,EAAE,MAAM,CAAC;GACrB,QAAQ,KAAK,EAAE;GACf,QAAQ,KAAK,EAAE;EACjB;EACA,OAAO,QAAQ,SAAS,SAAS,WAAW,CAAC,CAAC,CAAC;CACjD,SACM,QAAQ,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC,YACpC;AACF;;AAWA,SAAS,SAAS,MAAc,SAAqC;CACnE,MAAM,OAAO,QAAQ,QAAQ;CAC7B,IAAI,CAAC,OAAO,cAAc,IAAI,KAAK,OAAO,GAAG,MAAM,IAAI,WAAW,GAAG,KAAK,6CAA6C,KAAK,EAAE;CAC9H,MAAM,QAAQ,KAAK,QAAQ,SAAS,QAAS;CAC7C,MAAM,CAAC,QAAQ,WAAW,QAAQ,QAAQ,CAAC,MAAM,IAAI,IAAI;CACzD,IAAI,EAAE,UAAU,KAAK,SAAS,WAAW,WAAW,IAAI,MAAM,IAAI,WAAW,GAAG,KAAK,2CAA2C,OAAO,OAAO,QAAQ,EAAE;CACxJ,MAAM,QAAQ,QAAQ,OAAO,UAAU,SAAU,QAAQ,SAAS;CAClE,IAAI,EAAE,QAAQ,KAAK,QAAQ,IAAI,MAAM,IAAI,WAAW,GAAG,KAAK,8CAA8C,MAAM,EAAE;CAClH,OAAO;EAAE;EAAM;EAAQ;EAAS;EAAO,QAAQ,QAAQ,UAAU;CAAS;AAC5E;;AAGA,SAAS,KAAK,QAAkB,UAAkB,GAAa,MAAwB;CACrF,MAAM,EAAE,MAAM,UAAU;CACxB,IAAI,OAAO,WAAW,GAAG,OAAO;EAAE;EAAU,KAAK;EAAU,MAAM;EAAU;EAAO;EAAM,QAAQ;EAAG;CAAK;CACxG,MAAM,IAAI,OAAO,MAAM;CACvB,OAAO;EAAE;EAAU,KAAK,eAAe,GAAG,EAAE,QAAQ,EAAE,MAAM;EAAG,MAAM,eAAe,GAAG,EAAE,SAAS,EAAE,MAAM;EAAG;EAAO;EAAM,QAAQ,EAAE;EAAQ;CAAK;AACnJ;;;;;;AAOA,SAAS,WAAW,MAAc,SAA2B,KAA4B,KAA6B;CACpH,MAAM,IAAI,SAAS,MAAM,OAAO;CAChC,MAAM,IAAI,OAAO,QAAQ,QAAQ,CAAC;CAClC,MAAM,SAAmB,CAAC;CAC1B,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE,MAAM,KAAK;EAC/B,MAAM,IAAI,IAAI,CAAC;EACf,IAAI,OAAO,SAAS,CAAC,GAAG,OAAO,KAAK,CAAC;CACvC;CACA,OAAO,KAAK,QAAQ,IAAI,GAAG,GAAG,EAAE,IAAI;AACtC;;;;;AAMA,SAAS,YAAY,MAAc,SAA2B,GAAW,KAAuC,KAA0C;CACxJ,MAAM,IAAI,SAAS,MAAM,OAAO;CAChC,MAAM,IAAI,OAAO,QAAQ,QAAQ,CAAC;CAClC,MAAM,SAAS,MAAM,KAAK,EAAE,QAAQ,EAAE,SAAmB,CAAC,CAAC;CAC3D,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE,MAAM,KAAK;EAC/B,MAAM,IAAI,IAAI,CAAC;EACf,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,IAAI,OAAO,SAAS,EAAE,EAAE,GAAG,OAAQ,EAAE,CAAc,KAAK,EAAE,EAAY;CACpG;CACA,MAAM,WAAW,IAAI;CACrB,OAAO,OAAO,KAAK,MAAM,MAAM,KAAK,MAAM,SAAS,IAAc,GAAG,EAAE,IAAI,CAAC;AAC7E;;AAGA,SAAgB,gBAAgB,QAA2B,UAA4B,CAAC,GAAa;CACnG,OAAO,UAAU,QAAQ,QAAQ,OAAO;AAC1C;;;;;;AAOA,SAAgB,kBACd,MACA,SACA,WACA,UAA4B,CAAC,GACnB;CACV,MAAM,yBAAS,IAAI,IAAiB;CACpC,KAAK,MAAM,OAAO,MAAM;EACtB,MAAM,MAAM,QAAQ,GAAG;EACvB,MAAM,OAAO,OAAO,IAAI,GAAG;EAC3B,IAAI,MAAM,KAAK,KAAK,GAAG;OAClB,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC;CAC5B;CAEA,MAAM,SAAS,UAAU,CADP,GAAG,OAAO,OAAO,CACH,IAAI,UAAU,UAAU,MAAM,KAAK,CAAC,GAAG,OAAO;CAE9E,MAAM,WAAW,UAAU,IAAI;CAC/B,OAAO,OAAO,WAAW,IAAI;EAAE,GAAG;EAAQ;EAAU,KAAK;EAAU,MAAM;CAAS,IAAI;EAAE,GAAG;EAAQ;CAAS;AAC9G;;;;;;ACrNA,SAASA,QAAM,MAAc,OAAqB;CAChD,IAAI,CAAC,OAAO,cAAc,KAAK,KAAK,QAAQ,GAAG,MAAM,IAAI,WAAW,GAAG,KAAK,IAAI,MAAM,qCAAqC;AAC7H;;AAGA,SAAS,iBAAiB,GAAqB;CAC7C,MAAM,OAAiB,CAAC;CACxB,IAAI,YAAY;CAChB,KAAK,IAAI,IAAI,GAAG,KAAK,GAAG,KAAK;EAC3B,IAAI,IAAI,GAAG,aAAa,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC;EAChD,KAAK,KAAK,YAAY,IAAI,KAAK,GAAG;CACpC;CACA,OAAO;AACT;;AAGA,SAAS,UAAU,GAAW,GAAmB;CAC/C,IAAI,KAAK,GAAG,OAAO;CACnB,IAAI,IAAI,GAAG,OAAO;CAClB,MAAM,OAAO,iBAAiB,CAAC,CAAC,CAAC,MAAM,CAAC;CACxC,MAAM,MAAM,KAAK,IAAI,GAAG,IAAI;CAC5B,MAAM,MAAM,KAAK,QAAQ,GAAG,MAAM,IAAI,KAAK,IAAI,IAAI,GAAG,GAAG,CAAC;CAC1D,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,IAAI,GAAG;AACxC;;;;;;AAOA,SAAgB,SAAS,QAAgB,OAAe,QAAe,GAAW;CAChF,QAAM,YAAY,MAAM;CACxB,QAAM,YAAY,KAAK;CACvB,MAAM,IAAI,SAAS;CACnB,IAAI,MAAM,GAAG,OAAO;CACpB,IAAI,UAAU,GAAG,OAAO,UAAU,QAAQ,CAAC;CAC3C,OAAO,KAAK,IAAI,GAAG,IAAI,UAAU,KAAK,IAAI,QAAQ,KAAK,GAAG,CAAC,CAAC;AAC9D;;;;;AAMA,SAAgB,cAAc,GAAW,QAAQ,KAAM,QAAe,GAAuB;CAC3F,QAAM,iBAAiB,CAAC;CACxB,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI,CAAC,GAAG,KAAK,GAAG,KAAK,IAAI,SAAS,GAAG,IAAI,GAAG,KAAK,IAAI,OAAO,OAAO;AAE5F;;AAGA,MAAa,MAAM;;;;;AAYnB,SAAgB,OAAO,GAAW,GAAW,IAAY,KAAiB;CACxE,QAAM,UAAU,CAAC;CACjB,QAAM,UAAU,CAAC;CACjB,IAAI,IAAI,GAAG,MAAM,IAAI,WAAW,aAAa,EAAE,kBAAkB,EAAE,EAAE;CACrE,IAAI,MAAM,GAAG,OAAO;EAAE,KAAK;EAAG,MAAM;CAAE;CACtC,MAAM,IAAI,IAAI;CACd,MAAM,KAAK,IAAI;CACf,MAAM,cAAc,IAAI,KAAK;CAC7B,MAAM,UAAU,IAAI,MAAM,IAAI,MAAM;CACpC,MAAM,OAAQ,IAAI,cAAe,KAAK,KAAM,KAAK,IAAI,KAAM,IAAI,MAAM,IAAI,IAAI,EAAE;CAC/E,OAAO;EAAE,KAAK,KAAK,IAAI,GAAG,SAAS,IAAI;EAAG,MAAM,KAAK,IAAI,GAAG,SAAS,IAAI;CAAE;AAC7E;;;;;;AAiBA,SAAgB,KAAK,SAA4B,QAAQ,KAAmB;CAC1E,KAAK,MAAM,KAAK,SAAS,IAAI,EAAE,KAAK,KAAK,KAAK,IAAI,MAAM,IAAI,WAAW,oCAAoC,EAAE,EAAE;CAC/G,MAAM,IAAI,QAAQ;CAClB,MAAM,QAAQ,QAAQ,KAAK,GAAG,OAAO;EAAE;EAAG;CAAE,EAAE,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;CACrF,MAAM,WAAW,IAAI,MAAc,CAAC;CACpC,IAAI,UAAU;CACd,MAAM,SAAS,EAAE,GAAG,KAAK,SAAS;EAChC,UAAU,KAAK,IAAI,SAAS,KAAK,IAAI,IAAI,IAAI,QAAQ,CAAC,CAAC;EACvD,SAAS,KAAK;CAChB,CAAC;CACD,OAAO,QAAQ,KAAK,GAAG,OAAO;EAAE;EAAG,UAAU,SAAS;EAAc,QAAS,SAAS,KAAgB;CAAM,EAAE;AAChH;;;;;AAuBA,SAAgB,kBAAkB,WAA8B,UAA6B,UAA8B,CAAC,GAAsB;CAChJ,IAAI,UAAU,WAAW,SAAS,QAAQ,MAAM,IAAI,WAAW,qCAAqC,UAAU,OAAO,OAAO,SAAS,OAAO,SAAS;CACrJ,MAAM,cAAc,UAAU,KAAK,GAAG,MAAM,IAAK,SAAS,EAAa;CACvE,MAAM,YAAY,QAAQ,aAAa;CACvC,MAAM,OAAO,QAAQ,QAAQ;CAC7B,IAAI,CAAC,OAAO,cAAc,IAAI,KAAK,OAAO,GAAG,MAAM,IAAI,WAAW,+DAA+D,KAAK,EAAE;CACxI,MAAM,WAAW,UAAU,WAAW;CACtC,MAAM,IAAI,OAAO,QAAQ,QAAQ,CAAC;CAClC,MAAM,UAAU,IAAI,MAAc,YAAY,MAAM;CACpD,IAAI,UAAU;CACd,KAAK,IAAI,MAAM,GAAG,MAAM,MAAM,OAAO;EACnC,KAAK,IAAI,IAAI,GAAG,IAAI,YAAY,QAAQ,KAAK,QAAQ,KAAK,EAAE,KAAK,IAAI,KAAM,CAAE,YAAY,KAAiB,YAAY;EAEtH,IAAI,KAAK,IAAI,UAAU,OAAO,CAAC,KAAK,KAAK,IAAI,QAAQ,KAAK,IAAI,QAAQ;CACxE;CACA,OAAO;EAAE;EAAU,IAAI,IAAI,YAAY,IAAI;EAAO;CAAK;AACzD;;;;;;AC7IA,SAAS,UAAU,MAAc,GAAsB,GAA4B;CACjF,IAAI,EAAE,WAAW,EAAE,QAAQ,MAAM,IAAI,WAAW,GAAG,KAAK,mBAAmB,EAAE,OAAO,OAAO,EAAE,OAAO,SAAS;CAC7G,KAAK,MAAM,KAAK,GAAG,IAAI,OAAO,MAAM,CAAC,GAAG,MAAM,IAAI,WAAW,GAAG,KAAK,4BAA4B;CACjG,KAAK,MAAM,KAAK,GAAG,IAAI,OAAO,MAAM,CAAC,GAAG,MAAM,IAAI,WAAW,GAAG,KAAK,6BAA6B;AACpG;;AAGA,SAAgB,MAAM,QAAqC;CACzD,MAAM,QAAQ,OAAO,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAU,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,EAAE;CAC9E,MAAM,MAAM,IAAI,MAAc,OAAO,MAAM;CAC3C,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,SAAU;EAClC,IAAI,IAAI;EACR,OAAO,IAAI,IAAI,MAAM,UAAW,MAAM,IAAI,EAAE,CAA+B,OAAQ,MAAM,EAAE,CAA+B,IAAI;EAC9H,KAAK,IAAI,IAAI,GAAG,KAAK,GAAG,KAAK,IAAK,MAAM,EAAE,CAA+B,OAAO,IAAI,KAAK,IAAI;EAC7F,IAAI,IAAI;CACV;CACA,OAAO;AACT;;;;;AAMA,SAAgB,SAAS,GAAsB,GAA8B;CAC3E,UAAU,YAAY,GAAG,CAAC;CAC1B,MAAM,KAAK,MAAM,CAAC;CAClB,MAAM,KAAK,MAAM,CAAC;CAClB,MAAM,QAAQ,OAAkC,GAAG,QAAQ,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,GAAG;CACnF,MAAM,KAAK,KAAK,EAAE;CAClB,MAAM,KAAK,KAAK,EAAE;CAClB,IAAI,MAAM;CACV,IAAI,KAAK;CACT,IAAI,KAAK;CACT,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,QAAQ,KAAK;EAClC,QAAS,GAAG,KAAgB,OAAQ,GAAG,KAAgB;EACvD,OAAQ,GAAG,KAAgB,OAAO;EAClC,OAAQ,GAAG,KAAgB,OAAO;CACpC;CACA,OAAO,OAAO,KAAK,OAAO,IAAI,IAAI,MAAM,KAAK,KAAK,KAAK,EAAE;AAC3D;;AAGA,MAAa,gBAAgB;AAC7B,MAAM,iBAAiB;;;;;;AAOvB,SAAgB,WAAW,GAAsB,GAAsB,OAAwB,GAAW;CACxG,UAAU,cAAc,GAAG,CAAC;CAC5B,MAAM,IAAI,EAAE;CACZ,IAAI,IAAI,GAAG,OAAO;CAClB,IAAI,aAAa;CACjB,IAAI,aAAa;CACjB,IAAI,OAAO;CACX,IAAI,OAAO;CACX,MAAM,SAAS,GAAW,MAAoB;EAC5C,MAAM,KAAK,KAAK,KAAM,EAAE,KAAiB,EAAE,EAAa;EACxD,MAAM,KAAK,KAAK,KAAM,EAAE,KAAiB,EAAE,EAAa;EACxD,IAAI,OAAO,KAAK,OAAO,GAAG;EAC1B,IAAI,OAAO,GAAG;OACT,IAAI,OAAO,GAAG;OACd,IAAI,OAAO,IAAI;OACf;CACP;CACA,IAAI,KAAA,MACF,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,KAAK,IAAI,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,MAAM,GAAG,CAAC;MACjE;EACL,MAAM,IAAI,OAAO,IAAI;EACrB,KAAK,IAAI,IAAI,GAAG,IAAI,gBAAgB,KAAK;GACvC,MAAM,IAAI,EAAE,MAAM,CAAC;GACnB,MAAM,IAAI,EAAE,MAAM,CAAC;GACnB,IAAI,MAAM,GAAG,MAAM,GAAG,CAAC;EACzB;CACF;CACA,MAAM,MAAM,KAAK,MAAM,aAAa,aAAa,SAAS,aAAa,aAAa,KAAK;CACzF,OAAO,QAAQ,IAAI,KAAK,aAAa,cAAc;AACrD;;;;;;AC/EA,SAAS,MAAM,MAAc,OAAqB;CAChD,IAAI,CAAC,OAAO,cAAc,KAAK,KAAK,QAAQ,GAAG,MAAM,IAAI,WAAW,GAAG,KAAK,IAAI,MAAM,qCAAqC;AAC7H;AAEA,SAAS,QAAQ,MAAc,OAAuB;CACpD,IAAI,EAAE,QAAQ,KAAK,QAAQ,IAAI,MAAM,IAAI,WAAW,GAAG,KAAK,kDAAkD,MAAM,EAAE;CACtH,QAAQ,IAAI,SAAS;AACvB;;AAGA,SAAS,cAAc,GAAW,GAAqB;CACrD,IAAI,MAAM,GAAG,OAAO,MAAM,KAAK,EAAE,QAAQ,IAAI,EAAE,IAAI,GAAG,MAAO,MAAM,IAAI,IAAI,CAAE;CAC7E,IAAI,MAAM,GAAG,OAAO,MAAM,KAAK,EAAE,QAAQ,IAAI,EAAE,IAAI,GAAG,MAAO,MAAM,IAAI,IAAI,CAAE;CAC7E,MAAM,CAAC,MAAM,QAAQ,CAAC,KAAK,IAAI,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC;CACjD,MAAM,QAAkB,CAAC;CACzB,IAAI,YAAY;CAChB,KAAK,IAAI,IAAI,GAAG,KAAK,GAAG,KAAK;EAC3B,IAAI,IAAI,GAAG,aAAa,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC;EAChD,MAAM,KAAK,KAAK,IAAI,YAAY,IAAI,QAAQ,IAAI,KAAK,IAAI,CAAC;CAC5D;CACA,OAAO;AACT;;;;;;;;;AAoBA,SAAgB,eAAe,QAA2B,QAAQ,KAAsB;CACtF,IAAI,OAAO,WAAW,GAAG,MAAM,IAAI,WAAW,oCAAoC;CAClF,KAAK,MAAM,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,GAAG,MAAM,IAAI,WAAW,qCAAqC;CACvG,MAAM,OAAO,QAAQ,kBAAkB,KAAK;CAC5C,MAAM,IAAI,OAAO,MAAM;CACvB,MAAM,IAAI,EAAE;CACZ,MAAM,QAAQ,cAAc,GAAG,EAAG;CAElC,IAAI,IAAI;CACR,IAAI,QAAQ,MAAM;CAClB,OAAO,IAAI,KAAK,IAAI,KAAK,SAAS,MAAM;EACtC,KAAK;EACL,SAAS,MAAM;CACjB;CACA,MAAM,OAAO,KAAK,IAAI,GAAG,CAAC;CAC1B,IAAI,OAAO;CACX,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,KAAK,QAAQ,MAAM;CAC7C,OAAO;EAAE,KAAK,EAAE,OAAO;EAAc,MAAM,EAAE,IAAI;EAAiB;EAAM,UAAU,KAAK,IAAI,GAAG,IAAI,IAAI,IAAI;CAAE;AAC9G;;;;;;AAeA,SAAgB,iBAAiB,GAAW,GAAW,QAAQ,KAAqB;CAClF,MAAM,oBAAoB,CAAC;CAC3B,IAAI,EAAE,KAAK,KAAK,KAAK,IAAI,MAAM,IAAI,WAAW,2CAA2C,EAAE,EAAE;CAC7F,MAAM,OAAO,QAAQ,oBAAoB,KAAK;CAC9C,MAAM,QAAQ,cAAc,GAAG,CAAC;CAChC,IAAI,MAAM;CACV,IAAI,QAAQ,MAAM;CAClB,OAAO,MAAM,KAAK,SAAS,MAAM;EAC/B,OAAO;EACP,SAAS,MAAM;CACjB;CACA,IAAI,OAAO;CACX,IAAI,QAAQ,MAAM;CAClB,OAAO,OAAO,KAAK,SAAS,MAAM;EAChC,QAAQ;EACR,SAAS,MAAM;CACjB;CACA,IAAI,WAAW;CACf,KAAK,IAAI,IAAI,KAAK,KAAK,MAAM,KAAK,YAAY,MAAM;CACpD,OAAO;EAAE;EAAK;EAAM,UAAU,KAAK,IAAI,GAAG,QAAQ;CAAE;AACtD;;;;;;AAOA,SAAgB,yBAAyB,WAAmB,GAAW,QAAQ,KAAqB;CAClG,MAAM,4BAA4B,SAAS;CAC3C,IAAI,EAAE,IAAI,KAAK,KAAK,IAAI,MAAM,IAAI,WAAW,iEAAiE,EAAE,EAAE;CAClH,MAAM,OAAO,QAAQ,4BAA4B,KAAK;CACtD,MAAM,OAAO,KAAK,MAAM,CAAC,CAAC;CAC1B,IAAI,YAAY,YAAY,KAAK,IAAI,CAAC;CACtC,IAAI,QAAQ;CACZ,IAAI,MAAM;CACV,KAAK,IAAI,IAAI,IAAK,KAAK,GAAG;EACxB,MAAM,SAAS,KAAK,IAAI,SAAS;EACjC,IAAI,SAAS,MAAM,MAAM;EACzB,IAAI,QAAQ,UAAU,IAAI,MAAM;GAC9B,IAAI,WAAW;GACf,IAAI,KAAK,YAAY,KAAK,IAAI,CAAC;GAC/B,KAAK,IAAI,IAAI,GAAG,KAAK,GAAG,KAAK;IAC3B,IAAI,KAAK,KAAK,YAAY,KAAK,IAAI,EAAE;IACrC,MAAM,KAAK,KAAK,IAAI,cAAc,IAAI,EAAE,IAAI;GAC9C;GACA,OAAO;IAAE;IAAK,MAAM;IAAG,UAAU,KAAK,IAAI,GAAG,QAAQ;GAAE;EACzD;EACA,SAAS;EACT,aAAa,KAAK,KAAK,IAAI,cAAc,IAAI,EAAE,IAAI;CACrD;AACF;;;;;;;;;;;;AC9GA,SAAgB,WAAW,QAA2B,UAAwB,CAAC,GAAW;CACxF,MAAM,UAAU,QAAQ,WAAW;CACnC,IAAI,OAAO,SAAS,SAAS,MAAM,IAAI,WAAW,eAAe,OAAO,OAAO,0BAA0B,QAAQ,yBAAyB;CAC1I,QAAQ,QAAQ,KAAK,KAAK,GAAG,MAAM;AACrC;;;;;;;AAmDA,SAAgB,cAAc,QAA2B,UAA0B,CAAC,GAAe;CACjG,IAAI,OAAO,WAAW,GAAG,MAAM,IAAI,WAAW,mCAAmC;CACjF,MAAM,QAAQ,QAAQ,UAAU,cAAc,WAAW,IAAI;CAC7D,MAAM,MAAM,QAAQ,OAAO;CAC3B,MAAM,QAAQ,QAAQ,SAAS;CAC/B,IAAI,EAAE,OAAO,MAAM,EAAE,SAAS,IAAI,MAAM,IAAI,WAAW,6CAA6C;CACpG,IAAI,OAAO;CACX,IAAI,OAAO;CACX,IAAI,SAAS;CACb,IAAI,QAAQ;CACZ,IAAI,QAAQ;CACZ,MAAM,UAAoB,CAAC;CAC3B,KAAK,MAAM,SAAS,QAAQ;EAC1B,IAAI,CAAC,OAAO,SAAS,KAAK,GAAG,MAAM,IAAI,WAAW,qDAAqD,MAAM,EAAE;EAC/G,MAAM,IAAI,QAAQ,QAAQ;EAC1B,IAAI,KAAK,IAAI,QAAQ,CAAC,KAAK,KAAK;GAC9B;GACA;EACF;EACA,QAAQ,KAAK,KAAK;EAClB,IAAI,IAAI,GAAG;OACN;EACL,IAAI,IAAI,OAAO;OACV,IAAI,CAAC,IAAI,OAAO;CACvB;CACA,MAAM,IAAI,OAAO;CACjB,MAAM,IAAI,OAAO,OAAO;CACxB,MAAM,SAAS,EAAE,WAAW,IAAI,KAAA,IAAY;EAAE,GAAG,EAAE;EAAQ,QAAQ,OAAO,CAAC;EAAG,KAAK,eAAe,GAAG,EAAG;EAAG,KAAK,eAAe,GAAG,EAAG;CAAE;CACvI,OAAO;EACL;EACA;EACA;EACA;EACA,OAAO,SAAS,MAAM,MAAM;EAC5B;EACA;EACA;EACA,WAAW,QAAQ;EACnB,cAAc,OAAO,OAAO,CAAC;EAC7B,WAAW,QAAQ;EACnB,cAAc,OAAO,OAAO,CAAC;CAC/B;AACF;AAQA,SAAS,iBAAiB,MAAc,WAAsC;CAC5E,IAAI,UAAU,WAAW,GAAG,MAAM,IAAI,WAAW,GAAG,KAAK,qBAAqB;CAC9E,KAAK,MAAM,KAAK,WAAW,IAAI,EAAE,EAAE,KAAK,KAAK,EAAE,KAAK,IAAI,MAAM,IAAI,WAAW,GAAG,KAAK,+BAA+B,EAAE,EAAE,EAAE;AAC5H;;AAGA,SAAgB,MAAM,WAAwC;CAC5D,iBAAiB,SAAS,SAAS;CACnC,IAAI,MAAM;CACV,KAAK,MAAM,KAAK,WAAW,QAAQ,EAAE,KAAK,EAAE,MAAM,IAAI,OAAO;CAC7D,OAAO,MAAM,UAAU;AACzB;;AAcA,SAAgB,YAAY,WAAoD;CAC9E,iBAAiB,eAAe,SAAS;CACzC,MAAM,yBAAS,IAAI,IAAyC;CAC5D,KAAK,MAAM,KAAK,WAAW;EACzB,MAAM,QAAQ,OAAO,IAAI,EAAE,CAAC,KAAK;GAAE,GAAG;GAAG,MAAM;EAAE;EACjD,MAAM;EACN,IAAI,EAAE,KAAK,MAAM;EACjB,OAAO,IAAI,EAAE,GAAG,KAAK;CACvB;CACA,OAAO,CAAC,GAAG,MAAM,CAAC,CACf,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAC3B,KAAK,CAAC,QAAQ,EAAE,GAAG,aAAa;EAAE;EAAQ;EAAG;EAAM,MAAM,OAAO;EAAG,UAAU,OAAO,MAAM,CAAC;CAAE,EAAE;AACpG"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["whole"],"sources":["../src/describe.ts","../src/regression.ts","../src/bootstrap.ts","../src/ridge.ts","../src/tests.ts","../src/rank.ts","../src/discrete.ts","../src/compare.ts"],"sourcesContent":["/**\n * The descriptive statistics: the mean, the standard deviation, the median, the quantiles and a summary of a list.\n * Each function throws a RangeError for an empty list or for a value that is NaN. Thus a missing value cannot make a\n * quiet NaN in a record.\n */\n\n/** The definitions of a quantile that the engines use (Hyndman and Fan, 1996, and the names of NumPy). */\nexport type QuantileMethod =\n /** Type 7: a linear step between the two nearest ranks. The default of R and NumPy. */\n | \"linear\"\n /** Type 1: the smallest value with at least the share `p` of the values at or below it. */\n | \"nearest-rank\"\n /**\n * The higher of the two nearest ranks of type 7: `sorted[Math.ceil(p * (n - 1))]`. This is the method `\"higher\"` of\n * NumPy. The 0.5 quantile is the upper median `sorted[Math.floor(n / 2)]`. The rank `p * (n - 1)` is rounded to\n * `1e-9` before the ceiling. Thus a float error, for example `0.55 * 100 = 55.00000000000001`, does not move the rank up.\n * The rounding keeps the exact rank while `p * (n - 1) * 1e9` is below `2 ** 53`, so for `n` up to approximately 9 million.\n */\n | \"higher\";\n\nfunction checked(name: string, values: readonly number[]): void {\n if (values.length === 0) throw new RangeError(`${name}: the list is empty.`);\n for (const v of values) if (Number.isNaN(v)) throw new RangeError(`${name}: the list has a NaN.`);\n}\n\n/** A new list with the values from the smallest to the largest. */\nexport function sorted(values: readonly number[]): number[] {\n return [...values].sort((a, b) => a - b);\n}\n\nexport function mean(values: readonly number[]): number {\n checked(\"mean\", values);\n let sum = 0;\n for (const v of values) sum += v;\n return sum / values.length;\n}\n\n/** The sample standard deviation (the divisor is n - 1). It needs 2 values or more. */\nexport function sd(values: readonly number[]): number {\n checked(\"sd\", values);\n if (values.length < 2) throw new RangeError(\"sd: the list needs 2 values or more.\");\n const m = mean(values);\n let sum = 0;\n for (const v of values) sum += (v - m) ** 2;\n return Math.sqrt(sum / (values.length - 1));\n}\n\n/**\n * The `p` quantile of a list that is already sorted. Use it when you take several quantiles of one list.\n * The linear method gives the same numbers as the copies in highways, packing and layout-contract. The\n * nearest-rank method gives the same numbers as the copies in lag, lag-hud and the backtest of highways. The\n * higher method gives the upper median of the copies in highways with `p = 0.5`.\n */\nexport function quantileSorted(sortedValues: readonly number[], p: number, method: QuantileMethod = \"linear\"): number {\n checked(\"quantile\", sortedValues);\n if (!(p >= 0 && p <= 1)) throw new RangeError(`quantile: p is from 0 to 1, not ${p}.`);\n const n = sortedValues.length;\n if (method === \"nearest-rank\") return sortedValues[Math.min(n - 1, Math.max(0, Math.ceil(p * n) - 1))] as number;\n // The rank on a grid of 1e-9, so that a float error above a whole rank does not give the next rank.\n if (method === \"higher\") return sortedValues[Math.ceil(Math.round(p * (n - 1) * 1e9) / 1e9)] as number;\n const at = (n - 1) * p;\n const low = Math.floor(at);\n const part = at - low;\n const a = sortedValues[low] as number;\n if (part === 0) return a;\n const b = sortedValues[low + 1] as number;\n if (a === b) return a;\n return a + part * (b - a);\n}\n\n/** The `p` quantile of a list. */\nexport function quantile(values: readonly number[], p: number, method: QuantileMethod = \"linear\"): number {\n checked(\"quantile\", values);\n return quantileSorted(sorted(values), p, method);\n}\n\n/**\n * The median: the middle value, or the midpoint `(a + b) / 2` of the two middle values. The midpoint is correctly\n * rounded. `quantile(values, 0.5)` computes `a + 0.5 * (b - a)`, which can differ from it in the last bit.\n */\nexport function median(values: readonly number[]): number {\n checked(\"median\", values);\n const s = sorted(values);\n const middle = Math.floor(s.length / 2);\n return s.length % 2 === 1 ? (s[middle] as number) : ((s[middle - 1] as number) + (s[middle] as number)) / 2;\n}\n\n/** The summary of a list. The quartiles use the linear method. */\nexport interface Summary {\n readonly n: number;\n readonly mean: number;\n /** The sample standard deviation, or NaN for one value. */\n readonly sd: number;\n readonly min: number;\n /** The 0.25 quantile. */\n readonly q1: number;\n readonly median: number;\n /** The 0.75 quantile. */\n readonly q3: number;\n readonly max: number;\n /** The interquartile range: q3 - q1. */\n readonly iqr: number;\n}\n\nexport function summarize(values: readonly number[]): Summary {\n checked(\"summarize\", values);\n const s = sorted(values);\n const q1 = quantileSorted(s, 0.25);\n const q3 = quantileSorted(s, 0.75);\n return {\n n: s.length,\n // The mean and sd of the list in its own order, so that they are equal to mean(values) and sd(values).\n mean: mean(values),\n sd: s.length < 2 ? Number.NaN : sd(values),\n min: s[0] as number,\n q1,\n median: median(s),\n q3,\n max: s[s.length - 1] as number,\n iqr: q3 - q1,\n };\n}\n","/**\n * Ordinary least squares with a Householder QR decomposition. The QR decomposition does not square the condition\n * number of the design, as the normal equations do. A design without full rank gives NaN coefficients and does not\n * throw. Thus a bootstrap run with a singular draw is not finite, and it does not count.\n */\n\nexport interface LeastSquaresOptions {\n /** When true, the fit adds an intercept as coefficient 0. The default is true. */\n readonly intercept?: boolean;\n}\n\nexport interface LeastSquaresFit {\n /** The coefficients. With an intercept, coefficient 0 is the intercept and coefficient `j + 1` is predictor `j`. */\n readonly coefficients: number[];\n /** The residual standard deviation: the square root of the residual sum of squares divided by `n - k`. */\n readonly residualSd: number;\n /**\n * The coefficient of determination: 1 minus the residual sum of squares divided by the total sum of squares. With\n * an intercept, the total sum uses the distances from the mean of `y`. Without an intercept, it uses the values.\n */\n readonly r2: number;\n /** The number of rows. */\n readonly n: number;\n /** The number of coefficients, with the intercept. */\n readonly k: number;\n}\n\n/**\n * The relative tolerance of the rank test. A column is dependent when the part of it that is orthogonal to the\n * columns before it is shorter than this share of its length.\n */\nconst RANK_TOLERANCE = 1e-10;\n\n/**\n * The ordinary least-squares fit of `y` on the rows of `x`, with `k` coefficients. Each row has the same number of\n * predictors. The fit solves the problem with a Householder QR decomposition. When the design does not have full\n * rank, or when `n <= k`, the coefficients, `residualSd` and `r2` are NaN. When the total sum of squares is 0,\n * `r2` is NaN.\n *\n * This function throws a RangeError for an empty `x` and for rows of different lengths. It also throws\n * for `x` and `y` of different lengths, for a value that is not finite, and for a fit with no coefficient.\n */\nexport function leastSquares(x: readonly (readonly number[])[], y: readonly number[], options: LeastSquaresOptions = {}): LeastSquaresFit {\n const intercept = options.intercept ?? true;\n const k = checkedShape(\"leastSquares\", x, y, intercept);\n return fitRows(x, y, intercept, k);\n}\n\n/**\n * This function examines the shape and the values of a least-squares problem, and gives the number of\n * coefficients. It throws a RangeError for each fault.\n */\nexport function checkedShape(name: string, x: readonly (readonly number[])[], y: readonly number[], intercept: boolean): number {\n if (x.length === 0) throw new RangeError(`${name}: x is empty.`);\n if (x.length !== y.length) throw new RangeError(`${name}: x has ${x.length} rows and y has ${y.length} values. The two lengths must be equal.`);\n const p = (x[0] as readonly number[]).length;\n for (let i = 0; i < x.length; i++) {\n const row = x[i] as readonly number[];\n if (row.length !== p) throw new RangeError(`${name}: row ${i} of x has ${row.length} values, and row 0 has ${p}. Each row must have the same length.`);\n for (const v of row) if (!Number.isFinite(v)) throw new RangeError(`${name}: row ${i} of x has a value that is not finite.`);\n if (!Number.isFinite(y[i] as number)) throw new RangeError(`${name}: value ${i} of y is not finite.`);\n }\n const k = p + (intercept ? 1 : 0);\n if (k === 0) throw new RangeError(`${name}: the fit has no coefficient. Give a predictor or an intercept.`);\n return k;\n}\n\n/**\n * The fit of rows with a known shape. The caller examined the shape with `checkedShape`. The design is a matrix of\n * `n` rows and `k` columns, kept by column.\n */\nexport function fitRows(x: readonly (readonly number[])[], y: readonly number[], intercept: boolean, k: number): LeastSquaresFit {\n const n = x.length;\n const failed = (): LeastSquaresFit => ({ coefficients: new Array<number>(k).fill(Number.NaN), residualSd: Number.NaN, r2: Number.NaN, n, k });\n if (n <= k) return failed();\n const offset = intercept ? 1 : 0;\n const a = new Float64Array(n * k);\n for (let i = 0; i < n; i++) {\n const row = x[i] as readonly number[];\n if (intercept) a[i] = 1;\n for (let j = offset; j < k; j++) a[j * n + i] = row[j - offset] as number;\n }\n const qty = Float64Array.from(y);\n const diagonal = new Float64Array(k);\n for (let j = 0; j < k; j++) {\n const c = j * n;\n // A reflection keeps the length of a column. Thus the length of column j is the length of its first form.\n let head = 0;\n for (let i = 0; i < j; i++) head += (a[c + i] as number) ** 2;\n let tail2 = 0;\n for (let i = j; i < n; i++) tail2 += (a[c + i] as number) ** 2;\n // The tail is the part of column j that is orthogonal to the columns before it.\n const tail = Math.sqrt(tail2);\n if (!(tail > RANK_TOLERANCE * Math.sqrt(head + tail2))) return failed();\n const alpha = (a[c + j] as number) > 0 ? -tail : tail;\n // The Householder vector v is the tail of column j minus alpha times the first unit vector. It is kept in place.\n a[c + j] = (a[c + j] as number) - alpha;\n let vv = 0;\n for (let i = j; i < n; i++) vv += (a[c + i] as number) ** 2;\n const reflect = (target: Float64Array, start: number): void => {\n let dot = 0;\n for (let i = j; i < n; i++) dot += (a[c + i] as number) * (target[start + i] as number);\n const f = (2 * dot) / vv;\n for (let i = j; i < n; i++) target[start + i] = (target[start + i] as number) - f * (a[c + i] as number);\n };\n for (let m = j + 1; m < k; m++) reflect(a, m * n);\n reflect(qty, 0);\n diagonal[j] = alpha;\n }\n // The back substitution of R b = Q'y. Above the diagonal, R is in the columns of a.\n const b = new Array<number>(k).fill(0);\n for (let j = k - 1; j >= 0; j--) {\n let s = qty[j] as number;\n for (let m = j + 1; m < k; m++) s -= (a[m * n + j] as number) * (b[m] as number);\n b[j] = s / (diagonal[j] as number);\n }\n let center = 0;\n if (intercept) {\n for (const v of y) center += v;\n center /= n;\n }\n let rss = 0;\n let tss = 0;\n for (let i = 0; i < n; i++) {\n const row = x[i] as readonly number[];\n let fitted = intercept ? (b[0] as number) : 0;\n for (let j = offset; j < k; j++) fitted += (b[j] as number) * (row[j - offset] as number);\n rss += ((y[i] as number) - fitted) ** 2;\n tss += ((y[i] as number) - center) ** 2;\n }\n return { coefficients: b, residualSd: Math.sqrt(rss / (n - k)), r2: tss > 0 ? 1 - rss / tss : Number.NaN, n, k };\n}\n","/**\n * The percentile bootstrap. Each run draws n items with replacement (`below(n)` of rigor-generators, which is\n * `floor(next() * n)`), and computes the statistic of the sample. The interval is two quantiles of the statistics.\n * With the same seed, the draws are equal to the draws of the copies in highways, packing and layout-contract.\n * `bootstrapTwo` draws two independent samples in each run: first the items of `a`, then the items of `b`.\n * `bootstrapLeastSquares` draws whole rows, and gives one interval for each coefficient from the same draws.\n */\nimport { type Random, random } from \"@mark1russell7/rigor-generators\";\nimport { type QuantileMethod, median, quantileSorted, sorted } from \"./describe.ts\";\nimport { type LeastSquaresOptions, checkedShape, fitRows } from \"./regression.ts\";\n\nexport interface BootstrapOptions {\n /** The number of samples. The default is 10 000. */\n readonly runs?: number;\n /** The level of the interval. The default is 0.95. */\n readonly level?: number;\n /** The seed of the draws. The default is 1. */\n readonly seed?: number | string;\n /** The quantile method of the two ends of the interval. The default is linear. */\n readonly method?: QuantileMethod;\n /**\n * The quantiles of the two ends, in place of `level`, for example [0.025, 0.975] or an interval with one side.\n * The default is from the level: (1 - level) / 2 and 1 - (1 - level) / 2. In floating point, (1 - 0.95) / 2 is\n * not 0.025, so a copy that writes 0.025 needs this option to give the same numbers.\n */\n readonly ends?: readonly [number, number];\n}\n\nexport interface Interval {\n /** The statistic of all the data. */\n readonly estimate: number;\n readonly low: number;\n readonly high: number;\n readonly level: number;\n readonly runs: number;\n /** The number of runs whose statistic is a finite number. Only these runs make the interval. */\n readonly finite: number;\n /** The seed as a 32-bit number. */\n readonly seed: number;\n}\n\n/**\n * A percentile bootstrap interval of `statistic` over `data`. A run whose statistic is not finite (NaN or an\n * infinity) does not count. When no run is finite, low and high are equal to the estimate.\n */\nexport function bootstrap<T>(data: readonly T[], statistic: (sample: readonly T[]) => number, options: BootstrapOptions = {}): Interval {\n if (data.length === 0) throw new RangeError(\"bootstrap: the data is empty.\");\n const n = data.length;\n const sample = new Array<T>(n);\n return percentile(\n \"bootstrap\",\n options,\n (r) => {\n for (let i = 0; i < n; i++) sample[i] = data[r.below(n)] as T;\n return statistic(sample);\n },\n () => statistic(data),\n );\n}\n\n/**\n * A percentile bootstrap interval of `statistic` over two independent samples `a` and `b`. Use it when the two\n * samples are not paired, for example two arms of a benchmark. Each run draws `a.length` items of `a` with\n * replacement, and then `b.length` items of `b` with replacement. All the draws come from one stream of\n * `random(seed)`. The statistic reads the two drawn samples. The estimate is the statistic of all of `a` and `b`. A\n * run whose statistic is not finite does not count. When no run is finite, low and high are equal to the estimate.\n */\nexport function bootstrapTwo<A, B>(\n a: readonly A[],\n b: readonly B[],\n statistic: (a: readonly A[], b: readonly B[]) => number,\n options: BootstrapOptions = {},\n): Interval {\n if (a.length === 0) throw new RangeError(\"bootstrapTwo: the first sample is empty.\");\n if (b.length === 0) throw new RangeError(\"bootstrapTwo: the second sample is empty.\");\n const na = a.length;\n const nb = b.length;\n const sampleA = new Array<A>(na);\n const sampleB = new Array<B>(nb);\n return percentile(\n \"bootstrapTwo\",\n options,\n (r) => {\n for (let i = 0; i < na; i++) sampleA[i] = a[r.below(na)] as A;\n for (let i = 0; i < nb; i++) sampleB[i] = b[r.below(nb)] as B;\n return statistic(sampleA, sampleB);\n },\n () => statistic(a, b),\n );\n}\n\n/**\n * A bootstrap interval of the ratio `median(numerator) / median(denominator)` of two independent samples. The\n * interval is the uncertainty of the ratio of the two medians. It is not the spread of the samples. A run whose\n * denominator median is 0 is not finite, so it does not count.\n */\nexport function bootstrapMedianRatio(numerator: readonly number[], denominator: readonly number[], options: BootstrapOptions = {}): Interval {\n return bootstrapTwo(numerator, denominator, (a, b) => median(a) / median(b), options);\n}\n\n/**\n * A percentile bootstrap interval of each coefficient of the least-squares fit of `y` on the rows of `x`. Each run\n * draws `n` row indexes with replacement, and fits the drawn rows and their `y` values. All the intervals come from\n * the same draws. The estimate of each interval is the coefficient of the fit of all the data. A run with a singular\n * design gives NaN coefficients, so it does not count. The shape errors are the errors of `leastSquares`.\n */\nexport function bootstrapLeastSquares(\n x: readonly (readonly number[])[],\n y: readonly number[],\n options: BootstrapOptions & LeastSquaresOptions = {},\n): Interval[] {\n const intercept = options.intercept ?? true;\n const k = checkedShape(\"bootstrapLeastSquares\", x, y, intercept);\n const n = x.length;\n const sampleX = new Array<readonly number[]>(n);\n const sampleY = new Array<number>(n);\n return percentiles(\n \"bootstrapLeastSquares\",\n options,\n k,\n (r) => {\n for (let i = 0; i < n; i++) {\n const row = r.below(n);\n sampleX[i] = x[row] as readonly number[];\n sampleY[i] = y[row] as number;\n }\n return fitRows(sampleX, sampleY, intercept, k).coefficients;\n },\n () => fitRows(x, y, intercept, k).coefficients,\n );\n}\n\ninterface Settings {\n readonly runs: number;\n readonly lowEnd: number;\n readonly highEnd: number;\n readonly level: number;\n readonly method: QuantileMethod;\n}\n\n/** This function examines the options of a bootstrap, and gives the defaults. It throws a RangeError for each fault. */\nfunction settings(name: string, options: BootstrapOptions): Settings {\n const runs = options.runs ?? 10_000;\n if (!Number.isSafeInteger(runs) || runs < 1) throw new RangeError(`${name}: runs is a whole number of 1 or more, not ${runs}.`);\n const tail = (1 - (options.level ?? 0.95)) / 2;\n const [lowEnd, highEnd] = options.ends ?? [tail, 1 - tail];\n if (!(lowEnd >= 0 && lowEnd < highEnd && highEnd <= 1)) throw new RangeError(`${name}: the ends are 0 <= low < high <= 1, not ${lowEnd} and ${highEnd}.`);\n const level = options.ends ? highEnd - lowEnd : (options.level ?? 0.95);\n if (!(level > 0 && level < 1)) throw new RangeError(`${name}: level is more than 0 and less than 1, not ${level}.`);\n return { runs, lowEnd, highEnd, level, method: options.method ?? \"linear\" };\n}\n\n/** The interval of the finite statistics of the runs. When no run is finite, low and high are equal to the estimate. */\nfunction ends(values: number[], estimate: number, s: Settings, seed: number): Interval {\n const { runs, level } = s;\n if (values.length === 0) return { estimate, low: estimate, high: estimate, level, runs, finite: 0, seed };\n const v = sorted(values);\n return { estimate, low: quantileSorted(v, s.lowEnd, s.method), high: quantileSorted(v, s.highEnd, s.method), level, runs, finite: v.length, seed };\n}\n\n/**\n * The shared part of each percentile bootstrap. It examines the options, and starts one stream of `random(seed)`.\n * Each run gives the stream to `run`, which draws the samples and returns their statistic. Then `all` gives the\n * estimate. The order of the draws is the order in `run`.\n */\nfunction percentile(name: string, options: BootstrapOptions, run: (r: Random) => number, all: () => number): Interval {\n const s = settings(name, options);\n const r = random(options.seed ?? 1);\n const values: number[] = [];\n for (let i = 0; i < s.runs; i++) {\n const v = run(r);\n if (Number.isFinite(v)) values.push(v);\n }\n return ends(values, all(), s, r.seed);\n}\n\n/**\n * The percentile bootstrap of `k` statistics from the same draws. Each run gives `k` statistics. Each statistic\n * has its own count of finite runs.\n */\nfunction percentiles(name: string, options: BootstrapOptions, k: number, run: (r: Random) => readonly number[], all: () => readonly number[]): Interval[] {\n const s = settings(name, options);\n const r = random(options.seed ?? 1);\n const values = Array.from({ length: k }, (): number[] => []);\n for (let i = 0; i < s.runs; i++) {\n const v = run(r);\n for (let j = 0; j < k; j++) if (Number.isFinite(v[j])) (values[j] as number[]).push(v[j] as number);\n }\n const estimate = all();\n return values.map((list, j) => ends(list, estimate[j] as number, s, r.seed));\n}\n\n/** A bootstrap interval of the median. */\nexport function bootstrapMedian(values: readonly number[], options: BootstrapOptions = {}): Interval {\n return bootstrap(values, median, options);\n}\n\n/**\n * A cluster bootstrap: each run draws whole clusters with replacement, and the statistic reads the rows of the drawn\n * clusters. Use it when the rows of one cluster (one board, one seed, one site) are not independent. The clusters\n * are in the order of their first row.\n */\nexport function bootstrapClusters<T>(\n rows: readonly T[],\n cluster: (row: T) => string,\n statistic: (rows: readonly T[]) => number,\n options: BootstrapOptions = {},\n): Interval {\n const groups = new Map<string, T[]>();\n for (const row of rows) {\n const key = cluster(row);\n const list = groups.get(key);\n if (list) list.push(row);\n else groups.set(key, [row]);\n }\n const clusters = [...groups.values()];\n const result = bootstrap(clusters, (drawn) => statistic(drawn.flat()), options);\n // The estimate of all the rows in their own order, not in the order of the clusters.\n const estimate = statistic(rows);\n return result.finite === 0 ? { ...result, estimate, low: estimate, high: estimate } : { ...result, estimate };\n}\n","/**\n * The ridge solve of a least-squares problem from its normal equations. The caller gives the matrix `X'X` and the\n * vector `X'y`. Thus it can make them from sparse rows. It can also remove the sums of one fold of a cross-validation.\n * The solve uses a Cholesky factorization of `X'X + lambda * P`. The matrix `P` is the identity, with 0 on the\n * diagonal for each free coefficient, for example an intercept.\n */\n\nexport interface RidgeOptions {\n /** The indexes of the coefficients with no penalty, for example 0 for an intercept. The default is none. */\n readonly free?: readonly number[];\n}\n\n/**\n * The relative tolerance of the Cholesky pivots. A pivot is the squared length of the part of a column that is\n * orthogonal to the columns before it. The rounding error of a pivot is approximately 1e-16 times its diagonal value.\n * Thus a pivot of a dependent column is not exactly 0, and the tolerance is larger than that error.\n */\nconst PIVOT_TOLERANCE = 1e-12;\n\n/**\n * This function gives the coefficients `beta` that solve `(gram + lambda * P) beta = moment`.\n * - `gram` is the symmetric matrix `X'X` of size `k`, in row order. The function reads only its lower triangle.\n * - `moment` is the vector `X'y` of length `k`.\n * - With `lambda` 0, the result is the ordinary least-squares fit.\n *\n * The function does not change `gram` or `moment`. When the matrix is not positive definite, each coefficient is\n * NaN, as in `leastSquares`. The function throws a RangeError when `gram` does not have `k * k` values, and when\n * `k` is 0. It also throws for a value that is not finite, for a `lambda` below 0, and for a bad free index.\n */\nexport function ridgeSolve(gram: ArrayLike<number>, moment: ArrayLike<number>, lambda: number, options: RidgeOptions = {}): number[] {\n const k = moment.length;\n if (k === 0) throw new RangeError(\"ridgeSolve: the moment is empty.\");\n if (gram.length !== k * k) throw new RangeError(`ridgeSolve: the gram has ${gram.length} values, and a moment of length ${k} needs ${k * k}.`);\n if (!(lambda >= 0 && Number.isFinite(lambda))) throw new RangeError(`ridgeSolve: lambda is a finite number of 0 or more, not ${lambda}.`);\n const penalty = new Float64Array(k).fill(lambda);\n for (const i of options.free ?? []) {\n if (!Number.isSafeInteger(i) || i < 0 || i >= k) throw new RangeError(`ridgeSolve: a free index is a whole number from 0 to ${k - 1}, not ${i}.`);\n penalty[i] = 0;\n }\n const a = new Float64Array(k * k);\n for (let i = 0; i < k * k; i++) {\n const v = gram[i] as number;\n if (!Number.isFinite(v)) throw new RangeError(`ridgeSolve: the gram value ${i} is not finite.`);\n a[i] = v;\n }\n const x = new Float64Array(k);\n for (let i = 0; i < k; i++) {\n const v = moment[i] as number;\n if (!Number.isFinite(v)) throw new RangeError(`ridgeSolve: the moment value ${i} is not finite.`);\n x[i] = v;\n a[i * k + i] = (a[i * k + i] as number) + (penalty[i] as number);\n }\n if (!factor(a, k)) return new Array<number>(k).fill(Number.NaN);\n for (let i = 0; i < k; i++) {\n let s = x[i] as number;\n for (let j = 0; j < i; j++) s -= (a[i * k + j] as number) * (x[j] as number);\n x[i] = s / (a[i * k + i] as number);\n }\n for (let i = k - 1; i >= 0; i--) {\n let s = x[i] as number;\n for (let j = i + 1; j < k; j++) s -= (a[j * k + i] as number) * (x[j] as number);\n x[i] = s / (a[i * k + i] as number);\n }\n return Array.from(x);\n}\n\n/**\n * This function writes the Cholesky factor `L` of `a` into its lower triangle, with `a = L L'`. It returns false when\n * a pivot is not more than the tolerance times the diagonal value of its column.\n */\nfunction factor(a: Float64Array, k: number): boolean {\n for (let j = 0; j < k; j++) {\n const diagonal = a[j * k + j] as number;\n let d = diagonal;\n for (let m = 0; m < j; m++) d -= (a[j * k + m] as number) ** 2;\n if (!(d > PIVOT_TOLERANCE * Math.abs(diagonal)) || !(d > 0)) return false;\n const l = Math.sqrt(d);\n a[j * k + j] = l;\n for (let i = j + 1; i < k; i++) {\n let s = a[i * k + j] as number;\n for (let m = 0; m < j; m++) s -= (a[i * k + m] as number) * (a[j * k + m] as number);\n a[i * k + j] = s / l;\n }\n }\n return true;\n}\n","/**\n * The tests of a difference: the sign test, the paired permutation test, the Wilson interval of a proportion and\n * the Holm correction for several tests.\n */\nimport { random } from \"@mark1russell7/rigor-generators\";\nimport { mean } from \"./describe.ts\";\n\nfunction whole(name: string, value: number): void {\n if (!Number.isSafeInteger(value) || value < 0) throw new RangeError(`${name}: ${value} is not a whole number of 0 or more.`);\n}\n\n/** The log of each binomial term C(n, k) / 2^n, for each k from 0 to n. */\nfunction halfBinomialLogs(n: number): number[] {\n const logs: number[] = [];\n let logChoose = 0;\n for (let i = 0; i <= n; i++) {\n if (i > 0) logChoose += Math.log((n - i + 1) / i);\n logs.push(logChoose - n * Math.LN2);\n }\n return logs;\n}\n\n/** P(X >= k) for X ~ Binomial(n, 1/2), summed from the largest term so that a small tail keeps its digits. */\nfunction upperTail(k: number, n: number): number {\n if (k <= 0) return 1;\n if (k > n) return 0;\n const logs = halfBinomialLogs(n).slice(k);\n const top = Math.max(...logs);\n const sum = logs.reduce((s, l) => s + Math.exp(l - top), 0);\n return Math.min(1, Math.exp(top) * sum);\n}\n\n/**\n * The sign test of paired results: `better` inputs where the candidate wins and `worse` where it loses. The ties\n * do not count. One-sided (the default), it is the p of `better` wins or more if the two are equal. Two-sided, it is\n * two times the tail of the larger count, at most 1. The one-sided p is equal to `signTestP` of packing.\n */\nexport function signTest(better: number, worse: number, sides: 1 | 2 = 1): number {\n whole(\"signTest\", better);\n whole(\"signTest\", worse);\n const n = better + worse;\n if (n === 0) return 1;\n if (sides === 1) return upperTail(better, n);\n return Math.min(1, 2 * upperTail(Math.max(better, worse), n));\n}\n\n/**\n * The smallest number of wins out of `n` that the sign test calls significant at `level`. It is undefined when even\n * n wins out of n are not enough. Use it before a run, to know how many inputs a claim needs.\n */\nexport function signTestPower(n: number, level = 0.05, sides: 1 | 2 = 2): number | undefined {\n whole(\"signTestPower\", n);\n for (let k = Math.ceil(n / 2); k <= n; k++) if (signTest(k, n - k, sides) < level) return k;\n return undefined;\n}\n\n/** The z of a two-sided 95% interval. */\nexport const Z95 = 1.959963984540054;\n\n/** An interval of a proportion. */\nexport interface Proportion {\n readonly low: number;\n readonly high: number;\n}\n\n/**\n * The Wilson score interval of `k` successes in `n` trials (Wilson, 1927). It keeps its level for a small n and for\n * a proportion near 0 or 1, where the normal interval does not. For n = 0 the interval is 0 to 1.\n */\nexport function wilson(k: number, n: number, z: number = Z95): Proportion {\n whole(\"wilson\", k);\n whole(\"wilson\", n);\n if (k > n) throw new RangeError(`wilson: k ${k} is more than n ${n}.`);\n if (n === 0) return { low: 0, high: 1 };\n const p = k / n;\n const z2 = z * z;\n const denominator = 1 + z2 / n;\n const center = (p + z2 / (2 * n)) / denominator;\n const half = (z / denominator) * Math.sqrt((p * (1 - p)) / n + z2 / (4 * n * n));\n return { low: Math.max(0, center - half), high: Math.min(1, center + half) };\n}\n\n/** One test after the Holm correction. */\nexport interface Corrected {\n /** The p of the test. */\n readonly p: number;\n /** The p after the correction: compare it with the level of the whole family. */\n readonly adjusted: number;\n /** The adjusted p is less than the level. */\n readonly reject: boolean;\n}\n\n/**\n * The Holm step-down correction of a family of tests (Holm, 1979). It keeps the chance of one false claim or more\n * in the family at most `level`. It has no condition on how the tests depend on each other. The result is in the\n * order of the input.\n */\nexport function holm(pValues: readonly number[], level = 0.05): Corrected[] {\n for (const p of pValues) if (!(p >= 0 && p <= 1)) throw new RangeError(`holm: each p is from 0 to 1, not ${p}.`);\n const m = pValues.length;\n const order = pValues.map((p, i) => ({ p, i })).sort((a, b) => a.p - b.p || a.i - b.i);\n const adjusted = new Array<number>(m);\n let running = 0;\n order.forEach(({ p, i }, rank) => {\n running = Math.max(running, Math.min(1, (m - rank) * p));\n adjusted[i] = running;\n });\n return pValues.map((p, i) => ({ p, adjusted: adjusted[i] as number, reject: (adjusted[i] as number) < level }));\n}\n\nexport interface PermutationOptions {\n /** The number of random sign flips. The default is 10 000. */\n readonly runs?: number;\n /** The default is 1. */\n readonly seed?: number | string;\n /** The statistic of the differences. The default is the mean. */\n readonly statistic?: (differences: readonly number[]) => number;\n}\n\nexport interface PermutationResult {\n /** The statistic of the observed differences `candidate[i] - baseline[i]`. */\n readonly observed: number;\n /** The two-sided p: (1 + the flips with a statistic as far from 0 or farther) / (1 + runs). */\n readonly p: number;\n readonly runs: number;\n}\n\n/**\n * The paired permutation test (a random sign flip of each difference). It needs no normal distribution and uses\n * the size of each difference, which the sign test does not. A pair with a difference of 0 adds nothing.\n */\nexport function pairedPermutation(candidate: readonly number[], baseline: readonly number[], options: PermutationOptions = {}): PermutationResult {\n if (candidate.length !== baseline.length) throw new RangeError(`pairedPermutation: the lists have ${candidate.length} and ${baseline.length} values.`);\n const differences = candidate.map((c, i) => c - (baseline[i] as number));\n const statistic = options.statistic ?? mean;\n const runs = options.runs ?? 10_000;\n if (!Number.isSafeInteger(runs) || runs < 1) throw new RangeError(`pairedPermutation: runs is a whole number of 1 or more, not ${runs}.`);\n const observed = statistic(differences);\n const r = random(options.seed ?? 1);\n const flipped = new Array<number>(differences.length);\n let extreme = 0;\n for (let run = 0; run < runs; run++) {\n for (let i = 0; i < differences.length; i++) flipped[i] = r.next() < 0.5 ? -(differences[i] as number) : (differences[i] as number);\n // A small tolerance, so that a flip with the same statistic up to rounding counts as extreme.\n if (Math.abs(statistic(flipped)) >= Math.abs(observed) * (1 - 1e-12)) extreme++;\n }\n return { observed, p: (1 + extreme) / (1 + runs), runs };\n}\n","/**\n * Rank correlation: do two measures put the same items in the same order? Use it to test that a cheap proxy (a\n * predicted cost, a fast measure) orders the items as the real measure does.\n */\nimport { random } from \"@mark1russell7/rigor-generators\";\n\nfunction samePairs(name: string, a: readonly number[], b: readonly number[]): void {\n if (a.length !== b.length) throw new RangeError(`${name}: the lists have ${a.length} and ${b.length} values.`);\n for (const v of a) if (Number.isNaN(v)) throw new RangeError(`${name}: the first list has a NaN.`);\n for (const v of b) if (Number.isNaN(v)) throw new RangeError(`${name}: the second list has a NaN.`);\n}\n\n/** The ranks of the values, from 1. Equal values get the mean of their ranks. */\nexport function ranks(values: readonly number[]): number[] {\n const order = values.map((x, i) => [x, i] as const).sort((p, q) => p[0] - q[0]);\n const out = new Array<number>(values.length);\n for (let i = 0; i < order.length; ) {\n let j = i;\n while (j + 1 < order.length && (order[j + 1] as readonly [number, number])[0] === (order[i] as readonly [number, number])[0]) j++;\n for (let k = i; k <= j; k++) out[(order[k] as readonly [number, number])[1]] = (i + j) / 2 + 1;\n i = j + 1;\n }\n return out;\n}\n\n/**\n * The Spearman rank correlation: the Pearson correlation of the ranks, with mean ranks for ties. The value is from\n * -1 to 1. When one list has no spread, the value is 0. It is equal to the copy in the backtest of highways.\n */\nexport function spearman(a: readonly number[], b: readonly number[]): number {\n samePairs(\"spearman\", a, b);\n const ra = ranks(a);\n const rb = ranks(b);\n const mean = (xs: readonly number[]): number => xs.reduce((s, x) => s + x, 0) / xs.length;\n const ma = mean(ra);\n const mb = mean(rb);\n let num = 0;\n let da = 0;\n let db = 0;\n for (let i = 0; i < ra.length; i++) {\n num += ((ra[i] as number) - ma) * ((rb[i] as number) - mb);\n da += ((ra[i] as number) - ma) ** 2;\n db += ((rb[i] as number) - mb) ** 2;\n }\n return da === 0 || db === 0 ? 0 : num / Math.sqrt(da * db);\n}\n\n/** The largest number of values for which `kendallTau` examines each pair. Above it, a seeded sample of pairs. */\nexport const KENDALL_EXACT = 1500;\nconst KENDALL_SAMPLE = 200_000;\n\n/**\n * The Kendall tau-b of two lists (Kendall, 1938). The value is from -1 to 1. A pair with a tie in both lists does\n * not count. When the lists have fewer than 2 values, or no pair counts, the value is 1. Above `KENDALL_EXACT`\n * values, a seeded sample of 200 000 pairs gives an estimate. It is equal to the copy in highways.\n */\nexport function kendallTau(a: readonly number[], b: readonly number[], seed: number | string = 1): number {\n samePairs(\"kendallTau\", a, b);\n const n = a.length;\n if (n < 2) return 1;\n let concordant = 0;\n let discordant = 0;\n let tieA = 0;\n let tieB = 0;\n const visit = (i: number, j: number): void => {\n const da = Math.sign((a[i] as number) - (a[j] as number));\n const db = Math.sign((b[i] as number) - (b[j] as number));\n if (da === 0 && db === 0) return;\n if (da === 0) tieA++;\n else if (db === 0) tieB++;\n else if (da === db) concordant++;\n else discordant++;\n };\n if (n <= KENDALL_EXACT) {\n for (let i = 0; i < n; i++) for (let j = i + 1; j < n; j++) visit(i, j);\n } else {\n const r = random(seed);\n for (let k = 0; k < KENDALL_SAMPLE; k++) {\n const i = r.below(n);\n const j = r.below(n);\n if (i !== j) visit(i, j);\n }\n }\n const den = Math.sqrt((concordant + discordant + tieA) * (concordant + discordant + tieB));\n return den === 0 ? 1 : (concordant - discordant) / den;\n}\n","/**\n * The intervals that come from a discrete distribution. The interval of a median comes from the order statistics.\n * The central interval of a count comes from a binomial or a negative binomial distribution.\n */\nimport { sorted } from \"./describe.ts\";\n\nfunction whole(name: string, value: number): void {\n if (!Number.isSafeInteger(value) || value < 0) throw new RangeError(`${name}: ${value} is not a whole number of 0 or more.`);\n}\n\nfunction levelOf(name: string, level: number): number {\n if (!(level > 0 && level < 1)) throw new RangeError(`${name}: the level is more than 0 and less than 1, not ${level}.`);\n return (1 - level) / 2;\n}\n\n/** The chance of each count k from 0 to n of X ~ Binomial(n, p), from the logs of the terms. */\nfunction binomialTerms(n: number, p: number): number[] {\n if (p === 0) return Array.from({ length: n + 1 }, (_, k) => (k === 0 ? 1 : 0));\n if (p === 1) return Array.from({ length: n + 1 }, (_, k) => (k === n ? 1 : 0));\n const [logP, logQ] = [Math.log(p), Math.log1p(-p)];\n const terms: number[] = [];\n let logChoose = 0;\n for (let k = 0; k <= n; k++) {\n if (k > 0) logChoose += Math.log((n - k + 1) / k);\n terms.push(Math.exp(logChoose + k * logP + (n - k) * logQ));\n }\n return terms;\n}\n\n/** The distribution-free interval of a median, from two order statistics of the sample. */\nexport interface MedianInterval {\n readonly low: number;\n readonly high: number;\n /** The rank k of `low`, from 1. The interval is from x_(k) to x_(n + 1 - k) of the sorted values. */\n readonly rank: number;\n /** The chance that the interval holds the median of the population: 1 - 2 P(X <= k - 1), for X ~ Binomial(n, 1/2). */\n readonly coverage: number;\n}\n\n/**\n * The distribution-free interval of the median of a sample. It needs no assumption about the shape of the\n * distribution. It is x_(k) to x_(n + 1 - k), for the largest k whose two tails each hold (1 - level) / 2 or less.\n * For 11 values at the level 0.95, it is x_(2) to x_(10), with the coverage 0.988.\n *\n * A sample of 5 values or fewer has no rank with that coverage. Then the interval is the full range, and `coverage`\n * is less than `level`.\n */\nexport function medianInterval(values: readonly number[], level = 0.95): MedianInterval {\n if (values.length === 0) throw new RangeError(\"medianInterval: the list is empty.\");\n for (const v of values) if (Number.isNaN(v)) throw new RangeError(\"medianInterval: the list has a NaN.\");\n const tail = levelOf(\"medianInterval\", level);\n const s = sorted(values);\n const n = s.length;\n const terms = binomialTerms(n, 0.5);\n // The rank k + 1 is possible if P(X <= k), the tail that it leaves out on each side, is the tail or less.\n let k = 0;\n let below = terms[0] as number;\n while (k + 1 <= n / 2 && below <= tail) {\n k += 1;\n below += terms[k] as number;\n }\n const rank = Math.max(1, k);\n let left = 0;\n for (let i = 0; i < rank; i++) left += terms[i] as number;\n return { low: s[rank - 1] as number, high: s[n - rank] as number, rank, coverage: Math.max(0, 1 - 2 * left) };\n}\n\n/** A central interval of a count, from `low` to `high`, both included. */\nexport interface CountInterval {\n readonly low: number;\n readonly high: number;\n /** The chance of a count from `low` to `high`. It is `level` or more. */\n readonly coverage: number;\n}\n\n/**\n * The central interval of a count X ~ Binomial(n, p). `low` is the smallest k with P(X <= k) > (1 - level) / 2.\n * `high` is the largest k with P(X >= k) > (1 - level) / 2. Each tail outside the interval holds (1 - level) / 2\n * or less. The two tails are separate sums, so that a small upper tail keeps its digits.\n */\nexport function binomialInterval(n: number, p: number, level = 0.95): CountInterval {\n whole(\"binomialInterval\", n);\n if (!(p >= 0 && p <= 1)) throw new RangeError(`binomialInterval: p is from 0 to 1, not ${p}.`);\n const tail = levelOf(\"binomialInterval\", level);\n const terms = binomialTerms(n, p);\n let low = 0;\n let below = terms[0] as number;\n while (low < n && below <= tail) {\n low += 1;\n below += terms[low] as number;\n }\n let high = n;\n let above = terms[n] as number;\n while (high > 0 && above <= tail) {\n high -= 1;\n above += terms[high] as number;\n }\n let coverage = 0;\n for (let k = low; k <= high; k++) coverage += terms[k] as number;\n return { low, high, coverage: Math.min(1, coverage) };\n}\n\n/**\n * The central interval of a negative binomial count. X is the count of failures before `successes` successes, and\n * `p` is the chance of a success at each try. `low` is the smallest k with P(X <= k) > (1 - level) / 2.\n * `high` is the smallest k with P(X <= k) >= 1 - (1 - level) / 2.\n */\nexport function negativeBinomialInterval(successes: number, p: number, level = 0.95): CountInterval {\n whole(\"negativeBinomialInterval\", successes);\n if (!(p > 0 && p <= 1)) throw new RangeError(`negativeBinomialInterval: p is more than 0 and 1 or less, not ${p}.`);\n const tail = levelOf(\"negativeBinomialInterval\", level);\n const logQ = Math.log1p(-p);\n let logChance = successes * Math.log(p);\n let below = 0;\n let low = 0;\n for (let k = 0; ; k += 1) {\n const chance = Math.exp(logChance);\n if (below <= tail) low = k;\n if (below + chance >= 1 - tail) {\n let coverage = 0;\n let at = successes * Math.log(p);\n for (let i = 0; i <= k; i++) {\n if (i >= low) coverage += Math.exp(at);\n at += Math.log((i + successes) / (i + 1)) + logQ;\n }\n return { low, high: k, coverage: Math.min(1, coverage) };\n }\n below += chance;\n logChance += Math.log((k + successes) / (k + 1)) + logQ;\n }\n}\n","/**\n * The comparison of a candidate with a baseline, and the calibration of predictions. These functions make two fleet\n * rules into code. First, a change of a default is judged against the current default. The measure is the inputs that\n * gain and the inputs that lose beyond the noise, with the effect size. A sign test alone is not enough. Second, each\n * prediction states a probability, and the Brier score measures how good the stated probabilities were.\n */\nimport { median, quantileSorted, sd, sorted } from \"./describe.ts\";\nimport { type Proportion, signTest, wilson } from \"./tests.ts\";\n\nexport interface NoiseOptions {\n /** The number of standard deviations. The default is 2. */\n readonly k?: number;\n /** The fewest values (seeds or folds) that give a floor. The default is 5, the 5-seed rule. */\n readonly minimum?: number;\n}\n\n/**\n * The noise floor of a measure: k sample standard deviations of its value over independent seeds or folds. A\n * difference smaller than the floor is not a result.\n */\nexport function noiseFloor(values: readonly number[], options: NoiseOptions = {}): number {\n const minimum = options.minimum ?? 5;\n if (values.length < minimum) throw new RangeError(`noiseFloor: ${values.length} values; the rule needs ${minimum} or more seeds or folds.`);\n return (options.k ?? 2) * sd(values);\n}\n\nexport interface CompareOptions {\n /** \"higher\" (the default): a ratio above 1 is a gain. \"lower\": a ratio below 1 is a gain, as for a time or a cost. */\n readonly better?: \"higher\" | \"lower\";\n /** A ratio at this distance from 1 or nearer is a tie. The default is 0: only a ratio of exactly 1 is a tie. */\n readonly tie?: number;\n /** A gain or a loss counts only beyond this distance from 1. The default is 0. Use noiseFloor. */\n readonly noise?: number;\n}\n\n/** The effect on the inputs that are not ties. */\nexport interface Effect {\n readonly n: number;\n readonly median: number;\n /** The 0.1 quantile (linear). */\n readonly p10: number;\n /** The 0.9 quantile (linear). */\n readonly p90: number;\n}\n\nexport interface Comparison {\n /** The number of inputs. */\n readonly n: number;\n readonly ties: number;\n /** The inputs where the candidate is better, by any amount. */\n readonly wins: number;\n /** The inputs where the candidate is worse, by any amount. */\n readonly losses: number;\n /** The one-sided sign test of wins against losses. */\n readonly signP: number;\n /** The ratios of the inputs that are not ties, or undefined when each input is a tie. */\n readonly effect: Effect | undefined;\n /** The inputs that gain beyond the noise. */\n readonly gains: number;\n /** The inputs that lose beyond the noise. */\n readonly drops: number;\n /** gains / n, with its Wilson interval. */\n readonly gainShare: number;\n readonly gainInterval: Proportion;\n /** drops / n, with its Wilson interval. */\n readonly dropShare: number;\n readonly dropInterval: Proportion;\n}\n\n/**\n * The comparison of a candidate with a baseline, from the ratio candidate / baseline of each input. It answers the\n * three questions of a promotion. How often is the candidate better? By how much? How often is it worse beyond the\n * noise? A promotion reads `gains` against `drops` and `effect`, not `signP` alone, because a sign test counts a\n * win of any size.\n */\nexport function compareRatios(ratios: readonly number[], options: CompareOptions = {}): Comparison {\n if (ratios.length === 0) throw new RangeError(\"compareRatios: the list is empty.\");\n const sign = (options.better ?? \"higher\") === \"higher\" ? 1 : -1;\n const tie = options.tie ?? 0;\n const noise = options.noise ?? 0;\n if (!(tie >= 0) || !(noise >= 0)) throw new RangeError(\"compareRatios: tie and noise are 0 or more.\");\n let ties = 0;\n let wins = 0;\n let losses = 0;\n let gains = 0;\n let drops = 0;\n const changed: number[] = [];\n for (const ratio of ratios) {\n if (!Number.isFinite(ratio)) throw new RangeError(`compareRatios: each ratio is a finite number, not ${ratio}.`);\n const d = sign * (ratio - 1);\n if (Math.abs(ratio - 1) <= tie) {\n ties++;\n continue;\n }\n changed.push(ratio);\n if (d > 0) wins++;\n else losses++;\n if (d > noise) gains++;\n else if (-d > noise) drops++;\n }\n const n = ratios.length;\n const s = sorted(changed);\n const effect = s.length === 0 ? undefined : { n: s.length, median: median(s), p10: quantileSorted(s, 0.1), p90: quantileSorted(s, 0.9) };\n return {\n n,\n ties,\n wins,\n losses,\n signP: signTest(wins, losses),\n effect,\n gains,\n drops,\n gainShare: gains / n,\n gainInterval: wilson(gains, n),\n dropShare: drops / n,\n dropInterval: wilson(drops, n),\n };\n}\n\n/** A prediction: the stated probability that the claim holds, and if it held. */\nexport interface Forecast {\n readonly p: number;\n readonly hit: boolean;\n}\n\nfunction checkedForecasts(name: string, forecasts: readonly Forecast[]): void {\n if (forecasts.length === 0) throw new RangeError(`${name}: the list is empty.`);\n for (const f of forecasts) if (!(f.p >= 0 && f.p <= 1)) throw new RangeError(`${name}: each p is from 0 to 1, not ${f.p}.`);\n}\n\n/** The Brier score: the mean of (p - outcome)^2. 0 is perfect, and 0.25 is a constant 0.5. Lower is better. */\nexport function brier(forecasts: readonly Forecast[]): number {\n checkedForecasts(\"brier\", forecasts);\n let sum = 0;\n for (const f of forecasts) sum += (f.p - (f.hit ? 1 : 0)) ** 2;\n return sum / forecasts.length;\n}\n\n/** The predictions of one stated level. */\nexport interface CalibrationLevel {\n readonly stated: number;\n readonly n: number;\n readonly hits: number;\n /** hits / n. A calibrated level has a rate near `stated`. */\n readonly rate: number;\n /** The Wilson interval of the rate. A level is overconfident when `stated` is above it. */\n readonly interval: Proportion;\n}\n\n/** The hit rate of each stated level, from the lowest level. */\nexport function calibration(forecasts: readonly Forecast[]): CalibrationLevel[] {\n checkedForecasts(\"calibration\", forecasts);\n const levels = new Map<number, { n: number; hits: number }>();\n for (const f of forecasts) {\n const level = levels.get(f.p) ?? { n: 0, hits: 0 };\n level.n++;\n if (f.hit) level.hits++;\n levels.set(f.p, level);\n }\n return [...levels]\n .sort((a, b) => a[0] - b[0])\n .map(([stated, { n, hits }]) => ({ stated, n, hits, rate: hits / n, interval: wilson(hits, n) }));\n}\n"],"mappings":";;AAoBA,SAAS,QAAQ,MAAc,QAAiC;CAC9D,IAAI,OAAO,WAAW,GAAG,MAAM,IAAI,WAAW,GAAG,KAAK,qBAAqB;CAC3E,KAAK,MAAM,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,GAAG,MAAM,IAAI,WAAW,GAAG,KAAK,sBAAsB;AAClG;;AAGA,SAAgB,OAAO,QAAqC;CAC1D,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC;AACzC;AAEA,SAAgB,KAAK,QAAmC;CACtD,QAAQ,QAAQ,MAAM;CACtB,IAAI,MAAM;CACV,KAAK,MAAM,KAAK,QAAQ,OAAO;CAC/B,OAAO,MAAM,OAAO;AACtB;;AAGA,SAAgB,GAAG,QAAmC;CACpD,QAAQ,MAAM,MAAM;CACpB,IAAI,OAAO,SAAS,GAAG,MAAM,IAAI,WAAW,sCAAsC;CAClF,MAAM,IAAI,KAAK,MAAM;CACrB,IAAI,MAAM;CACV,KAAK,MAAM,KAAK,QAAQ,QAAQ,IAAI,MAAM;CAC1C,OAAO,KAAK,KAAK,OAAO,OAAO,SAAS,EAAE;AAC5C;;;;;;;AAQA,SAAgB,eAAe,cAAiC,GAAW,SAAyB,UAAkB;CACpH,QAAQ,YAAY,YAAY;CAChC,IAAI,EAAE,KAAK,KAAK,KAAK,IAAI,MAAM,IAAI,WAAW,mCAAmC,EAAE,EAAE;CACrF,MAAM,IAAI,aAAa;CACvB,IAAI,WAAW,gBAAgB,OAAO,aAAa,KAAK,IAAI,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC;CAEpG,IAAI,WAAW,UAAU,OAAO,aAAa,KAAK,KAAK,KAAK,MAAM,KAAK,IAAI,KAAK,GAAG,IAAI,GAAG;CAC1F,MAAM,MAAM,IAAI,KAAK;CACrB,MAAM,MAAM,KAAK,MAAM,EAAE;CACzB,MAAM,OAAO,KAAK;CAClB,MAAM,IAAI,aAAa;CACvB,IAAI,SAAS,GAAG,OAAO;CACvB,MAAM,IAAI,aAAa,MAAM;CAC7B,IAAI,MAAM,GAAG,OAAO;CACpB,OAAO,IAAI,QAAQ,IAAI;AACzB;;AAGA,SAAgB,SAAS,QAA2B,GAAW,SAAyB,UAAkB;CACxG,QAAQ,YAAY,MAAM;CAC1B,OAAO,eAAe,OAAO,MAAM,GAAG,GAAG,MAAM;AACjD;;;;;AAMA,SAAgB,OAAO,QAAmC;CACxD,QAAQ,UAAU,MAAM;CACxB,MAAM,IAAI,OAAO,MAAM;CACvB,MAAM,SAAS,KAAK,MAAM,EAAE,SAAS,CAAC;CACtC,OAAO,EAAE,SAAS,MAAM,IAAK,EAAE,WAAuB,EAAE,SAAS,KAAiB,EAAE,WAAsB;AAC5G;AAmBA,SAAgB,UAAU,QAAoC;CAC5D,QAAQ,aAAa,MAAM;CAC3B,MAAM,IAAI,OAAO,MAAM;CACvB,MAAM,KAAK,eAAe,GAAG,GAAI;CACjC,MAAM,KAAK,eAAe,GAAG,GAAI;CACjC,OAAO;EACL,GAAG,EAAE;EAEL,MAAM,KAAK,MAAM;EACjB,IAAI,EAAE,SAAS,IAAI,MAAa,GAAG,MAAM;EACzC,KAAK,EAAE;EACP;EACA,QAAQ,OAAO,CAAC;EAChB;EACA,KAAK,EAAE,EAAE,SAAS;EAClB,KAAK,KAAK;CACZ;AACF;;;;;;AC1FA,MAAM,iBAAiB;;;;;;;;;;AAWvB,SAAgB,aAAa,GAAmC,GAAsB,UAA+B,CAAC,GAAoB;CACxI,MAAM,YAAY,QAAQ,aAAa;CAEvC,OAAO,QAAQ,GAAG,GAAG,WADX,aAAa,gBAAgB,GAAG,GAAG,SACb,CAAC;AACnC;;;;;AAMA,SAAgB,aAAa,MAAc,GAAmC,GAAsB,WAA4B;CAC9H,IAAI,EAAE,WAAW,GAAG,MAAM,IAAI,WAAW,GAAG,KAAK,cAAc;CAC/D,IAAI,EAAE,WAAW,EAAE,QAAQ,MAAM,IAAI,WAAW,GAAG,KAAK,UAAU,EAAE,OAAO,kBAAkB,EAAE,OAAO,wCAAwC;CAC9I,MAAM,IAAK,EAAE,EAAE,CAAuB;CACtC,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;EACjC,MAAM,MAAM,EAAE;EACd,IAAI,IAAI,WAAW,GAAG,MAAM,IAAI,WAAW,GAAG,KAAK,QAAQ,EAAE,YAAY,IAAI,OAAO,yBAAyB,EAAE,sCAAsC;EACrJ,KAAK,MAAM,KAAK,KAAK,IAAI,CAAC,OAAO,SAAS,CAAC,GAAG,MAAM,IAAI,WAAW,GAAG,KAAK,QAAQ,EAAE,sCAAsC;EAC3H,IAAI,CAAC,OAAO,SAAS,EAAE,EAAY,GAAG,MAAM,IAAI,WAAW,GAAG,KAAK,UAAU,EAAE,qBAAqB;CACtG;CACA,MAAM,IAAI,KAAK,YAAY,IAAI;CAC/B,IAAI,MAAM,GAAG,MAAM,IAAI,WAAW,GAAG,KAAK,gEAAgE;CAC1G,OAAO;AACT;;;;;AAMA,SAAgB,QAAQ,GAAmC,GAAsB,WAAoB,GAA4B;CAC/H,MAAM,IAAI,EAAE;CACZ,MAAM,gBAAiC;EAAE,cAAc,IAAI,MAAc,CAAC,CAAC,CAAC,KAAK,GAAU;EAAG,YAAY;EAAY,IAAI;EAAY;EAAG;CAAE;CAC3I,IAAI,KAAK,GAAG,OAAO,OAAO;CAC1B,MAAM,SAAS,YAAY,IAAI;CAC/B,MAAM,IAAI,IAAI,aAAa,IAAI,CAAC;CAChC,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;EAC1B,MAAM,MAAM,EAAE;EACd,IAAI,WAAW,EAAE,KAAK;EACtB,KAAK,IAAI,IAAI,QAAQ,IAAI,GAAG,KAAK,EAAE,IAAI,IAAI,KAAK,IAAI,IAAI;CAC1D;CACA,MAAM,MAAM,aAAa,KAAK,CAAC;CAC/B,MAAM,WAAW,IAAI,aAAa,CAAC;CACnC,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;EAC1B,MAAM,IAAI,IAAI;EAEd,IAAI,OAAO;EACX,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,QAAS,EAAE,IAAI,MAAiB;EAC5D,IAAI,QAAQ;EACZ,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,SAAU,EAAE,IAAI,MAAiB;EAE7D,MAAM,OAAO,KAAK,KAAK,KAAK;EAC5B,IAAI,EAAE,OAAO,iBAAiB,KAAK,KAAK,OAAO,KAAK,IAAI,OAAO,OAAO;EACtE,MAAM,QAAS,EAAE,IAAI,KAAgB,IAAI,CAAC,OAAO;EAEjD,EAAE,IAAI,KAAM,EAAE,IAAI,KAAgB;EAClC,IAAI,KAAK;EACT,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,MAAO,EAAE,IAAI,MAAiB;EAC1D,MAAM,WAAW,QAAsB,UAAwB;GAC7D,IAAI,MAAM;GACV,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,OAAQ,EAAE,IAAI,KAAiB,OAAO,QAAQ;GAC1E,MAAM,IAAK,IAAI,MAAO;GACtB,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,OAAO,QAAQ,KAAM,OAAO,QAAQ,KAAgB,IAAK,EAAE,IAAI;EAC7F;EACA,KAAK,IAAI,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,QAAQ,GAAG,IAAI,CAAC;EAChD,QAAQ,KAAK,CAAC;EACd,SAAS,KAAK;CAChB;CAEA,MAAM,IAAI,IAAI,MAAc,CAAC,CAAC,CAAC,KAAK,CAAC;CACrC,KAAK,IAAI,IAAI,IAAI,GAAG,KAAK,GAAG,KAAK;EAC/B,IAAI,IAAI,IAAI;EACZ,KAAK,IAAI,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,KAAM,EAAE,IAAI,IAAI,KAAiB,EAAE;EACnE,EAAE,KAAK,IAAK,SAAS;CACvB;CACA,IAAI,SAAS;CACb,IAAI,WAAW;EACb,KAAK,MAAM,KAAK,GAAG,UAAU;EAC7B,UAAU;CACZ;CACA,IAAI,MAAM;CACV,IAAI,MAAM;CACV,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;EAC1B,MAAM,MAAM,EAAE;EACd,IAAI,SAAS,YAAa,EAAE,KAAgB;EAC5C,KAAK,IAAI,IAAI,QAAQ,IAAI,GAAG,KAAK,UAAW,EAAE,KAAiB,IAAI,IAAI;EACvE,QAAS,EAAE,KAAgB,WAAW;EACtC,QAAS,EAAE,KAAgB,WAAW;CACxC;CACA,OAAO;EAAE,cAAc;EAAG,YAAY,KAAK,KAAK,OAAO,IAAI,EAAE;EAAG,IAAI,MAAM,IAAI,IAAI,MAAM,MAAM;EAAY;EAAG;CAAE;AACjH;;;;;;;;;;;;;ACtFA,SAAgB,UAAa,MAAoB,WAA6C,UAA4B,CAAC,GAAa;CACtI,IAAI,KAAK,WAAW,GAAG,MAAM,IAAI,WAAW,+BAA+B;CAC3E,MAAM,IAAI,KAAK;CACf,MAAM,SAAS,IAAI,MAAS,CAAC;CAC7B,OAAO,WACL,aACA,UACC,MAAM;EACL,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,OAAO,KAAK,KAAK,EAAE,MAAM,CAAC;EACtD,OAAO,UAAU,MAAM;CACzB,SACM,UAAU,IAAI,CACtB;AACF;;;;;;;;AASA,SAAgB,aACd,GACA,GACA,WACA,UAA4B,CAAC,GACnB;CACV,IAAI,EAAE,WAAW,GAAG,MAAM,IAAI,WAAW,0CAA0C;CACnF,IAAI,EAAE,WAAW,GAAG,MAAM,IAAI,WAAW,2CAA2C;CACpF,MAAM,KAAK,EAAE;CACb,MAAM,KAAK,EAAE;CACb,MAAM,UAAU,IAAI,MAAS,EAAE;CAC/B,MAAM,UAAU,IAAI,MAAS,EAAE;CAC/B,OAAO,WACL,gBACA,UACC,MAAM;EACL,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK,QAAQ,KAAK,EAAE,EAAE,MAAM,EAAE;EACtD,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK,QAAQ,KAAK,EAAE,EAAE,MAAM,EAAE;EACtD,OAAO,UAAU,SAAS,OAAO;CACnC,SACM,UAAU,GAAG,CAAC,CACtB;AACF;;;;;;AAOA,SAAgB,qBAAqB,WAA8B,aAAgC,UAA4B,CAAC,GAAa;CAC3I,OAAO,aAAa,WAAW,cAAc,GAAG,MAAM,OAAO,CAAC,IAAI,OAAO,CAAC,GAAG,OAAO;AACtF;;;;;;;AAQA,SAAgB,sBACd,GACA,GACA,UAAkD,CAAC,GACvC;CACZ,MAAM,YAAY,QAAQ,aAAa;CACvC,MAAM,IAAI,aAAa,yBAAyB,GAAG,GAAG,SAAS;CAC/D,MAAM,IAAI,EAAE;CACZ,MAAM,UAAU,IAAI,MAAyB,CAAC;CAC9C,MAAM,UAAU,IAAI,MAAc,CAAC;CACnC,OAAO,YACL,yBACA,SACA,IACC,MAAM;EACL,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;GAC1B,MAAM,MAAM,EAAE,MAAM,CAAC;GACrB,QAAQ,KAAK,EAAE;GACf,QAAQ,KAAK,EAAE;EACjB;EACA,OAAO,QAAQ,SAAS,SAAS,WAAW,CAAC,CAAC,CAAC;CACjD,SACM,QAAQ,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC,YACpC;AACF;;AAWA,SAAS,SAAS,MAAc,SAAqC;CACnE,MAAM,OAAO,QAAQ,QAAQ;CAC7B,IAAI,CAAC,OAAO,cAAc,IAAI,KAAK,OAAO,GAAG,MAAM,IAAI,WAAW,GAAG,KAAK,6CAA6C,KAAK,EAAE;CAC9H,MAAM,QAAQ,KAAK,QAAQ,SAAS,QAAS;CAC7C,MAAM,CAAC,QAAQ,WAAW,QAAQ,QAAQ,CAAC,MAAM,IAAI,IAAI;CACzD,IAAI,EAAE,UAAU,KAAK,SAAS,WAAW,WAAW,IAAI,MAAM,IAAI,WAAW,GAAG,KAAK,2CAA2C,OAAO,OAAO,QAAQ,EAAE;CACxJ,MAAM,QAAQ,QAAQ,OAAO,UAAU,SAAU,QAAQ,SAAS;CAClE,IAAI,EAAE,QAAQ,KAAK,QAAQ,IAAI,MAAM,IAAI,WAAW,GAAG,KAAK,8CAA8C,MAAM,EAAE;CAClH,OAAO;EAAE;EAAM;EAAQ;EAAS;EAAO,QAAQ,QAAQ,UAAU;CAAS;AAC5E;;AAGA,SAAS,KAAK,QAAkB,UAAkB,GAAa,MAAwB;CACrF,MAAM,EAAE,MAAM,UAAU;CACxB,IAAI,OAAO,WAAW,GAAG,OAAO;EAAE;EAAU,KAAK;EAAU,MAAM;EAAU;EAAO;EAAM,QAAQ;EAAG;CAAK;CACxG,MAAM,IAAI,OAAO,MAAM;CACvB,OAAO;EAAE;EAAU,KAAK,eAAe,GAAG,EAAE,QAAQ,EAAE,MAAM;EAAG,MAAM,eAAe,GAAG,EAAE,SAAS,EAAE,MAAM;EAAG;EAAO;EAAM,QAAQ,EAAE;EAAQ;CAAK;AACnJ;;;;;;AAOA,SAAS,WAAW,MAAc,SAA2B,KAA4B,KAA6B;CACpH,MAAM,IAAI,SAAS,MAAM,OAAO;CAChC,MAAM,IAAI,OAAO,QAAQ,QAAQ,CAAC;CAClC,MAAM,SAAmB,CAAC;CAC1B,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE,MAAM,KAAK;EAC/B,MAAM,IAAI,IAAI,CAAC;EACf,IAAI,OAAO,SAAS,CAAC,GAAG,OAAO,KAAK,CAAC;CACvC;CACA,OAAO,KAAK,QAAQ,IAAI,GAAG,GAAG,EAAE,IAAI;AACtC;;;;;AAMA,SAAS,YAAY,MAAc,SAA2B,GAAW,KAAuC,KAA0C;CACxJ,MAAM,IAAI,SAAS,MAAM,OAAO;CAChC,MAAM,IAAI,OAAO,QAAQ,QAAQ,CAAC;CAClC,MAAM,SAAS,MAAM,KAAK,EAAE,QAAQ,EAAE,SAAmB,CAAC,CAAC;CAC3D,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE,MAAM,KAAK;EAC/B,MAAM,IAAI,IAAI,CAAC;EACf,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,IAAI,OAAO,SAAS,EAAE,EAAE,GAAG,OAAQ,EAAE,CAAc,KAAK,EAAE,EAAY;CACpG;CACA,MAAM,WAAW,IAAI;CACrB,OAAO,OAAO,KAAK,MAAM,MAAM,KAAK,MAAM,SAAS,IAAc,GAAG,EAAE,IAAI,CAAC;AAC7E;;AAGA,SAAgB,gBAAgB,QAA2B,UAA4B,CAAC,GAAa;CACnG,OAAO,UAAU,QAAQ,QAAQ,OAAO;AAC1C;;;;;;AAOA,SAAgB,kBACd,MACA,SACA,WACA,UAA4B,CAAC,GACnB;CACV,MAAM,yBAAS,IAAI,IAAiB;CACpC,KAAK,MAAM,OAAO,MAAM;EACtB,MAAM,MAAM,QAAQ,GAAG;EACvB,MAAM,OAAO,OAAO,IAAI,GAAG;EAC3B,IAAI,MAAM,KAAK,KAAK,GAAG;OAClB,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC;CAC5B;CAEA,MAAM,SAAS,UAAU,CADP,GAAG,OAAO,OAAO,CACH,IAAI,UAAU,UAAU,MAAM,KAAK,CAAC,GAAG,OAAO;CAE9E,MAAM,WAAW,UAAU,IAAI;CAC/B,OAAO,OAAO,WAAW,IAAI;EAAE,GAAG;EAAQ;EAAU,KAAK;EAAU,MAAM;CAAS,IAAI;EAAE,GAAG;EAAQ;CAAS;AAC9G;;;;;;;AC3MA,MAAM,kBAAkB;;;;;;;;;;;AAYxB,SAAgB,WAAW,MAAyB,QAA2B,QAAgB,UAAwB,CAAC,GAAa;CACnI,MAAM,IAAI,OAAO;CACjB,IAAI,MAAM,GAAG,MAAM,IAAI,WAAW,kCAAkC;CACpE,IAAI,KAAK,WAAW,IAAI,GAAG,MAAM,IAAI,WAAW,4BAA4B,KAAK,OAAO,kCAAkC,EAAE,SAAS,IAAI,EAAE,EAAE;CAC7I,IAAI,EAAE,UAAU,KAAK,OAAO,SAAS,MAAM,IAAI,MAAM,IAAI,WAAW,2DAA2D,OAAO,EAAE;CACxI,MAAM,UAAU,IAAI,aAAa,CAAC,CAAC,CAAC,KAAK,MAAM;CAC/C,KAAK,MAAM,KAAK,QAAQ,QAAQ,CAAC,GAAG;EAClC,IAAI,CAAC,OAAO,cAAc,CAAC,KAAK,IAAI,KAAK,KAAK,GAAG,MAAM,IAAI,WAAW,wDAAwD,IAAI,EAAE,QAAQ,EAAE,EAAE;EAChJ,QAAQ,KAAK;CACf;CACA,MAAM,IAAI,IAAI,aAAa,IAAI,CAAC;CAChC,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,GAAG,KAAK;EAC9B,MAAM,IAAI,KAAK;EACf,IAAI,CAAC,OAAO,SAAS,CAAC,GAAG,MAAM,IAAI,WAAW,8BAA8B,EAAE,gBAAgB;EAC9F,EAAE,KAAK;CACT;CACA,MAAM,IAAI,IAAI,aAAa,CAAC;CAC5B,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;EAC1B,MAAM,IAAI,OAAO;EACjB,IAAI,CAAC,OAAO,SAAS,CAAC,GAAG,MAAM,IAAI,WAAW,gCAAgC,EAAE,gBAAgB;EAChG,EAAE,KAAK;EACP,EAAE,IAAI,IAAI,KAAM,EAAE,IAAI,IAAI,KAAiB,QAAQ;CACrD;CACA,IAAI,CAAC,OAAO,GAAG,CAAC,GAAG,OAAO,IAAI,MAAc,CAAC,CAAC,CAAC,KAAK,GAAU;CAC9D,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;EAC1B,IAAI,IAAI,EAAE;EACV,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,KAAM,EAAE,IAAI,IAAI,KAAiB,EAAE;EAC/D,EAAE,KAAK,IAAK,EAAE,IAAI,IAAI;CACxB;CACA,KAAK,IAAI,IAAI,IAAI,GAAG,KAAK,GAAG,KAAK;EAC/B,IAAI,IAAI,EAAE;EACV,KAAK,IAAI,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,KAAM,EAAE,IAAI,IAAI,KAAiB,EAAE;EACnE,EAAE,KAAK,IAAK,EAAE,IAAI,IAAI;CACxB;CACA,OAAO,MAAM,KAAK,CAAC;AACrB;;;;;AAMA,SAAS,OAAO,GAAiB,GAAoB;CACnD,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;EAC1B,MAAM,WAAW,EAAE,IAAI,IAAI;EAC3B,IAAI,IAAI;EACR,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,KAAM,EAAE,IAAI,IAAI,MAAiB;EAC7D,IAAI,EAAE,IAAI,kBAAkB,KAAK,IAAI,QAAQ,MAAM,EAAE,IAAI,IAAI,OAAO;EACpE,MAAM,IAAI,KAAK,KAAK,CAAC;EACrB,EAAE,IAAI,IAAI,KAAK;EACf,KAAK,IAAI,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;GAC9B,IAAI,IAAI,EAAE,IAAI,IAAI;GAClB,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,KAAM,EAAE,IAAI,IAAI,KAAiB,EAAE,IAAI,IAAI;GACvE,EAAE,IAAI,IAAI,KAAK,IAAI;EACrB;CACF;CACA,OAAO;AACT;;;;;;AC9EA,SAASA,QAAM,MAAc,OAAqB;CAChD,IAAI,CAAC,OAAO,cAAc,KAAK,KAAK,QAAQ,GAAG,MAAM,IAAI,WAAW,GAAG,KAAK,IAAI,MAAM,qCAAqC;AAC7H;;AAGA,SAAS,iBAAiB,GAAqB;CAC7C,MAAM,OAAiB,CAAC;CACxB,IAAI,YAAY;CAChB,KAAK,IAAI,IAAI,GAAG,KAAK,GAAG,KAAK;EAC3B,IAAI,IAAI,GAAG,aAAa,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC;EAChD,KAAK,KAAK,YAAY,IAAI,KAAK,GAAG;CACpC;CACA,OAAO;AACT;;AAGA,SAAS,UAAU,GAAW,GAAmB;CAC/C,IAAI,KAAK,GAAG,OAAO;CACnB,IAAI,IAAI,GAAG,OAAO;CAClB,MAAM,OAAO,iBAAiB,CAAC,CAAC,CAAC,MAAM,CAAC;CACxC,MAAM,MAAM,KAAK,IAAI,GAAG,IAAI;CAC5B,MAAM,MAAM,KAAK,QAAQ,GAAG,MAAM,IAAI,KAAK,IAAI,IAAI,GAAG,GAAG,CAAC;CAC1D,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,IAAI,GAAG;AACxC;;;;;;AAOA,SAAgB,SAAS,QAAgB,OAAe,QAAe,GAAW;CAChF,QAAM,YAAY,MAAM;CACxB,QAAM,YAAY,KAAK;CACvB,MAAM,IAAI,SAAS;CACnB,IAAI,MAAM,GAAG,OAAO;CACpB,IAAI,UAAU,GAAG,OAAO,UAAU,QAAQ,CAAC;CAC3C,OAAO,KAAK,IAAI,GAAG,IAAI,UAAU,KAAK,IAAI,QAAQ,KAAK,GAAG,CAAC,CAAC;AAC9D;;;;;AAMA,SAAgB,cAAc,GAAW,QAAQ,KAAM,QAAe,GAAuB;CAC3F,QAAM,iBAAiB,CAAC;CACxB,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI,CAAC,GAAG,KAAK,GAAG,KAAK,IAAI,SAAS,GAAG,IAAI,GAAG,KAAK,IAAI,OAAO,OAAO;AAE5F;;AAGA,MAAa,MAAM;;;;;AAYnB,SAAgB,OAAO,GAAW,GAAW,IAAY,KAAiB;CACxE,QAAM,UAAU,CAAC;CACjB,QAAM,UAAU,CAAC;CACjB,IAAI,IAAI,GAAG,MAAM,IAAI,WAAW,aAAa,EAAE,kBAAkB,EAAE,EAAE;CACrE,IAAI,MAAM,GAAG,OAAO;EAAE,KAAK;EAAG,MAAM;CAAE;CACtC,MAAM,IAAI,IAAI;CACd,MAAM,KAAK,IAAI;CACf,MAAM,cAAc,IAAI,KAAK;CAC7B,MAAM,UAAU,IAAI,MAAM,IAAI,MAAM;CACpC,MAAM,OAAQ,IAAI,cAAe,KAAK,KAAM,KAAK,IAAI,KAAM,IAAI,MAAM,IAAI,IAAI,EAAE;CAC/E,OAAO;EAAE,KAAK,KAAK,IAAI,GAAG,SAAS,IAAI;EAAG,MAAM,KAAK,IAAI,GAAG,SAAS,IAAI;CAAE;AAC7E;;;;;;AAiBA,SAAgB,KAAK,SAA4B,QAAQ,KAAmB;CAC1E,KAAK,MAAM,KAAK,SAAS,IAAI,EAAE,KAAK,KAAK,KAAK,IAAI,MAAM,IAAI,WAAW,oCAAoC,EAAE,EAAE;CAC/G,MAAM,IAAI,QAAQ;CAClB,MAAM,QAAQ,QAAQ,KAAK,GAAG,OAAO;EAAE;EAAG;CAAE,EAAE,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;CACrF,MAAM,WAAW,IAAI,MAAc,CAAC;CACpC,IAAI,UAAU;CACd,MAAM,SAAS,EAAE,GAAG,KAAK,SAAS;EAChC,UAAU,KAAK,IAAI,SAAS,KAAK,IAAI,IAAI,IAAI,QAAQ,CAAC,CAAC;EACvD,SAAS,KAAK;CAChB,CAAC;CACD,OAAO,QAAQ,KAAK,GAAG,OAAO;EAAE;EAAG,UAAU,SAAS;EAAc,QAAS,SAAS,KAAgB;CAAM,EAAE;AAChH;;;;;AAuBA,SAAgB,kBAAkB,WAA8B,UAA6B,UAA8B,CAAC,GAAsB;CAChJ,IAAI,UAAU,WAAW,SAAS,QAAQ,MAAM,IAAI,WAAW,qCAAqC,UAAU,OAAO,OAAO,SAAS,OAAO,SAAS;CACrJ,MAAM,cAAc,UAAU,KAAK,GAAG,MAAM,IAAK,SAAS,EAAa;CACvE,MAAM,YAAY,QAAQ,aAAa;CACvC,MAAM,OAAO,QAAQ,QAAQ;CAC7B,IAAI,CAAC,OAAO,cAAc,IAAI,KAAK,OAAO,GAAG,MAAM,IAAI,WAAW,+DAA+D,KAAK,EAAE;CACxI,MAAM,WAAW,UAAU,WAAW;CACtC,MAAM,IAAI,OAAO,QAAQ,QAAQ,CAAC;CAClC,MAAM,UAAU,IAAI,MAAc,YAAY,MAAM;CACpD,IAAI,UAAU;CACd,KAAK,IAAI,MAAM,GAAG,MAAM,MAAM,OAAO;EACnC,KAAK,IAAI,IAAI,GAAG,IAAI,YAAY,QAAQ,KAAK,QAAQ,KAAK,EAAE,KAAK,IAAI,KAAM,CAAE,YAAY,KAAiB,YAAY;EAEtH,IAAI,KAAK,IAAI,UAAU,OAAO,CAAC,KAAK,KAAK,IAAI,QAAQ,KAAK,IAAI,QAAQ;CACxE;CACA,OAAO;EAAE;EAAU,IAAI,IAAI,YAAY,IAAI;EAAO;CAAK;AACzD;;;;;;AC7IA,SAAS,UAAU,MAAc,GAAsB,GAA4B;CACjF,IAAI,EAAE,WAAW,EAAE,QAAQ,MAAM,IAAI,WAAW,GAAG,KAAK,mBAAmB,EAAE,OAAO,OAAO,EAAE,OAAO,SAAS;CAC7G,KAAK,MAAM,KAAK,GAAG,IAAI,OAAO,MAAM,CAAC,GAAG,MAAM,IAAI,WAAW,GAAG,KAAK,4BAA4B;CACjG,KAAK,MAAM,KAAK,GAAG,IAAI,OAAO,MAAM,CAAC,GAAG,MAAM,IAAI,WAAW,GAAG,KAAK,6BAA6B;AACpG;;AAGA,SAAgB,MAAM,QAAqC;CACzD,MAAM,QAAQ,OAAO,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAU,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,EAAE;CAC9E,MAAM,MAAM,IAAI,MAAc,OAAO,MAAM;CAC3C,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,SAAU;EAClC,IAAI,IAAI;EACR,OAAO,IAAI,IAAI,MAAM,UAAW,MAAM,IAAI,EAAE,CAA+B,OAAQ,MAAM,EAAE,CAA+B,IAAI;EAC9H,KAAK,IAAI,IAAI,GAAG,KAAK,GAAG,KAAK,IAAK,MAAM,EAAE,CAA+B,OAAO,IAAI,KAAK,IAAI;EAC7F,IAAI,IAAI;CACV;CACA,OAAO;AACT;;;;;AAMA,SAAgB,SAAS,GAAsB,GAA8B;CAC3E,UAAU,YAAY,GAAG,CAAC;CAC1B,MAAM,KAAK,MAAM,CAAC;CAClB,MAAM,KAAK,MAAM,CAAC;CAClB,MAAM,QAAQ,OAAkC,GAAG,QAAQ,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,GAAG;CACnF,MAAM,KAAK,KAAK,EAAE;CAClB,MAAM,KAAK,KAAK,EAAE;CAClB,IAAI,MAAM;CACV,IAAI,KAAK;CACT,IAAI,KAAK;CACT,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,QAAQ,KAAK;EAClC,QAAS,GAAG,KAAgB,OAAQ,GAAG,KAAgB;EACvD,OAAQ,GAAG,KAAgB,OAAO;EAClC,OAAQ,GAAG,KAAgB,OAAO;CACpC;CACA,OAAO,OAAO,KAAK,OAAO,IAAI,IAAI,MAAM,KAAK,KAAK,KAAK,EAAE;AAC3D;;AAGA,MAAa,gBAAgB;AAC7B,MAAM,iBAAiB;;;;;;AAOvB,SAAgB,WAAW,GAAsB,GAAsB,OAAwB,GAAW;CACxG,UAAU,cAAc,GAAG,CAAC;CAC5B,MAAM,IAAI,EAAE;CACZ,IAAI,IAAI,GAAG,OAAO;CAClB,IAAI,aAAa;CACjB,IAAI,aAAa;CACjB,IAAI,OAAO;CACX,IAAI,OAAO;CACX,MAAM,SAAS,GAAW,MAAoB;EAC5C,MAAM,KAAK,KAAK,KAAM,EAAE,KAAiB,EAAE,EAAa;EACxD,MAAM,KAAK,KAAK,KAAM,EAAE,KAAiB,EAAE,EAAa;EACxD,IAAI,OAAO,KAAK,OAAO,GAAG;EAC1B,IAAI,OAAO,GAAG;OACT,IAAI,OAAO,GAAG;OACd,IAAI,OAAO,IAAI;OACf;CACP;CACA,IAAI,KAAA,MACF,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,KAAK,IAAI,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,MAAM,GAAG,CAAC;MACjE;EACL,MAAM,IAAI,OAAO,IAAI;EACrB,KAAK,IAAI,IAAI,GAAG,IAAI,gBAAgB,KAAK;GACvC,MAAM,IAAI,EAAE,MAAM,CAAC;GACnB,MAAM,IAAI,EAAE,MAAM,CAAC;GACnB,IAAI,MAAM,GAAG,MAAM,GAAG,CAAC;EACzB;CACF;CACA,MAAM,MAAM,KAAK,MAAM,aAAa,aAAa,SAAS,aAAa,aAAa,KAAK;CACzF,OAAO,QAAQ,IAAI,KAAK,aAAa,cAAc;AACrD;;;;;;AC/EA,SAAS,MAAM,MAAc,OAAqB;CAChD,IAAI,CAAC,OAAO,cAAc,KAAK,KAAK,QAAQ,GAAG,MAAM,IAAI,WAAW,GAAG,KAAK,IAAI,MAAM,qCAAqC;AAC7H;AAEA,SAAS,QAAQ,MAAc,OAAuB;CACpD,IAAI,EAAE,QAAQ,KAAK,QAAQ,IAAI,MAAM,IAAI,WAAW,GAAG,KAAK,kDAAkD,MAAM,EAAE;CACtH,QAAQ,IAAI,SAAS;AACvB;;AAGA,SAAS,cAAc,GAAW,GAAqB;CACrD,IAAI,MAAM,GAAG,OAAO,MAAM,KAAK,EAAE,QAAQ,IAAI,EAAE,IAAI,GAAG,MAAO,MAAM,IAAI,IAAI,CAAE;CAC7E,IAAI,MAAM,GAAG,OAAO,MAAM,KAAK,EAAE,QAAQ,IAAI,EAAE,IAAI,GAAG,MAAO,MAAM,IAAI,IAAI,CAAE;CAC7E,MAAM,CAAC,MAAM,QAAQ,CAAC,KAAK,IAAI,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC;CACjD,MAAM,QAAkB,CAAC;CACzB,IAAI,YAAY;CAChB,KAAK,IAAI,IAAI,GAAG,KAAK,GAAG,KAAK;EAC3B,IAAI,IAAI,GAAG,aAAa,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC;EAChD,MAAM,KAAK,KAAK,IAAI,YAAY,IAAI,QAAQ,IAAI,KAAK,IAAI,CAAC;CAC5D;CACA,OAAO;AACT;;;;;;;;;AAoBA,SAAgB,eAAe,QAA2B,QAAQ,KAAsB;CACtF,IAAI,OAAO,WAAW,GAAG,MAAM,IAAI,WAAW,oCAAoC;CAClF,KAAK,MAAM,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,GAAG,MAAM,IAAI,WAAW,qCAAqC;CACvG,MAAM,OAAO,QAAQ,kBAAkB,KAAK;CAC5C,MAAM,IAAI,OAAO,MAAM;CACvB,MAAM,IAAI,EAAE;CACZ,MAAM,QAAQ,cAAc,GAAG,EAAG;CAElC,IAAI,IAAI;CACR,IAAI,QAAQ,MAAM;CAClB,OAAO,IAAI,KAAK,IAAI,KAAK,SAAS,MAAM;EACtC,KAAK;EACL,SAAS,MAAM;CACjB;CACA,MAAM,OAAO,KAAK,IAAI,GAAG,CAAC;CAC1B,IAAI,OAAO;CACX,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,KAAK,QAAQ,MAAM;CAC7C,OAAO;EAAE,KAAK,EAAE,OAAO;EAAc,MAAM,EAAE,IAAI;EAAiB;EAAM,UAAU,KAAK,IAAI,GAAG,IAAI,IAAI,IAAI;CAAE;AAC9G;;;;;;AAeA,SAAgB,iBAAiB,GAAW,GAAW,QAAQ,KAAqB;CAClF,MAAM,oBAAoB,CAAC;CAC3B,IAAI,EAAE,KAAK,KAAK,KAAK,IAAI,MAAM,IAAI,WAAW,2CAA2C,EAAE,EAAE;CAC7F,MAAM,OAAO,QAAQ,oBAAoB,KAAK;CAC9C,MAAM,QAAQ,cAAc,GAAG,CAAC;CAChC,IAAI,MAAM;CACV,IAAI,QAAQ,MAAM;CAClB,OAAO,MAAM,KAAK,SAAS,MAAM;EAC/B,OAAO;EACP,SAAS,MAAM;CACjB;CACA,IAAI,OAAO;CACX,IAAI,QAAQ,MAAM;CAClB,OAAO,OAAO,KAAK,SAAS,MAAM;EAChC,QAAQ;EACR,SAAS,MAAM;CACjB;CACA,IAAI,WAAW;CACf,KAAK,IAAI,IAAI,KAAK,KAAK,MAAM,KAAK,YAAY,MAAM;CACpD,OAAO;EAAE;EAAK;EAAM,UAAU,KAAK,IAAI,GAAG,QAAQ;CAAE;AACtD;;;;;;AAOA,SAAgB,yBAAyB,WAAmB,GAAW,QAAQ,KAAqB;CAClG,MAAM,4BAA4B,SAAS;CAC3C,IAAI,EAAE,IAAI,KAAK,KAAK,IAAI,MAAM,IAAI,WAAW,iEAAiE,EAAE,EAAE;CAClH,MAAM,OAAO,QAAQ,4BAA4B,KAAK;CACtD,MAAM,OAAO,KAAK,MAAM,CAAC,CAAC;CAC1B,IAAI,YAAY,YAAY,KAAK,IAAI,CAAC;CACtC,IAAI,QAAQ;CACZ,IAAI,MAAM;CACV,KAAK,IAAI,IAAI,IAAK,KAAK,GAAG;EACxB,MAAM,SAAS,KAAK,IAAI,SAAS;EACjC,IAAI,SAAS,MAAM,MAAM;EACzB,IAAI,QAAQ,UAAU,IAAI,MAAM;GAC9B,IAAI,WAAW;GACf,IAAI,KAAK,YAAY,KAAK,IAAI,CAAC;GAC/B,KAAK,IAAI,IAAI,GAAG,KAAK,GAAG,KAAK;IAC3B,IAAI,KAAK,KAAK,YAAY,KAAK,IAAI,EAAE;IACrC,MAAM,KAAK,KAAK,IAAI,cAAc,IAAI,EAAE,IAAI;GAC9C;GACA,OAAO;IAAE;IAAK,MAAM;IAAG,UAAU,KAAK,IAAI,GAAG,QAAQ;GAAE;EACzD;EACA,SAAS;EACT,aAAa,KAAK,KAAK,IAAI,cAAc,IAAI,EAAE,IAAI;CACrD;AACF;;;;;;;;;;;;AC9GA,SAAgB,WAAW,QAA2B,UAAwB,CAAC,GAAW;CACxF,MAAM,UAAU,QAAQ,WAAW;CACnC,IAAI,OAAO,SAAS,SAAS,MAAM,IAAI,WAAW,eAAe,OAAO,OAAO,0BAA0B,QAAQ,yBAAyB;CAC1I,QAAQ,QAAQ,KAAK,KAAK,GAAG,MAAM;AACrC;;;;;;;AAmDA,SAAgB,cAAc,QAA2B,UAA0B,CAAC,GAAe;CACjG,IAAI,OAAO,WAAW,GAAG,MAAM,IAAI,WAAW,mCAAmC;CACjF,MAAM,QAAQ,QAAQ,UAAU,cAAc,WAAW,IAAI;CAC7D,MAAM,MAAM,QAAQ,OAAO;CAC3B,MAAM,QAAQ,QAAQ,SAAS;CAC/B,IAAI,EAAE,OAAO,MAAM,EAAE,SAAS,IAAI,MAAM,IAAI,WAAW,6CAA6C;CACpG,IAAI,OAAO;CACX,IAAI,OAAO;CACX,IAAI,SAAS;CACb,IAAI,QAAQ;CACZ,IAAI,QAAQ;CACZ,MAAM,UAAoB,CAAC;CAC3B,KAAK,MAAM,SAAS,QAAQ;EAC1B,IAAI,CAAC,OAAO,SAAS,KAAK,GAAG,MAAM,IAAI,WAAW,qDAAqD,MAAM,EAAE;EAC/G,MAAM,IAAI,QAAQ,QAAQ;EAC1B,IAAI,KAAK,IAAI,QAAQ,CAAC,KAAK,KAAK;GAC9B;GACA;EACF;EACA,QAAQ,KAAK,KAAK;EAClB,IAAI,IAAI,GAAG;OACN;EACL,IAAI,IAAI,OAAO;OACV,IAAI,CAAC,IAAI,OAAO;CACvB;CACA,MAAM,IAAI,OAAO;CACjB,MAAM,IAAI,OAAO,OAAO;CACxB,MAAM,SAAS,EAAE,WAAW,IAAI,KAAA,IAAY;EAAE,GAAG,EAAE;EAAQ,QAAQ,OAAO,CAAC;EAAG,KAAK,eAAe,GAAG,EAAG;EAAG,KAAK,eAAe,GAAG,EAAG;CAAE;CACvI,OAAO;EACL;EACA;EACA;EACA;EACA,OAAO,SAAS,MAAM,MAAM;EAC5B;EACA;EACA;EACA,WAAW,QAAQ;EACnB,cAAc,OAAO,OAAO,CAAC;EAC7B,WAAW,QAAQ;EACnB,cAAc,OAAO,OAAO,CAAC;CAC/B;AACF;AAQA,SAAS,iBAAiB,MAAc,WAAsC;CAC5E,IAAI,UAAU,WAAW,GAAG,MAAM,IAAI,WAAW,GAAG,KAAK,qBAAqB;CAC9E,KAAK,MAAM,KAAK,WAAW,IAAI,EAAE,EAAE,KAAK,KAAK,EAAE,KAAK,IAAI,MAAM,IAAI,WAAW,GAAG,KAAK,+BAA+B,EAAE,EAAE,EAAE;AAC5H;;AAGA,SAAgB,MAAM,WAAwC;CAC5D,iBAAiB,SAAS,SAAS;CACnC,IAAI,MAAM;CACV,KAAK,MAAM,KAAK,WAAW,QAAQ,EAAE,KAAK,EAAE,MAAM,IAAI,OAAO;CAC7D,OAAO,MAAM,UAAU;AACzB;;AAcA,SAAgB,YAAY,WAAoD;CAC9E,iBAAiB,eAAe,SAAS;CACzC,MAAM,yBAAS,IAAI,IAAyC;CAC5D,KAAK,MAAM,KAAK,WAAW;EACzB,MAAM,QAAQ,OAAO,IAAI,EAAE,CAAC,KAAK;GAAE,GAAG;GAAG,MAAM;EAAE;EACjD,MAAM;EACN,IAAI,EAAE,KAAK,MAAM;EACjB,OAAO,IAAI,EAAE,GAAG,KAAK;CACvB;CACA,OAAO,CAAC,GAAG,MAAM,CAAC,CACf,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAC3B,KAAK,CAAC,QAAQ,EAAE,GAAG,aAAa;EAAE;EAAQ;EAAG;EAAM,MAAM,OAAO;EAAG,UAAU,OAAO,MAAM,CAAC;CAAE,EAAE;AACpG"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package",
|
|
3
3
|
"name": "@mark1russell7/rigor-statistics",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.5",
|
|
5
5
|
"description": "The statistics of measured work: quantiles, bootstrap intervals, the sign test, the paired permutation test, Wilson intervals, the Holm correction, rank correlation, the comparison with a baseline beyond the noise, and the Brier score.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"statistics",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"node": ">=22"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@mark1russell7/rigor-generators": "^0.1.
|
|
45
|
+
"@mark1russell7/rigor-generators": "^0.1.1"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@mark1russell7/cue": "^1.0.2",
|