@descryy/ir 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 (94) hide show
  1. package/LICENSE +21 -0
  2. package/dist/capabilities.d.ts +83 -0
  3. package/dist/capabilities.d.ts.map +1 -0
  4. package/dist/capabilities.js +91 -0
  5. package/dist/capabilities.js.map +1 -0
  6. package/dist/conformance/bind.d.ts +82 -0
  7. package/dist/conformance/bind.d.ts.map +1 -0
  8. package/dist/conformance/bind.js +157 -0
  9. package/dist/conformance/bind.js.map +1 -0
  10. package/dist/conformance/cli.d.ts +25 -0
  11. package/dist/conformance/cli.d.ts.map +1 -0
  12. package/dist/conformance/cli.js +137 -0
  13. package/dist/conformance/cli.js.map +1 -0
  14. package/dist/conformance/compare.d.ts +74 -0
  15. package/dist/conformance/compare.d.ts.map +1 -0
  16. package/dist/conformance/compare.js +140 -0
  17. package/dist/conformance/compare.js.map +1 -0
  18. package/dist/conformance/compose.d.ts +79 -0
  19. package/dist/conformance/compose.d.ts.map +1 -0
  20. package/dist/conformance/compose.js +167 -0
  21. package/dist/conformance/compose.js.map +1 -0
  22. package/dist/conformance/golden.d.ts +110 -0
  23. package/dist/conformance/golden.d.ts.map +1 -0
  24. package/dist/conformance/golden.js +252 -0
  25. package/dist/conformance/golden.js.map +1 -0
  26. package/dist/conformance/index.d.ts +26 -0
  27. package/dist/conformance/index.d.ts.map +1 -0
  28. package/dist/conformance/index.js +18 -0
  29. package/dist/conformance/index.js.map +1 -0
  30. package/dist/conformance/manifest-check.d.ts +78 -0
  31. package/dist/conformance/manifest-check.d.ts.map +1 -0
  32. package/dist/conformance/manifest-check.js +149 -0
  33. package/dist/conformance/manifest-check.js.map +1 -0
  34. package/dist/conformance/manifest.d.ts +83 -0
  35. package/dist/conformance/manifest.d.ts.map +1 -0
  36. package/dist/conformance/manifest.js +158 -0
  37. package/dist/conformance/manifest.js.map +1 -0
  38. package/dist/conformance/report.d.ts +14 -0
  39. package/dist/conformance/report.d.ts.map +1 -0
  40. package/dist/conformance/report.js +87 -0
  41. package/dist/conformance/report.js.map +1 -0
  42. package/dist/conformance/run.d.ts +172 -0
  43. package/dist/conformance/run.d.ts.map +1 -0
  44. package/dist/conformance/run.js +626 -0
  45. package/dist/conformance/run.js.map +1 -0
  46. package/dist/contracts.d.ts +198 -0
  47. package/dist/contracts.d.ts.map +1 -0
  48. package/dist/contracts.js +10 -0
  49. package/dist/contracts.js.map +1 -0
  50. package/dist/contradiction.d.ts +112 -0
  51. package/dist/contradiction.d.ts.map +1 -0
  52. package/dist/contradiction.js +97 -0
  53. package/dist/contradiction.js.map +1 -0
  54. package/dist/finding.d.ts +567 -0
  55. package/dist/finding.d.ts.map +1 -0
  56. package/dist/finding.js +491 -0
  57. package/dist/finding.js.map +1 -0
  58. package/dist/hypothesis.d.ts +130 -0
  59. package/dist/hypothesis.d.ts.map +1 -0
  60. package/dist/hypothesis.js +116 -0
  61. package/dist/hypothesis.js.map +1 -0
  62. package/dist/identity.d.ts +295 -0
  63. package/dist/identity.d.ts.map +1 -0
  64. package/dist/identity.js +404 -0
  65. package/dist/identity.js.map +1 -0
  66. package/dist/index.d.ts +34 -0
  67. package/dist/index.d.ts.map +1 -0
  68. package/dist/index.js +21 -0
  69. package/dist/index.js.map +1 -0
  70. package/dist/ir.d.ts +360 -0
  71. package/dist/ir.d.ts.map +1 -0
  72. package/dist/ir.js +76 -0
  73. package/dist/ir.js.map +1 -0
  74. package/dist/model-tables.d.ts +111 -0
  75. package/dist/model-tables.d.ts.map +1 -0
  76. package/dist/model-tables.js +103 -0
  77. package/dist/model-tables.js.map +1 -0
  78. package/dist/normalise.d.ts +114 -0
  79. package/dist/normalise.d.ts.map +1 -0
  80. package/dist/normalise.js +603 -0
  81. package/dist/normalise.js.map +1 -0
  82. package/dist/reliability.d.ts +89 -0
  83. package/dist/reliability.d.ts.map +1 -0
  84. package/dist/reliability.js +181 -0
  85. package/dist/reliability.js.map +1 -0
  86. package/dist/tool-surface.d.ts +131 -0
  87. package/dist/tool-surface.d.ts.map +1 -0
  88. package/dist/tool-surface.js +133 -0
  89. package/dist/tool-surface.js.map +1 -0
  90. package/dist/vocabulary.d.ts +73 -0
  91. package/dist/vocabulary.d.ts.map +1 -0
  92. package/dist/vocabulary.js +150 -0
  93. package/dist/vocabulary.js.map +1 -0
  94. package/package.json +27 -0
