@untangle-code/context-artifacts 0.0.0-stage → 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 (109) hide show
  1. package/LICENSE +661 -0
  2. package/NOTICE +90 -0
  3. package/README.md +247 -2
  4. package/THIRD_PARTY_LICENSES.md +24 -0
  5. package/dist/adapters/asyncapi.d.ts +20 -0
  6. package/dist/adapters/asyncapi.d.ts.map +1 -0
  7. package/dist/adapters/asyncapi.js +95 -0
  8. package/dist/adapters/asyncapi.js.map +1 -0
  9. package/dist/adapters/docker.d.ts +43 -0
  10. package/dist/adapters/docker.d.ts.map +1 -0
  11. package/dist/adapters/docker.js +97 -0
  12. package/dist/adapters/docker.js.map +1 -0
  13. package/dist/adapters/kubernetes.d.ts +22 -0
  14. package/dist/adapters/kubernetes.d.ts.map +1 -0
  15. package/dist/adapters/kubernetes.js +56 -0
  16. package/dist/adapters/kubernetes.js.map +1 -0
  17. package/dist/adapters/markdown.d.ts +35 -0
  18. package/dist/adapters/markdown.d.ts.map +1 -0
  19. package/dist/adapters/markdown.js +36 -0
  20. package/dist/adapters/markdown.js.map +1 -0
  21. package/dist/adapters/openapi.d.ts +21 -0
  22. package/dist/adapters/openapi.d.ts.map +1 -0
  23. package/dist/adapters/openapi.js +101 -0
  24. package/dist/adapters/openapi.js.map +1 -0
  25. package/dist/adapters/protobuf.d.ts +34 -0
  26. package/dist/adapters/protobuf.d.ts.map +1 -0
  27. package/dist/adapters/protobuf.js +221 -0
  28. package/dist/adapters/protobuf.js.map +1 -0
  29. package/dist/adapters/shared.d.ts +65 -0
  30. package/dist/adapters/shared.d.ts.map +1 -0
  31. package/dist/adapters/shared.js +95 -0
  32. package/dist/adapters/shared.js.map +1 -0
  33. package/dist/adapters/sql.d.ts +104 -0
  34. package/dist/adapters/sql.d.ts.map +1 -0
  35. package/dist/adapters/sql.js +427 -0
  36. package/dist/adapters/sql.js.map +1 -0
  37. package/dist/adapters/terraform.d.ts +40 -0
  38. package/dist/adapters/terraform.d.ts.map +1 -0
  39. package/dist/adapters/terraform.js +186 -0
  40. package/dist/adapters/terraform.js.map +1 -0
  41. package/dist/adapters/text.d.ts +24 -0
  42. package/dist/adapters/text.d.ts.map +1 -0
  43. package/dist/adapters/text.js +31 -0
  44. package/dist/adapters/text.js.map +1 -0
  45. package/dist/config-validation.d.ts +18 -0
  46. package/dist/config-validation.d.ts.map +1 -0
  47. package/dist/config-validation.js +30 -0
  48. package/dist/config-validation.js.map +1 -0
  49. package/dist/coverage.d.ts +114 -0
  50. package/dist/coverage.d.ts.map +1 -0
  51. package/dist/coverage.js +0 -0
  52. package/dist/coverage.js.map +1 -0
  53. package/dist/ids.d.ts +12 -0
  54. package/dist/ids.d.ts.map +1 -0
  55. package/dist/ids.js +42 -0
  56. package/dist/ids.js.map +1 -0
  57. package/dist/index.d.ts +55 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +18 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/registry.d.ts +51 -0
  62. package/dist/registry.d.ts.map +1 -0
  63. package/dist/registry.js +86 -0
  64. package/dist/registry.js.map +1 -0
  65. package/dist/staleness.d.ts +44 -0
  66. package/dist/staleness.d.ts.map +1 -0
  67. package/dist/staleness.js +35 -0
  68. package/dist/staleness.js.map +1 -0
  69. package/dist/text/delimiter-balance.d.ts +95 -0
  70. package/dist/text/delimiter-balance.d.ts.map +1 -0
  71. package/dist/text/delimiter-balance.js +209 -0
  72. package/dist/text/delimiter-balance.js.map +1 -0
  73. package/dist/text/line-index.d.ts +61 -0
  74. package/dist/text/line-index.d.ts.map +1 -0
  75. package/dist/text/line-index.js +75 -0
  76. package/dist/text/line-index.js.map +1 -0
  77. package/dist/text/yaml-lite.d.ts +73 -0
  78. package/dist/text/yaml-lite.d.ts.map +1 -0
  79. package/dist/text/yaml-lite.js +486 -0
  80. package/dist/text/yaml-lite.js.map +1 -0
  81. package/package.json +61 -3
  82. package/src/adapters/__golden__/adr-0001-sections.json +68 -0
  83. package/src/adapters/__golden__/app-compose-services.json +24 -0
  84. package/src/adapters/__golden__/app-image-stages.json +24 -0
  85. package/src/adapters/__golden__/infra-main-sections.json +46 -0
  86. package/src/adapters/__golden__/orders-events-operations.json +24 -0
  87. package/src/adapters/__golden__/orders-proto-sections.json +57 -0
  88. package/src/adapters/__golden__/orders-schema-statements.json +68 -0
  89. package/src/adapters/__golden__/users-api-operations.json +46 -0
  90. package/src/adapters/__golden__/web-manifests-resources.json +24 -0
  91. package/src/adapters/asyncapi.ts +147 -0
  92. package/src/adapters/docker.ts +170 -0
  93. package/src/adapters/kubernetes.ts +103 -0
  94. package/src/adapters/markdown.ts +88 -0
  95. package/src/adapters/openapi.ts +156 -0
  96. package/src/adapters/protobuf.ts +286 -0
  97. package/src/adapters/shared.ts +151 -0
  98. package/src/adapters/sql.ts +555 -0
  99. package/src/adapters/terraform.ts +261 -0
  100. package/src/adapters/text.ts +72 -0
  101. package/src/config-validation.ts +41 -0
  102. package/src/coverage.ts +336 -0
  103. package/src/ids.ts +57 -0
  104. package/src/index.ts +105 -0
  105. package/src/registry.ts +155 -0
  106. package/src/staleness.ts +69 -0
  107. package/src/text/delimiter-balance.ts +295 -0
  108. package/src/text/line-index.ts +108 -0
  109. package/src/text/yaml-lite.ts +565 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/adapters/shared.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EACV,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACpB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAGL,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACxB,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAGvD,YAAY,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEjF,sGAAsG;AACtG,wBAAgB,cAAc,CAC5B,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,OAAO,CAAC,mBAAmB,EAAE,MAAM,CAAC,EAC1C,QAAQ,CAAC,EAAE,MAAM,GAChB,gBAAgB,EAAE,CAWpB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;;;OASG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,gBAAgB,EAC1B,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,UAAU,EAAE,GACnB,aAAa,EAAE,CA6BjB;AAED,4HAA4H;AAC5H,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,UAAU,CAG7F;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,gBAAgB,EAC1B,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,UAAU,EAAE,EACpB,MAAM,GAAE,kBAA8C,EACtD,iBAAiB,CAAC,EAAE,sBAAsB,GACzC,aAAa,EAAE,CAUjB"}
