@danielsimonjr/mathts-functions 0.71.0 → 0.72.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/README.md +26 -1
  2. package/dist/cas/real-roots.d.ts +30 -0
  3. package/dist/cas/real-roots.d.ts.map +1 -0
  4. package/dist/fit-scalar.d.ts +28 -0
  5. package/dist/fit-scalar.d.ts.map +1 -1
  6. package/dist/geometry/curves.d.ts +48 -0
  7. package/dist/geometry/curves.d.ts.map +1 -0
  8. package/dist/geometry/polygon-ops.d.ts +19 -0
  9. package/dist/geometry/polygon-ops.d.ts.map +1 -0
  10. package/dist/geometry/predicates.d.ts +38 -0
  11. package/dist/geometry/predicates.d.ts.map +1 -0
  12. package/dist/index.d.ts +50 -3
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +5276 -762
  15. package/dist/linalg-extra2.d.ts +36 -0
  16. package/dist/linalg-extra2.d.ts.map +1 -0
  17. package/dist/linalg-special-matrices.d.ts +62 -0
  18. package/dist/linalg-special-matrices.d.ts.map +1 -0
  19. package/dist/numbertheory/arithmetic-functions.d.ts +50 -0
  20. package/dist/numbertheory/arithmetic-functions.d.ts.map +1 -0
  21. package/dist/numbertheory/diophantine.d.ts +43 -0
  22. package/dist/numbertheory/diophantine.d.ts.map +1 -0
  23. package/dist/numbertheory/extra.d.ts +12 -6
  24. package/dist/numbertheory/extra.d.ts.map +1 -1
  25. package/dist/numbertheory/integer-matrices.d.ts +26 -0
  26. package/dist/numbertheory/integer-matrices.d.ts.map +1 -0
  27. package/dist/numbertheory/modular.d.ts +27 -0
  28. package/dist/numbertheory/modular.d.ts.map +1 -0
  29. package/dist/numbertheory/sequences.d.ts +36 -0
  30. package/dist/numbertheory/sequences.d.ts.map +1 -0
  31. package/dist/numeric/constrained.d.ts +42 -0
  32. package/dist/numeric/constrained.d.ts.map +1 -0
  33. package/dist/numeric/finite-differences.d.ts +54 -0
  34. package/dist/numeric/finite-differences.d.ts.map +1 -0
  35. package/dist/numeric/gauss-nodes-extra.d.ts +73 -0
  36. package/dist/numeric/gauss-nodes-extra.d.ts.map +1 -0
  37. package/dist/numeric/global-optimizers.d.ts +64 -0
  38. package/dist/numeric/global-optimizers.d.ts.map +1 -0
  39. package/dist/numeric/quadrature-extra.d.ts +64 -0
  40. package/dist/numeric/quadrature-extra.d.ts.map +1 -0
  41. package/dist/scalar-batch-parallel.d.ts +15 -9
  42. package/dist/scalar-batch-parallel.d.ts.map +1 -1
  43. package/dist/scalar-batch-parallel.js +108 -0
  44. package/dist/{scalar-batch-task-CZd6LPg9.js → scalar-batch-task-DApUqK6j.js} +21 -15
  45. package/dist/scalar-batch.worker.js +1 -1
  46. package/dist/scalar-compile.d.ts +4 -4
  47. package/dist/scalar-compile.d.ts.map +1 -1
  48. package/dist/scalar-dimension.d.ts +25 -0
  49. package/dist/scalar-dimension.d.ts.map +1 -1
  50. package/dist/scalar-eval.d.ts +4 -2
  51. package/dist/scalar-eval.d.ts.map +1 -1
  52. package/dist/scalar-node-bridge.d.ts.map +1 -1
  53. package/dist/scalar-search.d.ts +323 -14
  54. package/dist/scalar-search.d.ts.map +1 -1
  55. package/dist/signal/dtw.d.ts +32 -0
  56. package/dist/signal/dtw.d.ts.map +1 -0
  57. package/dist/signal/lomb-scargle.d.ts +25 -0
  58. package/dist/signal/lomb-scargle.d.ts.map +1 -0
  59. package/dist/signal/system-response.d.ts +82 -0
  60. package/dist/signal/system-response.d.ts.map +1 -0
  61. package/dist/signal/waveforms.d.ts +52 -0
  62. package/dist/signal/waveforms.d.ts.map +1 -0
  63. package/dist/signal/windows-extra.d.ts +52 -0
  64. package/dist/signal/windows-extra.d.ts.map +1 -0
  65. package/dist/special/angular-momentum.d.ts +38 -0
  66. package/dist/special/angular-momentum.d.ts.map +1 -0
  67. package/dist/special/erf-extra.d.ts +47 -0
  68. package/dist/special/erf-extra.d.ts.map +1 -0
  69. package/dist/special/exp-integrals.d.ts +38 -0
  70. package/dist/special/exp-integrals.d.ts.map +1 -0
  71. package/dist/special/spherical-bessel.d.ts +28 -0
  72. package/dist/special/spherical-bessel.d.ts.map +1 -0
  73. package/dist/special/zeta-extra.d.ts +36 -0
  74. package/dist/special/zeta-extra.d.ts.map +1 -0
  75. package/dist/stats/distances.d.ts +28 -0
  76. package/dist/stats/distances.d.ts.map +1 -0
  77. package/dist/stats/distributions-extra.d.ts +36 -0
  78. package/dist/stats/distributions-extra.d.ts.map +1 -0
  79. package/dist/stats/effect-sizes.d.ts +21 -0
  80. package/dist/stats/effect-sizes.d.ts.map +1 -0
  81. package/dist/stats/nonparametric-extra.d.ts +52 -0
  82. package/dist/stats/nonparametric-extra.d.ts.map +1 -0
  83. package/dist/stats/robust-stats.d.ts +38 -0
  84. package/dist/stats/robust-stats.d.ts.map +1 -0
  85. package/dist/stats/weighted-stats.d.ts +27 -0
  86. package/dist/stats/weighted-stats.d.ts.map +1 -0
  87. package/dist/typed/special.d.ts.map +1 -1
  88. package/dist/wasm/special/scalars.d.ts +27 -0
  89. package/dist/wasm/special/scalars.d.ts.map +1 -1
  90. package/package.json +5 -5