@@ -0,0 +1,103 @@
1
+ /**
2
+ * `DATABASE_TABLE`/`DATABASE_COLUMN` from a `MODEL`'s own mapped shape —
3
+ * DEC-240's Option 2.
4
+ *
5
+ * `adapter-sql` is the only producer of these two types until now, reading
6
+ * `*.sql` DDL. A Python (or, later, Java/C#) stack that maps its tables
7
+ * through an ORM and never checks in a migration file has no producer at
8
+ * all — 17 real tables on the stack this was measured against, zero
9
+ * `DATABASE_TABLE` nodes. DEC-240 ruled that the fix is not "teach
10
+ * `adapter-python`'s `orm.ts` to mint these too": a language adapter that did
11
+ * would also have to decide Django's/JPA's/EF Core's own implicit
12
+ * table-naming convention (app label + lowercased model name, a class name,
13
+ * a pluralisation rule) to cover the common case where no explicit table
14
+ * name is written — three adapters each independently inventing, or
15
+ * independently refusing, the same class of naming inference is three
16
+ * chances to disagree on the one byte that has to be identical for a join to
17
+ * happen at all. So the naming judgement — explicit name or refuse, never
18
+ * infer — lives here instead, once, and every adapter calls this function
19
+ * at its own emit time rather than re-deriving the rule.
20
+ *
21
+ * ## The part DEC-240's own ruling did not check, and the fix could not
22
+ * ship correctly without
23
+ *
24
+ * `nodeId` hashes `[scope, language, kind, qualifiedSymbolPath]` for every
25
+ * node type **except** the three in `FILELESS_NODE_TYPES` — and
26
+ * `DATABASE_TABLE`/`DATABASE_COLUMN` are not in that list. `adapter-sql`
27
+ * already hashes its own nodes with `language: "sql"`. A second producer
28
+ * hashing with its own language — `"python"`, later `"java"`, `"csharp"` —
29
+ * would mint a *different* id for the same real table than every other
30
+ * producer, and DEC-054's whole point (a Python `DATABASE_COLUMN` and a
31
+ * TypeScript `COMPONENT` meeting through one `API_ENDPOINT`) fails silently
32
+ * the identical way DEC-055 already found once: everything resolves,
33
+ * nothing errors, and the join returns nothing. So this function — and, to
34
+ * match it, `adapter-sql`'s own two call sites — hash with `language: null`
35
+ * unconditionally.
36
+ *
37
+ * **The emitted node's own `language` field is `null` too, not the real
38
+ * per-producer language.** The first cut of this function kept the real
39
+ * language there ("only the identity hash has to be language-blind, not the
40
+ * metadata") and that was wrong: the graph builder's collision detector
41
+ * (`identityFingerprint`, `packages/core/src/graph/merge.ts`) compares
42
+ * `[type, language]` for any two nodes that land on one id, precisely to
43
+ * catch two *different* things sharing an id by accident (DEC-024). A real
44
+ * per-producer language on this field means two genuine producers of the
45
+ * *same* table — a Python ORM and the `*.sql` DDL for it, this function's own
46
+ * motivating case — always disagree on `language` and always trip that
47
+ * detector, discarding one side's `DATABASE_COLUMN`s outright. `origin.language`
48
+ * is kept on {@link ModelTableOrigin} only as caller-supplied provenance for
49
+ * future use (e.g. `attrs`); it is not echoed onto the node. Per-producer
50
+ * provenance is still recoverable after a real merge through the node's
51
+ * `attrs.corroboratedBy`, the same mechanism every other cross-producer merge
52
+ * in this project already uses instead of a scalar field.
53
+ *
54
+ * `schema` defaults to `"public"` when a shape names none, matching
55
+ * `adapter-sql`'s own `DEFAULT_SCHEMA` — duplicated as a literal because
56
+ * `@descry/ir` cannot depend on an adapter package to import the constant.
57
+ * A model that maps to a non-default schema and never says so joins nothing
58
+ * either, the same silent-refusal shape `tableOf()` already accepts for an
59
+ * implicit table name.
60
+ */
61
+ import { nodeId, tableQsp } from "./identity.js";
62
+ /** Matches `adapter-sql`'s own `DEFAULT_SCHEMA` (`packages/adapter-sql` in `descry-adapters`). */
63
+ export const DEFAULT_MODEL_SCHEMA = "public";
64
+ /**
65
+ * `DATABASE_TABLE` plus one `DATABASE_COLUMN` per mapped field, or `[]` when
66
+ * `shape.table` is `null` — the disclosed refusal `tableOf()` already makes
67
+ * for an implicit table name, carried through rather than re-decided here.
68
+ */
69
+ export function databaseTableNodesFromModel(scope, shape, origin) {
70
+ if (shape.table === null)
71
+ return [];
72
+ const schema = shape.schema ?? DEFAULT_MODEL_SCHEMA;
73
+ const nodes = [];
74
+ const tableId = nodeId(scope, "DATABASE_TABLE", tableQsp(schema, shape.table), null);
75
+ nodes.push({
76
+ id: tableId,
77
+ type: "DATABASE_TABLE",
78
+ name: shape.table,
79
+ file: origin.file,
80
+ range: { startLine: origin.line, endLine: origin.line },
81
+ language: null,
82
+ producedBy: origin.producedBy,
83
+ resolution: origin.resolution,
84
+ attrs: { name: shape.table, schema },
85
+ });
86
+ for (const field of shape.fields) {
87
+ const columnName = field.columnName ?? field.name;
88
+ const columnId = nodeId(scope, "DATABASE_COLUMN", tableQsp(schema, shape.table, columnName), null);
89
+ nodes.push({
90
+ id: columnId,
91
+ type: "DATABASE_COLUMN",
92
+ name: `${shape.table}.${columnName}`,
93
+ file: origin.file,
94
+ range: { startLine: origin.line, endLine: origin.line },
95
+ language: null,
96
+ producedBy: origin.producedBy,
97
+ resolution: origin.resolution,
98
+ attrs: { name: columnName, nullable: field.nullable },
99
+ });
100
+ }
101
+ return nodes;
102
+ }
103
+ //# sourceMappingURL=model-tables.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-tables.js","sourceRoot":"","sources":["../src/model-tables.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AAEH,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAsB,MAAM,eAAe,CAAC;AAGrE,kGAAkG;AAClG,MAAM,CAAC,MAAM,oBAAoB,GAAG,QAAQ,CAAC;AA6C7C;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CACzC,KAAoB,EACpB,KAAsB,EACtB,MAAwB;IAExB,IAAI,KAAK,CAAC,KAAK,KAAK,IAAI;QAAE,OAAO,EAAE,CAAC;IACpC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,oBAAoB,CAAC;IAEpD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,EAAE,gBAAgB,EAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;IACrF,KAAK,CAAC,IAAI,CAAC;QACT,EAAE,EAAE,OAAO;QACX,IAAI,EAAE,gBAAgB;QACtB,IAAI,EAAE,KAAK,CAAC,KAAK;QACjB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE;QACvD,QAAQ,EAAE,IAAI;QACd,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE;KACrC,CAAC,CAAC;IAEH,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjC,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,IAAI,CAAC;QAClD,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,EAAE,iBAAiB,EAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,EAAE,UAAU,CAAC,EAAE,IAAI,CAAC,CAAC;QACnG,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,QAAQ;YACZ,IAAI,EAAE,iBAAiB;YACvB,IAAI,EAAE,GAAG,KAAK,CAAC,KAAK,IAAI,UAAU,EAAE;YACpC,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE;YACvD,QAAQ,EAAE,IAAI;YACd,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,KAAK,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE;SACtD,CAAC,CAAC;IACL,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * The Normaliser — the only door into the graph.
3
+ *
4
+ * Everything an adapter emits passes through here before anything is written.
5
+ * It exists because of one ordering rule in the build plan: **the Normaliser
6
+ * comes before the writer.** Build the writer first and "reject at the boundary"
7
+ * silently becomes "clean up in SQL", which is unrecoverable — once a bad edge
8
+ * is in the store, a dropped bad edge and a missing good one look identical, and
9
+ * §11B.6 recall has no denominator.
10
+ *
11
+ * Two rules govern the whole file:
12
+ *
13
+ * 1. **Drop and log, never repair.** A repair changes what an adapter claimed
14
+ * without telling anyone. The one exception is confidence, which is clamped
15
+ * *down* to a per-resolution ceiling and recorded — lowering a claim cannot
16
+ * manufacture a fact, and every clamp appears in the result.
17
+ * 2. **Trust nothing.** Adapters live in a different repo, on a different
18
+ * release cadence (DEC-001), and are third-party as far as this package is
19
+ * concerned. TypeScript types do not survive that boundary at runtime, so
20
+ * the input is `unknown` and every field is checked structurally.
21
+ *
22
+ * This package has zero dependencies, so it cannot see the store. The "edge
23
+ * references a node that does not exist" check therefore takes a `nodeExists`
24
+ * predicate: the caller supplies the store lookup, and the IR boundary stays
25
+ * dependency-free.
26
+ */
27
+ import type { IRBatch, ResolutionLevel } from "./ir.ts";
28
+ /**
29
+ * Every way a batch, node, edge or reference can be turned away.
30
+ *
31
+ * Typed rather than free-text because these are counted, not just printed:
32
+ * §20.2's "not analysable" category and §11B.6's recall denominator are both
33
+ * aggregates over this list. A rejection whose reason is a sentence cannot be
34
+ * aggregated.
35
+ */
36
+ export declare const REJECTION_CODES: readonly ["BATCH_MALFORMED", "BATCH_FIELD_INVALID", "BATCH_SOURCE_FILES_EMPTY", "UNKNOWN_NODE_TYPE", "UNKNOWN_EDGE_TYPE", "MALFORMED_NODE_ID", "DUPLICATE_NODE_ID", "EMPTY_NAME", "MALFORMED_PRODUCED_BY", "PRODUCED_BY_MISMATCH", "RESOLUTION_OUT_OF_RANGE", "RESOLUTION_EXCEEDS_BATCH", "R4_WITHOUT_OBSERVED_RUN", "OBSERVED_RUN_WITHOUT_R4", "CONFIDENCE_INVALID", "ABSOLUTE_PATH", "NON_PORTABLE_PATH", "FILE_OUTSIDE_SOURCE_FILES", "MISSING_FILE", "FILE_ON_FILELESS_TYPE", "RANGE_WITHOUT_FILE", "INVALID_RANGE", "MALFORMED_SKIPPED_FILE", "FILE_IN_SOURCE_AND_SKIPPED", "LANGUAGE_ON_JOIN_NODE", "UNKNOWN_WORKSPACE", "MALFORMED_ATTRS", "MALFORMED_UNRESOLVED_REF", "DANGLING_EDGE_ENDPOINT", "EDGE_ENDPOINT_DROPPED"];
37
+ export type RejectionCode = (typeof REJECTION_CODES)[number];
38
+ export interface Rejection {
39
+ readonly code: RejectionCode;
40
+ readonly scope: "batch" | "node" | "edge" | "unresolved";
41
+ /** Node id, `from→to:TYPE` for an edge, or the repo for a batch. Enough to find it. */
42
+ readonly subject: string;
43
+ readonly detail: string;
44
+ }
45
+ /** A confidence value lowered to its resolution's ceiling. Never raised. */
46
+ export interface Clamp {
47
+ readonly subject: string;
48
+ readonly resolution: ResolutionLevel;
49
+ readonly from: number;
50
+ readonly to: number;
51
+ }
52
+ export interface NormaliseResult {
53
+ /** `null` when the envelope itself was rejected — nothing in it can be trusted. */
54
+ readonly batch: IRBatch | null;
55
+ readonly rejections: readonly Rejection[];
56
+ readonly clamps: readonly Clamp[];
57
+ }
58
+ /**
59
+ * The maximum confidence an edge may claim at each resolution level.
60
+ *
61
+ * **The numbers for R0–R2 are provisional.** Architecture §32 item 13 lists
62
+ * `EdgeConfidence` per resolution level as open *tuning*, to be set "once two
63
+ * adapters exist and can be compared" — which is Step 14 of this build, not
64
+ * Step 5. Only two of the five values are actually pinned by the architecture:
65
+ * §12.4 states 1.0 for R3 and R4.
66
+ *
67
+ * What is NOT provisional is the shape, and that is what the tests assert:
68
+ * monotonically non-decreasing in resolution, never above 1.0, and 1.0 exactly
69
+ * at R3 and R4. Tuning the middle three later cannot violate any of those, so
70
+ * measuring them later does not invalidate anything built on this now.
71
+ *
72
+ * Override via `NormaliseOptions.confidenceCeilings` rather than editing here —
73
+ * the accuracy benchmark (§11B.6) will want to sweep them.
74
+ */
75
+ export declare const DEFAULT_CONFIDENCE_CEILINGS: Readonly<Record<ResolutionLevel, number>>;
76
+ export interface NormaliseOptions {
77
+ /**
78
+ * Does a node with this id already exist in the store? An edge may legally
79
+ * point at a node written by an earlier batch — a call from this file into one
80
+ * that did not change is the normal case, not an error.
81
+ *
82
+ * Omitted means "the batch is the whole world", which is what the fake
83
+ * adapters and the conformance harness want.
84
+ */
85
+ readonly nodeExists?: (id: string) => boolean;
86
+ readonly confidenceCeilings?: Readonly<Record<ResolutionLevel, number>>;
87
+ /**
88
+ * The workspace ids this run was configured to know about (DEC-054).
89
+ *
90
+ * A workspace id must be byte-identical in every repository that shares it, and
91
+ * the failure when it is not has no symptoms: `billing-platform` here and
92
+ * `billing_platform` there produces a graph that is structurally perfect,
93
+ * internally consistent, and joins nothing. Zero joins, zero errors, zero
94
+ * warnings.
95
+ *
96
+ * So an unrecognised workspace is treated as a typo rather than as a new
97
+ * workspace, and the batch is rejected whole — its workspace-scoped ids were
98
+ * computed under a scope no other repository will ever produce, which makes
99
+ * every one of them wrong rather than merely unmatched.
100
+ *
101
+ * Omitted means "accept any", which is what a single-repo run and the
102
+ * conformance harness want.
103
+ */
104
+ readonly knownWorkspaces?: readonly string[];
105
+ }
106
+ /**
107
+ * Validate and normalise one `IRBatch`.
108
+ *
109
+ * Never throws on bad input — a malformed batch is a result, not an exception,
110
+ * because a run over 40 adapters must report all of them rather than die on the
111
+ * first. It throws only on programmer error in the options.
112
+ */
113
+ export declare function normaliseBatch(input: unknown, options?: NormaliseOptions): NormaliseResult;
114
+ //# sourceMappingURL=normalise.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalise.d.ts","sourceRoot":"","sources":["../src/normalise.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH,OAAO,KAAK,EACV,OAAO,EAIP,eAAe,EAGhB,MAAM,SAAS,CAAC;AAQjB;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,ksBAwClB,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7D,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,YAAY,CAAC;IACzD,uFAAuF;IACvF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,4EAA4E;AAC5E,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,mFAAmF;IACnF,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,UAAU,EAAE,SAAS,SAAS,EAAE,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,CAAC;CACnC;AAMD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,2BAA2B,EAAE,QAAQ,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,CAMjF,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;OAOG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;IAC9C,QAAQ,CAAC,kBAAkB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC;IACxE;;;;;;;;;;;;;;;;OAgBG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9C;AAqED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,GAAE,gBAAqB,GAAG,eAAe,CAkO9F"}