@@ -0,0 +1,95 @@
1
+ import { sha256Hex } from "@untangle-code/domain";
2
+ import { buildArtifactSkipLedger, defaultSkipLedgerReporter, } from "../coverage.js";
3
+ import { buildArtifactChunkId } from "../ids.js";
4
+ import { rangeForLines, sliceBytes, sliceLines } from "../text/line-index.js";
5
+ /** Builds one `ArtifactDocument` per file in `input.files` (spec.md §19.2: files AND directories). */
6
+ export function buildDocuments(input, type, language) {
7
+ return input.files.map((file) => {
8
+ const document = {
9
+ artifactName: input.config.name,
10
+ type,
11
+ path: file.path,
12
+ contentHash: file.contentHash,
13
+ content: file.content,
14
+ };
15
+ return language === undefined ? document : { ...document, language };
16
+ });
17
+ }
18
+ /**
19
+ * Turns line-range drafts into fully-formed `ArtifactChunk`s: computes
20
+ * `range` (via `index`, or the draft's own `startByte`/`endByte` when
21
+ * given), byte-exact `content` (a slice of the SAME buffer `index` was
22
+ * built from — never a re-encoded copy, so content is always byte-identical
23
+ * to the source, spec.md §19.2), `contentHash`, and a deterministic
24
+ * `chunkId` (ordinal = position in `drafts`).
25
+ */
26
+ export function buildChunks(document, index, drafts) {
27
+ return drafts.map((draft, ordinal) => {
28
+ const hasExactBytes = draft.startByte !== undefined && draft.endByte !== undefined;
29
+ const range = hasExactBytes
30
+ ? {
31
+ startLine: draft.startLine,
32
+ endLine: draft.endLine,
33
+ startByte: draft.startByte,
34
+ endByte: draft.endByte,
35
+ }
36
+ : rangeForLines(index, draft.startLine, draft.endLine);
37
+ const content = hasExactBytes
38
+ ? sliceBytes(index, draft.startByte, draft.endByte)
39
+ : sliceLines(index, draft.startLine, draft.endLine);
40
+ const chunk = {
41
+ chunkId: buildArtifactChunkId({
42
+ artifactName: document.artifactName,
43
+ documentPath: document.path,
44
+ kind: draft.kind,
45
+ ordinal,
46
+ }),
47
+ artifactName: document.artifactName,
48
+ kind: draft.kind,
49
+ range,
50
+ content,
51
+ contentHash: sha256Hex(content),
52
+ };
53
+ return draft.title === undefined ? chunk : { ...chunk, title: draft.title };
54
+ });
55
+ }
56
+ /** A single chunk spanning the whole document, used for parse-error degrades and the text fallback's single-window case. */
57
+ export function wholeDocumentDraft(kind, index, title) {
58
+ const draft = { kind, startLine: 1, endLine: Math.max(index.lineCount, 1) };
59
+ return title === undefined ? draft : { ...draft, title };
60
+ }
61
+ /**
62
+ * `buildChunks`, plus BUILD_PLAN §12 E4: `buildArtifactSkipLedger()` must
63
+ * never be a "Bringschuld" (an obligation a caller has to remember) —
64
+ * every format adapter's `chunk()` calls this instead of `buildChunks`
65
+ * directly, so a loss becomes visible in the SAME call that produces
66
+ * chunks, with zero extra action from whoever calls `adapter.chunk()`.
67
+ *
68
+ * `checkPlausibility` (optional, WP-118) reicht die formatspezifische
69
+ * Plausibilitätsprüfung des Adapters an den Ledger durch: ein Fragment,
70
+ * das MITTEN DURCH ein Konstrukt geschnitten wurde, ist auch dann ein
71
+ * Befund, wenn die Byte-Abdeckung lückenlos ist. Siehe
72
+ * `coverage.ts::ChunkPlausibilityCheck` und `text/delimiter-balance.ts`.
73
+ *
74
+ * Only entries beyond plain `"whitespace_or_comment"` are reported —
75
+ * `"unclassified_content"` and `"semantic_loss"` are the two reasons that
76
+ * indicate a real problem (see coverage.ts's module doc); a benign gap
77
+ * between two well-formed sections is expected and stays silent here too,
78
+ * exactly as it does for a caller who inspects the ledger directly.
79
+ *
80
+ * `report` defaults to `defaultSkipLedgerReporter` (a single stderr line
81
+ * per finding) but every `create*Adapter()` factory accepts an
82
+ * `onSkipLedgerGap` override — inject a real structured logger, a test
83
+ * spy, or a no-op, without this package depending on any particular
84
+ * logging implementation.
85
+ */
86
+ export function buildChunksReportingSkips(document, index, drafts, report = defaultSkipLedgerReporter, checkPlausibility) {
87
+ const chunks = buildChunks(document, index, drafts);
88
+ const options = checkPlausibility === undefined ? {} : { checkPlausibility };
89
+ const actionable = buildArtifactSkipLedger(document, chunks, options).filter((entry) => entry.reason !== "whitespace_or_comment");
90
+ if (actionable.length > 0) {
91
+ report(actionable, document);
92
+ }
93
+ return chunks;
94
+ }
95
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/adapters/shared.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * SQL schema adapter (architecture.md §20: "Tabellen, Views, Indizes,
3
+ * Constraints als semantische Abschnitte").
4
+ *
5
+ * Splits the file into top-level statements (terminated by a `;` that is
6
+ * not inside a string literal, a quoted identifier, or a comment), then
7
+ * classifies each statement by its leading keywords. An unrecognized
8
+ * statement (e.g. `INSERT`, `GRANT`) still becomes a chunk — kind
9
+ * `"sql_statement"` — rather than being dropped; nothing in a schema file
10
+ * is silently skipped (rule 4 / BUILD_PLAN §12 E4).
11
+ *
12
+ * Statement boundaries are tracked as exact BYTE offsets, not just line
13
+ * numbers (WP-81 review finding): two statements can share one physical
14
+ * line (`CREATE TABLE a (id int); CREATE TABLE b (id int);`), and a
15
+ * line-only span can't tell them apart — either the second collapses into
16
+ * an empty/inverted range (a phantom chunk carrying no content) or its
17
+ * bytes get silently absorbed into the first statement's chunk, which
18
+ * still reports zero gap (byte coverage looks complete) even though the
19
+ * second statement's identity was lost. `splitStatements` below scans the
20
+ * document's own UTF-8 bytes once, so every statement — including a second
21
+ * one sharing its predecessor's line — gets its own precise, non-empty,
22
+ * non-overlapping byte range that `ChunkDraft.startByte`/`endByte`
23
+ * (`adapters/shared.ts`) carries straight through, instead of snapping to
24
+ * whole-line boundaries.
25
+ *
26
+ * The file's LAST statement is not required to end in `;` — a schema file
27
+ * missing its final terminator (a common paste/truncation mistake) still
28
+ * gets its own chunk for that trailing statement; nothing after the last
29
+ * real `;` is ever silently dropped.
30
+ *
31
+ * WP-118: Der Zerleger kannte lange nur die verdoppelte
32
+ * Anführungszeichen-Konvention (`''`) als Escape. Ein Literal mit `\'` und
33
+ * einem `;` darin — in Dumps alltäglich — zerriss deshalb EIN Statement in
34
+ * zwei syntaktisch kaputte Fragmente, und zwar bei NULL Ledger-Warnungen:
35
+ * die Byte-Abdeckung war lückenlos, die Fragmente weder leer noch
36
+ * überlappend. Zwei Änderungen beheben das:
37
+ *
38
+ * 1. Die Escape-Behandlung ist dialektbewusst ({@link SqlDialect}), mit
39
+ * einem benannten, begründeten Standardwert ({@link DEFAULT_SQL_DIALECT})
40
+ * statt einer Vermutung über die vorliegende Datei. Zusätzlich erkennt
41
+ * der Scanner `$tag$`-Literale, in denen ein `;` genauso alltäglich ist.
42
+ * 2. Wichtiger: `sqlPlausibilityCheck` prüft JEDES fertige Fragment auf
43
+ * offene Zeichenketten, offene Kommentare und unausgeglichene Klammern.
44
+ * Damit greift E4 auch dann, wenn nichts FEHLT, sondern etwas FALSCH
45
+ * GESCHNITTEN ist — unabhängig davon, ob der Dialekt richtig gewählt
46
+ * war. Eine falsche Dialektwahl ist danach sichtbar, nicht still.
47
+ */
48
+ import type { ArtifactAdapter } from "@untangle-code/domain";
49
+ import type { SkipLedgerReporter } from "./shared.js";
50
+ /**
51
+ * Escape-Konvention für Zeichenketten-Literale. Die SQL-Dialekte
52
+ * WIDERSPRECHEN sich hier, und zwar unauflösbar:
53
+ *
54
+ * - `"doubled-quotes-only"` — Standard-SQL: das EINZIGE Escape in einem
55
+ * Literal ist das verdoppelte Anführungszeichen (`'it''s'`). Ein `\` ist
56
+ * ein ganz normales Zeichen; `'it\'` ist eine ABGESCHLOSSENE Zeichenkette
57
+ * mit einem Backslash am Ende.
58
+ * - `"backslash-escapes"` — die verbreitete Erweiterung: zusätzlich zum
59
+ * verdoppelten Anführungszeichen maskiert `\'` ein Anführungszeichen,
60
+ * `` ` `` klammert Bezeichner und `#` leitet einen Zeilenkommentar ein.
61
+ *
62
+ * Dieselbe Datei bedeutet also je nach Dialekt etwas anderes, und der
63
+ * Dialekt steht NICHT in der Datei. Deshalb wird hier nicht geraten: die
64
+ * Wahl ist eine explizite Option mit einem benannten Standardwert, und
65
+ * jedes Ergebnis, das unter der gewählten Konvention unsinnig aussieht,
66
+ * erzeugt einen sichtbaren Befund (siehe `sqlPlausibilityCheck`).
67
+ */
68
+ export type SqlDialect = "backslash-escapes" | "doubled-quotes-only";
69
+ /**
70
+ * Standardwert: `"backslash-escapes"` — bewusst NICHT der Standard-SQL-Dialekt.
71
+ *
72
+ * Begründung (asymmetrische Fehlerkosten für einen ZERLEGER, nicht für
73
+ * einen Ausführer): dieser Adapter führt kein SQL aus, er schneidet nur
74
+ * Abschnitte. Der teure Fehler ist der Schnitt MITTEN durch ein Statement,
75
+ * denn er erzeugt zwei syntaktisch kaputte Chunks, die niemand mehr als
76
+ * ein Statement erkennt (WP-118). Der billige Fehler ist der zu späte
77
+ * Schnitt: zwei Statements landen in einem Chunk, der immer noch gültiges,
78
+ * vollständiges SQL enthält.
79
+ *
80
+ * - Nimmt man `\'` als Escape und die Datei war Standard-SQL, kann nur ein
81
+ * Literal betroffen sein, das unmittelbar vor seinem Schlusszeichen auf
82
+ * `\` endet (`'C:\'`) — selten, und das Ergebnis ist eine offene
83
+ * Zeichenkette, die die Plausibilitätsprüfung meldet.
84
+ * - Nimmt man `\'` NICHT als Escape und die Datei nutzt es, zerreißt jedes
85
+ * Literal mit `\'` und einem folgenden `;` ein Statement — genau der
86
+ * gemeldete Defekt, und in Dumps alltäglich.
87
+ *
88
+ * Wer Standard-SQL indexiert und die Backtick-/`#`-Erweiterungen
89
+ * ausschließen will, setzt `dialect: "doubled-quotes-only"`.
90
+ */
91
+ export declare const DEFAULT_SQL_DIALECT: SqlDialect;
92
+ export interface SqlAdapterOptions {
93
+ /** Overrides how a real skip-ledger finding surfaces from `chunk()` (default: a stderr warning) — see `coverage.ts`'s `SkipLedgerReporter`. */
94
+ onSkipLedgerGap?: SkipLedgerReporter;
95
+ /**
96
+ * Escape-Konvention der Zeichenketten-Literale. Standard:
97
+ * {@link DEFAULT_SQL_DIALECT} (`"backslash-escapes"`) — die Begründung
98
+ * dieser Wahl steht dort. Der Dialekt wird NICHT aus dem Dateiinhalt
99
+ * erraten; er ist eine Entscheidung des Aufrufers.
100
+ */
101
+ dialect?: SqlDialect;
102
+ }
103
+ export declare function createSqlAdapter(options?: SqlAdapterOptions): ArtifactAdapter;
104
+ //# sourceMappingURL=sql.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql.d.ts","sourceRoot":"","sources":["../../src/adapters/sql.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,OAAO,KAAK,EACV,eAAe,EAKhB,MAAM,uBAAuB,CAAC;AAW/B,OAAO,KAAK,EAAsC,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAK1F;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,UAAU,GAAG,mBAAmB,GAAG,qBAAqB,CAAC;AAErE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,mBAAmB,EAAE,UAAgC,CAAC;AA2XnE,MAAM,WAAW,iBAAiB;IAChC,+IAA+I;IAC/I,eAAe,CAAC,EAAE,kBAAkB,CAAC;IACrC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,UAAU,CAAC;CACtB;AAED,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,iBAAsB,GAAG,eAAe,CAoDjF"}
@@ -0,0 +1,427 @@
1
+ import { describeDelimiterImbalances, findDelimiterImbalances } from "../text/delimiter-balance.js";
2
+ import { buildLineIndex, lineNumberForByte, sliceBytes, } from "../text/line-index.js";
3
+ import { buildChunks, buildChunksReportingSkips, buildDocuments } from "./shared.js";
4
+ const SQL_EXTENSION = /\.sql$/i;
5
+ /**
6
+ * Standardwert: `"backslash-escapes"` — bewusst NICHT der Standard-SQL-Dialekt.
7
+ *
8
+ * Begründung (asymmetrische Fehlerkosten für einen ZERLEGER, nicht für
9
+ * einen Ausführer): dieser Adapter führt kein SQL aus, er schneidet nur
10
+ * Abschnitte. Der teure Fehler ist der Schnitt MITTEN durch ein Statement,
11
+ * denn er erzeugt zwei syntaktisch kaputte Chunks, die niemand mehr als
12
+ * ein Statement erkennt (WP-118). Der billige Fehler ist der zu späte
13
+ * Schnitt: zwei Statements landen in einem Chunk, der immer noch gültiges,
14
+ * vollständiges SQL enthält.
15
+ *
16
+ * - Nimmt man `\'` als Escape und die Datei war Standard-SQL, kann nur ein
17
+ * Literal betroffen sein, das unmittelbar vor seinem Schlusszeichen auf
18
+ * `\` endet (`'C:\'`) — selten, und das Ergebnis ist eine offene
19
+ * Zeichenkette, die die Plausibilitätsprüfung meldet.
20
+ * - Nimmt man `\'` NICHT als Escape und die Datei nutzt es, zerreißt jedes
21
+ * Literal mit `\'` und einem folgenden `;` ein Statement — genau der
22
+ * gemeldete Defekt, und in Dumps alltäglich.
23
+ *
24
+ * Wer Standard-SQL indexiert und die Backtick-/`#`-Erweiterungen
25
+ * ausschließen will, setzt `dialect: "doubled-quotes-only"`.
26
+ */
27
+ export const DEFAULT_SQL_DIALECT = "backslash-escapes";
28
+ function isAsciiWhitespaceByte(byte) {
29
+ return (byte === 0x20 ||
30
+ byte === 0x09 ||
31
+ byte === 0x0a ||
32
+ byte === 0x0d ||
33
+ byte === 0x0b ||
34
+ byte === 0x0c);
35
+ }
36
+ /**
37
+ * After a statement-terminating `;` (buffer offset `semicolonEnd`, already
38
+ * past the `;` itself), decides how far the just-CLOSED statement's span
39
+ * should extend: through the rest of this physical line — its trailing
40
+ * whitespace, an optional trailing `-- ...` line comment, and the newline
41
+ * itself — when nothing else remains before that newline. This matches how
42
+ * a statement "owns" the rest of its own terminator line in the common
43
+ * case, where a schema file has exactly one statement per line (the exact
44
+ * byte a hand-formatted schema's next statement starts on is then, as
45
+ * before, the first byte of the following line).
46
+ *
47
+ * When real content follows the `;` on the SAME line instead — a second
48
+ * statement sharing that line — this returns `semicolonEnd` UNCHANGED, so
49
+ * that content starts its own span right where it begins rather than being
50
+ * silently folded into the span that just closed (the WP-81 review's
51
+ * "two statements, one line" defect: `TABLE_RE`/`VIEW_RE`/etc. would only
52
+ * ever see the FIRST statement's text, and the second statement's own span
53
+ * would either come out empty or never exist at all).
54
+ */
55
+ function extendPastTrailingLineNoise(buffer, semicolonEnd) {
56
+ let j = semicolonEnd;
57
+ for (;;) {
58
+ while (j < buffer.length && buffer[j] !== 0x0a && isAsciiWhitespaceByte(buffer[j])) {
59
+ j += 1;
60
+ }
61
+ if (j < buffer.length && buffer[j] === 0x2d && buffer[j + 1] === 0x2d) {
62
+ // "--": a trailing line comment on the terminator's own line is also
63
+ // benign noise, not a new statement — skip to (not past) its newline.
64
+ while (j < buffer.length && buffer[j] !== 0x0a) {
65
+ j += 1;
66
+ }
67
+ continue; // a comment could be followed by more whitespace before the newline
68
+ }
69
+ break;
70
+ }
71
+ if (j >= buffer.length)
72
+ return buffer.length;
73
+ if (buffer[j] === 0x0a)
74
+ return j + 1;
75
+ return semicolonEnd; // real content follows on the same line: do not extend past the `;`
76
+ }
77
+ /** Byte-Konstanten des Scanners — alles Einzelbyte-ASCII, siehe `splitStatements`. */
78
+ const BYTE_NEWLINE = 0x0a;
79
+ const BYTE_HASH = 0x23;
80
+ const BYTE_DOLLAR = 0x24;
81
+ const BYTE_SINGLE_QUOTE = 0x27;
82
+ const BYTE_DOUBLE_QUOTE = 0x22;
83
+ const BYTE_BACKTICK = 0x60;
84
+ const BYTE_BACKSLASH = 0x5c;
85
+ const BYTE_STAR = 0x2a;
86
+ const BYTE_SLASH = 0x2f;
87
+ const BYTE_DASH = 0x2d;
88
+ const BYTE_SEMICOLON = 0x3b;
89
+ const BYTE_UNDERSCORE = 0x5f;
90
+ function isDigitByte(byte) {
91
+ return byte >= 0x30 && byte <= 0x39;
92
+ }
93
+ function isLetterByte(byte) {
94
+ return (byte >= 0x41 && byte <= 0x5a) || (byte >= 0x61 && byte <= 0x7a);
95
+ }
96
+ /** Zeichen, die in einem `$tag$`-Etikett vorkommen dürfen (ohne `$` selbst). */
97
+ function isTagByte(byte) {
98
+ return (byte !== undefined && (isLetterByte(byte) || isDigitByte(byte) || byte === BYTE_UNDERSCORE));
99
+ }
100
+ /**
101
+ * Länge eines `$tag$`-Öffners an Position `i` (0, wenn dort keiner steht).
102
+ *
103
+ * Ein Dollar-Literal (`$$ … $$`, `$body$ … $body$`) ist der übliche Weg,
104
+ * einen Funktionsrumpf einzubetten — und darin steht fast immer ein `;`.
105
+ * Ohne diese Erkennung zerreißt jeder Funktionsrumpf in Fragmente, also
106
+ * exakt derselbe Defekt wie bei den Backslash-Escapes, nur mit anderem
107
+ * Auslöser. Erkannt wird das dialektübergreifend: `$tag$` hat außerhalb
108
+ * einer Zeichenkette in keinem gängigen Dialekt eine andere Bedeutung, die
109
+ * einen Statement-Zerleger interessieren müsste.
110
+ *
111
+ * Ein vorangehendes Bezeichnerzeichen verhindert die Erkennung — sonst
112
+ * würde der Bezeichner `my$col$x` fälschlich ein Literal öffnen.
113
+ */
114
+ function dollarQuoteLength(buffer, i) {
115
+ if (buffer[i] !== BYTE_DOLLAR)
116
+ return 0;
117
+ const previous = i > 0 ? buffer[i - 1] : undefined;
118
+ if (previous !== undefined && (isTagByte(previous) || previous === BYTE_DOLLAR))
119
+ return 0;
120
+ let j = i + 1;
121
+ const first = buffer[j];
122
+ if (first !== undefined && (isLetterByte(first) || first === BYTE_UNDERSCORE)) {
123
+ j += 1;
124
+ while (j < buffer.length && isTagByte(buffer[j]))
125
+ j += 1;
126
+ }
127
+ if (buffer[j] !== BYTE_DOLLAR)
128
+ return 0;
129
+ return j + 1 - i;
130
+ }
131
+ /** Ob an Position `i` genau das Etikett steht, das bei `tagStart` geöffnet wurde. */
132
+ function matchesDollarTag(buffer, i, tagStart, tagLength) {
133
+ if (i + tagLength > buffer.length)
134
+ return false;
135
+ for (let k = 0; k < tagLength; k += 1) {
136
+ if (buffer[i + k] !== buffer[tagStart + k])
137
+ return false;
138
+ }
139
+ return true;
140
+ }
141
+ /**
142
+ * Splits `index`'s underlying document into top-level statement byte spans
143
+ * (terminated by `;` outside strings/comments — see the module doc for why
144
+ * this is byte-, not line-, precise). Scans the raw UTF-8 `Buffer` directly
145
+ * (never the decoded JS string): every byte this function compares against
146
+ * (`'`, `"`, `` ` ``, `$`, `#`, `;`, `-`, `/`, `*`, `\\`, ASCII whitespace) is
147
+ * single-byte ASCII, and any UTF-8 continuation/multibyte-lead byte is
148
+ * `>= 0x80` and never matches one of those comparisons — so scanning raw
149
+ * bytes instead of UTF-16 code units never misreads a multibyte character
150
+ * (e.g. inside a comment or string) as one of these ASCII control
151
+ * characters. Das gilt auch für das Überspringen des Zeichens nach einem
152
+ * `\\`: übersprungen wird ein einzelnes Byte, und die restlichen Bytes
153
+ * eines Mehrbyte-Zeichens sind `>= 0x80` und lösen selbst nichts aus.
154
+ *
155
+ * `dialect` entscheidet über die Escape-Konvention (siehe {@link SqlDialect}).
156
+ * Falsch geschnittene Ergebnisse bleiben trotzdem möglich — deshalb prüft
157
+ * `sqlPlausibilityCheck` jedes fertige Fragment nach (WP-118, E4).
158
+ */
159
+ function splitStatements(index, dialect) {
160
+ const { buffer } = index;
161
+ const backslashEscapes = dialect === "backslash-escapes";
162
+ const backtickIdentifiers = backslashEscapes;
163
+ const hashLineComments = backslashEscapes;
164
+ const spans = [];
165
+ let statementStartByte = 0;
166
+ let statementHasContent = false;
167
+ /** Offenes Anführungszeichen (`'`, `"` oder `` ` ``), sonst `undefined`. */
168
+ let quoteByte;
169
+ /** Länge des offenen `$tag$`-Etiketts (0 = kein Dollar-Literal offen). */
170
+ let dollarTagLength = 0;
171
+ let dollarTagStart = 0;
172
+ let inLineComment = false;
173
+ let inBlockComment = false;
174
+ const flush = (endByteExclusive) => {
175
+ if (!statementHasContent)
176
+ return;
177
+ spans.push({
178
+ startByte: statementStartByte,
179
+ endByte: endByteExclusive,
180
+ startLine: lineNumberForByte(index, statementStartByte),
181
+ endLine: lineNumberForByte(index, endByteExclusive - 1),
182
+ });
183
+ };
184
+ for (let i = 0; i < buffer.length; i += 1) {
185
+ const c = buffer[i];
186
+ const next = buffer[i + 1];
187
+ if (inBlockComment) {
188
+ if (c === BYTE_STAR && next === BYTE_SLASH) {
189
+ inBlockComment = false;
190
+ i += 1;
191
+ }
192
+ continue;
193
+ }
194
+ if (inLineComment) {
195
+ if (c === BYTE_NEWLINE)
196
+ inLineComment = false;
197
+ continue;
198
+ }
199
+ if (dollarTagLength > 0) {
200
+ if (c === BYTE_DOLLAR && matchesDollarTag(buffer, i, dollarTagStart, dollarTagLength)) {
201
+ i += dollarTagLength - 1;
202
+ dollarTagLength = 0;
203
+ }
204
+ statementHasContent = true;
205
+ continue;
206
+ }
207
+ if (quoteByte !== undefined) {
208
+ // Reihenfolge: erst Backslash (verschluckt AUCH ein direkt folgendes
209
+ // Anführungszeichen), dann das verdoppelte Anführungszeichen, dann
210
+ // das schließende. Innerhalb von `` ` `` ist `\` kein Escape — dort
211
+ // ist die Verdopplung die einzige Konvention.
212
+ if (backslashEscapes && quoteByte !== BYTE_BACKTICK && c === BYTE_BACKSLASH) {
213
+ i += 1;
214
+ }
215
+ else if (c === quoteByte && next === quoteByte) {
216
+ i += 1;
217
+ }
218
+ else if (c === quoteByte) {
219
+ quoteByte = undefined;
220
+ }
221
+ statementHasContent = true;
222
+ continue;
223
+ }
224
+ if (c === BYTE_DASH && next === BYTE_DASH) {
225
+ inLineComment = true;
226
+ i += 1;
227
+ continue;
228
+ }
229
+ if (hashLineComments && c === BYTE_HASH) {
230
+ inLineComment = true;
231
+ continue;
232
+ }
233
+ if (c === BYTE_SLASH && next === BYTE_STAR) {
234
+ inBlockComment = true;
235
+ i += 1;
236
+ continue;
237
+ }
238
+ const dollarLength = dollarQuoteLength(buffer, i);
239
+ if (dollarLength > 0) {
240
+ dollarTagStart = i;
241
+ dollarTagLength = dollarLength;
242
+ i += dollarLength - 1;
243
+ statementHasContent = true;
244
+ continue;
245
+ }
246
+ if (c === BYTE_SINGLE_QUOTE ||
247
+ c === BYTE_DOUBLE_QUOTE ||
248
+ (backtickIdentifiers && c === BYTE_BACKTICK)) {
249
+ quoteByte = c;
250
+ statementHasContent = true;
251
+ continue;
252
+ }
253
+ if (c === BYTE_SEMICOLON) {
254
+ const endByteExclusive = extendPastTrailingLineNoise(buffer, i + 1);
255
+ flush(endByteExclusive);
256
+ statementStartByte = endByteExclusive;
257
+ statementHasContent = false;
258
+ i = endByteExclusive - 1;
259
+ continue;
260
+ }
261
+ if (!isAsciiWhitespaceByte(c)) {
262
+ statementHasContent = true;
263
+ }
264
+ }
265
+ // A final statement with no terminating `;` (the file's last statement
266
+ // missing its semicolon) still becomes its own span — never silently
267
+ // dropped (rule 4 / BUILD_PLAN §12 E4). Trailing whitespace-only content
268
+ // after the true last `;` reaches here with `statementHasContent` still
269
+ // `false` and correctly produces no extra span.
270
+ flush(buffer.length);
271
+ return spans;
272
+ }
273
+ /**
274
+ * Trennzeichen-Konventionen für die Plausibilitätsprüfung, abgeleitet aus
275
+ * demselben Dialekt wie die Zerlegung. Geprüft werden nur runde Klammern —
276
+ * eckige Klammern sind in manchen Dialekten Bezeichner-Klammern und in
277
+ * anderen Array-Syntax; sie zu prüfen brächte Fehlalarme statt Befunde.
278
+ */
279
+ function sqlScanOptions(dialect) {
280
+ const backslashEscapes = dialect === "backslash-escapes";
281
+ const quotes = [
282
+ { open: "'", close: "'", backslashEscapes, doubledEscapes: true, spansLines: true },
283
+ { open: '"', close: '"', backslashEscapes, doubledEscapes: true, spansLines: true },
284
+ // Backtick-Bezeichner kennt der Zerleger nur im Backslash-Dialekt, der
285
+ // Prüfer dagegen IMMER — er darf misstrauischer sein als der Zerleger
286
+ // (siehe `text/delimiter-balance.ts`). Genau so wird die falsche
287
+ // Dialektwahl sichtbar: eine Datei mit `` `a;b` `` wird unter
288
+ // `"doubled-quotes-only"` falsch geschnitten, und beide Fragmente
289
+ // melden dann einen offenen Backtick, statt still zu bleiben. In
290
+ // Standard-SQL ist ein einzelner Backtick ohnehin ungültig, ein
291
+ // Fehlalarm also nicht möglich.
292
+ { open: "`", close: "`", backslashEscapes: false, doubledEscapes: true, spansLines: true },
293
+ ];
294
+ return {
295
+ quotes,
296
+ brackets: [{ open: "(", close: ")" }],
297
+ lineComments: backslashEscapes ? ["--", "#"] : ["--"],
298
+ blockComment: { open: "/*", close: "*/" },
299
+ dollarQuotedStrings: true,
300
+ };
301
+ }
302
+ /**
303
+ * Die eigentliche Antwort auf WP-118: ein Statement-Fragment mit offener
304
+ * Zeichenkette, offenem Kommentar oder unausgeglichenen Klammern ist ein
305
+ * Befund — auch dann, wenn die Byte-Abdeckung lückenlos ist, weil nichts
306
+ * FEHLT, sondern etwas FALSCH GESCHNITTEN wurde.
307
+ */
308
+ function sqlPlausibilityCheck(dialect) {
309
+ const scanOptions = sqlScanOptions(dialect);
310
+ return (chunk) => {
311
+ const imbalances = findDelimiterImbalances(chunk.content, scanOptions);
312
+ return imbalances.length === 0 ? undefined : describeDelimiterImbalances(imbalances);
313
+ };
314
+ }
315
+ const TABLE_RE = /^\s*CREATE\s+(?:OR\s+REPLACE\s+)?(?:TEMP(?:ORARY)?\s+)?TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?["`[]?([\w.]+)["`\]]?/i;
316
+ const VIEW_RE = /^\s*CREATE\s+(?:OR\s+REPLACE\s+)?VIEW\s+(?:IF\s+NOT\s+EXISTS\s+)?["`[]?([\w.]+)["`\]]?/i;
317
+ const INDEX_RE = /^\s*CREATE\s+(?:UNIQUE\s+)?INDEX\s+(?:IF\s+NOT\s+EXISTS\s+)?["`[]?([\w.]+)["`\]]?\s+ON\s+["`[]?([\w.]+)["`\]]?/i;
318
+ const ALTER_CONSTRAINT_RE = /^\s*ALTER\s+TABLE\s+["`[]?([\w.]+)["`\]]?\s+ADD\s+CONSTRAINT\s+["`[]?([\w.]+)["`\]]?/i;
319
+ /** Strips leading whitespace and leading `--`/`/* *\/` comments so classification regexes only ever see real SQL. */
320
+ function stripLeadingComments(text) {
321
+ let remaining = text;
322
+ for (;;) {
323
+ const trimmed = remaining.replace(/^\s+/, "");
324
+ if (trimmed.startsWith("--")) {
325
+ const newlineIndex = trimmed.indexOf("\n");
326
+ remaining = newlineIndex === -1 ? "" : trimmed.slice(newlineIndex + 1);
327
+ continue;
328
+ }
329
+ if (trimmed.startsWith("/*")) {
330
+ const closeIndex = trimmed.indexOf("*/");
331
+ remaining = closeIndex === -1 ? "" : trimmed.slice(closeIndex + 2);
332
+ continue;
333
+ }
334
+ return trimmed;
335
+ }
336
+ }
337
+ function classify(rawStatementText) {
338
+ const statementText = stripLeadingComments(rawStatementText);
339
+ const table = TABLE_RE.exec(statementText);
340
+ if (table)
341
+ return { kind: "sql_table", title: table[1] };
342
+ const view = VIEW_RE.exec(statementText);
343
+ if (view)
344
+ return { kind: "sql_view", title: view[1] };
345
+ const index = INDEX_RE.exec(statementText);
346
+ if (index)
347
+ return { kind: "sql_index", title: `${index[1]} ON ${index[2]}` };
348
+ const constraint = ALTER_CONSTRAINT_RE.exec(statementText);
349
+ if (constraint)
350
+ return { kind: "sql_constraint", title: `${constraint[2]} ON ${constraint[1]}` };
351
+ const firstWord = /^\s*(\w+)/.exec(statementText)?.[1] ?? "statement";
352
+ return { kind: "sql_statement", title: firstWord.toUpperCase() };
353
+ }
354
+ function sqlDrafts(index, dialect) {
355
+ return splitStatements(index, dialect).map((span) => {
356
+ const text = sliceBytes(index, span.startByte, span.endByte);
357
+ const { kind, title } = classify(text);
358
+ return {
359
+ kind,
360
+ startLine: span.startLine,
361
+ endLine: span.endLine,
362
+ title,
363
+ startByte: span.startByte,
364
+ endByte: span.endByte,
365
+ };
366
+ });
367
+ }
368
+ /** Table name a chunk defines, when its kind is `"sql_table"` — used by `links()`. */
369
+ function tableNameOf(chunk) {
370
+ return chunk.kind === "sql_table" ? chunk.title : undefined;
371
+ }
372
+ /** `snake_case`/`kebab-case` table name → PascalCase-ish repository class name guess. */
373
+ function guessRepositoryName(tableName) {
374
+ const bareName = tableName.includes(".") ? tableName.split(".").at(-1) : tableName;
375
+ const pascal = bareName
376
+ .split(/[_-]+/)
377
+ .filter((part) => part.length > 0)
378
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
379
+ .join("");
380
+ return `${pascal}Repository`;
381
+ }
382
+ export function createSqlAdapter(options = {}) {
383
+ const dialect = options.dialect ?? DEFAULT_SQL_DIALECT;
384
+ const checkPlausibility = sqlPlausibilityCheck(dialect);
385
+ return {
386
+ supports(type, path) {
387
+ return type === "sql" || (type === "auto" && SQL_EXTENSION.test(path));
388
+ },
389
+ async read(input) {
390
+ return buildDocuments(input, "sql");
391
+ },
392
+ chunk(document) {
393
+ const index = buildLineIndex(document.content);
394
+ return buildChunksReportingSkips(document, index, sqlDrafts(index, dialect), options.onSkipLedgerGap, checkPlausibility);
395
+ },
396
+ /**
397
+ * Heuristic-only (architecture.md §20): guesses that table `orders`
398
+ * has a corresponding `OrdersRepository` code symbol, purely from a
399
+ * naming convention. `targetId` is deliberately left unset — this
400
+ * adapter has no code-symbol index to resolve against, only the
401
+ * repository-adapter graph-linking stage (a different WP) can turn
402
+ * `targetName` into a real `targetId`. Confidence is fixed and
403
+ * conservative: this guess is right often enough to be worth surfacing,
404
+ * wrong often enough that a caller MUST treat it as a hint, never a fact.
405
+ */
406
+ links(document) {
407
+ const index = buildLineIndex(document.content);
408
+ const chunks = buildChunks(document, index, sqlDrafts(index, dialect));
409
+ const links = [];
410
+ for (const chunk of chunks) {
411
+ const tableName = tableNameOf(chunk);
412
+ if (tableName === undefined)
413
+ continue;
414
+ links.push({
415
+ fromChunkId: chunk.chunkId,
416
+ targetKind: "symbol",
417
+ targetName: guessRepositoryName(tableName),
418
+ heuristic: true,
419
+ confidence: 0.4,
420
+ note: `naming-convention guess: SQL table "${tableName}" → repository symbol, not a resolved reference`,
421
+ });
422
+ }
423
+ return links;
424
+ },
425
+ };
426
+ }
427
+ //# sourceMappingURL=sql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql.js","sourceRoot":"","sources":["../../src/adapters/sql.ts"],"names":[],"mappings":"AAwDA,OAAO,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACpG,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,UAAU,GAEX,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,WAAW,EAAE,yBAAyB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAErF,MAAM,aAAa,GAAG,SAAS,CAAC;AAsBhC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAe,mBAAmB,CAAC;AASnE,SAAS,qBAAqB,CAAC,IAAY;IACzC,OAAO,CACL,IAAI,KAAK,IAAI;QACb,IAAI,KAAK,IAAI;QACb,IAAI,KAAK,IAAI;QACb,IAAI,KAAK,IAAI;QACb,IAAI,KAAK,IAAI;QACb,IAAI,KAAK,IAAI,CACd,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,SAAS,2BAA2B,CAAC,MAAc,EAAE,YAAoB;IACvE,IAAI,CAAC,GAAG,YAAY,CAAC;IACrB,SAAS,CAAC;QACR,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC;YACpF,CAAC,IAAI,CAAC,CAAC;QACT,CAAC;QACD,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACtE,qEAAqE;YACrE,sEAAsE;YACtE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;gBAC/C,CAAC,IAAI,CAAC,CAAC;YACT,CAAC;YACD,SAAS,CAAC,oEAAoE;QAChF,CAAC;QACD,MAAM;IACR,CAAC;IACD,IAAI,CAAC,IAAI,MAAM,CAAC,MAAM;QAAE,OAAO,MAAM,CAAC,MAAM,CAAC;IAC7C,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI;QAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IACrC,OAAO,YAAY,CAAC,CAAC,oEAAoE;AAC3F,CAAC;AAED,sFAAsF;AACtF,MAAM,YAAY,GAAG,IAAI,CAAC;AAC1B,MAAM,SAAS,GAAG,IAAI,CAAC;AACvB,MAAM,WAAW,GAAG,IAAI,CAAC;AACzB,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAC/B,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAC/B,MAAM,aAAa,GAAG,IAAI,CAAC;AAC3B,MAAM,cAAc,GAAG,IAAI,CAAC;AAC5B,MAAM,SAAS,GAAG,IAAI,CAAC;AACvB,MAAM,UAAU,GAAG,IAAI,CAAC;AACxB,MAAM,SAAS,GAAG,IAAI,CAAC;AACvB,MAAM,cAAc,GAAG,IAAI,CAAC;AAC5B,MAAM,eAAe,GAAG,IAAI,CAAC;AAE7B,SAAS,WAAW,CAAC,IAAY;IAC/B,OAAO,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC;AACtC,CAAC;AAED,SAAS,YAAY,CAAC,IAAY;IAChC,OAAO,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC,CAAC;AAC1E,CAAC;AAED,gFAAgF;AAChF,SAAS,SAAS,CAAC,IAAwB;IACzC,OAAO,CACL,IAAI,KAAK,SAAS,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,IAAI,KAAK,eAAe,CAAC,CAC5F,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,SAAS,iBAAiB,CAAC,MAAc,EAAE,CAAS;IAClD,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,WAAW;QAAE,OAAO,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACnD,IAAI,QAAQ,KAAK,SAAS,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,QAAQ,KAAK,WAAW,CAAC;QAAE,OAAO,CAAC,CAAC;IAC1F,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACd,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACxB,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,KAAK,KAAK,eAAe,CAAC,EAAE,CAAC;QAC9E,CAAC,IAAI,CAAC,CAAC;QACP,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAAE,CAAC,IAAI,CAAC,CAAC;IAC3D,CAAC;IACD,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,WAAW;QAAE,OAAO,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACnB,CAAC;AAED,qFAAqF;AACrF,SAAS,gBAAgB,CAAC,MAAc,EAAE,CAAS,EAAE,QAAgB,EAAE,SAAiB;IACtF,IAAI,CAAC,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAChD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;IAC3D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,SAAS,eAAe,CAAC,KAAgB,EAAE,OAAmB;IAC5D,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IACzB,MAAM,gBAAgB,GAAG,OAAO,KAAK,mBAAmB,CAAC;IACzD,MAAM,mBAAmB,GAAG,gBAAgB,CAAC;IAC7C,MAAM,gBAAgB,GAAG,gBAAgB,CAAC;IAE1C,MAAM,KAAK,GAAoB,EAAE,CAAC;IAClC,IAAI,kBAAkB,GAAG,CAAC,CAAC;IAC3B,IAAI,mBAAmB,GAAG,KAAK,CAAC;IAChC,4EAA4E;IAC5E,IAAI,SAA6B,CAAC;IAClC,0EAA0E;IAC1E,IAAI,eAAe,GAAG,CAAC,CAAC;IACxB,IAAI,cAAc,GAAG,CAAC,CAAC;IACvB,IAAI,aAAa,GAAG,KAAK,CAAC;IAC1B,IAAI,cAAc,GAAG,KAAK,CAAC;IAE3B,MAAM,KAAK,GAAG,CAAC,gBAAwB,EAAQ,EAAE;QAC/C,IAAI,CAAC,mBAAmB;YAAE,OAAO;QACjC,KAAK,CAAC,IAAI,CAAC;YACT,SAAS,EAAE,kBAAkB;YAC7B,OAAO,EAAE,gBAAgB;YACzB,SAAS,EAAE,iBAAiB,CAAC,KAAK,EAAE,kBAAkB,CAAC;YACvD,OAAO,EAAE,iBAAiB,CAAC,KAAK,EAAE,gBAAgB,GAAG,CAAC,CAAC;SACxD,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1C,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAE,CAAC;QACrB,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAE3B,IAAI,cAAc,EAAE,CAAC;YACnB,IAAI,CAAC,KAAK,SAAS,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;gBAC3C,cAAc,GAAG,KAAK,CAAC;gBACvB,CAAC,IAAI,CAAC,CAAC;YACT,CAAC;YACD,SAAS;QACX,CAAC;QACD,IAAI,aAAa,EAAE,CAAC;YAClB,IAAI,CAAC,KAAK,YAAY;gBAAE,aAAa,GAAG,KAAK,CAAC;YAC9C,SAAS;QACX,CAAC;QACD,IAAI,eAAe,GAAG,CAAC,EAAE,CAAC;YACxB,IAAI,CAAC,KAAK,WAAW,IAAI,gBAAgB,CAAC,MAAM,EAAE,CAAC,EAAE,cAAc,EAAE,eAAe,CAAC,EAAE,CAAC;gBACtF,CAAC,IAAI,eAAe,GAAG,CAAC,CAAC;gBACzB,eAAe,GAAG,CAAC,CAAC;YACtB,CAAC;YACD,mBAAmB,GAAG,IAAI,CAAC;YAC3B,SAAS;QACX,CAAC;QACD,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,qEAAqE;YACrE,mEAAmE;YACnE,oEAAoE;YACpE,8CAA8C;YAC9C,IAAI,gBAAgB,IAAI,SAAS,KAAK,aAAa,IAAI,CAAC,KAAK,cAAc,EAAE,CAAC;gBAC5E,CAAC,IAAI,CAAC,CAAC;YACT,CAAC;iBAAM,IAAI,CAAC,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACjD,CAAC,IAAI,CAAC,CAAC;YACT,CAAC;iBAAM,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;gBAC3B,SAAS,GAAG,SAAS,CAAC;YACxB,CAAC;YACD,mBAAmB,GAAG,IAAI,CAAC;YAC3B,SAAS;QACX,CAAC;QACD,IAAI,CAAC,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YAC1C,aAAa,GAAG,IAAI,CAAC;YACrB,CAAC,IAAI,CAAC,CAAC;YACP,SAAS;QACX,CAAC;QACD,IAAI,gBAAgB,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;YACxC,aAAa,GAAG,IAAI,CAAC;YACrB,SAAS;QACX,CAAC;QACD,IAAI,CAAC,KAAK,UAAU,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YAC3C,cAAc,GAAG,IAAI,CAAC;YACtB,CAAC,IAAI,CAAC,CAAC;YACP,SAAS;QACX,CAAC;QACD,MAAM,YAAY,GAAG,iBAAiB,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAClD,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;YACrB,cAAc,GAAG,CAAC,CAAC;YACnB,eAAe,GAAG,YAAY,CAAC;YAC/B,CAAC,IAAI,YAAY,GAAG,CAAC,CAAC;YACtB,mBAAmB,GAAG,IAAI,CAAC;YAC3B,SAAS;QACX,CAAC;QACD,IACE,CAAC,KAAK,iBAAiB;YACvB,CAAC,KAAK,iBAAiB;YACvB,CAAC,mBAAmB,IAAI,CAAC,KAAK,aAAa,CAAC,EAC5C,CAAC;YACD,SAAS,GAAG,CAAC,CAAC;YACd,mBAAmB,GAAG,IAAI,CAAC;YAC3B,SAAS;QACX,CAAC;QACD,IAAI,CAAC,KAAK,cAAc,EAAE,CAAC;YACzB,MAAM,gBAAgB,GAAG,2BAA2B,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;YACpE,KAAK,CAAC,gBAAgB,CAAC,CAAC;YACxB,kBAAkB,GAAG,gBAAgB,CAAC;YACtC,mBAAmB,GAAG,KAAK,CAAC;YAC5B,CAAC,GAAG,gBAAgB,GAAG,CAAC,CAAC;YACzB,SAAS;QACX,CAAC;QACD,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9B,mBAAmB,GAAG,IAAI,CAAC;QAC7B,CAAC;IACH,CAAC;IACD,uEAAuE;IACvE,qEAAqE;IACrE,yEAAyE;IACzE,wEAAwE;IACxE,gDAAgD;IAChD,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACrB,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,SAAS,cAAc,CAAC,OAAmB;IACzC,MAAM,gBAAgB,GAAG,OAAO,KAAK,mBAAmB,CAAC;IACzD,MAAM,MAAM,GAAgB;QAC1B,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,gBAAgB,EAAE,cAAc,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE;QACnF,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,gBAAgB,EAAE,cAAc,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE;QACnF,uEAAuE;QACvE,sEAAsE;QACtE,iEAAiE;QACjE,8DAA8D;QAC9D,kEAAkE;QAClE,iEAAiE;QACjE,gEAAgE;QAChE,gCAAgC;QAChC,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,gBAAgB,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE;KAC3F,CAAC;IACF,OAAO;QACL,MAAM;QACN,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;QACrC,YAAY,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACrD,YAAY,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;QACzC,mBAAmB,EAAE,IAAI;KAC1B,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAS,oBAAoB,CAAC,OAAmB;IAC/C,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IAC5C,OAAO,CAAC,KAAK,EAAE,EAAE;QACf,MAAM,UAAU,GAAG,uBAAuB,CAAC,KAAK,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QACvE,OAAO,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,2BAA2B,CAAC,UAAU,CAAC,CAAC;IACvF,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,QAAQ,GACZ,gHAAgH,CAAC;AACnH,MAAM,OAAO,GACX,yFAAyF,CAAC;AAC5F,MAAM,QAAQ,GACZ,iHAAiH,CAAC;AACpH,MAAM,mBAAmB,GACvB,uFAAuF,CAAC;AAE1F,qHAAqH;AACrH,SAAS,oBAAoB,CAAC,IAAY;IACxC,IAAI,SAAS,GAAG,IAAI,CAAC;IACrB,SAAS,CAAC;QACR,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC9C,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC3C,SAAS,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC;YACvE,SAAS;QACX,CAAC;QACD,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACzC,SAAS,GAAG,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;YACnE,SAAS;QACX,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,gBAAwB;IACxC,MAAM,aAAa,GAAG,oBAAoB,CAAC,gBAAgB,CAAC,CAAC;IAC7D,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC3C,IAAI,KAAK;QAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAE,EAAE,CAAC;IAC1D,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACzC,IAAI,IAAI;QAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAE,EAAE,CAAC;IACvD,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC3C,IAAI,KAAK;QAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC,CAAC,CAAE,OAAO,KAAK,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC;IAC/E,MAAM,UAAU,GAAG,mBAAmB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC3D,IAAI,UAAU;QACZ,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC,CAAC,CAAE,OAAO,UAAU,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC;IACrF,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC;IACtE,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,SAAS,CAAC,WAAW,EAAE,EAAE,CAAC;AACnE,CAAC;AAED,SAAS,SAAS,CAAC,KAAgB,EAAE,OAAmB;IACtD,OAAO,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QAClD,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7D,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QACvC,OAAO;YACL,IAAI;YACJ,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,KAAK;YACL,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,sFAAsF;AACtF,SAAS,WAAW,CAAC,KAAoB;IACvC,OAAO,KAAK,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AAC9D,CAAC;AAED,yFAAyF;AACzF,SAAS,mBAAmB,CAAC,SAAiB;IAC5C,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACpF,MAAM,MAAM,GAAG,QAAQ;SACpB,KAAK,CAAC,OAAO,CAAC;SACd,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;SACjC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SAC3D,IAAI,CAAC,EAAE,CAAC,CAAC;IACZ,OAAO,GAAG,MAAM,YAAY,CAAC;AAC/B,CAAC;AAcD,MAAM,UAAU,gBAAgB,CAAC,UAA6B,EAAE;IAC9D,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,mBAAmB,CAAC;IACvD,MAAM,iBAAiB,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;IACxD,OAAO;QACL,QAAQ,CAAC,IAAY,EAAE,IAAY;YACjC,OAAO,IAAI,KAAK,KAAK,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACzE,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,KAAoB;YAC7B,OAAO,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACtC,CAAC;QAED,KAAK,CAAC,QAA0B;YAC9B,MAAM,KAAK,GAAG,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC/C,OAAO,yBAAyB,CAC9B,QAAQ,EACR,KAAK,EACL,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,EACzB,OAAO,CAAC,eAAe,EACvB,iBAAiB,CAClB,CAAC;QACJ,CAAC;QAED;;;;;;;;;WASG;QACH,KAAK,CAAC,QAA0B;YAC9B,MAAM,KAAK,GAAG,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC/C,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;YACvE,MAAM,KAAK,GAAmB,EAAE,CAAC;YACjC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;gBACrC,IAAI,SAAS,KAAK,SAAS;oBAAE,SAAS;gBACtC,KAAK,CAAC,IAAI,CAAC;oBACT,WAAW,EAAE,KAAK,CAAC,OAAO;oBAC1B,UAAU,EAAE,QAAQ;oBACpB,UAAU,EAAE,mBAAmB,CAAC,SAAS,CAAC;oBAC1C,SAAS,EAAE,IAAI;oBACf,UAAU,EAAE,GAAG;oBACf,IAAI,EAAE,uCAAuC,SAAS,iDAAiD;iBACxG,CAAC,CAAC;YACL,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;KACF,CAAC;AACJ,CAAC"}