@clossys/writer 0.3.2

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 (115) hide show
  1. package/CHANGELOG.md +196 -0
  2. package/LICENSE +21 -0
  3. package/README.md +593 -0
  4. package/dist/addressability.d.ts +245 -0
  5. package/dist/addressability.d.ts.map +1 -0
  6. package/dist/addressability.js +567 -0
  7. package/dist/addressability.js.map +1 -0
  8. package/dist/checker.d.ts +159 -0
  9. package/dist/checker.d.ts.map +1 -0
  10. package/dist/checker.js +177 -0
  11. package/dist/checker.js.map +1 -0
  12. package/dist/cli.d.ts +149 -0
  13. package/dist/cli.d.ts.map +1 -0
  14. package/dist/cli.js +1049 -0
  15. package/dist/cli.js.map +1 -0
  16. package/dist/copy-gate.d.ts +107 -0
  17. package/dist/copy-gate.d.ts.map +1 -0
  18. package/dist/copy-gate.js +132 -0
  19. package/dist/copy-gate.js.map +1 -0
  20. package/dist/fingerprint.d.ts +61 -0
  21. package/dist/fingerprint.d.ts.map +1 -0
  22. package/dist/fingerprint.js +64 -0
  23. package/dist/fingerprint.js.map +1 -0
  24. package/dist/index.d.ts +47 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +63 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/locale-coverage.d.ts +227 -0
  29. package/dist/locale-coverage.d.ts.map +1 -0
  30. package/dist/locale-coverage.js +414 -0
  31. package/dist/locale-coverage.js.map +1 -0
  32. package/dist/passage.d.ts +294 -0
  33. package/dist/passage.d.ts.map +1 -0
  34. package/dist/passage.js +463 -0
  35. package/dist/passage.js.map +1 -0
  36. package/dist/path-exclusions.d.ts +114 -0
  37. package/dist/path-exclusions.d.ts.map +1 -0
  38. package/dist/path-exclusions.js +213 -0
  39. package/dist/path-exclusions.js.map +1 -0
  40. package/dist/registry.d.ts +61 -0
  41. package/dist/registry.d.ts.map +1 -0
  42. package/dist/registry.js +64 -0
  43. package/dist/registry.js.map +1 -0
  44. package/dist/resolve.d.ts +33 -0
  45. package/dist/resolve.d.ts.map +1 -0
  46. package/dist/resolve.js +133 -0
  47. package/dist/resolve.js.map +1 -0
  48. package/dist/scan.d.ts +457 -0
  49. package/dist/scan.d.ts.map +1 -0
  50. package/dist/scan.js +1698 -0
  51. package/dist/scan.js.map +1 -0
  52. package/dist/schema.d.ts +81 -0
  53. package/dist/schema.d.ts.map +1 -0
  54. package/dist/schema.js +482 -0
  55. package/dist/schema.js.map +1 -0
  56. package/dist/types.d.ts +268 -0
  57. package/dist/types.d.ts.map +1 -0
  58. package/dist/types.js +40 -0
  59. package/dist/types.js.map +1 -0
  60. package/dist/voice/checker.d.ts +186 -0
  61. package/dist/voice/checker.d.ts.map +1 -0
  62. package/dist/voice/checker.js +483 -0
  63. package/dist/voice/checker.js.map +1 -0
  64. package/dist/voice/derivation-coverage.d.ts +168 -0
  65. package/dist/voice/derivation-coverage.d.ts.map +1 -0
  66. package/dist/voice/derivation-coverage.js +181 -0
  67. package/dist/voice/derivation-coverage.js.map +1 -0
  68. package/dist/voice/fields.d.ts +107 -0
  69. package/dist/voice/fields.d.ts.map +1 -0
  70. package/dist/voice/fields.js +144 -0
  71. package/dist/voice/fields.js.map +1 -0
  72. package/dist/voice/index.d.ts +19 -0
  73. package/dist/voice/index.d.ts.map +1 -0
  74. package/dist/voice/index.js +24 -0
  75. package/dist/voice/index.js.map +1 -0
  76. package/dist/voice/internal/parse-template.d.ts +27 -0
  77. package/dist/voice/internal/parse-template.d.ts.map +1 -0
  78. package/dist/voice/internal/parse-template.js +111 -0
  79. package/dist/voice/internal/parse-template.js.map +1 -0
  80. package/dist/voice/internal/pattern-safety.d.ts +111 -0
  81. package/dist/voice/internal/pattern-safety.d.ts.map +1 -0
  82. package/dist/voice/internal/pattern-safety.js +278 -0
  83. package/dist/voice/internal/pattern-safety.js.map +1 -0
  84. package/dist/voice/schema.d.ts +65 -0
  85. package/dist/voice/schema.d.ts.map +1 -0
  86. package/dist/voice/schema.js +535 -0
  87. package/dist/voice/schema.js.map +1 -0
  88. package/dist/voice/types.d.ts +282 -0
  89. package/dist/voice/types.d.ts.map +1 -0
  90. package/dist/voice/types.js +37 -0
  91. package/dist/voice/types.js.map +1 -0
  92. package/package.json +72 -0
  93. package/src/addressability.ts +664 -0
  94. package/src/checker.ts +293 -0
  95. package/src/cli.ts +1166 -0
  96. package/src/copy-gate.ts +197 -0
  97. package/src/fingerprint.ts +66 -0
  98. package/src/index.ts +163 -0
  99. package/src/locale-coverage.ts +512 -0
  100. package/src/passage.ts +644 -0
  101. package/src/path-exclusions.ts +265 -0
  102. package/src/registry.ts +103 -0
  103. package/src/resolve.ts +172 -0
  104. package/src/scan.ts +1959 -0
  105. package/src/schema.ts +528 -0
  106. package/src/types.ts +301 -0
  107. package/src/voice/checker.ts +590 -0
  108. package/src/voice/derivation-coverage.ts +217 -0
  109. package/src/voice/fields.ts +160 -0
  110. package/src/voice/index.ts +55 -0
  111. package/src/voice/internal/parse-template.ts +114 -0
  112. package/src/voice/internal/pattern-safety.ts +336 -0
  113. package/src/voice/schema.ts +585 -0
  114. package/src/voice/types.ts +329 -0
  115. package/templates/voice-record.template.jsonc +135 -0