@@ -3,19 +3,29 @@
3
3
  *
4
4
  * `populations` islands each evolve by tournament selection and
5
5
  * {@link weightedMutation}. Each generation breeds `populationSize` offspring per
6
- * island from tournament winners, evaluates them in one batch, and keeps the best
7
- * `populationSize` distinct trees of parents and offspring (elitist truncation, not
8
- * age-based replacement). After every generation the islands exchange their
9
- * best trees (migration). A hall of fame shared by every island keeps the best tree
10
- * per complexity; its Pareto front is reported through {@link paretoFront} and
11
- * {@link scoreFront}.
6
+ * island from tournament winners, evaluates every island's batch at the same time
7
+ * (the score calls overlap in this process when worker scoring is in use; each
8
+ * island keeps its own rng; without `parallel`, or below the row threshold, scoring
9
+ * stays on the caller thread and overlap buys no throughput), and
10
+ * keeps the best `populationSize` distinct trees of parents and offspring per
11
+ * island (elitist truncation, not age-based replacement), applied in island-index
12
+ * order after every island's batch has finished. After every generation the islands
13
+ * exchange their best trees (migration). A hall of fame shared by every island keeps the best loss
14
+ * per complexity among stored trees and one evaluated tree per {@link scalarCanonicalKey}
15
+ * (loss first, then complexity, then first recorded); its Pareto front is reported
16
+ * through {@link paretoFront} and {@link scoreFront}. Subtree crossover
17
+ * ({@link crossoverSubtrees}) is opt-in:
18
+ * {@link ScalarSearchOptions.crossoverProbability} defaults to 0, so the
19
+ * offspring loop stays mutation-only and the default random stream is unchanged.
12
20
  *
13
21
  * @packageDocumentation
14
22
  */
15
23
  import { type SeededRng } from '@danielsimonjr/mathts-core';
16
- import { type ScalarGrammar, type ScalarNode } from '@danielsimonjr/mathts-expression';
24
+ import { type ScalarComplexityWeights, type ScalarGrammar, type ScalarNode } from '@danielsimonjr/mathts-expression';
25
+ import { type NamedScalarLoss } from './fit-scalar.js';
17
26
  import { type ScoredCandidate } from './pareto-front.js';
18
27
  import { type ScalarPopulationParallelOptions } from './scalar-batch-parallel.js';
28
+ import { type RationalDimension } from './scalar-dimension.js';
19
29
  /** Columnar regression target for {@link searchScalars}. */
