@setsquare/review-sdk 0.0.1

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 (181) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +57 -0
  3. package/README.md +338 -0
  4. package/THIRD-PARTY-NOTICES.md +61 -0
  5. package/dist/autoscan.d.ts +25 -0
  6. package/dist/autoscan.d.ts.map +1 -0
  7. package/dist/autoscan.js +332 -0
  8. package/dist/autoscan.js.map +1 -0
  9. package/dist/axe.d.ts +96 -0
  10. package/dist/axe.d.ts.map +1 -0
  11. package/dist/axe.js +210 -0
  12. package/dist/axe.js.map +1 -0
  13. package/dist/bin/setsquare.d.ts +3 -0
  14. package/dist/bin/setsquare.d.ts.map +1 -0
  15. package/dist/bin/setsquare.js +21 -0
  16. package/dist/bin/setsquare.js.map +1 -0
  17. package/dist/brand.d.ts +84 -0
  18. package/dist/brand.d.ts.map +1 -0
  19. package/dist/brand.js +335 -0
  20. package/dist/brand.js.map +1 -0
  21. package/dist/checks/dynamic.d.ts +57 -0
  22. package/dist/checks/dynamic.d.ts.map +1 -0
  23. package/dist/checks/dynamic.js +184 -0
  24. package/dist/checks/dynamic.js.map +1 -0
  25. package/dist/checks/rule-pack.d.ts +34 -0
  26. package/dist/checks/rule-pack.d.ts.map +1 -0
  27. package/dist/checks/rule-pack.js +270 -0
  28. package/dist/checks/rule-pack.js.map +1 -0
  29. package/dist/checks/versions.d.ts +28 -0
  30. package/dist/checks/versions.d.ts.map +1 -0
  31. package/dist/checks/versions.js +45 -0
  32. package/dist/checks/versions.js.map +1 -0
  33. package/dist/ci.d.ts +37 -0
  34. package/dist/ci.d.ts.map +1 -0
  35. package/dist/ci.js +199 -0
  36. package/dist/ci.js.map +1 -0
  37. package/dist/contract.d.ts +334 -0
  38. package/dist/contract.d.ts.map +1 -0
  39. package/dist/contract.js +35 -0
  40. package/dist/contract.js.map +1 -0
  41. package/dist/dedupe.d.ts +79 -0
  42. package/dist/dedupe.d.ts.map +1 -0
  43. package/dist/dedupe.js +102 -0
  44. package/dist/dedupe.js.map +1 -0
  45. package/dist/document.d.ts +29 -0
  46. package/dist/document.d.ts.map +1 -0
  47. package/dist/document.js +94 -0
  48. package/dist/document.js.map +1 -0
  49. package/dist/envelope.d.ts +124 -0
  50. package/dist/envelope.d.ts.map +1 -0
  51. package/dist/envelope.js +337 -0
  52. package/dist/envelope.js.map +1 -0
  53. package/dist/escape.d.ts +14 -0
  54. package/dist/escape.d.ts.map +1 -0
  55. package/dist/escape.js +20 -0
  56. package/dist/escape.js.map +1 -0
  57. package/dist/findings.d.ts +47 -0
  58. package/dist/findings.d.ts.map +1 -0
  59. package/dist/findings.js +229 -0
  60. package/dist/findings.js.map +1 -0
  61. package/dist/fixture.d.ts +7 -0
  62. package/dist/fixture.d.ts.map +1 -0
  63. package/dist/fixture.js +237 -0
  64. package/dist/fixture.js.map +1 -0
  65. package/dist/group.d.ts +214 -0
  66. package/dist/group.d.ts.map +1 -0
  67. package/dist/group.js +709 -0
  68. package/dist/group.js.map +1 -0
  69. package/dist/html-report.d.ts +68 -0
  70. package/dist/html-report.d.ts.map +1 -0
  71. package/dist/html-report.js +649 -0
  72. package/dist/html-report.js.map +1 -0
  73. package/dist/human.d.ts +65 -0
  74. package/dist/human.d.ts.map +1 -0
  75. package/dist/human.js +111 -0
  76. package/dist/human.js.map +1 -0
  77. package/dist/index.d.ts +34 -0
  78. package/dist/index.d.ts.map +1 -0
  79. package/dist/index.js +33 -0
  80. package/dist/index.js.map +1 -0
  81. package/dist/infer.d.ts +65 -0
  82. package/dist/infer.d.ts.map +1 -0
  83. package/dist/infer.js +67 -0
  84. package/dist/infer.js.map +1 -0
  85. package/dist/insights.d.ts +140 -0
  86. package/dist/insights.d.ts.map +1 -0
  87. package/dist/insights.js +483 -0
  88. package/dist/insights.js.map +1 -0
  89. package/dist/install.d.ts +8 -0
  90. package/dist/install.d.ts.map +1 -0
  91. package/dist/install.js +114 -0
  92. package/dist/install.js.map +1 -0
  93. package/dist/links.d.ts +45 -0
  94. package/dist/links.d.ts.map +1 -0
  95. package/dist/links.js +45 -0
  96. package/dist/links.js.map +1 -0
  97. package/dist/mask.d.ts +85 -0
  98. package/dist/mask.d.ts.map +1 -0
  99. package/dist/mask.js +98 -0
  100. package/dist/mask.js.map +1 -0
  101. package/dist/observe.d.ts +51 -0
  102. package/dist/observe.d.ts.map +1 -0
  103. package/dist/observe.js +233 -0
  104. package/dist/observe.js.map +1 -0
  105. package/dist/options.d.ts +249 -0
  106. package/dist/options.d.ts.map +1 -0
  107. package/dist/options.js +185 -0
  108. package/dist/options.js.map +1 -0
  109. package/dist/output.d.ts +113 -0
  110. package/dist/output.d.ts.map +1 -0
  111. package/dist/output.js +231 -0
  112. package/dist/output.js.map +1 -0
  113. package/dist/perf.d.ts +11 -0
  114. package/dist/perf.d.ts.map +1 -0
  115. package/dist/perf.js +150 -0
  116. package/dist/perf.js.map +1 -0
  117. package/dist/reading-level.d.ts +73 -0
  118. package/dist/reading-level.d.ts.map +1 -0
  119. package/dist/reading-level.js +189 -0
  120. package/dist/reading-level.js.map +1 -0
  121. package/dist/reporter.d.ts +94 -0
  122. package/dist/reporter.d.ts.map +1 -0
  123. package/dist/reporter.js +709 -0
  124. package/dist/reporter.js.map +1 -0
  125. package/dist/rules.d.ts +55 -0
  126. package/dist/rules.d.ts.map +1 -0
  127. package/dist/rules.js +77 -0
  128. package/dist/rules.js.map +1 -0
  129. package/dist/runtime.d.ts +32 -0
  130. package/dist/runtime.d.ts.map +1 -0
  131. package/dist/runtime.js +67 -0
  132. package/dist/runtime.js.map +1 -0
  133. package/dist/sanitise.d.ts +116 -0
  134. package/dist/sanitise.d.ts.map +1 -0
  135. package/dist/sanitise.js +247 -0
  136. package/dist/sanitise.js.map +1 -0
  137. package/dist/scan.d.ts +60 -0
  138. package/dist/scan.d.ts.map +1 -0
  139. package/dist/scan.js +246 -0
  140. package/dist/scan.js.map +1 -0
  141. package/dist/screens.d.ts +98 -0
  142. package/dist/screens.d.ts.map +1 -0
  143. package/dist/screens.js +301 -0
  144. package/dist/screens.js.map +1 -0
  145. package/dist/settle.d.ts +65 -0
  146. package/dist/settle.d.ts.map +1 -0
  147. package/dist/settle.js +162 -0
  148. package/dist/settle.js.map +1 -0
  149. package/dist/shots.d.ts +109 -0
  150. package/dist/shots.d.ts.map +1 -0
  151. package/dist/shots.js +113 -0
  152. package/dist/shots.js.map +1 -0
  153. package/dist/style.d.ts +47 -0
  154. package/dist/style.d.ts.map +1 -0
  155. package/dist/style.js +154 -0
  156. package/dist/style.js.map +1 -0
  157. package/dist/suite.d.ts +218 -0
  158. package/dist/suite.d.ts.map +1 -0
  159. package/dist/suite.js +219 -0
  160. package/dist/suite.js.map +1 -0
  161. package/dist/summary.d.ts +268 -0
  162. package/dist/summary.d.ts.map +1 -0
  163. package/dist/summary.js +1308 -0
  164. package/dist/summary.js.map +1 -0
  165. package/dist/unscannable.d.ts +75 -0
  166. package/dist/unscannable.d.ts.map +1 -0
  167. package/dist/unscannable.js +111 -0
  168. package/dist/unscannable.js.map +1 -0
  169. package/dist/versions.d.ts +13 -0
  170. package/dist/versions.d.ts.map +1 -0
  171. package/dist/versions.js +39 -0
  172. package/dist/versions.js.map +1 -0
  173. package/dist/wcag-map.d.ts +19 -0
  174. package/dist/wcag-map.d.ts.map +1 -0
  175. package/dist/wcag-map.js +52 -0
  176. package/dist/wcag-map.js.map +1 -0
  177. package/dist/with-setsquare.d.ts +26 -0
  178. package/dist/with-setsquare.d.ts.map +1 -0
  179. package/dist/with-setsquare.js +70 -0
  180. package/dist/with-setsquare.js.map +1 -0
  181. package/package.json +81 -0