@@ -0,0 +1,245 @@
1
+ /**
2
+ * `scanAddressabilitySources` and `checkAddressability` — the
3
+ * copy-ADDRESSABILITY gate: is user-facing prose resolved from a copy
4
+ * registry BY ID, or typed directly into a component? A DIFFERENT, STRICTER
5
+ * question than `copy-gate.ts`'s traceability check. Traceability accepts a
6
+ * literal that happens to match a registered `CopyEntry.text`'s SHAPE, or
7
+ * that carries a `copy:<id>` citation comment — both of which still leave
8
+ * the actual sentence sitting in the component's own source. That is cheap
9
+ * to verify but NOT cheap to change: marketing renaming a CTA means editing
10
+ * every component that typed it, not one registry entry. Addressability is
11
+ * the property that keeps that rename cheap: the component's own source
12
+ * contains an id, never the sentence. This file does not accept a citation
13
+ * or a text-shape match as satisfying — see `extractAddressabilityCandidates`
14
+ * below, which has no `CopyRecord` input at all and therefore nothing to
15
+ * match against; a literal is either not present as authored prose in a
16
+ * position this gate can see, or it is a violation.
17
+ *
18
+ * Measured across four real sites at the time this gate was written: 2
19
+ * inline prose strings on one, 4 attribute-borne on another, 0 elsewhere —
20
+ * so the property currently holds, by luck rather than enforcement. This
21
+ * file is what turns that measurement into something that stays true.
22
+ *
23
+ * NO PARSER LIBRARY, no new dependency — `packages/copy` ships zero runtime
24
+ * dependencies and this file adds none. It reuses `scan.ts`'s
25
+ * `extractCopyCandidates` for the genuinely hard part (finding every
26
+ * string/template literal and JSX text-node BOUNDARY correctly — escaped
27
+ * quotes, nested interpolation, comments, regex literals, and JSX itself),
28
+ * and `path-exclusions.ts`'s `validatePathExclusions`/`matchesPathExclusion`
29
+ * for the file-scope exclusion mechanism, exactly the way `scan.ts` itself
30
+ * does. This file's own walker (`scanAddressabilitySources`) mirrors
31
+ * `scan.ts`'s `scanCopySourceTree` and `@example/ui`'s
32
+ * `style-scan.ts`'s `scanStyleSources` closely (same extensions/skipDirs
33
+ * defaults, same `SKIP_FILE_RE`, same fail-closed-on-unreadable-directory
34
+ * contract) — a thin per-file dispatch loop, not a second tokenizer: the
35
+ * actual literal/JSX-boundary parsing is ENTIRELY delegated to `scan.ts`.
36
+ *
37
+ * ============================================================================
38
+ * THREE POSITIONS, THREE CLASSIFICATIONS
39
+ * ============================================================================
40
+ *
41
+ * 1. MARKUP TEXT NODES (`<span>Hello</span>`'s `Hello`) — `scan.ts`'s own
42
+ * `kind: "jsx-text"` candidates. `scan.ts` already dropped
43
+ * whitespace-only and no-letters runs before these ever reach this
44
+ * file, so every one remaining is real, rendered prose authored
45
+ * directly in markup — never resolved through an id, by construction
46
+ * (a JSX text node IS the literal text; an id-resolved child would be
47
+ * an EXPRESSION child, `{copy(id)}`, which `scan.ts`'s tokenizer treats
48
+ * as code, never a text-node candidate at all — see `scan.ts`'s own
49
+ * top doc comment, "JSX TEXT NODES"). ALWAYS a violation.
50
+ *
51
+ * 2. THE FOUR USER-FACING ATTRIBUTES — `aria-label`, `placeholder`, `alt`,
52
+ * `title`. These carry prose a person reads (an accessible name, a
53
+ * hint, alt text, a tooltip) and are NOT text nodes; a scanner that
54
+ * only understands text nodes reports zero on a real component whose
55
+ * ENTIRE user-facing surface is `<input aria-label="..." placeholder=
56
+ * "..." />` and calls that a clean pass. `scan.ts` itself already
57
+ * excludes `aria-label` from its own candidate list (bundled under
58
+ * `"aria-or-data-attribute-value"` together with `aria-hidden`,
59
+ * `aria-describedby`, every `data-*` attribute — a deliberate SCOPE
60
+ * decision for traceability, see `scan.ts`'s exclusion #4) and leaves
61
+ * `placeholder`/`alt`/`title` as ordinary default-included candidates
62
+ * (neither aria/data-shaped nor on its structural denylist). This gate
63
+ * re-derives each literal's own attribute NAME locally — a string
64
+ * literal never spans a line (see `scan.ts`'s `scanStringLiteral`), so
65
+ * "the identifier immediately before this literal's own quote, on the
66
+ * SAME line" is an exact lookup, not an approximation — specifically to
67
+ * recover `aria-label` back into scope while leaving every OTHER
68
+ * aria-*, data-* attribute exactly where `scan.ts` already decided it
69
+ * belongs: out of copy governance entirely. A literal-valued occurrence
70
+ * of one of the four, carrying at least one letter, is ALWAYS a
71
+ * violation — there is no citation or registry-text-match escape hatch
72
+ * here (see this file's top comment for why) — UNLESS the assignment
73
+ * this gate re-derived is itself a DESTRUCTURING-PATTERN DEFAULT or a
74
+ * plain (non-destructured) PARAMETER DEFAULT (`{ "aria-label":
75
+ * ariaLabel = "Pagination" }`, `{ placeholder = "Search" }`,
76
+ * `function f(alt = "...")`), never a JSX attribute at all — see
77
+ * `isDestructuringOrParameterDefault`. A default value in a
78
+ * destructuring pattern is exactly the property this gate exists to
79
+ * protect: the CONSUMER can override it, so the component's own source
80
+ * does not lock the sentence in the way a hardcoded JSX attribute
81
+ * does. Reporting one as a violation would not just be a false
82
+ * positive — it would INVERT the verdict on a construct that is
83
+ * already correctly addressable.
84
+ *
85
+ * 3. EVERYTHING ELSE THIS GATE CANNOT CONFIDENTLY CLASSIFY — a template
86
+ * literal (in ANY position, including one of the four attributes above:
87
+ * a template can carry an interpolated copy id, a partial sentence, or
88
+ * genuine inline prose, and this gate does not attempt to tell those
89
+ * apart), an object/array literal VALUE (`scan.ts` only excludes object
90
+ * KEYS, never values — `{ tooltip: "Explain this" }`'s `"Explain
91
+ * this"` is a default-included candidate with no attribute name at
92
+ * all), or a plain string in a prop that is none of the four (a custom
93
+ * `tooltip`, a bare variable assignment, ...) — UNLESS that string is
94
+ * itself shaped like a CSS/Tailwind utility class LIST (`"border-t
95
+ * border-line-base pt-xs"`, `"grid-cols-1 tablet:grid-cols-2"`), which
96
+ * is definitively not prose and is excluded here for the same reason
97
+ * `scan.ts` already excludes that shape when it DOES have an attribute
98
+ * name to key off (a literal `className="..."` value) — see
99
+ * `looksLikeUtilityClassList`. Everything else in this category is
100
+ * NEVER silently treated as clean, and NEVER treated as a violation
101
+ * either — reported as `unchecked`, the same discipline `scan.ts`'s own
102
+ * `UncheckedItem` and `checkCopyTraceability`'s `unchecked` passthrough
103
+ * already hold JSX parse ambiguities to. A measurement may round an
104
+ * unknown down to "probably fine"; a gate may not — that is the whole
105
+ * reason this file exists rather than a grep for `aria-label="`.
106
+ *
107
+ * `scan.ts`'s own exclusions for genuinely non-user-facing literals
108
+ * (`className`, `data-testid`, an import specifier, a `cx(...)` argument, a
109
+ * developer diagnostic, a decorative no-letters glyph, an enum-shaped
110
+ * single token, a `type`/`interface` context) apply here for free: a
111
+ * literal `scan.ts` excludes for one of THOSE reasons never becomes a
112
+ * `candidates` entry at all, so it never reaches this file's own
113
+ * classification and is never reported by it, in any of the three
114
+ * categories above. This is what keeps this gate from flagging `className`,
115
+ * `data-*`, an import specifier, or a `testId` — see this file's own test
116
+ * suite for a fixture proving exactly that.
117
+ *
118
+ * ============================================================================
119
+ * THE TERNARY
120
+ * ============================================================================
121
+ *
122
+ * Deliberately DIFFERENT from `copy-gate.ts`/`scan.ts`'s "an `unchecked[]`
123
+ * list gates a `2` before findings are counted" precedence — see issue #407.
124
+ * On this gate specifically, partial coverage of a real tree is not a rare
125
+ * edge case: hundreds of string positions are token data (category 3 above)
126
+ * this gate cannot classify BY DESIGN, on every real tree it has ever been
127
+ * run against. Letting "at least one unclassified position" outrank a
128
+ * confirmed violation therefore does not model "an occasional coverage gap
129
+ * might be hiding something" — it makes the `"violated"` branch permanently
130
+ * unreachable outside a fixture, because a real tree always has unclassified
131
+ * positions somewhere. A gate that can only ever report `"indeterminate"` or
132
+ * `"satisfied"` in production has one usable state, and a caller that
133
+ * learns to treat `2` as "coverage is never complete, ignore it" will walk
134
+ * straight past five named, file-and-line violations without ever seeing
135
+ * them — see `packages/inspector/src/review-evidence.ts`'s own argument
136
+ * against the mirror image of this mistake (folding an outage into a
137
+ * verdict); this is folding a verdict into an outage.
138
+ *
139
+ * - `"violated"` — at least one inline user-facing prose string found
140
+ * (category 1 or 2 above), REGARDLESS of how many string positions are
141
+ * unclassified. The coverage gap is not hidden: `reasons` and
142
+ * `unchecked` are still populated and still printed (`cli.ts`'s
143
+ * `printAddressabilityAccounting` reports `unchecked` unconditionally,
144
+ * independent of verdict) — a `"violated"` verdict never claims full
145
+ * coverage, it claims that what WAS seen included a definite violation,
146
+ * which is true regardless of what else was not seen.
147
+ * - `"indeterminate"` — zero violations, AND the source tree could not be
148
+ * read at all (this file's `scanAddressabilitySources` fails closed,
149
+ * throwing, exactly like `scan.ts`'s `scanCopySourceTree`), ZERO
150
+ * components were successfully scanned (nothing matched, or every
151
+ * matched file failed to parse), a `pathExclusions` entry was
152
+ * malformed, or ANY string position could not be confidently classified
153
+ * (category 3 above, or a JSX construct `scan.ts` itself could not
154
+ * resolve). The honest "found nothing, but did not see everything"
155
+ * case — it must never read as a pass.
156
+ * - `"satisfied"` — at least one component scanned, every string
157
+ * position classified, and no inline user-facing prose found.
158
+ */
159
+ import type { ParseFailure, SkippedFile } from "./scan.js";
160
+ import { type ExcludedPath, type PathExclusion, type PathExclusionFinding } from "./path-exclusions.js";
161
+ export type { ParseFailure, SkippedFile } from "./scan.js";
162
+ export type { ExcludedPath, PathExclusion, PathExclusionFinding } from "./path-exclusions.js";
163
+ export interface AddressabilityScanOptions {
164
+ /** File extensions to read, each including the leading dot. Default: `.ts`, `.tsx`, `.js`, `.jsx`. */
165
+ extensions?: string[];
166
+ /** Directory names never descended into. Default: node_modules, .git, dist, build, coverage. */
167
+ skipDirs?: string[];
168
+ /** Same mechanism `scan.ts`'s `ScanOptions.pathExclusions` uses — see `path-exclusions.ts`. */
169
+ pathExclusions?: PathExclusion[];
170
+ }
171
+ export type AddressabilityPosition = "markup-text" | "user-facing-attribute";
172
+ export interface AddressabilityViolation {
173
+ file: string;
174
+ line: number;
175
+ position: AddressabilityPosition;
176
+ /** Set only for `"user-facing-attribute"` — which of the four this literal was the value of. */
177
+ attribute?: "aria-label" | "placeholder" | "alt" | "title";
178
+ /** The literal's own raw source text, for a human auditing the finding. */
179
+ raw: string;
180
+ }
181
+ export interface AddressabilityUncheckedItem {
182
+ file: string;
183
+ line: number;
184
+ /** A short, stable machine-readable name — see this file's top doc comment, category 3, and `extractAddressabilityCandidates`'s own inline comments for every kind this can be. */
185
+ kind: string;
186
+ detail: string;
187
+ }
188
+ export interface AddressabilityScanResult {
189
+ /** Files whose content was successfully tokenized. Required to be > 0 for a satisfied verdict — see this file's top doc comment, "THE TERNARY". */
190
+ filesScanned: number;
191
+ violations: AddressabilityViolation[];
192
+ /** Every string position this gate could not confidently classify — never silently dropped. See this file's top doc comment, category 3. */
193
+ unchecked: AddressabilityUncheckedItem[];
194
+ skippedByDesign: SkippedFile[];
195
+ parseFailures: ParseFailure[];
196
+ excludedFiles: ExcludedPath[];
197
+ pathExclusionFindings: PathExclusionFinding[];
198
+ }
199
+ /**
200
+ * Walks `root` recursively, reads every matching file, and extracts
201
+ * addressability violations/unchecked positions from each (see
202
+ * `extractAddressabilityCandidates`). FAILS CLOSED on an unreadable
203
+ * directory or file — throws a plain `Error`, matching `scan.ts`'s
204
+ * `scanCopySourceTree` exactly, for the identical reason: a directory this
205
+ * function could not read might be hiding an unknown amount of inline
206
+ * prose, and reporting "0 files scanned" for that case would read as a
207
+ * clean pass when nothing was actually verified.
208
+ */
209
+ export declare function scanAddressabilitySources(root: string, options?: AddressabilityScanOptions): AddressabilityScanResult;
210
+ interface AddressabilityExtractResult {
211
+ violations: AddressabilityViolation[];
212
+ unchecked: AddressabilityUncheckedItem[];
213
+ parseFailure?: string;
214
+ }
215
+ /**
216
+ * Pure — no I/O. Classifies every string/template literal and JSX text
217
+ * node `scan.ts`'s `extractCopyCandidates` finds in `content` into one of
218
+ * this file's three positions (see top doc comment). Exported so a test
219
+ * can exercise classification directly against a source-text fixture,
220
+ * mirroring `extractCopyCandidates` itself.
221
+ */
222
+ export declare function extractAddressabilityCandidates(content: string, filePath: string): AddressabilityExtractResult;
223
+ export type AddressabilityVerdict = "satisfied" | "violated" | "indeterminate";
224
+ export interface AddressabilityGateResult {
225
+ verdict: AddressabilityVerdict;
226
+ violations: AddressabilityViolation[];
227
+ unchecked: AddressabilityUncheckedItem[];
228
+ filesScanned: number;
229
+ /**
230
+ * Human-readable reasons coverage is incomplete — empty for `"satisfied"`.
231
+ * Since #407, this can be non-empty for `"violated"` too: a run can find a
232
+ * definite violation AND have unclassified positions left over in the
233
+ * same scan. Only `"indeterminate"` requires `reasons.length > 0`; a
234
+ * `"violated"` verdict does not promise `reasons` is empty, only that at
235
+ * least one real finding exists regardless of what else `reasons` lists.
236
+ */
237
+ reasons: string[];
238
+ }
239
+ /**
240
+ * Pure — takes an already-computed `AddressabilityScanResult`, decides the
241
+ * ternary verdict. Mirrors `copy-gate.ts`'s `checkCopyTraceability` split
242
+ * from `scan.ts`: this function does no I/O and never throws.
243
+ */
244
+ export declare function checkAddressability(scan: AddressabilityScanResult): AddressabilityGateResult;
245
+ //# sourceMappingURL=addressability.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addressability.d.ts","sourceRoot":"","sources":["../src/addressability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6JG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,oBAAoB,EAE1B,MAAM,sBAAsB,CAAC;AAE9B,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC3D,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAI9F,MAAM,WAAW,yBAAyB;IACxC,sGAAsG;IACtG,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,gGAAgG;IAChG,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,+FAA+F;IAC/F,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;CAClC;AAQD,MAAM,MAAM,sBAAsB,GAAG,aAAa,GAAG,uBAAuB,CAAC;AAE7E,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,sBAAsB,CAAC;IACjC,gGAAgG;IAChG,SAAS,CAAC,EAAE,YAAY,GAAG,aAAa,GAAG,KAAK,GAAG,OAAO,CAAC;IAC3D,2EAA2E;IAC3E,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,2BAA2B;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,mLAAmL;IACnL,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,wBAAwB;IACvC,mJAAmJ;IACnJ,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,uBAAuB,EAAE,CAAC;IACtC,4IAA4I;IAC5I,SAAS,EAAE,2BAA2B,EAAE,CAAC;IACzC,eAAe,EAAE,WAAW,EAAE,CAAC;IAC/B,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,qBAAqB,EAAE,oBAAoB,EAAE,CAAC;CAC/C;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,yBAA8B,GAAG,wBAAwB,CAgGzH;AA+ID,UAAU,2BAA2B;IACnC,UAAU,EAAE,uBAAuB,EAAE,CAAC;IACtC,SAAS,EAAE,2BAA2B,EAAE,CAAC;IACzC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,2BAA2B,CA+G9G;AAID,MAAM,MAAM,qBAAqB,GAAG,WAAW,GAAG,UAAU,GAAG,eAAe,CAAC;AAE/E,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,qBAAqB,CAAC;IAC/B,UAAU,EAAE,uBAAuB,EAAE,CAAC;IACtC,SAAS,EAAE,2BAA2B,EAAE,CAAC;IACzC,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,wBAAwB,GAAG,wBAAwB,CAuC5F"}