20
30
  export interface ScalarSearchProblem {
21
31
  /** Names of the input columns, in the order of `columns`. */
@@ -27,6 +37,32 @@ export interface ScalarSearchProblem {
27
37
  /** Fitted constants. Defaults to `grammar.parameters`. */
28
38
  readonly parameters?: readonly string[];
29
39
  }
40
+ /**
41
+ * Opt-in SI dimension filter for the scalar search
42
+ * ({@link ScalarSearchOptions.dimensions}).
43
+ *
44
+ * `symbols` binds variable and parameter names to dimensions. A name omitted
45
+ * from `symbols` is a solver unknown when it is a parameter and
46
+ * `unknown-symbol` when it is a variable. `target` is the dimension the scored
47
+ * tree's root must have. `onUnderdetermined` decides a solve whose parameter
48
+ * dimensions are not fixed by the equations implied by the tree: `'keep'` (the
49
+ * default) scores the tree normally — for example `x^p` with a free exponent
50
+ * parameter stays scorable under any `target` because the solver does not assign
51
+ * a unique dimension to `p`. `'reject'` scores it `Infinity`. Listed grammar
52
+ * parameters that do not appear in the tree are ignored for underdetermined
53
+ * detection. Before the first yield the filter is copied into a frozen snapshot
54
+ * (plain-data `symbols` only, same rules as `complexityWeights`).
55
+ */
56
+ export interface ScalarDimensionFilter {
57
+ readonly symbols: Readonly<Record<string, RationalDimension>>;
58
+ readonly target: RationalDimension;
59
+ readonly onUnderdetermined?: 'keep' | 'reject';
60
+ }
61
+ /**
62
+ * When adaptive parsimony records offspring complexities within one generation.
63
+ * @internal Test hook only; not on the package barrel.
64
+ */
65
+ export type FrequencyRecordTiming = 'island-boundary' | 'after-merge' | 'per-offspring';
30
66
  /** Budget and evolution knobs for {@link searchScalars}. */
31
67
  export interface ScalarSearchOptions {
32
68
  readonly grammar: ScalarGrammar;
@@ -40,11 +76,116 @@ export interface ScalarSearchOptions {
40
76
  readonly tournamentP?: number;
41
77
  /** Chance that an evaluated tree has its parameters refitted. Default 0.14. */
42
78
  readonly optimizeProbability?: number;
79
+ /**
80
+ * Residual loss for ranking and for every refit. Default `'l2'`: today's sum of
81
+ * squares, including `+Infinity` when any row is invalid. `'l1'` and `'huber'`
82
+ * reuse {@link fitScalarParameters}'s named losses. Omitted is the default
83
+ * branch, so the seed-7 pin is unchanged.
84
+ */
85
+ readonly loss?: NamedScalarLoss;
86
+ /**
87
+ * Per-row weights for that loss. Length must equal `observed.length`; every
88
+ * weight is finite and `>= 0`. A zero weight drops that row. Omitted: every
89
+ * row weighs 1.
90
+ */
91
+ readonly rowWeights?: Float64Array;
92
+ /**
93
+ * How a tree that is invalid on at least one row is ranked. Default `'reject'`:
94
+ * today's `+Infinity` — such a tree never enters the hall. `'penalize'` scores
95
+ * {@link INVALID_ROW_PENALTY} (the fitter's existing invalid-row penalty) times
96
+ * the number of invalid rows a positive `rowWeights` entry covers, plus the
97
+ * chosen `loss` on the valid rows; a zero-weight row is dropped on both sides.
98
+ * A tree with no valid row reports the penalty times the number of positively
99
+ * weighted rows (each invalid among them adds one penalty). The penalty is
100
+ * absolute, not scaled to the target magnitude. The ranker adds that sum on top
101
+ * of the valid-row loss; the fitter's reported loss counts only valid rows and
102
+ * freezes invalid rows with a squared penalty inside LM — different objectives.
103
+ * Refit acceptance compares both sides with {@link scoreOnProblem} / the ranker.
104
+ * Omitted is the default branch, so the seed-7 pin is unchanged.
105
+ */
106
+ readonly invalidRows?: 'reject' | 'penalize';
107
+ /**
108
+ * Per-node weights for the complexity the hall, the truncation tie-break, and
109
+ * adaptive parsimony rank by. `ScalarComplexityWeights` from
110
+ * `@danielsimonjr/mathts-expression`; omitted fields weigh 1, so `{}` (and an
111
+ * omitted option) is today's node count. Weights are normalized once before the
112
+ * first yield into a frozen snapshot; only plain data objects are accepted at
113
+ * the top level and on `op`, `call`, and per-name `symbol` records (prototype
114
+ * `Object.prototype` or `null`). Own keys are read exactly once via
115
+ * `Reflect.ownKeys`; non-enumerable keys and accessor properties throw
116
+ * `RangeError`. Every weight must be a finite number; weights that would make
117
+ * `grammar.maxSize` nodes sum to a non-finite complexity also throw before the
118
+ * first yield. Zero and negative weights are accepted: they are summed and
119
+ * `Math.round`ed by `scalarComplexity` like any other weight. Nested record
120
+ * keys must use lowered call names (`ln` is stored as `log`); unknown keys are
121
+ * kept in the snapshot but ignored at scoring time.
122
+ */
123
+ readonly complexityWeights?: ScalarComplexityWeights;
124
+ /**
125
+ * Refit knobs forwarded to {@link fitScalarParameters}. An omitted field is
126
+ * today's call: `restarts` 2, `maxIterations` 8, no bounds, the fitter's
127
+ * default algorithm, and `initial` set to the inherited vector (ones for the
128
+ * initial population). The values are forwarded, not reimplemented; a bad
129
+ * bound or length throws the fitter's `RangeError` before the first yield.
130
+ */
131
+ readonly fit?: ScalarFitOptions;
132
+ /**
133
+ * Chance that an offspring is a subtree crossover of two tournament parents
134
+ * instead of a mutation of the first. Default 0: the coin is not drawn, so the
135
+ * random stream matches a search that never had this option. In (0, 1] the
136
+ * island stream draws the coin; on success a second parent is drawn with the
137
+ * same tournament, {@link crossoverSubtrees} runs, and the child is kept when
138
+ * it is non-null and the grammar (including `admit`) accepts it. Otherwise the search falls
139
+ * through to the existing mutation attempts. The inherited parameter vector
140
+ * is always the first parent's.
141
+ */
142
+ readonly crossoverProbability?: number;
143
+ /**
144
+ * Simplify each seed and each bred offspring once, before the grammar check and
145
+ * the score, so the scored tree is the tree whose parameters are fitted. Default
146
+ * `'off'`: neither simplifier runs and the seed-7 pin is unchanged. `'constants'`
147
+ * folds numeric-only subtrees ({@link simplifyConstants}). `'algebraic'` runs the
148
+ * expression simplifier ({@link simplifyScalar}); when it throws
149
+ * `ScalarBuildError`, or its result fails the grammar (including `admit`), the
150
+ * tree keeps its unsimplified shape. Trees that come out of `enumerateScalars`
151
+ * are not simplified. Simplification draws no random numbers, but different
152
+ * accepted trees can change how many mutation attempts succeed, so a run with
153
+ * `simplify` on may diverge from an otherwise identical run with `'off'`; two
154
+ * runs that share the same `simplify` mode and seed still match. Progress event
155
+ * count stays budget-driven (`maxEvaluations`). When the simplified tree fails
156
+ * the grammar, changes the valid/invalid pattern on a positively weighted row,
157
+ * or disagrees in value within tolerance on such a row, the unsimplified tree
158
+ * is kept. `admit` runs on the simplified tree when its canonical key differs;
159
+ * a no-op fold (same key) is checked once. Algebraic simplification costs
160
+ * milliseconds per tree; the option stays off by default and no speed claim is
161
+ * made here.
162
+ */
163
+ readonly simplify?: 'off' | 'constants' | 'algebraic';
164
+ /**
165
+ * Opt-in SI dimension filter. Omitted: no dimension walk and the seed-7 pin is
166
+ * unchanged. Set: after the grammar check (and any simplification) and before
167
+ * the score, the tree that will be scored is checked. With parameters the
168
+ * check is {@link solveParameterDimensions} when the fitted parameter list is
169
+ * non-empty; an empty `problem.parameters` array forces infer mode even when
170
+ * the grammar lists parameters. Without fitted parameters the check is
171
+ * {@link inferScalarDimension}. In both modes the inferred or solved root
172
+ * dimension must equal `target`.
173
+ * An `add-mismatch`, `transcendental-arg-not-dimensionless`,
174
+ * `non-literal-exponent-on-dimensional-base`, or `unknown-symbol` violation,
175
+ * or an `inconsistent` solve, scores `Infinity` and never enters the hall —
176
+ * the same bucket as a numerical failure — but still counts as an evaluation.
177
+ * An underdetermined solve is scored normally (`'keep'`, the default) or
178
+ * scored `Infinity` (`'reject'`). The check draws no random numbers.
179
+ */
180
+ readonly dimensions?: ScalarDimensionFilter;
43
181
  /** Cap on tree evaluations, the initial population included. */
44
182
  readonly maxEvaluations: number;
45
183
  /** Second cap on tree evaluations, reported as `'max-candidates'`. */
46
184
  readonly maxCandidates?: number;
47
- /** Trees injected into the initial population (`seeds`); the grammar filters them. */
185
+ /**
186
+ * Trees injected into the initial population (`seeds`). The grammar's structural
187
+ * rules filter them, and so does `grammar.admit` when it is set.
188
+ */
48
189
  readonly seeds?: readonly ScalarNode[];
49
190
  /** Constant-perturbation scale handed to the mutations. Default 0.25. */
50
191
  readonly perturbationFactor?: number;
@@ -53,9 +194,17 @@ export interface ScalarSearchOptions {
53
194
  /**
54
195
  * Independent islands, each with `populationSize` trees and its own random stream
55
196
  * (`rng.fork('island:' + index)`). Default 1, which draws from `rng.fork('population')`.
56
- * Evaluations are counted across all islands.
197
+ * Evaluations are counted across all islands. The islands' score calls overlap
198
+ * within one generation when worker scoring is active; without `parallel`, or below
199
+ * the row threshold, evaluation stays on the caller thread and overlap does not
200
+ * increase throughput. The merge after the scores runs in island-index order.
57
201
  */
58
202
  readonly populations?: number;
203
+ /**
204
+ * @internal Test hook only: when offspring complexities reach the adaptive-parsimony
205
+ * window within a generation. Default `island-boundary` matches the sequential schedule.
206
+ */
207
+ readonly frequencyRecordTiming?: FrequencyRecordTiming;
59
208
  /**
60
209
  * Expected share of each island replaced by another island's best trees after every
61
210
  * generation, in [0, 1]. The count is the expectation rounded at random. Default 0.00036
@@ -83,11 +232,74 @@ export interface ScalarSearchOptions {
83
232
  * 100 rows; below that, and when omitted, evaluation stays on the caller thread. The
84
233
  * workers return the values the caller thread would compute, bit for bit, and parameter
85
234
  * refits and every random draw stay on the caller thread, so a parallel run equals the
86
- * serial run for the same seed. `timeoutMs` (default 30000, must be positive) bounds each
87
- * worker call. A `pool` you pass is yours to terminate; without one the search starts a
88
- * pool when it first needs it and terminates it when the generator finishes or is closed.
235
+ * serial run for the same seed. Overlapped islands only overlap worker score calls; the
236
+ * caller-thread path does not gain throughput from SR-13. `timeoutMs` (default 30000,
237
+ * must be positive) bounds each worker task, including time queued behind other islands'
238
+ * submissions in the same generation — scale it with `populations` when several islands
239
+ * score together. A `pool` you pass is yours to terminate; without one the search starts
240
+ * a pool when it first needs it and terminates it when the generator finishes or is closed.
89
241
  */
90
242
  readonly parallel?: ScalarPopulationParallelOptions;
243
+ /**
244
+ * Cancellation signal (SR-15). The search checks it before the initial population
245
+ * and between generations, never in the middle of a random draw or a scored batch.
246
+ * Already aborted before the first yield: the result has an empty front,
247
+ * `evaluations: 0`, and `stopReason: 'cancelled'`. Aborted after a yield: the
248
+ * generator returns the last progress as the result with `stopReason: 'cancelled'`
249
+ * and does not start another generation (a generation that was already breeding
250
+ * and scoring runs to completion first). A pool the search owns is still
251
+ * terminated. Omitted: no cancellation and the seed-7 pin is unchanged.
252
+ */
253
+ readonly signal?: AbortSignal;
254
+ /**
255
+ * Optional early stop (SR-15). Omitted: the search always runs to
256
+ * `max-evaluations` (or `'max-candidates'`). Set: after a generation whose best
257
+ * finite hall loss is `<= loss`, and that has stayed true for `generations`
258
+ * consecutive generations, the search returns `stopReason: 'early-stop'` after
259
+ * yielding that generation's progress. The streak is counted over the hall after
260
+ * the generation (the initial population included), and it resets when a
261
+ * generation leaves the best loss above `loss` — the best hall loss can only
262
+ * improve, so a reset happens only while the hall is still empty or the best
263
+ * loss has not yet reached `loss`. `loss` must be finite and `generations` an
264
+ * integer `>= 1` (`RangeError` otherwise). A run that never reaches `loss`
265
+ * still ends on `'max-evaluations'`.
266
+ */
267
+ readonly earlyStop?: {
268
+ readonly loss: number;
269
+ readonly generations: number;
270
+ };
271
+ /**
272
+ * Factor forwarded to {@link selectFrontModel}'s `bestLossFactor` when
273
+ * `modelSelection` is set (SR-16). Omitted: the factor `selectFrontModel`
274
+ * already defaults to (1.5), so today's call is unchanged. A non-finite value
275
+ * throws `RangeError` before the search starts, even when `modelSelection` is
276
+ * omitted. Only read when `modelSelection` is set. Values in `(0, 1)` can make
277
+ * the `'best'` filter keep no row once selection runs, which throws
278
+ * {@link ParetoFrontError} mid-run; `1` is the safe lower boundary (only
279
+ * minimum-loss rows qualify).
280
+ */
281
+ readonly bestLossFactor?: number;
282
+ }
283
+ /** Budget, bounds, and start-vector knobs for the search's parameter refits. */
284
+ export interface ScalarFitOptions {
285
+ /** Restarted fits per refit. Default 2. Must be an integer >= 0. */
286
+ readonly restarts?: number;
287
+ /** Optimizer iterations per fit. Default 8. Must be an integer >= 0. */
288
+ readonly maxIterations?: number;
289
+ /**
290
+ * One `[lo, hi]` pair per parameter. Endpoints are finite or `±Infinity`;
291
+ * `lo` must not exceed `hi`, and the length must equal the parameter count.
292
+ * Default: unbounded.
293
+ */
294
+ readonly bounds?: readonly (readonly [number, number])[];
295
+ /** Optimizer. Default: the fitter's choice (`'lm'` for `'l2'`, `'bfgs'` otherwise). */
296
+ readonly algorithm?: 'lm' | 'bfgs' | 'nelder-mead';
297
+ /**
298
+ * Start vector of every refit. Length must equal the parameter count and every
299
+ * value must be finite. Default: the tree's inherited vector (ones at the
300
+ * initial population).
301
+ */
302
+ readonly initial?: ArrayLike<number>;
91
303
  }
92
304
  /** One progress event; `status` is always `'fitted'`. */
93
305
  export interface SearchProgress {
@@ -101,7 +313,7 @@ export interface SearchProgress {
101
313
  readonly fittedParameters: Float64Array[];
102
314
  readonly selected?: ScoredCandidate<ScalarNode>;
103
315
  }
104
- export type ScalarSearchStopReason = 'max-evaluations' | 'max-candidates';
316
+ export type ScalarSearchStopReason = 'max-evaluations' | 'max-candidates' | 'cancelled' | 'early-stop';
105
317
  /** Final value of the async generator returned by {@link searchScalars}. */
106
318
  export interface ScalarSearchResult {
107
319
  readonly front: ScoredCandidate<ScalarNode>[];
@@ -111,7 +323,21 @@ export interface ScalarSearchResult {
111
323
  readonly evaluations: number;
112
324
  readonly seed: number;
113
325
  readonly selected?: ScoredCandidate<ScalarNode>;
326
+ /**
327
+ * How often a seed or offspring kept its unsimplified shape because simplification
328
+ * threw (other than `ScalarBuildError`), failed the grammar or row-wise evaluation
329
+ * check, or hit a `RangeError` from a deep simplify. Zero when `simplify` is
330
+ * `'off'` or omitted.
331
+ */
332
+ readonly simplifyFallbacks: number;
114
333
  }
334
+ /** @internal Exported for unit tests; not part of the package barrel. */
335
+ export declare function simplifyCandidateForTest(node: ScalarNode, mode: ScalarSearchOptions['simplify'], recordFallback?: () => void): ScalarNode;
336
+ /** @internal Exported for unit tests; not part of the package barrel. */
337
+ export declare function hallFrontForTest(individuals: readonly EvaluatedIndividual[]): {
338
+ front: ScoredCandidate<ScalarNode>[];
339
+ fittedParameters: Float64Array[];
340
+ };
115
341
  /** @internal One evaluated tree; exported for the unit tests, not the package barrel. */
116
342
  export interface EvaluatedIndividual {
117
343
  readonly node: ScalarNode;
@@ -168,9 +394,92 @@ export declare function migrateIslands(islands: Island[], fractionReplaced: numb
168
394
  * The generator yields one {@link SearchProgress} after the initial population
169
395
  * and one after every generation, and returns a {@link ScalarSearchResult}.
170
396
  * Evaluations never exceed `maxEvaluations`. `options.rng` is not advanced, so two
171
- * runs with the same inputs and seed agree bit for bit.
397
+ * runs with the same inputs and seed agree bit for bit. When `grammar.admit` is
398
+ * set it binds seeds and mutation offspring (`scalarGrammarAccepts`, then `admit`).
399
+ * A rejected child is a failed attempt; a rejected seed is skipped. `admit` must
400
+ * be a pure function of the node — a predicate that reads a clock or a random
401
+ * stream makes the run unreproducible. `admitMonotone` is left to enumeration.
402
+ * Ranking and refit share `loss` (`'l2'` by default) and optional `rowWeights`.
403
+ * `invalidRows` defaults to `'reject'` (`+Infinity` on any invalid row); `'penalize'`
404
+ * adds {@link INVALID_ROW_PENALTY} per positively weighted invalid row on top of the
405
+ * valid-row loss (absolute, not target-scaled). Under `'penalize'` the advisory refit
406
+ * still runs when every weighted row is invalid; refit acceptance uses the ranker on
407
+ * both sides. `complexityWeights` weighs the nodes of the complexity the hall, the
408
+ * truncation tie-break, and adaptive parsimony use; omitted, it is today's size.
409
+ * When set, weights are copied into a frozen snapshot before the first yield (plain
410
+ * data objects only; non-enumerable keys and accessors are rejected). Record keys
411
+ * use lowered call names (`ln` → `log`); unknown keys are ignored by
412
+ * `scalarComplexity`. `grammar.maxSize` counts raw nodes, not weighted complexity;
413
+ * `Math.round` on the sum can map distinct trees to one hall slot. The hall keeps one
414
+ * tree per canonical key at add time (best loss, then complexity, then first recorded);
415
+ * elitist truncation already keeps one tree per key in the population with the same
416
+ * loss-first order. Weights change reported complexity only, not which duplicate survives.
417
+ * `fit`
418
+ * forwards `restarts` (default 2), `maxIterations` (default 8), `bounds`,
419
+ * `algorithm`, and `initial` (default the inherited vector) to the fitter; a bad
420
+ * bound or length throws before the first yield. Omitted fields are today's call.
421
+ * `crossoverProbability` defaults to 0 (no coin). A positive probability draws
422
+ * the coin on the island stream and, on success, a second tournament parent.
423
+ * `simplify` defaults to `'off'` (no simplifier runs). `'constants'` folds
424
+ * numeric-only subtrees and `'algebraic'` runs the expression simplifier, once
425
+ * per seed and per bred offspring, before the grammar check and the score; a
426
+ * `ScalarBuildError`, `RangeError`, grammar rejection (including `admit`), or
427
+ * row-wise evaluation mismatch keeps the unsimplified tree. Enumerated trees are
428
+ * not simplified. Simplification draws no random numbers, but different accepted
429
+ * trees can change mutation outcomes, so a run with `simplify` on may diverge from
430
+ * `'off'`; two runs that share the same mode and seed still match. Progress event
431
+ * count stays budget-driven. `dimensions` (opt-in) checks the SI dimension of the
432
+ * tree that will be scored — after the grammar check, before the score — against
433
+ * `target`: a violation or an `inconsistent` solve scores `Infinity` (still an
434
+ * evaluation, never in the hall), an underdetermined solve is kept by default or
435
+ * rejected with `'reject'`, and the check draws no random numbers. `signal`
436
+ * (opt-in) is checked before the initial population and between generations, never
437
+ * mid-draw: already aborted before the first yield the result carries an empty
438
+ * front and `evaluations: 0`; aborted after a yield the last progress is returned
439
+ * as the result, both with `stopReason: 'cancelled'`. `earlyStop` (opt-in) ends
440
+ * the run with `stopReason: 'early-stop'` once the best finite hall loss has been
441
+ * `<= loss` for `generations` consecutive generations (hall after the generation,
442
+ * initial population included).
172
443
  *
173
444
  * @throws {RangeError} A malformed problem or option, or a grammar that admits no tree.
174
445
  */
175
446
  export declare function searchScalars(problem: ScalarSearchProblem, options: ScalarSearchOptions): AsyncGenerator<SearchProgress, ScalarSearchResult>;
447
+ /**
448
+ * Problem input for {@link runScalarSearch}: like {@link ScalarSearchProblem},
449
+ * but `columns` may be a record keyed by variable name instead of the aligned
450
+ * array `searchScalars` requires.
451
+ */
452
+ export interface ScalarSearchRunProblem extends Omit<ScalarSearchProblem, 'columns'> {
453
+ /**
454
+ * One column per variable. Either the aligned array `searchScalars` takes, or a
455
+ * record keyed by the names in `variables`; the wrapper reads a record in
456
+ * `variables` order to build that array. A name without an entry throws
457
+ * `RangeError`. A column whose length differs from `observed.length` throws
458
+ * `RangeError` from `searchScalars` as usual.
459
+ */
460
+ readonly columns: readonly Float64Array[] | Readonly<Record<string, Float64Array>>;
461
+ }
462
+ /**
463
+ * Options for {@link runScalarSearch}: {@link ScalarSearchOptions} with `rng`
464
+ * optional — exactly one of `seed` and `rng` must be set.
465
+ */
466
+ export type ScalarSearchRunOptions = Omit<ScalarSearchOptions, 'rng'> & {
467
+ /** Seed for a fresh {@link createSeededRng}; required when `rng` is omitted. */
468
+ readonly seed?: number;
469
+ /** Caller-owned random stream; required when `seed` is omitted, never advanced. */
470
+ readonly rng?: SeededRng;
471
+ };
472
+ /**
473
+ * Consume {@link searchScalars} to its final {@link ScalarSearchResult} (SR-16).
474
+ * A thin wrapper: when `seed` is set and `rng` is omitted it builds
475
+ * {@link createSeededRng}(seed) and passes that; when both are set, or neither
476
+ * is, it throws `RangeError`. A `columns` record is read in `variables` order.
477
+ * It does not reimplement any search behavior, so every documented default and
478
+ * the seed-7 pin hold unchanged.
479
+ *
480
+ * @throws {RangeError} `seed` and `rng` are both set, neither is set, a variable
481
+ * has no entry in `columns`, `bestLossFactor` is non-finite, or any check
482
+ * {@link searchScalars} itself performs fails.
483
+ */
484
+ export declare function runScalarSearch(problem: ScalarSearchRunProblem, options: ScalarSearchRunOptions): Promise<ScalarSearchResult>;
176
485
  //# sourceMappingURL=scalar-search.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scalar-search.d.ts","sourceRoot":"","sources":["../src/scalar-search.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scalar-search.d.ts","sourceRoot":"","sources":["../src/scalar-search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Dynamic time warping with an optional Sakoe-Chiba band.
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+ type Vec = readonly number[] | Float64Array;
7
+ /** Options for {@link dtw}. */
8
+ export interface DtwOptions {
9
+ /**
10
+ * Sakoe-Chiba band half-width in samples. Widened automatically to at least
11
+ * |a.length - b.length|. Default: unconstrained.
12
+ */
13
+ window?: number;
14
+ /** Local cost between two samples (default `|x - y|`). */
15
+ dist?: (x: number, y: number) => number;
16
+ }
17
+ /** Result of {@link dtw}. */
18
+ export interface DtwResult {
19
+ /** Accumulated cost of the optimal warping path. */
20
+ distance: number;
21
+ /** Optimal alignment as (i, j) index pairs from [0, 0] to [n-1, m-1]. */
22
+ path: Array<[number, number]>;
23
+ }
24
+ /**
25
+ * Dynamic time warping between two sequences.
26
+ *
27
+ * @example
28
+ * dtw([1, 2, 3], [1, 2, 2, 3]).distance; // 0
29
+ */
30
+ export declare function dtw(a: Vec, b: Vec, opts?: DtwOptions): DtwResult;
31
+ export {};
32
+ //# sourceMappingURL=dtw.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dtw.d.ts","sourceRoot":"","sources":["../../src/signal/dtw.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,KAAK,GAAG,GAAG,SAAS,MAAM,EAAE,GAAG,YAAY,CAAC;AAG5C,+BAA+B;AAC/B,MAAM,WAAW,UAAU;IACzB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;CACzC;AAED,6BAA6B;AAC7B,MAAM,WAAW,SAAS;IACxB,oDAAoD;IACpD,QAAQ,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,IAAI,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC/B;AAED;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,SAAS,CAsDhE"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Lomb-Scargle periodogram for unevenly sampled data (classic Scargle form with
3
+ * the tau time offset, as in scipy.signal.lombscargle).
4
+ *
5
+ * @packageDocumentation
6
+ */
7
+ type Vec = readonly number[] | Float64Array;
8
+ /** Options for {@link lombScargle}. */
9
+ export interface LombScargleOptions {
10
+ /** Scale so that a pure sinusoid of unit amplitude peaks near 1 (default false). */
11
+ normalize?: boolean;
12
+ /** Subtract the mean of y before the transform (default false). */
13
+ precenter?: boolean;
14
+ }
15
+ /**
16
+ * Lomb-Scargle power at each angular frequency in `freqs` (rad per time unit).
17
+ *
18
+ * @param t - Sample times
19
+ * @param y - Sample values, same length as t
20
+ * @param freqs - Angular frequencies omega
21
+ * @returns Power per frequency (unnormalized: 0.5 * sum of squared projections)
22
+ */
23
+ export declare function lombScargle(t: Vec, y: Vec, freqs: Vec, opts?: LombScargleOptions): number[];
24
+ export {};
25
+ //# sourceMappingURL=lomb-scargle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lomb-scargle.d.ts","sourceRoot":"","sources":["../../src/signal/lomb-scargle.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,KAAK,GAAG,GAAG,SAAS,MAAM,EAAE,GAAG,YAAY,CAAC;AAG5C,uCAAuC;AACvC,MAAM,WAAW,kBAAkB;IACjC,oFAAoF;IACpF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,mEAAmE;IACnE,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,kBAAkB,GAAG,MAAM,EAAE,CA0C3F"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * LTI system responses, transfer-function / state-space conversions, and
3
+ * simple IIR notch / peak designs (scipy.signal parity for the covered cases).
4
+ *
5
+ * Transfer-function coefficient arrays are highest-power first (scipy order).
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ import type { ComplexNumber } from './fft.js';
10
+ type Vec = readonly number[] | Float64Array;
11
+ /** Continuous or discrete state-space realisation. */
12
+ export interface StateSpace {
13
+ A: number[][];
14
+ B: number[][];
15
+ C: number[][];
16
+ D: number[][];
17
+ }
18
+ /** Discretisation method for {@link cont2discrete}. */
19
+ export type DiscretizeMethod = 'zoh' | 'bilinear' | 'euler';
20
+ /** Second-order-section filter coefficients. */
21
+ export interface BiquadCoefficients {
22
+ b: number[];
23
+ a: number[];
24
+ }
25
+ /** Impulse response h[0..n-1] of the filter b / a. */
26
+ export declare function impulseResponse(b: Vec, a: Vec, n: number): number[];
27
+ /** Step response y[0..n-1] of the filter b / a. */
28
+ export declare function stepResponse(b: Vec, a: Vec, n: number): number[];
29
+ /**
30
+ * Transfer function to controllable canonical state space (SISO), as scipy.signal.tf2ss.
31
+ *
32
+ * @example
33
+ * tf2ss([1], [1, 3, 2]); // A = [[-3, -2], [1, 0]], B = [[1], [0]], C = [[0, 1]], D = [[0]]
34
+ */
35
+ export declare function tf2ss(b: Vec, a: Vec): StateSpace;
36
+ /**
37
+ * State space to transfer function (SISO), as scipy.signal.ss2tf.
38
+ * num is returned without leading zeros.
39
+ */
40
+ export declare function ss2tf(A: number[][], B: number[][], C: number[][], D: number[][]): {
41
+ num: number[];
42
+ den: number[];
43
+ };
44
+ /**
45
+ * Convert a continuous state-space system to discrete time with sample period dt.
46
+ *
47
+ * - `zoh`: exact zero-order hold, via the exponential of [[A, B], [0, 0]] dt
48
+ * - `bilinear`: Tustin (scipy, alpha = 1/2), with M = (I - A dt/2)^-1:
49
+ * Ad = M (I + A dt/2), Bd = M B dt, Cd = C M, Dd = D + C Bd / 2
50
+ * - `euler`: forward Euler, Ad = I + A dt, Bd = B dt
51
+ */
52
+ export declare function cont2discrete(sys: StateSpace, dt: number, method?: DiscretizeMethod): StateSpace;
53
+ /**
54
+ * Second-order IIR notch at normalised frequency w0 (x pi rad/sample), quality
55
+ * factor Q = w0 / bandwidth (scipy.signal.iirnotch convention: -3 dB bandwidth
56
+ * w0 pi / Q). Zero at w0, unity gain at DC.
57
+ */
58
+ export declare function iirNotch(w0: number, Q: number): BiquadCoefficients;
59
+ /**
60
+ * Second-order IIR peak (band-pass) at w0 (x pi rad/sample), unity gain at w0 and
61
+ * zero gain at DC and Nyquist (scipy.signal.iirpeak convention, Q = w0 / bandwidth).
62
+ */
63
+ export declare function iirPeak(w0: number, Q: number): BiquadCoefficients;
64
+ /**
65
+ * Transfer function to zeros, poles and gain (scipy.signal.tf2zpk). Zeros and
66
+ * poles are sorted by real then imaginary part.
67
+ */
68
+ export declare function tf2zpk(b: Vec, a: Vec): {
69
+ z: ComplexNumber[];
70
+ p: ComplexNumber[];
71
+ k: number;
72
+ };
73
+ /**
74
+ * Cascade of second-order sections to a single transfer function. Each section
75
+ * is [b0, b1, b2, a0, a1, a2]; the result is not normalised by a0.
76
+ */
77
+ export declare function sos2tf(sos: ReadonlyArray<readonly number[]>): {
78
+ b: number[];
79
+ a: number[];
80
+ };
81
+ export {};
82
+ //# sourceMappingURL=system-response.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-response.d.ts","sourceRoot":"","sources":["../../src/signal/system-response.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,KAAK,GAAG,GAAG,SAAS,MAAM,EAAE,GAAG,YAAY,CAAC;AAG5C,sDAAsD;AACtD,MAAM,WAAW,UAAU;IACzB,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;IACd,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;IACd,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;IACd,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;CACf;AAED,uDAAuD;AACvD,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,UAAU,GAAG,OAAO,CAAC;AAE5D,gDAAgD;AAChD,MAAM,WAAW,kBAAkB;IACjC,CAAC,EAAE,MAAM,EAAE,CAAC;IACZ,CAAC,EAAE,MAAM,EAAE,CAAC;CACb;AAuFD,sDAAsD;AACtD,wBAAgB,eAAe,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAKnE;AAED,mDAAmD;AACnD,wBAAgB,YAAY,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAEhE;AAMD;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,GAAG,UAAU,CAqBhD;AAyBD;;;GAGG;AACH,wBAAgB,KAAK,CACnB,CAAC,EAAE,MAAM,EAAE,EAAE,EACb,CAAC,EAAE,MAAM,EAAE,EAAE,EACb,CAAC,EAAE,MAAM,EAAE,EAAE,EACb,CAAC,EAAE,MAAM,EAAE,EAAE,GACZ;IAAE,GAAG,EAAE,MAAM,EAAE,CAAC;IAAC,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,CAWlC;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,UAAU,EACf,EAAE,EAAE,MAAM,EACV,MAAM,GAAE,gBAAwB,GAC/B,UAAU,CA0CZ;AAmBD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,kBAAkB,CAQlE;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,kBAAkB,CAQjE;AAoDD;;;GAGG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,GAAG;IAAE,CAAC,EAAE,aAAa,EAAE,CAAC;IAAC,CAAC,EAAE,aAAa,EAAE,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAM5F;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,aAAa,CAAC,SAAS,MAAM,EAAE,CAAC,GAAG;IAAE,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAc1F"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Test waveform generators (scipy.signal.waveforms parity).
3
+ *
4
+ * Phase offsets `phi` are in radians (scipy takes degrees for chirp/sweep_poly).
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ type Vec = readonly number[] | Float64Array;
9
+ /** Frequency sweep method for {@link chirp}. */
10
+ export type ChirpMethod = 'linear' | 'quadratic' | 'logarithmic' | 'hyperbolic';
11
+ /** Options for {@link chirp}. */
12
+ export interface ChirpOptions {
13
+ /** Sweep law (default `'linear'`). */
14
+ method?: ChirpMethod;
15
+ /** Phase offset in radians (default 0). */
16
+ phi?: number;
17
+ }
18
+ /**
19
+ * Cosine chirp sweeping from f0 at t = 0 to f1 at t = t1 (frequencies in Hz).
20
+ *
21
+ * @example
22
+ * chirp([0], 1, 1, 10); // [1]
23
+ */
24
+ export declare function chirp(t: Vec, f0: number, t1: number, f1: number, opts?: ChirpOptions): number[];
25
+ /**
26
+ * Square wave: +1 while frac(t / 2 pi) < duty, otherwise -1.
27
+ */
28
+ export declare function squareWave(t: Vec, duty?: number): number[];
29
+ /**
30
+ * Sawtooth wave: -1 at phase 0 rising to +1 at phase 2 pi * width, then falling
31
+ * back. `width = 1` is a rising ramp; `width = 0.5` is a triangle.
32
+ */
33
+ export declare function sawtooth(t: Vec, width?: number): number[];
34
+ /**
35
+ * Gaussian-modulated cosine pulse.
36
+ *
37
+ * @param fc - Centre frequency (Hz)
38
+ * @param bw - Fractional bandwidth (default 0.5)
39
+ * @param bwr - Reference level in dB for the bandwidth (default -6)
40
+ */
41
+ export declare function gaussPulse(t: Vec, fc: number, bw?: number, bwr?: number): number[];
42
+ /**
43
+ * Discrete unit impulse of length n. `idx` defaults to 0, `'mid'` is floor(n / 2).
44
+ */
45
+ export declare function unitImpulse(n: number, idx?: number | 'mid'): number[];
46
+ /**
47
+ * Cosine with a polynomial instantaneous frequency f(t) = sum_k c_k t^(p-k) Hz.
48
+ * `polyCoeffs` are highest-order first (numpy poly1d order).
49
+ */
50
+ export declare function sweepPoly(t: Vec, polyCoeffs: readonly number[], phi?: number): number[];
51
+ export {};
52
+ //# sourceMappingURL=waveforms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"waveforms.d.ts","sourceRoot":"","sources":["../../src/signal/waveforms.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,KAAK,GAAG,GAAG,SAAS,MAAM,EAAE,GAAG,YAAY,CAAC;AAI5C,gDAAgD;AAChD,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,WAAW,GAAG,aAAa,GAAG,YAAY,CAAC;AAEhF,iCAAiC;AACjC,MAAM,WAAW,YAAY;IAC3B,sCAAsC;IACtC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,2CAA2C;IAC3C,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,MAAM,EAAE,CAM/F;AAuCD;;GAEG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,GAAE,MAAY,GAAG,MAAM,EAAE,CAM/D;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,GAAE,MAAU,GAAG,MAAM,EAAE,CAO5D;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,GAAE,MAAY,EAAE,GAAG,GAAE,MAAW,GAAG,MAAM,EAAE,CAI3F;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,GAAG,KAAS,GAAG,MAAM,EAAE,CASxE;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,SAAS,MAAM,EAAE,EAAE,GAAG,GAAE,MAAU,GAAG,MAAM,EAAE,CAW1F"}