@@ -0,0 +1,249 @@
1
+ import type { InferenceConfig } from './infer.js';
2
+ import type { MaskConfig } from './mask.js';
3
+ import { type RulePolicy } from './rules.js';
4
+ import { type SettleConfig } from './settle.js';
5
+ /**
6
+ * Configuration for `withSetsquare()`.
7
+ *
8
+ * Everything here is optional, and that is the product claim rather than a
9
+ * convenience: the promise is a single config line, so an empty options object
10
+ * has to produce a useful run. Options exist to correct inference, never to
11
+ * enable it.
12
+ */
13
+ export interface SetsquareOptions {
14
+ /**
15
+ * Where the run envelope and its sidecar are written.
16
+ *
17
+ * Relative paths resolve against the Playwright config's directory, not the
18
+ * process working directory — a suite run from a monorepo root and the same
19
+ * suite run from its own package must put their output in the same place, or
20
+ * the artifact moves depending on where you were standing.
21
+ */
22
+ outputDir?: string;
23
+ /**
24
+ * Print the closing block that explains what the platform adds.
25
+ *
26
+ * Once per run, at the end, five lines at most, derived from the run's own
27
+ * numbers. Off is honoured without complaint — a tool that nags is a tool
28
+ * people configure around, and then they have configured away the summary too.
29
+ */
30
+ promo?: boolean;
31
+ /**
32
+ * The WCAG conformance level to assess against. Defaults to `AA`.
33
+ *
34
+ * AA is the floor because it is what conformance normally means in practice
35
+ * and what procurement, EN 301 549 and the EAA actually ask for. AAA is opt-in
36
+ * rather than default because it is a deliberate commitment — WCAG itself does
37
+ * not recommend AAA as a general policy, since some AAA criteria cannot be
38
+ * satisfied for all content, so defaulting to it would report every team as
39
+ * failing a bar they never set.
40
+ */
41
+ wcag?: 'AA' | 'AAA';
42
+ /**
43
+ * Include axe's 30 advisory `best-practice` rules. Defaults to `false`.
44
+ *
45
+ * They catch real problems and are worth turning on. They are off by default
46
+ * because they are NOT WCAG failures, and a conformance grid that mixes advice
47
+ * with conformance cannot honestly answer "does this meet AA?". Findings from
48
+ * them are always distinguishable in the payload — a best-practice rule carries
49
+ * no `wcag` block.
50
+ */
51
+ bestPractice?: boolean;
52
+ /** Scan automatically on settled navigation. On by default — it is the promise. */
53
+ autoScan?: boolean;
54
+ /** How long a page must be quiet before it counts as settled. Default 500ms. */
55
+ quietMs?: number;
56
+ /**
57
+ * Hard ceiling before scanning anyway. Default 5000ms.
58
+ *
59
+ * A page that never goes quiet is common — a spinner, a poller, a carousel —
60
+ * and declining to scan it would produce 'no findings', which reads as 'no
61
+ * problems'. On expiry the scan happens and the payload records that it did.
62
+ */
63
+ settleTimeoutMs?: number;
64
+ /** Route pattern to surface name: `{ '/items/:id/edit': 'item-editor' }`. */
65
+ surfaces?: InferenceConfig['surfaces'];
66
+ /** Playwright project name to persona. */
67
+ personas?: InferenceConfig['personas'];
68
+ /** Playwright project name to theme. */
69
+ themes?: InferenceConfig['themes'];
70
+ /** The escape hatch for suites whose project names carry neither. */
71
+ persona?: InferenceConfig['persona'];
72
+ theme?: InferenceConfig['theme'];
73
+ /**
74
+ * Extra regions to mask, composed WITH the built-in defaults.
75
+ *
76
+ * Masking has no effect on the local path, which writes no images at all —
77
+ * it is configured here so the posture is set before any bytes are ever
78
+ * captured, rather than being bolted on when upload arrives.
79
+ */
80
+ mask?: MaskConfig['mask'];
81
+ /** Drop the built-in mask defaults. A deliberate, documented act. */
82
+ maskDefaults?: MaskConfig['maskDefaults'];
83
+ /**
84
+ * How the run's summary is printed.
85
+ *
86
+ * `text` is for a human at a terminal. `markdown` survives being pasted into
87
+ * Slack, an issue, or an LLM prompt — which is the main thing that happens to
88
+ * this output. `json` is for a machine, and omits the closing block entirely.
89
+ */
90
+ format?: 'text' | 'markdown' | 'json';
91
+ /**
92
+ * How the conformance grid renders in the terminal summary. Default `matrix`.
93
+ *
94
+ * `matrix` draws criteria × surfaces as aligned single-glyph columns — no
95
+ * box-drawing, so it survives being pasted — and falls back to per-criterion
96
+ * rows by itself when the run has more surfaces than the width budget fits.
97
+ * `rows` skips the matrix always, for people who find it noise.
98
+ */
99
+ grid?: 'matrix' | 'rows';
100
+ /**
101
+ * Estimate reading level (WCAG 3.1.5, AAA) on scanned pages.
102
+ *
103
+ * Defaults to on when the run targets AAA — 3.1.5 is an AAA criterion — and
104
+ * off at AA unless opted in. Always a needs-review heuristic, never a
105
+ * violation: formulas approximate a grade, and the SC itself allows
106
+ * supplemental content and alternate versions no formula can see.
107
+ */
108
+ readingLevel?: boolean;
109
+ /**
110
+ * The longest a single scan may hold a customer's test.
111
+ *
112
+ * Exists because it was missing and that turned out to matter. The SDK's first
113
+ * promise is that it never fails a build, and an unbounded axe run on a heavy
114
+ * page breaks it in the most confusing way available — the customer's test
115
+ * times out, blames itself, and nothing points at us.
116
+ */
117
+ scanTimeoutMs?: number;
118
+ }
119
+ /** Options after defaulting, which is what the reporter actually holds. */
120
+ export interface ResolvedSetsquareOptions {
121
+ outputDir: string;
122
+ promo: boolean;
123
+ rules: RulePolicy;
124
+ autoScan: boolean;
125
+ settle: SettleConfig;
126
+ inference: InferenceConfig;
127
+ mask: MaskConfig;
128
+ format: 'text' | 'markdown' | 'json';
129
+ grid: 'matrix' | 'rows';
130
+ readingLevel: boolean;
131
+ scanTimeoutMs: number;
132
+ /** Off entirely. Set by `SETSQUARE_DISABLED`, and nothing else. */
133
+ disabled: boolean;
134
+ }
135
+ /**
136
+ * `.setsquare/` rather than something prettier: it sorts with the other tool
137
+ * directories, it is obviously ours, and `setsquare init` suggests exactly this line
138
+ * for the customer's `.gitignore`.
139
+ */
140
+ export declare const DEFAULT_OUTPUT_DIR = ".setsquare";
141
+ /**
142
+ * Ten seconds, and the number is a compromise with a reason on each side.
143
+ *
144
+ * axe on a large real page legitimately takes seconds — a drag-and-drop builder
145
+ * with thousands of nodes is not being slow, it is being big — so a tight budget
146
+ * would throw away exactly the evidence hardest to get any other way. But a test
147
+ * that a customer wrote against a 30-second budget cannot afford to lend us most
148
+ * of it.
149
+ *
150
+ * Ten seconds fits every scan measured on the fixture site and on the reference
151
+ * implementation's ordinary pages, and cuts off the pathological case before it
152
+ * can take a test down with it.
153
+ */
154
+ export declare const DEFAULT_SCAN_TIMEOUT_MS = 10000;
155
+ /**
156
+ * The kill switch, read from the environment rather than from config.
157
+ *
158
+ * A customer who suspects the SDK of breaking their suite needs to test that
159
+ * suspicion in one command, on a branch they have not touched, in CI they cannot
160
+ * edit. Making them change a config file first means the check is annoying enough
161
+ * to skip — and "is it you or is it me" is the question we most want them to be
162
+ * able to answer quickly, because the answer is sometimes yes.
163
+ *
164
+ * It is also how we get a baseline for our own measurements without asking anyone
165
+ * to revert anything.
166
+ */
167
+ export declare function isDisabled(env?: NodeJS.ProcessEnv): boolean;
168
+ /**
169
+ * Per-invocation auto-scan override, from the environment.
170
+ *
171
+ * Exists for multi-invocation suites: axe is the bulk of the SDK's per-test
172
+ * cost, and a functional lane whose surfaces the a11y lane scans anyway is
173
+ * paying that cost twice for evidence the merge would deduplicate. The config
174
+ * file cannot carry this — it is the same file for every lane — so the lane
175
+ * that should not scan says so: `SETSQUARE_AUTOSCAN=0`.
176
+ *
177
+ * Deliberately narrower than the kill switch. `SETSQUARE_DISABLED` removes the SDK
178
+ * from the run entirely; this keeps observations, test outcomes and the run
179
+ * artifact — the lane still contributes to the merged run's e2e visibility and
180
+ * to the visited-but-never-scanned union — and skips only the scanning.
181
+ * Explicit `setsquare.scan()` calls still run: the customer asked for those by name.
182
+ *
183
+ * Returns undefined when unset, so config and defaults keep deciding.
184
+ */
185
+ export declare function autoScanOverride(env?: NodeJS.ProcessEnv): boolean | undefined;
186
+ /**
187
+ * Per-invocation output directory, from the environment.
188
+ *
189
+ * Exists for `setsquare verify`, and the reason is a hazard rather than a
190
+ * convenience. Verify re-runs one surface to see whether a rule still fires — which
191
+ * means invoking the customer's own Playwright, which means the SDK writes a run.
192
+ * Writing it into `.setsquare/runs/` would make the re-scan **become the latest
193
+ * run**: `audit`, `report`, `findings` and `sarif` all read that, and `pruneRuns`
194
+ * would delete the real run it replaced. A command that silently overwrites the
195
+ * artefact every other command reads is worse than no command, so verify redirects
196
+ * the output instead.
197
+ *
198
+ * An env rather than a config option, for the same reason `SETSQUARE_RUN_ID` and
199
+ * `SETSQUARE_AUTOSCAN` are: it changes per invocation while the config file does
200
+ * not, and Playwright constructs reporters from JSON-safe config entries.
201
+ *
202
+ * Useful beyond verify — a CI lane that wants its evidence somewhere specific can
203
+ * set it — which is why it is a general option and not a `SETSQUARE_VERIFY=1` flag.
204
+ *
205
+ * Returns undefined when unset, so config and defaults keep deciding.
206
+ */
207
+ export declare function outputDirOverride(env?: NodeJS.ProcessEnv): string | undefined;
208
+ /**
209
+ * Where to write the run summary as markdown.
210
+ *
211
+ * `SETSQUARE_SUMMARY_MD=<path>` makes the reporter write the summary it just
212
+ * printed, rendered through `renderMarkdown`, to that path as well. Nothing else
213
+ * changes: the terminal still gets whatever `format` asks for, and the file is a
214
+ * second rendering of the SAME input rather than a second summary.
215
+ *
216
+ * It exists for CI job summaries — GitHub's `$GITHUB_STEP_SUMMARY`, GitLab's
217
+ * report pages — and it is deliberately a path rather than a `github: true` flag,
218
+ * because the SDK has no business knowing which CI it is running under. The
219
+ * official Action points this at a file it owns and appends that file itself, so
220
+ * append-versus-replace stays the caller's decision.
221
+ *
222
+ * An env rather than a config option for the same reason as `SETSQUARE_OUTPUT_DIR`:
223
+ * it changes per invocation while the config file does not.
224
+ *
225
+ * The alternative was a CLI command that renders markdown from `run.json` — but
226
+ * `@setsquare/review-sdk` depends on `@setsquare/review-cli`, so the CLI cannot read the
227
+ * SDK's renderer, and rewriting it there is exactly the second renderer that
228
+ * `report.ts` forbids. One renderer, a second destination.
229
+ */
230
+ export declare function summaryMarkdownPath(env?: NodeJS.ProcessEnv): string | undefined;
231
+ /**
232
+ * Changed-only mode: scan just the surfaces a change can reach.
233
+ *
234
+ * `SETSQUARE_CHANGED_ONLY=<path>` points at the file `setsquare changed` writes.
235
+ * The SDK does no route reasoning of its own — it compares patterns it already
236
+ * computes against a list, which is why this is a few lines rather than an adapter.
237
+ * The route knowledge lives in the CLI, where the adapters are, and
238
+ * `sdk/src/style.ts` records the standing decision that CLI code must not enter a
239
+ * test process's import graph.
240
+ *
241
+ * Two shapes in that file mean different things and must not be conflated:
242
+ * `routes: []` is "nothing changed that touches a route", and `routes: null` is
243
+ * "we could not work it out". Only the first licenses skipping anything; `null`
244
+ * means scan everything, because a set that might be missing surfaces is worse
245
+ * than no set at all.
246
+ */
247
+ export declare function changedOnlyRoutes(env?: NodeJS.ProcessEnv, read?: (path: string) => string): Set<string> | undefined;
248
+ export declare function resolveOptions(options?: SetsquareOptions): ResolvedSetsquareOptions;
249
+ //# sourceMappingURL=options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,185 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { DEFAULT_RULE_POLICY } from './rules.js';
3
+ import { DEFAULT_SETTLE } from './settle.js';
4
+ /**
5
+ * `.setsquare/` rather than something prettier: it sorts with the other tool
6
+ * directories, it is obviously ours, and `setsquare init` suggests exactly this line
7
+ * for the customer's `.gitignore`.
8
+ */
9
+ export const DEFAULT_OUTPUT_DIR = '.setsquare';
10
+ /**
11
+ * Ten seconds, and the number is a compromise with a reason on each side.
12
+ *
13
+ * axe on a large real page legitimately takes seconds — a drag-and-drop builder
14
+ * with thousands of nodes is not being slow, it is being big — so a tight budget
15
+ * would throw away exactly the evidence hardest to get any other way. But a test
16
+ * that a customer wrote against a 30-second budget cannot afford to lend us most
17
+ * of it.
18
+ *
19
+ * Ten seconds fits every scan measured on the fixture site and on the reference
20
+ * implementation's ordinary pages, and cuts off the pathological case before it
21
+ * can take a test down with it.
22
+ */
23
+ export const DEFAULT_SCAN_TIMEOUT_MS = 10_000;
24
+ /**
25
+ * The kill switch, read from the environment rather than from config.
26
+ *
27
+ * A customer who suspects the SDK of breaking their suite needs to test that
28
+ * suspicion in one command, on a branch they have not touched, in CI they cannot
29
+ * edit. Making them change a config file first means the check is annoying enough
30
+ * to skip — and "is it you or is it me" is the question we most want them to be
31
+ * able to answer quickly, because the answer is sometimes yes.
32
+ *
33
+ * It is also how we get a baseline for our own measurements without asking anyone
34
+ * to revert anything.
35
+ */
36
+ export function isDisabled(env = process.env) {
37
+ const value = env['SETSQUARE_DISABLED'];
38
+ return value !== undefined && value !== '' && value !== '0' && value !== 'false';
39
+ }
40
+ /**
41
+ * Per-invocation auto-scan override, from the environment.
42
+ *
43
+ * Exists for multi-invocation suites: axe is the bulk of the SDK's per-test
44
+ * cost, and a functional lane whose surfaces the a11y lane scans anyway is
45
+ * paying that cost twice for evidence the merge would deduplicate. The config
46
+ * file cannot carry this — it is the same file for every lane — so the lane
47
+ * that should not scan says so: `SETSQUARE_AUTOSCAN=0`.
48
+ *
49
+ * Deliberately narrower than the kill switch. `SETSQUARE_DISABLED` removes the SDK
50
+ * from the run entirely; this keeps observations, test outcomes and the run
51
+ * artifact — the lane still contributes to the merged run's e2e visibility and
52
+ * to the visited-but-never-scanned union — and skips only the scanning.
53
+ * Explicit `setsquare.scan()` calls still run: the customer asked for those by name.
54
+ *
55
+ * Returns undefined when unset, so config and defaults keep deciding.
56
+ */
57
+ export function autoScanOverride(env = process.env) {
58
+ const value = env['SETSQUARE_AUTOSCAN'];
59
+ if (value === undefined || value === '')
60
+ return undefined;
61
+ return value !== '0' && value !== 'false';
62
+ }
63
+ /**
64
+ * Per-invocation output directory, from the environment.
65
+ *
66
+ * Exists for `setsquare verify`, and the reason is a hazard rather than a
67
+ * convenience. Verify re-runs one surface to see whether a rule still fires — which
68
+ * means invoking the customer's own Playwright, which means the SDK writes a run.
69
+ * Writing it into `.setsquare/runs/` would make the re-scan **become the latest
70
+ * run**: `audit`, `report`, `findings` and `sarif` all read that, and `pruneRuns`
71
+ * would delete the real run it replaced. A command that silently overwrites the
72
+ * artefact every other command reads is worse than no command, so verify redirects
73
+ * the output instead.
74
+ *
75
+ * An env rather than a config option, for the same reason `SETSQUARE_RUN_ID` and
76
+ * `SETSQUARE_AUTOSCAN` are: it changes per invocation while the config file does
77
+ * not, and Playwright constructs reporters from JSON-safe config entries.
78
+ *
79
+ * Useful beyond verify — a CI lane that wants its evidence somewhere specific can
80
+ * set it — which is why it is a general option and not a `SETSQUARE_VERIFY=1` flag.
81
+ *
82
+ * Returns undefined when unset, so config and defaults keep deciding.
83
+ */
84
+ export function outputDirOverride(env = process.env) {
85
+ const value = env['SETSQUARE_OUTPUT_DIR'];
86
+ if (value === undefined || value.trim() === '')
87
+ return undefined;
88
+ return value.trim();
89
+ }
90
+ /**
91
+ * Where to write the run summary as markdown.
92
+ *
93
+ * `SETSQUARE_SUMMARY_MD=<path>` makes the reporter write the summary it just
94
+ * printed, rendered through `renderMarkdown`, to that path as well. Nothing else
95
+ * changes: the terminal still gets whatever `format` asks for, and the file is a
96
+ * second rendering of the SAME input rather than a second summary.
97
+ *
98
+ * It exists for CI job summaries — GitHub's `$GITHUB_STEP_SUMMARY`, GitLab's
99
+ * report pages — and it is deliberately a path rather than a `github: true` flag,
100
+ * because the SDK has no business knowing which CI it is running under. The
101
+ * official Action points this at a file it owns and appends that file itself, so
102
+ * append-versus-replace stays the caller's decision.
103
+ *
104
+ * An env rather than a config option for the same reason as `SETSQUARE_OUTPUT_DIR`:
105
+ * it changes per invocation while the config file does not.
106
+ *
107
+ * The alternative was a CLI command that renders markdown from `run.json` — but
108
+ * `@setsquare/review-sdk` depends on `@setsquare/review-cli`, so the CLI cannot read the
109
+ * SDK's renderer, and rewriting it there is exactly the second renderer that
110
+ * `report.ts` forbids. One renderer, a second destination.
111
+ */
112
+ export function summaryMarkdownPath(env = process.env) {
113
+ const value = env['SETSQUARE_SUMMARY_MD'];
114
+ if (value === undefined || value.trim() === '')
115
+ return undefined;
116
+ return value.trim();
117
+ }
118
+ /**
119
+ * Changed-only mode: scan just the surfaces a change can reach.
120
+ *
121
+ * `SETSQUARE_CHANGED_ONLY=<path>` points at the file `setsquare changed` writes.
122
+ * The SDK does no route reasoning of its own — it compares patterns it already
123
+ * computes against a list, which is why this is a few lines rather than an adapter.
124
+ * The route knowledge lives in the CLI, where the adapters are, and
125
+ * `sdk/src/style.ts` records the standing decision that CLI code must not enter a
126
+ * test process's import graph.
127
+ *
128
+ * Two shapes in that file mean different things and must not be conflated:
129
+ * `routes: []` is "nothing changed that touches a route", and `routes: null` is
130
+ * "we could not work it out". Only the first licenses skipping anything; `null`
131
+ * means scan everything, because a set that might be missing surfaces is worse
132
+ * than no set at all.
133
+ */
134
+ export function changedOnlyRoutes(env = process.env, read = (path) => readFileSync(path, 'utf8')) {
135
+ const path = env['SETSQUARE_CHANGED_ONLY'];
136
+ if (path === undefined || path.trim() === '')
137
+ return undefined;
138
+ try {
139
+ const parsed = JSON.parse(read(path.trim()));
140
+ // `null`, a missing key, or anything that is not an array: not a licence to skip.
141
+ if (!Array.isArray(parsed.routes))
142
+ return undefined;
143
+ return new Set(parsed.routes.filter((route) => typeof route === 'string'));
144
+ }
145
+ catch {
146
+ // Unreadable or malformed. Scanning everything is the safe failure.
147
+ return undefined;
148
+ }
149
+ }
150
+ export function resolveOptions(options = {}) {
151
+ return {
152
+ scanTimeoutMs: options.scanTimeoutMs ?? DEFAULT_SCAN_TIMEOUT_MS,
153
+ disabled: isDisabled(),
154
+ // The env wins over the config: it is the per-invocation statement, and the
155
+ // config file is the same file for every lane.
156
+ outputDir: outputDirOverride() ?? options.outputDir ?? DEFAULT_OUTPUT_DIR,
157
+ promo: options.promo ?? true,
158
+ rules: {
159
+ target: options.wcag ?? DEFAULT_RULE_POLICY.target,
160
+ bestPractice: options.bestPractice ?? DEFAULT_RULE_POLICY.bestPractice,
161
+ },
162
+ // Env outranks config here, because the config is shared across lanes and
163
+ // the whole point of the override is to differ per lane.
164
+ autoScan: autoScanOverride() ?? options.autoScan ?? true,
165
+ format: options.format ?? 'text',
166
+ grid: options.grid ?? 'matrix',
167
+ readingLevel: options.readingLevel ?? (options.wcag ?? DEFAULT_RULE_POLICY.target) === 'AAA',
168
+ settle: {
169
+ quietMs: options.quietMs ?? DEFAULT_SETTLE.quietMs,
170
+ settleTimeoutMs: options.settleTimeoutMs ?? DEFAULT_SETTLE.settleTimeoutMs,
171
+ },
172
+ mask: {
173
+ ...(options.mask ? { mask: options.mask } : {}),
174
+ ...(options.maskDefaults !== undefined ? { maskDefaults: options.maskDefaults } : {}),
175
+ },
176
+ inference: {
177
+ ...(options.surfaces ? { surfaces: options.surfaces } : {}),
178
+ ...(options.personas ? { personas: options.personas } : {}),
179
+ ...(options.themes ? { themes: options.themes } : {}),
180
+ ...(options.persona ? { persona: options.persona } : {}),
181
+ ...(options.theme ? { theme: options.theme } : {}),
182
+ },
183
+ };
184
+ }
185
+ //# sourceMappingURL=options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAIvC,OAAO,EAAE,mBAAmB,EAAmB,MAAM,YAAY,CAAC;AAClE,OAAO,EAAE,cAAc,EAAqB,MAAM,aAAa,CAAC;AAkJhE;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,YAAY,CAAC;AAE/C;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAC;AAE9C;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,UAAU,CAAC,MAAyB,OAAO,CAAC,GAAG;IAC7D,MAAM,KAAK,GAAG,GAAG,CAAC,oBAAoB,CAAC,CAAC;IACxC,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,OAAO,CAAC;AACnF,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACnE,MAAM,KAAK,GAAG,GAAG,CAAC,oBAAoB,CAAC,CAAC;IACxC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,SAAS,CAAC;IAC1D,OAAO,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,OAAO,CAAC;AAC5C,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACpE,MAAM,KAAK,GAAG,GAAG,CAAC,sBAAsB,CAAC,CAAC;IAC1C,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,SAAS,CAAC;IACjE,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACtE,MAAM,KAAK,GAAG,GAAG,CAAC,sBAAsB,CAAC,CAAC;IAC1C,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,SAAS,CAAC;IACjE,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAyB,OAAO,CAAC,GAAG,EACpC,OAAiC,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC;IAErE,MAAM,IAAI,GAAG,GAAG,CAAC,wBAAwB,CAAC,CAAC;IAC3C,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,SAAS,CAAC;IAE/D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAyB,CAAC;QACrE,kFAAkF;QAClF,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;YAAE,OAAO,SAAS,CAAC;QACpD,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC;IAC9F,CAAC;IAAC,MAAM,CAAC;QACP,oEAAoE;QACpE,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,UAA4B,EAAE;IAC3D,OAAO;QACL,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,uBAAuB;QAC/D,QAAQ,EAAE,UAAU,EAAE;QACtB,4EAA4E;QAC5E,+CAA+C;QAC/C,SAAS,EAAE,iBAAiB,EAAE,IAAI,OAAO,CAAC,SAAS,IAAI,kBAAkB;QACzE,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,IAAI;QAC5B,KAAK,EAAE;YACL,MAAM,EAAE,OAAO,CAAC,IAAI,IAAI,mBAAmB,CAAC,MAAM;YAClD,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,mBAAmB,CAAC,YAAY;SACvE;QACD,0EAA0E;QAC1E,yDAAyD;QACzD,QAAQ,EAAE,gBAAgB,EAAE,IAAI,OAAO,CAAC,QAAQ,IAAI,IAAI;QACxD,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,MAAM;QAChC,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,QAAQ;QAC9B,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,mBAAmB,CAAC,MAAM,CAAC,KAAK,KAAK;QAC5F,MAAM,EAAE;YACN,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,cAAc,CAAC,OAAO;YAClD,eAAe,EAAE,OAAO,CAAC,eAAe,IAAI,cAAc,CAAC,eAAe;SAC3E;QACD,IAAI,EAAE;YACJ,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/C,GAAG,CAAC,OAAO,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACtF;QACD,SAAS,EAAE;YACT,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3D,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3D,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrD,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxD,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACnD;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,113 @@
1
+ import type { RunEnvelope, RunMeta } from './contract.js';
2
+ /**
3
+ * Write the run to disk: the envelope, and its sidecar.
4
+ *
5
+ * Two files, and the split is the whole design. `run.json` is the ingest request
6
+ * body byte-for-byte — nothing added, nothing removed — so the SDK's own test
7
+ * suite can validate it against the generated JSON Schema and the claim "the
8
+ * same artifact the platform would have received" is checkable. Every local fact
9
+ * that would otherwise have to be smuggled into the wire shape goes in
10
+ * `meta.json` instead.
11
+ *
12
+ * This is also why there is no `x-setsquare-local` extension field. The envelope is
13
+ * `.strict()`, and that strictness is exactly the mechanism that stopped `runId`
14
+ * creeping back after P1-17.7 removed it. Putting a licensed hole in it to carry
15
+ * a file path would trade a real guarantee for a small convenience.
16
+ */
17
+ export interface WriteRunResult {
18
+ runDir: string;
19
+ envelopePath: string;
20
+ metaPath: string;
21
+ }
22
+ /**
23
+ * Sortable, collision-resistant, and readable at a glance in a directory listing.
24
+ *
25
+ * Derived from `generatedAt` rather than a fresh clock so the directory name and
26
+ * the envelope's own timestamp can never disagree. Colons are stripped because
27
+ * they are illegal in filenames on Windows, and a customer on Windows finding
28
+ * that we cannot write our own output would be an unforced error.
29
+ *
30
+ * The engine used to be part of this name and deliberately is not any more. A
31
+ * single Playwright run can span three engines — the compatibility matrix
32
+ * requires it — so a directory named after one of them would be wrong for every
33
+ * mixed run, and quietly right-looking. The engine belongs to each test result,
34
+ * which is the only place it is ever singular.
35
+ */
36
+ export declare function runDirName(generatedAt: string): string;
37
+ /**
38
+ * Write a file so no reader can ever observe it half-written.
39
+ *
40
+ * A plain `writeFile` is atomic against other writers of *different* files, but
41
+ * not against a reader that lists the directory the instant the file appears —
42
+ * which is exactly what a concurrent invocation's merge does. Content goes to a
43
+ * uniquely-named sibling first, then renames into place; rename is atomic on
44
+ * every filesystem we run on, so a reader sees the old bytes or the new bytes
45
+ * and never a prefix.
46
+ *
47
+ * The rename is retried because Windows refuses to replace a file another
48
+ * process holds open without FILE_SHARE_DELETE — antivirus scanners and search
49
+ * indexers do this routinely, briefly. A short backoff outlasts almost all of
50
+ * them; persistent failure propagates, because falling back to a plain
51
+ * overwrite would reintroduce the torn read this function exists to prevent.
52
+ */
53
+ export declare function writeFileAtomic(path: string, content: string): Promise<void>;
54
+ export declare function writeRun(outputDir: string, baseDir: string, envelope: RunEnvelope, meta: Omit<RunMeta, 'envelopePath' | 'outputDir'>): Promise<WriteRunResult>;
55
+ /**
56
+ * The write itself, with the destination chosen by the caller.
57
+ *
58
+ * Split from `writeRun` because a grouped run's directory is keyed by the
59
+ * orchestrator's id rather than by this invocation's clock — but what goes IN
60
+ * the directory, and how it gets there, must not differ between the two paths.
61
+ *
62
+ * `run.json` lands before `meta.json`, deliberately: the sidecar describes the
63
+ * envelope (down to a content hash, when grouped), so a reader must never find
64
+ * a sidecar whose envelope does not exist yet.
65
+ */
66
+ export declare function writeRunInto(runDir: string, outputRoot: string, envelope: RunEnvelope, meta: Omit<RunMeta, 'envelopePath' | 'outputDir'>): Promise<WriteRunResult>;
67
+ /** A run-group directory, keyed by the orchestrator's id rather than a clock. */
68
+ export declare const GROUP_DIR_PATTERN: RegExp;
69
+ export interface PruneOptions {
70
+ /** A timestamp-named run dir to keep; timestamp dirs sorting before it go. */
71
+ currentName?: string;
72
+ /** A group dir name to keep unconditionally — the run being written now. */
73
+ currentGroupName?: string;
74
+ }
75
+ export declare function pruneRuns(runsRoot: string, options: PruneOptions): Promise<void>;
76
+ /**
77
+ * The HTML report, written beside `run.json` in the same run directory.
78
+ *
79
+ * Separate from `writeRun` rather than folded into it, because the two must be
80
+ * allowed to fail independently: a template bug must cost the customer the
81
+ * report and nothing else — never the envelope, and never the terminal
82
+ * summary. The reporter wraps this call in its own try.
83
+ */
84
+ export declare function writeHtmlReport(runDir: string, html: string): Promise<string>;
85
+ /**
86
+ * The visual contact sheet, written beside `report.html` in the same run
87
+ * directory.
88
+ *
89
+ * Its own file and its own failure domain, for the same reason the HTML report
90
+ * has one: a template bug in the sheet must cost the customer the sheet and
91
+ * nothing else — not the envelope, not the accessibility report, not the
92
+ * terminal summary. The reporter wraps this call in its own try.
93
+ *
94
+ * The name is stable and boring on purpose. It is a path people put in a
95
+ * `.gitignore`, a CI artifact glob and a bookmark, and renaming it later would
96
+ * break all three.
97
+ */
98
+ export declare function writeScreensReport(runDir: string, html: string): Promise<string>;
99
+ /**
100
+ * The summary as markdown, at a path the caller named.
101
+ *
102
+ * Directed by `SETSQUARE_SUMMARY_MD` and written nowhere by default, because this
103
+ * is not one of the run's artefacts — it is a second rendering of the terminal
104
+ * summary for a CI job-summary panel, and a file that appears in every
105
+ * `.setsquare/runs/` directory whether anyone asked for it or not would be one
106
+ * more thing to explain and one more thing to gitignore.
107
+ *
108
+ * `resolve` against the base directory rather than trusting the string, and its own
109
+ * failure domain like every other optional artefact here: a summary that could not
110
+ * be written must cost the summary and nothing else.
111
+ */
112
+ export declare function writeSummaryMarkdown(baseDir: string, path: string, markdown: string): Promise<string>;
113
+ //# sourceMappingURL=output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE1D;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBlF;AAED,wBAAsB,QAAQ,CAC5B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,WAAW,EACrB,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,WAAW,CAAC,GAChD,OAAO,CAAC,cAAc,CAAC,CAazB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,WAAW,EACrB,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,WAAW,CAAC,GAChD,OAAO,CAAC,cAAc,CAAC,CAezB;AAkBD,iFAAiF;AACjF,eAAO,MAAM,iBAAiB,QAA4C,CAAC;AAa3E,MAAM,WAAW,YAAY;IAC3B,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAuCtF;AA8BD;;;;;;;GAOG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAOnF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAItF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,CAKjB"}