smokin 0.1.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 (76) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/LICENSE +21 -0
  3. package/README.md +366 -0
  4. package/dist/dataset/dataset.d.ts +43 -0
  5. package/dist/dataset/dataset.d.ts.map +1 -0
  6. package/dist/dataset/dataset.js +63 -0
  7. package/dist/dataset/dataset.js.map +1 -0
  8. package/dist/dataset/relate.d.ts +32 -0
  9. package/dist/dataset/relate.d.ts.map +1 -0
  10. package/dist/dataset/relate.js +46 -0
  11. package/dist/dataset/relate.js.map +1 -0
  12. package/dist/foundation/axes.d.ts +92 -0
  13. package/dist/foundation/axes.d.ts.map +1 -0
  14. package/dist/foundation/axes.js +42 -0
  15. package/dist/foundation/axes.js.map +1 -0
  16. package/dist/foundation/errors.d.ts +30 -0
  17. package/dist/foundation/errors.d.ts.map +1 -0
  18. package/dist/foundation/errors.js +53 -0
  19. package/dist/foundation/errors.js.map +1 -0
  20. package/dist/foundation/hash.d.ts +16 -0
  21. package/dist/foundation/hash.d.ts.map +1 -0
  22. package/dist/foundation/hash.js +26 -0
  23. package/dist/foundation/hash.js.map +1 -0
  24. package/dist/foundation/ir.d.ts +79 -0
  25. package/dist/foundation/ir.d.ts.map +1 -0
  26. package/dist/foundation/ir.js +16 -0
  27. package/dist/foundation/ir.js.map +1 -0
  28. package/dist/foundation/prng.d.ts +27 -0
  29. package/dist/foundation/prng.d.ts.map +1 -0
  30. package/dist/foundation/prng.js +56 -0
  31. package/dist/foundation/prng.js.map +1 -0
  32. package/dist/foundation/types.d.ts +59 -0
  33. package/dist/foundation/types.d.ts.map +1 -0
  34. package/dist/foundation/types.js +99 -0
  35. package/dist/foundation/types.js.map +1 -0
  36. package/dist/foundation/walk.d.ts +43 -0
  37. package/dist/foundation/walk.d.ts.map +1 -0
  38. package/dist/foundation/walk.js +156 -0
  39. package/dist/foundation/walk.js.map +1 -0
  40. package/dist/generator/engine.d.ts +62 -0
  41. package/dist/generator/engine.d.ts.map +1 -0
  42. package/dist/generator/engine.js +369 -0
  43. package/dist/generator/engine.js.map +1 -0
  44. package/dist/generator/replay.d.ts +31 -0
  45. package/dist/generator/replay.d.ts.map +1 -0
  46. package/dist/generator/replay.js +66 -0
  47. package/dist/generator/replay.js.map +1 -0
  48. package/dist/generator/trace.d.ts +50 -0
  49. package/dist/generator/trace.d.ts.map +1 -0
  50. package/dist/generator/trace.js +39 -0
  51. package/dist/generator/trace.js.map +1 -0
  52. package/dist/index.d.ts +32 -0
  53. package/dist/index.d.ts.map +1 -0
  54. package/dist/index.js +37 -0
  55. package/dist/index.js.map +1 -0
  56. package/dist/schema/composites.d.ts +91 -0
  57. package/dist/schema/composites.d.ts.map +1 -0
  58. package/dist/schema/composites.js +94 -0
  59. package/dist/schema/composites.js.map +1 -0
  60. package/dist/schema/conditional.d.ts +22 -0
  61. package/dist/schema/conditional.d.ts.map +1 -0
  62. package/dist/schema/conditional.js +29 -0
  63. package/dist/schema/conditional.js.map +1 -0
  64. package/dist/schema/decimal.d.ts +31 -0
  65. package/dist/schema/decimal.d.ts.map +1 -0
  66. package/dist/schema/decimal.js +39 -0
  67. package/dist/schema/decimal.js.map +1 -0
  68. package/dist/schema/primitives.d.ts +29 -0
  69. package/dist/schema/primitives.d.ts.map +1 -0
  70. package/dist/schema/primitives.js +44 -0
  71. package/dist/schema/primitives.js.map +1 -0
  72. package/dist/validator/parse.d.ts +17 -0
  73. package/dist/validator/parse.d.ts.map +1 -0
  74. package/dist/validator/parse.js +218 -0
  75. package/dist/validator/parse.js.map +1 -0
  76. package/package.json +59 -0
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Data-schema axes (Phase 2).
3
+ *
4
+ * Each axis is optional metadata attached to a schema node via `Modifiers.axes`.
5
+ * The generator inspects axes during sampling; the validator inspects only
6
+ * `domain` (since distribution is a sampling hint, not a conformance constraint).
7
+ *
8
+ * Priority order during generation (high → low; from Z_PLAN §4.6.1):
9
+ * 1. invariants (single-record predicates that must hold)
10
+ * 2. identity (dataset-level — handled by dataset engine)
11
+ * 3. derived (computed from other fields → fixed)
12
+ * 4. conditional shape (handled by union/discriminated)
13
+ * 5. domain (closed candidate set)
14
+ * 6. distribution (weighting within domain ∩ type)
15
+ * 7. type defaults
16
+ */
17
+ /** A generation context exposed to derived functions and invariants. */
18
+ export type GenContext = {
19
+ /** Root value being built, accessible by JSON-pointer-like path. */
20
+ readonly root: unknown;
21
+ /** Sibling object for the current field (the immediate parent object's data). */
22
+ readonly parent: Readonly<Record<string, unknown>>;
23
+ /** Nearest enclosing array index. `undefined` when no array is in scope. */
24
+ readonly index?: number;
25
+ /** Caller-supplied context channel (free-form key/value, never sampled). */
26
+ readonly input?: Readonly<Record<string, unknown>>;
27
+ /** Stable seed string for this node (derived from path + identity). */
28
+ readonly seed: string;
29
+ };
30
+ /** A single-record predicate. Returns true if the value is acceptable. */
31
+ export type InvariantFn = (value: unknown, ctx: GenContext) => boolean;
32
+ /** A pure function computing a field's value from sibling/root data. */
33
+ export type DerivedFn = (ctx: GenContext) => unknown;
34
+ /** A weighted distribution over discrete enum values. */
35
+ export type WeightedDistribution = {
36
+ readonly kind: 'weighted';
37
+ /** Map of value → weight (relative; need not sum to 1). */
38
+ readonly weights: ReadonlyArray<readonly [string | number | boolean, number]>;
39
+ };
40
+ /** A normal (Gaussian) distribution for numbers. */
41
+ export type NormalDistribution = {
42
+ readonly kind: 'normal';
43
+ readonly mean: number;
44
+ readonly stddev: number;
45
+ };
46
+ /** A typical-range distribution (uniform within [from, to], reachable subset of [min, max]). */
47
+ export type TypicalDistribution = {
48
+ readonly kind: 'typical';
49
+ readonly from: number;
50
+ readonly to: number;
51
+ };
52
+ /**
53
+ * An "occasionally" override: with probability `p`, the produced value is
54
+ * forced to `value`. Stacks before the base distribution.
55
+ */
56
+ export type OccasionalOverride = {
57
+ readonly value: unknown;
58
+ readonly p: number;
59
+ };
60
+ /**
61
+ * An "eventually" override (A6): every `every` rows the produced value is
62
+ * forced to `value`, deterministically driven by `ctx.index`.
63
+ *
64
+ * Stacks before `occasionally`. Skipped when `ctx.index` is undefined.
65
+ */
66
+ export type EventuallyOverride = {
67
+ readonly value: unknown;
68
+ readonly every: number;
69
+ readonly offset?: number;
70
+ };
71
+ export type Distribution = WeightedDistribution | NormalDistribution | TypicalDistribution;
72
+ /** A closed candidate set the value must belong to (`D` in the formal model). */
73
+ export type DomainConstraint = {
74
+ readonly kind: 'values';
75
+ readonly values: readonly unknown[];
76
+ } | {
77
+ readonly kind: 'lookup';
78
+ readonly fromField: string;
79
+ readonly map: Readonly<Record<string, readonly unknown[]>>;
80
+ };
81
+ /** All axis metadata attached to a schema node. */
82
+ export type Axes = {
83
+ readonly distribution?: Distribution;
84
+ readonly occasionally?: readonly OccasionalOverride[];
85
+ readonly eventually?: readonly EventuallyOverride[];
86
+ readonly derived?: DerivedFn;
87
+ readonly invariants?: readonly InvariantFn[];
88
+ readonly domain?: DomainConstraint;
89
+ };
90
+ /** Merge two axis records (right-hand wins for scalar fields, lists concat). */
91
+ export declare const mergeAxes: (a: Axes | undefined, b: Axes) => Axes;
92
+ //# sourceMappingURL=axes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"axes.d.ts","sourceRoot":"","sources":["../../src/foundation/axes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Data-schema axes (Phase 2).
3
+ *
4
+ * Each axis is optional metadata attached to a schema node via `Modifiers.axes`.
5
+ * The generator inspects axes during sampling; the validator inspects only
6
+ * `domain` (since distribution is a sampling hint, not a conformance constraint).
7
+ *
8
+ * Priority order during generation (high → low; from Z_PLAN §4.6.1):
9
+ * 1. invariants (single-record predicates that must hold)
10
+ * 2. identity (dataset-level — handled by dataset engine)
11
+ * 3. derived (computed from other fields → fixed)
12
+ * 4. conditional shape (handled by union/discriminated)
13
+ * 5. domain (closed candidate set)
14
+ * 6. distribution (weighting within domain ∩ type)
15
+ * 7. type defaults
16
+ */
17
+ /** Merge two axis records (right-hand wins for scalar fields, lists concat). */
18
+ export const mergeAxes = (a, b) => {
19
+ if (a === undefined)
20
+ return b;
21
+ const merged = {};
22
+ const dist = b.distribution ?? a.distribution;
23
+ if (dist !== undefined)
24
+ merged.distribution = dist;
25
+ const der = b.derived ?? a.derived;
26
+ if (der !== undefined)
27
+ merged.derived = der;
28
+ const dom = b.domain ?? a.domain;
29
+ if (dom !== undefined)
30
+ merged.domain = dom;
31
+ const occ = [...(a.occasionally ?? []), ...(b.occasionally ?? [])];
32
+ if (occ.length > 0)
33
+ merged.occasionally = occ;
34
+ const evn = [...(a.eventually ?? []), ...(b.eventually ?? [])];
35
+ if (evn.length > 0)
36
+ merged.eventually = evn;
37
+ const inv = [...(a.invariants ?? []), ...(b.invariants ?? [])];
38
+ if (inv.length > 0)
39
+ merged.invariants = inv;
40
+ return merged;
41
+ };
42
+ //# sourceMappingURL=axes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"axes.js","sourceRoot":"","sources":["../../src/foundation/axes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAiFH,gFAAgF;AAChF,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAmB,EAAE,CAAO,EAAQ,EAAE;IAC9D,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,CAAC,CAAA;IAC7B,MAAM,MAAM,GAOR,EAAE,CAAA;IACN,MAAM,IAAI,GAAG,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,YAAY,CAAA;IAC7C,IAAI,IAAI,KAAK,SAAS;QAAE,MAAM,CAAC,YAAY,GAAG,IAAI,CAAA;IAClD,MAAM,GAAG,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,CAAA;IAClC,IAAI,GAAG,KAAK,SAAS;QAAE,MAAM,CAAC,OAAO,GAAG,GAAG,CAAA;IAC3C,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,CAAA;IAChC,IAAI,GAAG,KAAK,SAAS;QAAE,MAAM,CAAC,MAAM,GAAG,GAAG,CAAA;IAC1C,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,CAAA;IAClE,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,CAAC,YAAY,GAAG,GAAG,CAAA;IAC7C,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,CAAA;IAC9D,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,CAAC,UAAU,GAAG,GAAG,CAAA;IAC3C,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,CAAA;IAC9D,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,CAAC,UAAU,GAAG,GAAG,CAAA;IAC3C,OAAO,MAAM,CAAA;AACf,CAAC,CAAA"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * smokin error hierarchy. All errors carry a JSON-pointer style `path` so that
3
+ * deeply nested failures can be reported precisely.
4
+ */
5
+ export type Issue = {
6
+ readonly path: readonly (string | number)[];
7
+ readonly message: string;
8
+ readonly expected?: string;
9
+ readonly received?: unknown;
10
+ };
11
+ /**
12
+ * Thrown by {@link parse} when a value does not conform to a schema.
13
+ * Use {@link safeParse} to receive a result rather than an exception.
14
+ */
15
+ export declare class ConformError extends Error {
16
+ readonly issues: readonly Issue[];
17
+ constructor(issues: readonly Issue[]);
18
+ }
19
+ /**
20
+ * Thrown when an axis combination is unsatisfiable
21
+ * (Phase 2+: invariants conflict with distribution, derived returns
22
+ * out-of-domain value, etc.). Phase 1 surfaces this only for impossible
23
+ * primitive bounds (e.g. `int().min(10).max(5)`).
24
+ */
25
+ export declare class SchemaConflictError extends Error {
26
+ readonly path: readonly (string | number)[];
27
+ readonly hint?: string;
28
+ constructor(message: string, path?: readonly (string | number)[], hint?: string);
29
+ }
30
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/foundation/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,KAAK,GAAG;IAClB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAA;IAC3C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAC5B,CAAA;AAED;;;GAGG;AACH,qBAAa,YAAa,SAAQ,KAAK;IACrC,QAAQ,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,CAAA;gBAErB,MAAM,EAAE,SAAS,KAAK,EAAE;CASrC;AAED;;;;;GAKG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAA;IAC3C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;gBAEV,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAO,EAAE,IAAI,CAAC,EAAE,MAAM;CAMpF"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * smokin error hierarchy. All errors carry a JSON-pointer style `path` so that
3
+ * deeply nested failures can be reported precisely.
4
+ */
5
+ /**
6
+ * Thrown by {@link parse} when a value does not conform to a schema.
7
+ * Use {@link safeParse} to receive a result rather than an exception.
8
+ */
9
+ export class ConformError extends Error {
10
+ issues;
11
+ constructor(issues) {
12
+ const summary = issues.length === 1
13
+ ? formatIssue(issues[0])
14
+ : `${issues.length} issues:\n${issues.map((i) => ' - ' + formatIssue(i)).join('\n')}`;
15
+ super(summary);
16
+ this.name = 'ConformError';
17
+ this.issues = issues;
18
+ }
19
+ }
20
+ /**
21
+ * Thrown when an axis combination is unsatisfiable
22
+ * (Phase 2+: invariants conflict with distribution, derived returns
23
+ * out-of-domain value, etc.). Phase 1 surfaces this only for impossible
24
+ * primitive bounds (e.g. `int().min(10).max(5)`).
25
+ */
26
+ export class SchemaConflictError extends Error {
27
+ path;
28
+ hint;
29
+ constructor(message, path = [], hint) {
30
+ super(hint ? `${message} (hint: ${hint})` : message);
31
+ this.name = 'SchemaConflictError';
32
+ this.path = path;
33
+ if (hint !== undefined)
34
+ this.hint = hint;
35
+ }
36
+ }
37
+ const formatIssue = (i) => {
38
+ const p = i.path.length === 0 ? '(root)' : i.path.map((s) => String(s)).join('.');
39
+ const expected = i.expected !== undefined ? ` expected=${i.expected}` : '';
40
+ const received = 'received' in i
41
+ ? ` received=${safeStringify(i.received)}`
42
+ : '';
43
+ return `${p}: ${i.message}${expected}${received}`;
44
+ };
45
+ const safeStringify = (v) => {
46
+ try {
47
+ return JSON.stringify(v);
48
+ }
49
+ catch {
50
+ return String(v);
51
+ }
52
+ };
53
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/foundation/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH;;;GAGG;AACH,MAAM,OAAO,YAAa,SAAQ,KAAK;IAC5B,MAAM,CAAkB;IAEjC,YAAY,MAAwB;QAClC,MAAM,OAAO,GACX,MAAM,CAAC,MAAM,KAAK,CAAC;YACjB,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC;YACzB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,aAAa,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAA;QAC1F,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,cAAc,CAAA;QAC1B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IACnC,IAAI,CAA8B;IAClC,IAAI,CAAS;IAEtB,YAAY,OAAe,EAAE,OAAqC,EAAE,EAAE,IAAa;QACjF,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO,WAAW,IAAI,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;QACpD,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAA;QACjC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,IAAI,KAAK,SAAS;YAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;IAC1C,CAAC;CACF;AAED,MAAM,WAAW,GAAG,CAAC,CAAQ,EAAU,EAAE;IACvC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACjF,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;IAC1E,MAAM,QAAQ,GACZ,UAAU,IAAI,CAAC;QACb,CAAC,CAAC,aAAa,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE;QAC1C,CAAC,CAAC,EAAE,CAAA;IACR,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,QAAQ,GAAG,QAAQ,EAAE,CAAA;AACnD,CAAC,CAAA;AAED,MAAM,aAAa,GAAG,CAAC,CAAU,EAAU,EAAE;IAC3C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,CAAC,CAAC,CAAA;IAClB,CAAC;AACH,CAAC,CAAA"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Stable identity hash for seed derivation.
3
+ *
4
+ * Uses node:crypto sha256 (Node ≥ 18.17 stdlib — counts as zero dependency).
5
+ */
6
+ /** sha256(input) → lowercase hex string. */
7
+ export declare const sha256: (input: string) => string;
8
+ /**
9
+ * Build a deterministic identity string from sorted query/path/identity values.
10
+ *
11
+ * Example:
12
+ * identityKey('GET', '/inventory', { base_code: 'CT', date: '2026-05-22' })
13
+ * → 'GET|/inventory|base_code=CT&date=2026-05-22'
14
+ */
15
+ export declare const identityKey: (method: string, path: string, parts: Record<string, string | number | boolean | null | undefined>) => string;
16
+ //# sourceMappingURL=hash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/foundation/hash.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,4CAA4C;AAC5C,eAAO,MAAM,MAAM,UAAW,MAAM,KAAG,MACmB,CAAA;AAE1D;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,WACd,MAAM,QACR,MAAM,SACL,OAAO,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,KAClE,MASF,CAAA"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Stable identity hash for seed derivation.
3
+ *
4
+ * Uses node:crypto sha256 (Node ≥ 18.17 stdlib — counts as zero dependency).
5
+ */
6
+ import { createHash } from 'node:crypto';
7
+ /** sha256(input) → lowercase hex string. */
8
+ export const sha256 = (input) => createHash('sha256').update(input, 'utf8').digest('hex');
9
+ /**
10
+ * Build a deterministic identity string from sorted query/path/identity values.
11
+ *
12
+ * Example:
13
+ * identityKey('GET', '/inventory', { base_code: 'CT', date: '2026-05-22' })
14
+ * → 'GET|/inventory|base_code=CT&date=2026-05-22'
15
+ */
16
+ export const identityKey = (method, path, parts) => {
17
+ const flat = Object.keys(parts)
18
+ .sort()
19
+ .map((k) => {
20
+ const v = parts[k];
21
+ return `${k}=${v === undefined || v === null ? '' : String(v)}`;
22
+ })
23
+ .join('&');
24
+ return `${method}|${path}|${flat}`;
25
+ };
26
+ //# sourceMappingURL=hash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/foundation/hash.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC,4CAA4C;AAC5C,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,KAAa,EAAU,EAAE,CAC9C,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAE1D;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,MAAc,EACd,IAAY,EACZ,KAAmE,EAC3D,EAAE;IACV,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;SAC5B,IAAI,EAAE;SACN,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QAClB,OAAO,GAAG,CAAC,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAA;IACjE,CAAC,CAAC;SACD,IAAI,CAAC,GAAG,CAAC,CAAA;IACZ,OAAO,GAAG,MAAM,IAAI,IAAI,IAAI,IAAI,EAAE,CAAA;AACpC,CAAC,CAAA"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Internal Representation (IR) of a smokin schema.
3
+ *
4
+ * Every schema builder compiles to one of these serializable nodes.
5
+ * The generator and validator operate on IR — never on builder classes —
6
+ * so IR can be inspected, logged, transformed, or transported.
7
+ */
8
+ export type StringFormat = 'plain' | 'uuid' | 'email' | 'url' | 'ipv4' | 'ipv6' | 'date' | 'datetime' | 'time';
9
+ export type NumberKind = {
10
+ readonly kind: 'number';
11
+ readonly int: boolean;
12
+ readonly bits?: 8 | 16 | 32 | 64;
13
+ readonly unsigned?: boolean;
14
+ readonly min?: number;
15
+ readonly max?: number;
16
+ };
17
+ export type StringKind = {
18
+ readonly kind: 'string';
19
+ readonly format: StringFormat;
20
+ readonly min?: number;
21
+ readonly max?: number;
22
+ readonly pattern?: string;
23
+ };
24
+ export type DecimalKind = {
25
+ readonly kind: 'decimal';
26
+ readonly precision: number;
27
+ readonly scale: number;
28
+ readonly min?: string;
29
+ readonly max?: string;
30
+ };
31
+ export type BooleanKind = {
32
+ readonly kind: 'boolean';
33
+ };
34
+ export type NullKind = {
35
+ readonly kind: 'null';
36
+ };
37
+ export type LiteralKind = {
38
+ readonly kind: 'literal';
39
+ readonly value: string | number | boolean | null;
40
+ };
41
+ export type EnumKind = {
42
+ readonly kind: 'enum';
43
+ readonly values: readonly (string | number)[];
44
+ };
45
+ export type ArrayKind = {
46
+ readonly kind: 'array';
47
+ readonly item: SchemaNode;
48
+ readonly length?: number;
49
+ readonly minLength?: number;
50
+ readonly maxLength?: number;
51
+ };
52
+ export type ObjectKind = {
53
+ readonly kind: 'object';
54
+ readonly fields: Readonly<Record<string, SchemaNode>>;
55
+ };
56
+ export type TupleKind = {
57
+ readonly kind: 'tuple';
58
+ readonly items: readonly SchemaNode[];
59
+ };
60
+ export type UnionKind = {
61
+ readonly kind: 'union';
62
+ readonly options: readonly SchemaNode[];
63
+ };
64
+ import type { Axes } from './axes.js';
65
+ export type Modifiers = {
66
+ readonly nullable?: boolean;
67
+ readonly optional?: boolean;
68
+ readonly hasDefault?: boolean;
69
+ readonly defaultValue?: unknown;
70
+ readonly description?: string;
71
+ readonly axes?: Axes;
72
+ };
73
+ export type SchemaCore = NumberKind | StringKind | DecimalKind | BooleanKind | NullKind | LiteralKind | EnumKind | ArrayKind | ObjectKind | TupleKind | UnionKind;
74
+ export type SchemaNode = SchemaCore & {
75
+ readonly mods?: Modifiers;
76
+ };
77
+ /** Helper: produce a fresh node with merged modifiers. `axes` are deep-merged. */
78
+ export declare const withMods: (node: SchemaNode, patch: Partial<Modifiers>) => SchemaNode;
79
+ //# sourceMappingURL=ir.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ir.d.ts","sourceRoot":"","sources":["../../src/foundation/ir.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Internal Representation (IR) of a smokin schema.
3
+ *
4
+ * Every schema builder compiles to one of these serializable nodes.
5
+ * The generator and validator operate on IR — never on builder classes —
6
+ * so IR can be inspected, logged, transformed, or transported.
7
+ */
8
+ import { mergeAxes } from './axes.js';
9
+ /** Helper: produce a fresh node with merged modifiers. `axes` are deep-merged. */
10
+ export const withMods = (node, patch) => {
11
+ const prev = node.mods ?? {};
12
+ const mergedAxes = patch.axes !== undefined ? mergeAxes(prev.axes, patch.axes) : prev.axes;
13
+ const next = mergedAxes !== undefined ? { ...prev, ...patch, axes: mergedAxes } : { ...prev, ...patch };
14
+ return { ...node, mods: next };
15
+ };
16
+ //# sourceMappingURL=ir.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ir.js","sourceRoot":"","sources":["../../src/foundation/ir.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA2EH,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AA4BrC,kFAAkF;AAClF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,IAAgB,EAAE,KAAyB,EAAc,EAAE;IAClF,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,EAAE,CAAA;IAC5B,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAA;IAC1F,MAAM,IAAI,GAAc,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,EAAE,CAAA;IAClH,OAAO,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;AAChC,CAAC,CAAA"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * mulberry32 — tiny, fast, deterministic 32-bit PRNG.
3
+ *
4
+ * Zero-dependency. Identical seed → identical sequence on every machine.
5
+ * Period ≈ 2^32, ample for mock generation.
6
+ *
7
+ * Reference: https://gist.github.com/tommyettinger/46a3a48c0d7fe27ea3aaa5fa8f1ba0e8
8
+ */
9
+ export type Rng = {
10
+ /** Next uniformly-distributed float in `[0, 1)`. */
11
+ next(): number;
12
+ /** Next integer in `[min, max]` (inclusive). */
13
+ int(min: number, max: number): number;
14
+ /** Pick one element of `items` uniformly. */
15
+ pick<T>(items: readonly T[]): T;
16
+ };
17
+ /**
18
+ * Create a deterministic PRNG seeded by a 32-bit unsigned integer.
19
+ *
20
+ * For string seeds, use {@link rngFromString}.
21
+ */
22
+ export declare const mulberry32: (seed: number) => Rng;
23
+ /** Derive a 32-bit unsigned seed from an arbitrary string (FNV-1a 32-bit). */
24
+ export declare const seedFromString: (s: string) => number;
25
+ /** Convenience: build an Rng from a string seed. */
26
+ export declare const rngFromString: (s: string) => Rng;
27
+ //# sourceMappingURL=prng.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prng.d.ts","sourceRoot":"","sources":["../../src/foundation/prng.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,GAAG,GAAG;IAChB,oDAAoD;IACpD,IAAI,IAAI,MAAM,CAAA;IACd,gDAAgD;IAChD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;IACrC,6CAA6C;IAC7C,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,GAAG,CAAC,CAAA;CAChC,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,UAAU,SAAU,MAAM,KAAG,GA8BzC,CAAA;AAED,8EAA8E;AAC9E,eAAO,MAAM,cAAc,MAAO,MAAM,KAAG,MAO1C,CAAA;AAED,oDAAoD;AACpD,eAAO,MAAM,aAAa,MAAO,MAAM,KAAG,GAAoC,CAAA"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * mulberry32 — tiny, fast, deterministic 32-bit PRNG.
3
+ *
4
+ * Zero-dependency. Identical seed → identical sequence on every machine.
5
+ * Period ≈ 2^32, ample for mock generation.
6
+ *
7
+ * Reference: https://gist.github.com/tommyettinger/46a3a48c0d7fe27ea3aaa5fa8f1ba0e8
8
+ */
9
+ /**
10
+ * Create a deterministic PRNG seeded by a 32-bit unsigned integer.
11
+ *
12
+ * For string seeds, use {@link rngFromString}.
13
+ */
14
+ export const mulberry32 = (seed) => {
15
+ // Force u32.
16
+ let state = seed >>> 0;
17
+ const next = () => {
18
+ state = (state + 0x6d2b79f5) >>> 0;
19
+ let t = state;
20
+ t = Math.imul(t ^ (t >>> 15), t | 1);
21
+ t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
22
+ return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
23
+ };
24
+ return {
25
+ next,
26
+ int(min, max) {
27
+ if (!Number.isFinite(min) || !Number.isFinite(max)) {
28
+ throw new RangeError(`rng.int requires finite bounds, got [${min}, ${max}]`);
29
+ }
30
+ if (min > max)
31
+ throw new RangeError(`rng.int: min (${min}) > max (${max})`);
32
+ const lo = Math.ceil(min);
33
+ const hi = Math.floor(max);
34
+ return lo + Math.floor(next() * (hi - lo + 1));
35
+ },
36
+ pick(items) {
37
+ if (items.length === 0)
38
+ throw new RangeError('rng.pick: empty array');
39
+ const idx = Math.floor(next() * items.length);
40
+ // Safe: idx ∈ [0, items.length-1]
41
+ return items[idx];
42
+ },
43
+ };
44
+ };
45
+ /** Derive a 32-bit unsigned seed from an arbitrary string (FNV-1a 32-bit). */
46
+ export const seedFromString = (s) => {
47
+ let h = 0x811c9dc5;
48
+ for (let i = 0; i < s.length; i += 1) {
49
+ h ^= s.charCodeAt(i);
50
+ h = Math.imul(h, 0x01000193);
51
+ }
52
+ return h >>> 0;
53
+ };
54
+ /** Convenience: build an Rng from a string seed. */
55
+ export const rngFromString = (s) => mulberry32(seedFromString(s));
56
+ //# sourceMappingURL=prng.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prng.js","sourceRoot":"","sources":["../../src/foundation/prng.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAWH;;;;GAIG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAY,EAAO,EAAE;IAC9C,aAAa;IACb,IAAI,KAAK,GAAG,IAAI,KAAK,CAAC,CAAA;IAEtB,MAAM,IAAI,GAAG,GAAW,EAAE;QACxB,KAAK,GAAG,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAA;QAClC,IAAI,CAAC,GAAG,KAAK,CAAA;QACb,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;QACpC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAA;QACzC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,UAAU,CAAA;IAC9C,CAAC,CAAA;IAED,OAAO;QACL,IAAI;QACJ,GAAG,CAAC,GAAG,EAAE,GAAG;YACV,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACnD,MAAM,IAAI,UAAU,CAAC,wCAAwC,GAAG,KAAK,GAAG,GAAG,CAAC,CAAA;YAC9E,CAAC;YACD,IAAI,GAAG,GAAG,GAAG;gBAAE,MAAM,IAAI,UAAU,CAAC,iBAAiB,GAAG,YAAY,GAAG,GAAG,CAAC,CAAA;YAC3E,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YACzB,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YAC1B,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAA;QAChD,CAAC;QACD,IAAI,CAAI,KAAmB;YACzB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;gBAAE,MAAM,IAAI,UAAU,CAAC,uBAAuB,CAAC,CAAA;YACrE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAA;YAC7C,kCAAkC;YAClC,OAAO,KAAK,CAAC,GAAG,CAAM,CAAA;QACxB,CAAC;KACF,CAAA;AACH,CAAC,CAAA;AAED,8EAA8E;AAC9E,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAS,EAAU,EAAE;IAClD,IAAI,CAAC,GAAG,UAAU,CAAA;IAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACrC,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;QACpB,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,UAAU,CAAC,CAAA;IAC9B,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,CAAA;AAChB,CAAC,CAAA;AAED,oDAAoD;AACpD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAS,EAAO,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAA"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Phantom-typed schema builder + Infer<>.
3
+ *
4
+ * Every builder carries:
5
+ * - `_node`: serializable IR (runtime)
6
+ * - `_type`: phantom TS type parameter for inference (compile-time only)
7
+ *
8
+ * Modifiers (.nullable / .optional / .default / .describe) return a *new*
9
+ * builder with updated phantom type and updated IR.
10
+ */
11
+ import type { Axes, DerivedFn, Distribution, DomainConstraint, InvariantFn } from './axes.js';
12
+ import type { Modifiers, SchemaNode } from './ir.js';
13
+ /** Base builder. Subclasses (StringSchema, NumberSchema, …) extend this. */
14
+ export declare class Schema<out T = unknown> {
15
+ readonly _type: T;
16
+ readonly _node: SchemaNode;
17
+ constructor(node: SchemaNode);
18
+ nullable(): Schema<T | null>;
19
+ optional(): Schema<T | undefined>;
20
+ default(value: T): Schema<T>;
21
+ describe(text: string): this;
22
+ /** Weighted distribution over discrete values. Weights are relative. */
23
+ weighted(weights: ReadonlyArray<readonly [T & (string | number | boolean), number]>): this;
24
+ /** Normal (Gaussian) distribution for numeric schemas. */
25
+ normal(mean: number, stddev: number): this;
26
+ /** Typical range — values concentrate uniformly inside [from, to]. */
27
+ typically(from: number, to: number): this;
28
+ /** Force `value` with probability `p` (stacks before base distribution). */
29
+ occasionally(value: T, p: number): this;
30
+ /**
31
+ * Force `value` every `every` rows (deterministic, driven by `ctx.index`).
32
+ *
33
+ * Useful for periodic rare events that must hit at a guaranteed cadence
34
+ * (e.g. monthly maintenance shutdown). Skipped when `ctx.index` is undefined.
35
+ */
36
+ eventually(every: number, value: T, opts?: {
37
+ readonly offset?: number;
38
+ }): this;
39
+ /** Field is computed from sibling/root context — generator skips sampling. */
40
+ derivedFrom(fn: DerivedFn): this;
41
+ /** Single-record predicate. Generator retries up to MAX_ATTEMPTS to satisfy. */
42
+ invariant(fn: InvariantFn): this;
43
+ /** Restrict to a closed candidate set or a lookup-by-sibling-field map. */
44
+ in(constraint: DomainConstraint | readonly unknown[]): this;
45
+ protected withAxes(axes: Axes): this;
46
+ protected withModsPreserveType(patch: Partial<Modifiers>): this;
47
+ }
48
+ /**
49
+ * Infer the TypeScript type a schema generates / accepts.
50
+ *
51
+ * ```ts
52
+ * const User = obj({ id: int(), name: str() })
53
+ * type User = Infer<typeof User> // { id: number; name: string }
54
+ * ```
55
+ */
56
+ export type Infer<S> = S extends Schema<infer T> ? T : never;
57
+ /** Re-export modifier shape for advanced consumers. */
58
+ export type { Distribution, DomainConstraint, Modifiers, SchemaNode };
59
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/foundation/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,gBAAgB,EAAsB,WAAW,EAAsB,MAAM,WAAW,CAAA;AACrI,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAGpD,4EAA4E;AAC5E,qBAAa,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO;IACjC,SAAiB,KAAK,EAAE,CAAC,CAAA;IACzB,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;gBAEd,IAAI,EAAE,UAAU;IAI5B,QAAQ,IAAI,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC;IAI5B,QAAQ,IAAI,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC;IAIjC,OAAO,CAAC,KAAK,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;IAI5B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAM5B,wEAAwE;IACxE,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI;IAS1F,0DAA0D;IAC1D,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAI1C,sEAAsE;IACtE,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI;IAIzC,4EAA4E;IAC5E,YAAY,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IAMvC;;;;;OAKG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAY9E,8EAA8E;IAC9E,WAAW,CAAC,EAAE,EAAE,SAAS,GAAG,IAAI;IAIhC,gFAAgF;IAChF,SAAS,CAAC,EAAE,EAAE,WAAW,GAAG,IAAI;IAIhC,2EAA2E;IAC3E,EAAE,CAAC,UAAU,EAAE,gBAAgB,GAAG,SAAS,OAAO,EAAE,GAAG,IAAI;IAS3D,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAIpC,SAAS,CAAC,oBAAoB,CAAC,KAAK,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI;CAOhE;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;AAE5D,uDAAuD;AACvD,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,SAAS,EAAE,UAAU,EAAE,CAAA"}