council-review 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 (108) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +374 -0
  3. package/dist/bin.d.ts +3 -0
  4. package/dist/bin.d.ts.map +1 -0
  5. package/dist/bin.js +19 -0
  6. package/dist/bin.js.map +1 -0
  7. package/dist/cli.d.ts +14 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +829 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/config.d.ts +61 -0
  12. package/dist/config.d.ts.map +1 -0
  13. package/dist/config.js +235 -0
  14. package/dist/config.js.map +1 -0
  15. package/dist/herdr.d.ts +36 -0
  16. package/dist/herdr.d.ts.map +1 -0
  17. package/dist/herdr.js +196 -0
  18. package/dist/herdr.js.map +1 -0
  19. package/dist/index.d.ts +30 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +30 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/levels.d.ts +9 -0
  24. package/dist/levels.d.ts.map +1 -0
  25. package/dist/levels.js +19 -0
  26. package/dist/levels.js.map +1 -0
  27. package/dist/merge.d.ts +90 -0
  28. package/dist/merge.d.ts.map +1 -0
  29. package/dist/merge.js +441 -0
  30. package/dist/merge.js.map +1 -0
  31. package/dist/node-guard.d.ts +9 -0
  32. package/dist/node-guard.d.ts.map +1 -0
  33. package/dist/node-guard.js +21 -0
  34. package/dist/node-guard.js.map +1 -0
  35. package/dist/panel.d.ts +89 -0
  36. package/dist/panel.d.ts.map +1 -0
  37. package/dist/panel.js +275 -0
  38. package/dist/panel.js.map +1 -0
  39. package/dist/picker.d.ts +24 -0
  40. package/dist/picker.d.ts.map +1 -0
  41. package/dist/picker.js +182 -0
  42. package/dist/picker.js.map +1 -0
  43. package/dist/providers.d.ts +66 -0
  44. package/dist/providers.d.ts.map +1 -0
  45. package/dist/providers.js +544 -0
  46. package/dist/providers.js.map +1 -0
  47. package/dist/report.d.ts +116 -0
  48. package/dist/report.d.ts.map +1 -0
  49. package/dist/report.js +493 -0
  50. package/dist/report.js.map +1 -0
  51. package/dist/resolve.d.ts +58 -0
  52. package/dist/resolve.d.ts.map +1 -0
  53. package/dist/resolve.js +147 -0
  54. package/dist/resolve.js.map +1 -0
  55. package/dist/reviewer-spawn.d.ts +67 -0
  56. package/dist/reviewer-spawn.d.ts.map +1 -0
  57. package/dist/reviewer-spawn.js +94 -0
  58. package/dist/reviewer-spawn.js.map +1 -0
  59. package/dist/reviewer-tools.d.ts +113 -0
  60. package/dist/reviewer-tools.d.ts.map +1 -0
  61. package/dist/reviewer-tools.js +557 -0
  62. package/dist/reviewer-tools.js.map +1 -0
  63. package/dist/runner.d.ts +79 -0
  64. package/dist/runner.d.ts.map +1 -0
  65. package/dist/runner.js +811 -0
  66. package/dist/runner.js.map +1 -0
  67. package/dist/schema.d.ts +63 -0
  68. package/dist/schema.d.ts.map +1 -0
  69. package/dist/schema.js +302 -0
  70. package/dist/schema.js.map +1 -0
  71. package/dist/scope.d.ts +40 -0
  72. package/dist/scope.d.ts.map +1 -0
  73. package/dist/scope.js +372 -0
  74. package/dist/scope.js.map +1 -0
  75. package/dist/snapshot.d.ts +57 -0
  76. package/dist/snapshot.d.ts.map +1 -0
  77. package/dist/snapshot.js +471 -0
  78. package/dist/snapshot.js.map +1 -0
  79. package/dist/status.d.ts +90 -0
  80. package/dist/status.d.ts.map +1 -0
  81. package/dist/status.js +336 -0
  82. package/dist/status.js.map +1 -0
  83. package/dist/thinking.d.ts +53 -0
  84. package/dist/thinking.d.ts.map +1 -0
  85. package/dist/thinking.js +116 -0
  86. package/dist/thinking.js.map +1 -0
  87. package/package.json +81 -0
  88. package/src/bin.ts +20 -0
  89. package/src/cli.ts +996 -0
  90. package/src/config.ts +338 -0
  91. package/src/herdr.ts +231 -0
  92. package/src/index.ts +30 -0
  93. package/src/levels.ts +23 -0
  94. package/src/merge.ts +548 -0
  95. package/src/node-guard.ts +25 -0
  96. package/src/panel.ts +354 -0
  97. package/src/picker.ts +230 -0
  98. package/src/providers.ts +778 -0
  99. package/src/report.ts +594 -0
  100. package/src/resolve.ts +179 -0
  101. package/src/reviewer-spawn.ts +131 -0
  102. package/src/reviewer-tools.ts +715 -0
  103. package/src/runner.ts +1120 -0
  104. package/src/schema.ts +373 -0
  105. package/src/scope.ts +448 -0
  106. package/src/snapshot.ts +536 -0
  107. package/src/status.ts +470 -0
  108. package/src/thinking.ts +148 -0
@@ -0,0 +1,116 @@
1
+ import type { MergedFinding } from './merge.js';
2
+ import type { ResolutionOutcome } from './resolve.js';
3
+ import type { ReviewerResult, RunPanelOutcome } from './runner.js';
4
+ import type { ResolvedScope } from './scope.js';
5
+ import type { SnapshotIdentity } from './snapshot.js';
6
+ export interface RunDir {
7
+ id: string;
8
+ path: string;
9
+ reviewsDir: string;
10
+ }
11
+ /** `<projectRoot>/.council/reviews` — the container directory for every run. */
12
+ export declare function reviewsDirPath(projectRoot: string): string;
13
+ /**
14
+ * Creates a fresh, uniquely named run directory (plus its `reviewers/` subdirectory) under
15
+ * `<projectRoot>/.council/reviews`. On the vanishingly unlikely event that two runs start in the
16
+ * same millisecond, a numeric suffix is appended to the id until directory creation succeeds —
17
+ * the suffixed id is still lexicographically greater than its unsuffixed base (a string that is a
18
+ * strict prefix of another always sorts before it), so chronological ordering is preserved either
19
+ * way.
20
+ */
21
+ export declare function createRunDir(projectRoot: string): RunDir;
22
+ /**
23
+ * Atomically creates or replaces the `last` symlink to point at `run`. Symlinking to the run's
24
+ * own id (a relative target, not an absolute path) keeps the pointer valid even if the whole
25
+ * `.council/reviews` directory is later moved or copied.
26
+ *
27
+ * `fs.renameSync` is used rather than removing then recreating `last`, because rename is atomic
28
+ * on POSIX: there is no window in which `last` is absent or pointing at a half-written target.
29
+ * The caller must be able to rely on this — it's what makes "the pointer is updated even by a
30
+ * degraded run" true in the presence of a crash immediately after this call.
31
+ */
32
+ export declare function updateLastPointer(run: RunDir): void;
33
+ /**
34
+ * Deterministic, collision-free filename slug for a `provider/model` pair. A pure
35
+ * lowercase-and-replace scheme is not collision-free on its own — `openrouter/a/b` and
36
+ * `openrouter/a-b` would both sanitize to the same text — so the slug always carries an 8-hex-char
37
+ * SHA-256 prefix of the exact, untouched `"provider/model"` string. Two different models collide
38
+ * on a filename only if they collide on that hash, which is what "collision-free" is grounded in
39
+ * here rather than in the sanitization itself.
40
+ */
41
+ export declare function slugifyModel(provider: string, model: string): string;
42
+ /**
43
+ * Writes the three raw artifacts for one reviewer, regardless of its outcome — including a
44
+ * reviewer that failed validation on both attempts. `findings` is written as `null` (valid JSON)
45
+ * when the reviewer never produced a schema-valid block, which is itself informative: the file's
46
+ * presence, not its content, is what the spec requires for every reviewer.
47
+ */
48
+ export declare function writeReviewerArtifacts(run: RunDir, r: ReviewerResult): void;
49
+ /** The exact text written to `findings.json` and emitted in machine-readable mode — kept as one
50
+ * function so the two can never drift apart. */
51
+ export declare function serializeFindings(findings: readonly MergedFinding[]): string;
52
+ export declare function writeFindings(run: RunDir, findings: readonly MergedFinding[]): string;
53
+ /**
54
+ * Machine-readable output mode (task 15.8): writes ONLY the merged findings document to `stream`
55
+ * (defaulting to `process.stdout`, overridable for tests). This function touches no other stream
56
+ * and prints nothing else, which is what keeps stdout parseable in that mode — the caller (the
57
+ * CLI) is responsible for routing progress and diagnostics to stderr instead of calling
58
+ * `console.log`/`process.stdout.write` itself while this mode is active.
59
+ */
60
+ export declare function emitMachineReadableFindings(findings: readonly MergedFinding[], stream?: NodeJS.WritableStream): void;
61
+ export interface ManifestInput {
62
+ run: RunDir;
63
+ identity: SnapshotIdentity;
64
+ scope: ResolvedScope;
65
+ outcome: RunPanelOutcome;
66
+ suppressed: number;
67
+ overrides: {
68
+ allowCorrelated: boolean;
69
+ includeContextFiles: boolean;
70
+ noSuppress: boolean;
71
+ };
72
+ hostVersion: string | null;
73
+ }
74
+ /**
75
+ * Writes the manifest: everything needed to explain and reproduce a run, per the reporting
76
+ * spec's "Manifest contract" requirement. Deliberately omits `scope.patch` (the diff text) —
77
+ * that content already exists verbatim as `patch.diff`, and there is no reason for a document
78
+ * whose scenarios are about reproducibility metadata to carry a second copy of it.
79
+ *
80
+ * Nothing here ever reads `process.env`, a credential store, or reviewer stdout beyond the
81
+ * already-structured `ReviewerResult` fields (`usage`, `cost`, `depth`, `state`, `error`) — see
82
+ * the "Manifest carries no credentials" test in `test/unit/report.test.ts`.
83
+ */
84
+ export declare function writeManifest(i: ManifestInput): string;
85
+ /**
86
+ * Writes the human report. Ordering is fixed by the spec and is exactly the order this function
87
+ * builds it in: the resolution summary (when resolution diffing was requested — i.e. `resolution
88
+ * !== null` — whether or not a baseline turned out to be available), then the panel, then
89
+ * findings in merged (agreement) order, then the footer's suppressed/degraded/cost summary.
90
+ *
91
+ * A run with no findings still produces a complete, valid report: the panel section is unaffected
92
+ * and the findings section states plainly that none were raised, per the "Report for a run with
93
+ * no findings" scenario.
94
+ */
95
+ export declare function writeReport(run: RunDir, i: ManifestInput, findings: readonly MergedFinding[], resolution: ResolutionOutcome | null): string;
96
+ /**
97
+ * Writes the handoff prompt — addressed to a coding agent, not to a person — naming the run
98
+ * directory and the merged findings file, requiring reproduction before any fix, directing
99
+ * ambiguity to the raw per-reviewer artifacts, and framing a low-agreement finding as a
100
+ * hypothesis to test rather than an established defect.
101
+ */
102
+ export declare function writeHandoff(run: RunDir, findingsPath: string): string;
103
+ /** Every run directory under `<projectRoot>/.council/reviews`, newest first. Lexicographic sort
104
+ * is chronological sort, per `createRunDir`'s id format. Returns `[]` when no run has ever been
105
+ * written (the reviews directory does not exist yet), rather than throwing. */
106
+ export declare function listRuns(projectRoot: string): RunDir[];
107
+ /**
108
+ * Prunes stored runs, retaining the `keep` most recent ones, and never removing the run `last`
109
+ * resolves to even if it would otherwise fall outside that count (it never does in practice,
110
+ * since `last` always points at the newest run, but the protection is explicit rather than
111
+ * incidental). Returns the ids removed; an empty array when there was nothing to prune.
112
+ */
113
+ export declare function gcRuns(projectRoot: string, keep: number): {
114
+ removed: string[];
115
+ };
116
+ //# sourceMappingURL=report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,iBAAiB,EAAmB,MAAM,cAAc,CAAC;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAOtD,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,gFAAgF;AAChF,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE1D;AAsBD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAqBxD;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAiBnD;AAcD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAIpE;AAMD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,cAAc,GAAG,IAAI,CAoB3E;AAMD;gDACgD;AAChD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,GAAG,MAAM,CAE5E;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,aAAa,EAAE,GAAG,MAAM,CAIrF;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,SAAS,aAAa,EAAE,EAClC,MAAM,GAAE,MAAM,CAAC,cAA+B,GAC7C,IAAI,CAEN;AAMD,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,KAAK,EAAE,aAAa,CAAC;IACrB,OAAO,EAAE,eAAe,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE;QAAE,eAAe,EAAE,OAAO,CAAC;QAAC,mBAAmB,EAAE,OAAO,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAE,CAAC;IAC3F,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM,CAoEtD;AAoFD;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,MAAM,EACX,CAAC,EAAE,aAAa,EAChB,QAAQ,EAAE,SAAS,aAAa,EAAE,EAClC,UAAU,EAAE,iBAAiB,GAAG,IAAI,GACnC,MAAM,CA8DR;AAMD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CA4CtE;AAMD;;+EAE+E;AAC/E,wBAAgB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAwBtD;AAYD;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAgB/E"}
package/dist/report.js ADDED
@@ -0,0 +1,493 @@
1
+ /**
2
+ * Writes everything a run leaves behind: the run directory itself and the most-recent pointer,
3
+ * the manifest, the per-reviewer raw artifacts, the merged findings document, the human report,
4
+ * the handoff prompt, and the machine-readable stdout form of the findings document. Also reads
5
+ * and prunes past runs (`listRuns`, `gcRuns`), which back the `show` and `gc` CLI commands.
6
+ *
7
+ * See `openspec/changes/add-council-review/specs/council-review/reporting/spec.md` for the
8
+ * requirements this implements, and CONTRACT.md's "PINNED: run-directory layout and the
9
+ * most-recent pointer" for the exact on-disk shape other sections (`resolve.ts`, `cli.ts`) read
10
+ * against:
11
+ *
12
+ * .council/reviews/
13
+ * <run-id>/
14
+ * manifest.json
15
+ * patch.diff written by snapshot.ts's writePatch(), never by this module
16
+ * findings.json JSON array of MergedFinding
17
+ * REPORT.md
18
+ * HANDOFF.md
19
+ * reviewers/<slug>.findings.json | .text.md | .trace.jsonl
20
+ * last -> <run-id> SYMLINK to the most recent run directory
21
+ *
22
+ * This module never calls a model, never touches the network, and never calls `process.exit`.
23
+ */
24
+ import fs from 'node:fs';
25
+ import path from 'node:path';
26
+ import { createHash } from 'node:crypto';
27
+ /** `<projectRoot>/.council/reviews` — the container directory for every run. */
28
+ export function reviewsDirPath(projectRoot) {
29
+ return path.join(projectRoot, '.council', 'reviews');
30
+ }
31
+ /**
32
+ * A timestamp id down to the millisecond, in a fixed-width, purely numeric-plus-`T`/`Z` form
33
+ * (`20260904T153012123Z`). Fixed-width fields with no separators mean lexicographic string order
34
+ * is exactly chronological order, and every character is filesystem-safe on POSIX (and Windows,
35
+ * incidentally, since the usual offender — `:` — never appears).
36
+ */
37
+ function timestampId(now) {
38
+ const pad = (n, len = 2) => String(n).padStart(len, '0');
39
+ return (`${now.getUTCFullYear()}${pad(now.getUTCMonth() + 1)}${pad(now.getUTCDate())}T` +
40
+ `${pad(now.getUTCHours())}${pad(now.getUTCMinutes())}${pad(now.getUTCSeconds())}${pad(now.getUTCMilliseconds(), 3)}Z`);
41
+ }
42
+ function isEexistError(err) {
43
+ return (typeof err === 'object' && err !== null && err.code === 'EEXIST');
44
+ }
45
+ /**
46
+ * Creates a fresh, uniquely named run directory (plus its `reviewers/` subdirectory) under
47
+ * `<projectRoot>/.council/reviews`. On the vanishingly unlikely event that two runs start in the
48
+ * same millisecond, a numeric suffix is appended to the id until directory creation succeeds —
49
+ * the suffixed id is still lexicographically greater than its unsuffixed base (a string that is a
50
+ * strict prefix of another always sorts before it), so chronological ordering is preserved either
51
+ * way.
52
+ */
53
+ export function createRunDir(projectRoot) {
54
+ const reviewsDir = reviewsDirPath(projectRoot);
55
+ fs.mkdirSync(reviewsDir, { recursive: true });
56
+ const base = timestampId(new Date());
57
+ let id = base;
58
+ let dir = path.join(reviewsDir, id);
59
+ let suffix = 1;
60
+ for (;;) {
61
+ try {
62
+ fs.mkdirSync(dir);
63
+ break;
64
+ }
65
+ catch (err) {
66
+ if (!isEexistError(err))
67
+ throw err;
68
+ suffix += 1;
69
+ id = `${base}-${suffix}`;
70
+ dir = path.join(reviewsDir, id);
71
+ }
72
+ }
73
+ fs.mkdirSync(path.join(dir, 'reviewers'));
74
+ return { id, path: dir, reviewsDir };
75
+ }
76
+ /**
77
+ * Atomically creates or replaces the `last` symlink to point at `run`. Symlinking to the run's
78
+ * own id (a relative target, not an absolute path) keeps the pointer valid even if the whole
79
+ * `.council/reviews` directory is later moved or copied.
80
+ *
81
+ * `fs.renameSync` is used rather than removing then recreating `last`, because rename is atomic
82
+ * on POSIX: there is no window in which `last` is absent or pointing at a half-written target.
83
+ * The caller must be able to rely on this — it's what makes "the pointer is updated even by a
84
+ * degraded run" true in the presence of a crash immediately after this call.
85
+ */
86
+ export function updateLastPointer(run) {
87
+ const lastPath = path.join(run.reviewsDir, 'last');
88
+ const tmpPath = path.join(run.reviewsDir, `.last.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
89
+ fs.symlinkSync(run.id, tmpPath, 'dir');
90
+ try {
91
+ fs.renameSync(tmpPath, lastPath);
92
+ }
93
+ catch (err) {
94
+ try {
95
+ fs.rmSync(tmpPath, { force: true });
96
+ }
97
+ catch {
98
+ // best-effort cleanup of the temp link; the rename error is what matters
99
+ }
100
+ throw err;
101
+ }
102
+ }
103
+ // -------------------------------------------------------------------------------------------
104
+ // Filename slugification (task 15.2)
105
+ // -------------------------------------------------------------------------------------------
106
+ function sanitizeSegment(s) {
107
+ const cleaned = s
108
+ .toLowerCase()
109
+ .replace(/[^a-z0-9]+/g, '-')
110
+ .replace(/^-+|-+$/g, '');
111
+ return cleaned.length > 0 ? cleaned : 'x';
112
+ }
113
+ /**
114
+ * Deterministic, collision-free filename slug for a `provider/model` pair. A pure
115
+ * lowercase-and-replace scheme is not collision-free on its own — `openrouter/a/b` and
116
+ * `openrouter/a-b` would both sanitize to the same text — so the slug always carries an 8-hex-char
117
+ * SHA-256 prefix of the exact, untouched `"provider/model"` string. Two different models collide
118
+ * on a filename only if they collide on that hash, which is what "collision-free" is grounded in
119
+ * here rather than in the sanitization itself.
120
+ */
121
+ export function slugifyModel(provider, model) {
122
+ const key = `${provider}/${model}`;
123
+ const hash = createHash('sha256').update(key, 'utf8').digest('hex').slice(0, 8);
124
+ return `${hash}-${sanitizeSegment(provider)}__${sanitizeSegment(model)}`;
125
+ }
126
+ // -------------------------------------------------------------------------------------------
127
+ // Per-reviewer raw artifacts (task 15.3)
128
+ // -------------------------------------------------------------------------------------------
129
+ /**
130
+ * Writes the three raw artifacts for one reviewer, regardless of its outcome — including a
131
+ * reviewer that failed validation on both attempts. `findings` is written as `null` (valid JSON)
132
+ * when the reviewer never produced a schema-valid block, which is itself informative: the file's
133
+ * presence, not its content, is what the spec requires for every reviewer.
134
+ */
135
+ export function writeReviewerArtifacts(run, r) {
136
+ const slug = slugifyModel(r.reviewer.provider, r.reviewer.model);
137
+ const dir = path.join(run.path, 'reviewers');
138
+ fs.mkdirSync(dir, { recursive: true });
139
+ fs.writeFileSync(path.join(dir, `${slug}.findings.json`), `${JSON.stringify(r.findings, null, 2)}\n`, 'utf8');
140
+ const heading = `${r.reviewer.provider}/${r.reviewer.model}`;
141
+ const textParts = [`# ${heading} — attempt 1\n\n${r.finalText}`];
142
+ if (r.repairText !== null) {
143
+ textParts.push(`\n\n---\n\n# ${heading} — repair attempt\n\n${r.repairText}`);
144
+ }
145
+ fs.writeFileSync(path.join(dir, `${slug}.text.md`), `${textParts.join('')}\n`, 'utf8');
146
+ const trace = r.rawTrace.length > 0 ? `${r.rawTrace.join('\n')}\n` : '';
147
+ fs.writeFileSync(path.join(dir, `${slug}.trace.jsonl`), trace, 'utf8');
148
+ }
149
+ // -------------------------------------------------------------------------------------------
150
+ // Merged findings document
151
+ // -------------------------------------------------------------------------------------------
152
+ /** The exact text written to `findings.json` and emitted in machine-readable mode — kept as one
153
+ * function so the two can never drift apart. */
154
+ export function serializeFindings(findings) {
155
+ return `${JSON.stringify(findings, null, 2)}\n`;
156
+ }
157
+ export function writeFindings(run, findings) {
158
+ const dest = path.join(run.path, 'findings.json');
159
+ fs.writeFileSync(dest, serializeFindings(findings), 'utf8');
160
+ return dest;
161
+ }
162
+ /**
163
+ * Machine-readable output mode (task 15.8): writes ONLY the merged findings document to `stream`
164
+ * (defaulting to `process.stdout`, overridable for tests). This function touches no other stream
165
+ * and prints nothing else, which is what keeps stdout parseable in that mode — the caller (the
166
+ * CLI) is responsible for routing progress and diagnostics to stderr instead of calling
167
+ * `console.log`/`process.stdout.write` itself while this mode is active.
168
+ */
169
+ export function emitMachineReadableFindings(findings, stream = process.stdout) {
170
+ stream.write(serializeFindings(findings));
171
+ }
172
+ /**
173
+ * Writes the manifest: everything needed to explain and reproduce a run, per the reporting
174
+ * spec's "Manifest contract" requirement. Deliberately omits `scope.patch` (the diff text) —
175
+ * that content already exists verbatim as `patch.diff`, and there is no reason for a document
176
+ * whose scenarios are about reproducibility metadata to carry a second copy of it.
177
+ *
178
+ * Nothing here ever reads `process.env`, a credential store, or reviewer stdout beyond the
179
+ * already-structured `ReviewerResult` fields (`usage`, `cost`, `depth`, `state`, `error`) — see
180
+ * the "Manifest carries no credentials" test in `test/unit/report.test.ts`.
181
+ */
182
+ export function writeManifest(i) {
183
+ const manifest = {
184
+ runId: i.run.id,
185
+ createdAt: new Date().toISOString(),
186
+ hostVersion: i.hostVersion,
187
+ reviewed: {
188
+ commit: i.identity.head,
189
+ dirty: i.identity.dirty,
190
+ treeHash: i.identity.treeHash,
191
+ },
192
+ scope: {
193
+ mode: i.scope.mode,
194
+ selectors: i.scope.selectors,
195
+ baseBranch: i.scope.baseBranch,
196
+ mergeBase: i.scope.mergeBase,
197
+ endRevision: i.scope.endRevision,
198
+ head: i.scope.head,
199
+ dirty: i.scope.dirty,
200
+ empty: i.scope.empty,
201
+ files: i.scope.files,
202
+ },
203
+ panel: i.outcome.results.map((r) => ({
204
+ provider: r.reviewer.provider,
205
+ model: r.reviewer.model,
206
+ vendor: r.reviewer.vendor,
207
+ thinking: {
208
+ requested: r.reviewer.thinking.requested,
209
+ effective: r.reviewer.thinking.effective,
210
+ applicable: r.reviewer.thinking.applicable,
211
+ clamped: r.reviewer.thinking.clamped,
212
+ },
213
+ })),
214
+ reviewers: i.outcome.results.map((r) => ({
215
+ provider: r.reviewer.provider,
216
+ model: r.reviewer.model,
217
+ state: r.state,
218
+ startedAt: r.startedAt,
219
+ endedAt: r.endedAt,
220
+ durationMs: r.endedAt - r.startedAt,
221
+ usage: r.usage,
222
+ cost: r.cost,
223
+ depth: {
224
+ filesOpenedCount: r.depth.filesOpened.length,
225
+ filesOpened: r.depth.filesOpened,
226
+ searches: r.depth.searches,
227
+ },
228
+ ...(r.error !== undefined ? { error: r.error } : {}),
229
+ })),
230
+ counts: {
231
+ launched: i.outcome.launched,
232
+ reporting: i.outcome.reporting,
233
+ suppressed: i.suppressed,
234
+ },
235
+ cost: {
236
+ total: i.outcome.totalCost, // null === unknown, never coerced to 0
237
+ incomplete: i.outcome.costIncomplete,
238
+ },
239
+ degraded: i.outcome.degraded,
240
+ overrides: {
241
+ allowCorrelated: i.overrides.allowCorrelated,
242
+ includeContextFiles: i.overrides.includeContextFiles,
243
+ noSuppress: i.overrides.noSuppress,
244
+ },
245
+ };
246
+ const dest = path.join(i.run.path, 'manifest.json');
247
+ fs.writeFileSync(dest, `${JSON.stringify(manifest, null, 2)}\n`, 'utf8');
248
+ return dest;
249
+ }
250
+ // -------------------------------------------------------------------------------------------
251
+ // REPORT.md (task 15.6)
252
+ // -------------------------------------------------------------------------------------------
253
+ function formatThinking(t) {
254
+ if (!t.applicable)
255
+ return 'n/a';
256
+ if (t.effective === null)
257
+ return 'none';
258
+ return t.clamped ? `${t.effective} (clamped from ${t.requested})` : t.effective;
259
+ }
260
+ function formatCost(cost) {
261
+ return cost === null ? 'unknown' : `$${cost.toFixed(4)}`;
262
+ }
263
+ function formatDepth(d) {
264
+ const files = d.filesOpened.length;
265
+ return `${files} file${files === 1 ? '' : 's'} opened, ${d.searches} search${d.searches === 1 ? '' : 'es'}`;
266
+ }
267
+ function renderResolutionSection(resolution) {
268
+ if (resolution.baselineRunId === null) {
269
+ return [
270
+ '## Resolution',
271
+ '',
272
+ 'No baseline run was available for comparison, so findings below carry no resolution ' +
273
+ 'marking. This is the first run to be diffed, not a run with zero new findings.',
274
+ '',
275
+ ];
276
+ }
277
+ const { resolved, stillPresent, new: newCount } = resolution.counts;
278
+ const lines = [
279
+ '## Resolution',
280
+ '',
281
+ `Compared against run \`${resolution.baselineRunId}\`: ${resolved} resolved, ` +
282
+ `${stillPresent} still present, ${newCount} new.`,
283
+ '',
284
+ ];
285
+ if (resolution.resolved.length > 0) {
286
+ lines.push('Resolved since the baseline run:', '');
287
+ for (const f of resolution.resolved) {
288
+ lines.push(`- \`${f.file}:${f.line}\` — ${f.claim}`);
289
+ }
290
+ lines.push('');
291
+ }
292
+ return lines;
293
+ }
294
+ function renderFinding(f, resolutionByFingerprint) {
295
+ const marker = resolutionByFingerprint?.get(f.fingerprint) ?? null;
296
+ const markerText = marker ? ` [${marker}]` : '';
297
+ const location = f.endLine !== null ? `${f.file}:${f.line}-${f.endLine}` : `${f.file}:${f.line}`;
298
+ const lines = [
299
+ `### ${f.id} — ${f.severity.toUpperCase()} · ${f.category}${markerText}`,
300
+ '',
301
+ `**Location:** \`${location}\``,
302
+ `**Agreement:** ${f.agreement.raisers}/${f.agreement.reporting} reviewers (${f.raisedBy.join(', ')})`,
303
+ `**Claim:** ${f.claim}`,
304
+ `**Impact:** ${f.impact}`,
305
+ ];
306
+ if (f.unverifiable) {
307
+ lines.push('', '_This finding references a path absent from the reviewed snapshot; it could not be verified._');
308
+ }
309
+ if (f.evidence.length > 0) {
310
+ lines.push('', '**Evidence:**');
311
+ for (const e of f.evidence)
312
+ lines.push(`- ${e}`);
313
+ }
314
+ if (f.suggestions.length > 0) {
315
+ lines.push('', '**Suggestions:**');
316
+ for (const s of f.suggestions)
317
+ lines.push(`- ${s}`);
318
+ }
319
+ lines.push('');
320
+ return lines;
321
+ }
322
+ /**
323
+ * Writes the human report. Ordering is fixed by the spec and is exactly the order this function
324
+ * builds it in: the resolution summary (when resolution diffing was requested — i.e. `resolution
325
+ * !== null` — whether or not a baseline turned out to be available), then the panel, then
326
+ * findings in merged (agreement) order, then the footer's suppressed/degraded/cost summary.
327
+ *
328
+ * A run with no findings still produces a complete, valid report: the panel section is unaffected
329
+ * and the findings section states plainly that none were raised, per the "Report for a run with
330
+ * no findings" scenario.
331
+ */
332
+ export function writeReport(run, i, findings, resolution) {
333
+ const lines = [`# Council Review — ${run.id}`, ''];
334
+ if (resolution !== null) {
335
+ lines.push(...renderResolutionSection(resolution));
336
+ }
337
+ lines.push('## Panel', '', '| Reviewer | Vendor | Thinking | Cost | Depth |', '|---|---|---|---|---|');
338
+ for (const r of i.outcome.results) {
339
+ lines.push(`| ${r.reviewer.provider}/${r.reviewer.model} | ${r.reviewer.vendor} | ` +
340
+ `${formatThinking(r.reviewer.thinking)} | ${formatCost(r.cost)} | ${formatDepth(r.depth)} |`);
341
+ }
342
+ lines.push('');
343
+ lines.push('## Findings', '');
344
+ if (findings.length === 0) {
345
+ lines.push('No findings were raised.', '');
346
+ }
347
+ else {
348
+ const resolutionByFingerprint = resolution !== null
349
+ ? new Map(resolution.current.map((f) => [f.fingerprint, f.resolution]))
350
+ : null;
351
+ for (const f of findings) {
352
+ lines.push(...renderFinding(f, resolutionByFingerprint));
353
+ }
354
+ }
355
+ lines.push('## Summary', '');
356
+ lines.push(`- Launched: ${i.outcome.launched}, reporting: ${i.outcome.reporting}`);
357
+ lines.push(`- Suppressed: ${i.suppressed}`);
358
+ const degradedReviewers = i.outcome.results.filter((r) => r.state !== 'ok');
359
+ if (degradedReviewers.length > 0) {
360
+ const detail = degradedReviewers
361
+ .map((r) => `${r.reviewer.provider}/${r.reviewer.model} (${r.state}${r.error ? `: ${r.error}` : ''})`)
362
+ .join('; ');
363
+ lines.push(`- Degraded (${degradedReviewers.length}): ${detail}`);
364
+ }
365
+ else {
366
+ lines.push('- Degraded: none');
367
+ }
368
+ const costSuffix = i.outcome.costIncomplete
369
+ ? ' (incomplete — one or more reviewers had no cost data)'
370
+ : '';
371
+ lines.push(`- Total cost: ${i.outcome.totalCost === null ? 'unknown' : `$${i.outcome.totalCost.toFixed(4)}`}${costSuffix}`);
372
+ lines.push('');
373
+ const dest = path.join(run.path, 'REPORT.md');
374
+ fs.writeFileSync(dest, lines.join('\n'), 'utf8');
375
+ return dest;
376
+ }
377
+ // -------------------------------------------------------------------------------------------
378
+ // HANDOFF.md (task 15.7)
379
+ // -------------------------------------------------------------------------------------------
380
+ /**
381
+ * Writes the handoff prompt — addressed to a coding agent, not to a person — naming the run
382
+ * directory and the merged findings file, requiring reproduction before any fix, directing
383
+ * ambiguity to the raw per-reviewer artifacts, and framing a low-agreement finding as a
384
+ * hypothesis to test rather than an established defect.
385
+ */
386
+ export function writeHandoff(run, findingsPath) {
387
+ const reviewersDir = path.join(run.path, 'reviewers');
388
+ const text = [
389
+ '# Council review handoff',
390
+ '',
391
+ 'You are a coding agent picking up the output of an automated, multi-model code review panel.',
392
+ 'Treat this document as your instructions for what to do next, not as a report to read.',
393
+ '',
394
+ `Run directory: \`${run.path}\``,
395
+ `Merged findings: \`${findingsPath}\``,
396
+ '',
397
+ '## Before you change any code',
398
+ '',
399
+ 'Every entry in the merged findings file is a claim made by one or more independent reviewer ' +
400
+ 'models reading a frozen snapshot of the changed code, not a confirmed defect. For each ' +
401
+ 'finding you intend to act on: reproduce it first — read the referenced file and line range ' +
402
+ 'yourself and confirm the claimed behavior actually occurs — before you change anything. Do ' +
403
+ 'not edit code to address a finding you have not reproduced.',
404
+ '',
405
+ '## When a finding is ambiguous',
406
+ '',
407
+ "If a merged finding's claim, location or severity is unclear, do not guess at what the " +
408
+ `reviewer meant. Consult that reviewer's raw output under \`${reviewersDir}\`: the ` +
409
+ '`<slug>.text.md` file holds its verbatim response (both attempts, if it needed a repair), ' +
410
+ 'and the `<slug>.trace.jsonl` file holds every tool call and stream event it produced. The ' +
411
+ 'merged claim is a summary; the raw artifact is the source of truth for what a reviewer ' +
412
+ 'actually said.',
413
+ '',
414
+ '## Low-agreement findings are hypotheses, not defects',
415
+ '',
416
+ "Each finding records how many of the panel's reviewers raised it out of how many reported " +
417
+ '(its `agreement` field). A finding raised by only one or two reviewers out of a larger ' +
418
+ 'panel is a hypothesis worth testing, not an established defect: treat it exactly as you ' +
419
+ "would treat a colleague's unconfirmed suspicion — worth investigating, not worth acting on " +
420
+ 'without confirmation. A finding every reporting reviewer agreed on still requires the same ' +
421
+ 'reproduction step above, but a low-agreement one additionally requires you to explain, in ' +
422
+ 'your own investigation, why the disagreeing reviewers did not see it before treating it as ' +
423
+ 'real.',
424
+ '',
425
+ ].join('\n');
426
+ const dest = path.join(run.path, 'HANDOFF.md');
427
+ fs.writeFileSync(dest, text, 'utf8');
428
+ return dest;
429
+ }
430
+ // -------------------------------------------------------------------------------------------
431
+ // Reading and pruning past runs (tasks feeding the `show` and `gc` CLI commands)
432
+ // -------------------------------------------------------------------------------------------
433
+ /** Every run directory under `<projectRoot>/.council/reviews`, newest first. Lexicographic sort
434
+ * is chronological sort, per `createRunDir`'s id format. Returns `[]` when no run has ever been
435
+ * written (the reviews directory does not exist yet), rather than throwing. */
436
+ export function listRuns(projectRoot) {
437
+ const reviewsDir = reviewsDirPath(projectRoot);
438
+ let entries;
439
+ try {
440
+ entries = fs.readdirSync(reviewsDir, { withFileTypes: true });
441
+ }
442
+ catch {
443
+ return [];
444
+ }
445
+ const ids = entries
446
+ .filter((e) => e.name !== 'last' && !e.name.startsWith('.'))
447
+ .map((e) => e.name)
448
+ .filter((name) => {
449
+ try {
450
+ return fs.statSync(path.join(reviewsDir, name)).isDirectory();
451
+ }
452
+ catch {
453
+ return false;
454
+ }
455
+ })
456
+ .sort()
457
+ .reverse();
458
+ return ids.map((id) => ({ id, path: path.join(reviewsDir, id), reviewsDir }));
459
+ }
460
+ /** Resolves the `last` symlink to the run id it points at, or `null` if it is absent, dangling, or
461
+ * not a symlink at all. Mirrors `resolve.ts`'s own reading of this pointer. */
462
+ function resolveLastRunId(reviewsDir) {
463
+ try {
464
+ return path.basename(fs.realpathSync(path.join(reviewsDir, 'last')));
465
+ }
466
+ catch {
467
+ return null;
468
+ }
469
+ }
470
+ /**
471
+ * Prunes stored runs, retaining the `keep` most recent ones, and never removing the run `last`
472
+ * resolves to even if it would otherwise fall outside that count (it never does in practice,
473
+ * since `last` always points at the newest run, but the protection is explicit rather than
474
+ * incidental). Returns the ids removed; an empty array when there was nothing to prune.
475
+ */
476
+ export function gcRuns(projectRoot, keep) {
477
+ const reviewsDir = reviewsDirPath(projectRoot);
478
+ const runs = listRuns(projectRoot); // newest first
479
+ const protectedId = resolveLastRunId(reviewsDir);
480
+ const keepCount = Math.max(0, keep);
481
+ const toKeep = new Set(runs.slice(0, keepCount).map((r) => r.id));
482
+ if (protectedId !== null)
483
+ toKeep.add(protectedId);
484
+ const removed = [];
485
+ for (const run of runs) {
486
+ if (toKeep.has(run.id))
487
+ continue;
488
+ fs.rmSync(run.path, { recursive: true, force: true });
489
+ removed.push(run.id);
490
+ }
491
+ return { removed };
492
+ }
493
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAmBzC,gFAAgF;AAChF,MAAM,UAAU,cAAc,CAAC,WAAmB;IAChD,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;AACvD,CAAC;AAED;;;;;GAKG;AACH,SAAS,WAAW,CAAC,GAAS;IAC5B,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,GAAG,GAAG,CAAC,EAAU,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACzE,OAAO,CACL,GAAG,GAAG,CAAC,cAAc,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,GAAG;QAC/E,GAAG,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC,GAAG,CACtH,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,GAAY;IACjC,OAAO,CACL,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,CAC5F,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,WAAmB;IAC9C,MAAM,UAAU,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;IAC/C,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE9C,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IACrC,IAAI,EAAE,GAAG,IAAI,CAAC;IACd,IAAI,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACpC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,SAAS,CAAC;QACR,IAAI,CAAC;YACH,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YAClB,MAAM;QACR,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC;gBAAE,MAAM,GAAG,CAAC;YACnC,MAAM,IAAI,CAAC,CAAC;YACZ,EAAE,GAAG,GAAG,IAAI,IAAI,MAAM,EAAE,CAAC;YACzB,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IACD,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC;IAC1C,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC;AACvC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAW;IAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACnD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CACvB,GAAG,CAAC,UAAU,EACd,aAAa,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAChF,CAAC;IACF,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IACvC,IAAI,CAAC;QACH,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACnC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC;YACH,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,yEAAyE;QAC3E,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED,8FAA8F;AAC9F,qCAAqC;AACrC,8FAA8F;AAE9F,SAAS,eAAe,CAAC,CAAS;IAChC,MAAM,OAAO,GAAG,CAAC;SACd,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC3B,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;AAC5C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgB,EAAE,KAAa;IAC1D,MAAM,GAAG,GAAG,GAAG,QAAQ,IAAI,KAAK,EAAE,CAAC;IACnC,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAChF,OAAO,GAAG,IAAI,IAAI,eAAe,CAAC,QAAQ,CAAC,KAAK,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;AAC3E,CAAC;AAED,8FAA8F;AAC9F,yCAAyC;AACzC,8FAA8F;AAE9F;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,GAAW,EAAE,CAAiB;IACnE,MAAM,IAAI,GAAG,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACjE,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAC7C,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEvC,EAAE,CAAC,aAAa,CACd,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,gBAAgB,CAAC,EACvC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAC1C,MAAM,CACP,CAAC;IAEF,MAAM,OAAO,GAAG,GAAG,CAAC,CAAC,QAAQ,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;IAC7D,MAAM,SAAS,GAAa,CAAC,KAAK,OAAO,mBAAmB,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;IAC3E,IAAI,CAAC,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;QAC1B,SAAS,CAAC,IAAI,CAAC,gBAAgB,OAAO,wBAAwB,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;IAChF,CAAC;IACD,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,UAAU,CAAC,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAEvF,MAAM,KAAK,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACxE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,cAAc,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;AACzE,CAAC;AAED,8FAA8F;AAC9F,2BAA2B;AAC3B,8FAA8F;AAE9F;gDACgD;AAChD,MAAM,UAAU,iBAAiB,CAAC,QAAkC;IAClE,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAW,EAAE,QAAkC;IAC3E,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;IAClD,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,iBAAiB,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC;IAC5D,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,2BAA2B,CACzC,QAAkC,EAClC,SAAgC,OAAO,CAAC,MAAM;IAE9C,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC5C,CAAC;AAgBD;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAAC,CAAgB;IAC5C,MAAM,QAAQ,GAAG;QACf,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE;QACf,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,WAAW,EAAE,CAAC,CAAC,WAAW;QAC1B,QAAQ,EAAE;YACR,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI;YACvB,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK;YACvB,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ;SAC9B;QACD,KAAK,EAAE;YACL,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI;YAClB,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS;YAC5B,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU;YAC9B,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS;YAC5B,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW;YAChC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI;YAClB,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK;YACpB,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK;YACpB,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK;SACrB;QACD,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACnC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ;YAC7B,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK;YACvB,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM;YACzB,QAAQ,EAAE;gBACR,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS;gBACxC,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS;gBACxC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,UAAU;gBAC1C,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO;aACrC;SACF,CAAC,CAAC;QACH,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACvC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ;YAC7B,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK;YACvB,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,UAAU,EAAE,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,SAAS;YACnC,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,KAAK,EAAE;gBACL,gBAAgB,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM;gBAC5C,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW;gBAChC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ;aAC3B;YACD,GAAG,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACrD,CAAC,CAAC;QACH,MAAM,EAAE;YACN,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ;YAC5B,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS;YAC9B,UAAU,EAAE,CAAC,CAAC,UAAU;SACzB;QACD,IAAI,EAAE;YACJ,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,uCAAuC;YACnE,UAAU,EAAE,CAAC,CAAC,OAAO,CAAC,cAAc;SACrC;QACD,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ;QAC5B,SAAS,EAAE;YACT,eAAe,EAAE,CAAC,CAAC,SAAS,CAAC,eAAe;YAC5C,mBAAmB,EAAE,CAAC,CAAC,SAAS,CAAC,mBAAmB;YACpD,UAAU,EAAE,CAAC,CAAC,SAAS,CAAC,UAAU;SACnC;KACF,CAAC;IAEF,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;IACpD,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACzE,OAAO,IAAI,CAAC;AACd,CAAC;AAED,8FAA8F;AAC9F,wBAAwB;AACxB,8FAA8F;AAE9F,SAAS,cAAc,CAAC,CAAmB;IACzC,IAAI,CAAC,CAAC,CAAC,UAAU;QAAE,OAAO,KAAK,CAAC;IAChC,IAAI,CAAC,CAAC,SAAS,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC;IACxC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,kBAAkB,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAClF,CAAC;AAED,SAAS,UAAU,CAAC,IAAmB;IACrC,OAAO,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;AAC3D,CAAC;AAED,SAAS,WAAW,CAAC,CAA8C;IACjE,MAAM,KAAK,GAAG,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC;IACnC,OAAO,GAAG,KAAK,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,QAAQ,UAAU,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AAC9G,CAAC;AAED,SAAS,uBAAuB,CAAC,UAA6B;IAC5D,IAAI,UAAU,CAAC,aAAa,KAAK,IAAI,EAAE,CAAC;QACtC,OAAO;YACL,eAAe;YACf,EAAE;YACF,sFAAsF;gBACpF,gFAAgF;YAClF,EAAE;SACH,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC;IACpE,MAAM,KAAK,GAAG;QACZ,eAAe;QACf,EAAE;QACF,0BAA0B,UAAU,CAAC,aAAa,OAAO,QAAQ,aAAa;YAC5E,GAAG,YAAY,mBAAmB,QAAQ,OAAO;QACnD,EAAE;KACH,CAAC;IACF,IAAI,UAAU,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnC,KAAK,CAAC,IAAI,CAAC,kCAAkC,EAAE,EAAE,CAAC,CAAC;QACnD,KAAK,MAAM,CAAC,IAAI,UAAU,CAAC,QAAQ,EAAE,CAAC;YACpC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QACvD,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,aAAa,CACpB,CAAgB,EAChB,uBAAmE;IAEnE,MAAM,MAAM,GAAG,uBAAuB,EAAE,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC;IACnE,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAChD,MAAM,QAAQ,GAAG,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IAEjG,MAAM,KAAK,GAAG;QACZ,OAAO,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,QAAQ,GAAG,UAAU,EAAE;QACxE,EAAE;QACF,mBAAmB,QAAQ,IAAI;QAC/B,kBAAkB,CAAC,CAAC,SAAS,CAAC,OAAO,IAAI,CAAC,CAAC,SAAS,CAAC,SAAS,eAAe,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;QACrG,cAAc,CAAC,CAAC,KAAK,EAAE;QACvB,eAAe,CAAC,CAAC,MAAM,EAAE;KAC1B,CAAC;IACF,IAAI,CAAC,CAAC,YAAY,EAAE,CAAC;QACnB,KAAK,CAAC,IAAI,CACR,EAAE,EACF,+FAA+F,CAChG,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;QAChC,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ;YAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACnD,CAAC;IACD,IAAI,CAAC,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,kBAAkB,CAAC,CAAC;QACnC,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,WAAW;YAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACtD,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,WAAW,CACzB,GAAW,EACX,CAAgB,EAChB,QAAkC,EAClC,UAAoC;IAEpC,MAAM,KAAK,GAAa,CAAC,sBAAsB,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAE7D,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,GAAG,uBAAuB,CAAC,UAAU,CAAC,CAAC,CAAC;IACrD,CAAC;IAED,KAAK,CAAC,IAAI,CACR,UAAU,EACV,EAAE,EACF,iDAAiD,EACjD,uBAAuB,CACxB,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QAClC,KAAK,CAAC,IAAI,CACR,KAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,KAAK;YACtE,GAAG,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAC/F,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;IAC9B,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,KAAK,CAAC,IAAI,CAAC,0BAA0B,EAAE,EAAE,CAAC,CAAC;IAC7C,CAAC;SAAM,CAAC;QACN,MAAM,uBAAuB,GAC3B,UAAU,KAAK,IAAI;YACjB,CAAC,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;YACvE,CAAC,CAAC,IAAI,CAAC;QACX,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,KAAK,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,CAAC,EAAE,uBAAuB,CAAC,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IAC7B,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,QAAQ,gBAAgB,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACnF,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;IAE5C,MAAM,iBAAiB,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC;IAC5E,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,iBAAiB;aAC7B,GAAG,CACF,CAAC,CAAC,EAAE,EAAE,CACJ,GAAG,CAAC,CAAC,QAAQ,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAC5F;aACA,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,KAAK,CAAC,IAAI,CAAC,eAAe,iBAAiB,CAAC,MAAM,MAAM,MAAM,EAAE,CAAC,CAAC;IACpE,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IACjC,CAAC;IAED,MAAM,UAAU,GAAG,CAAC,CAAC,OAAO,CAAC,cAAc;QACzC,CAAC,CAAC,wDAAwD;QAC1D,CAAC,CAAC,EAAE,CAAC;IACP,KAAK,CAAC,IAAI,CACR,iBAAiB,CAAC,CAAC,OAAO,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,UAAU,EAAE,CAChH,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAC9C,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;IACjD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,8FAA8F;AAC9F,yBAAyB;AACzB,8FAA8F;AAE9F;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,YAAoB;IAC5D,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IACtD,MAAM,IAAI,GAAG;QACX,0BAA0B;QAC1B,EAAE;QACF,8FAA8F;QAC9F,wFAAwF;QACxF,EAAE;QACF,oBAAoB,GAAG,CAAC,IAAI,IAAI;QAChC,sBAAsB,YAAY,IAAI;QACtC,EAAE;QACF,+BAA+B;QAC/B,EAAE;QACF,8FAA8F;YAC5F,yFAAyF;YACzF,6FAA6F;YAC7F,6FAA6F;YAC7F,6DAA6D;QAC/D,EAAE;QACF,gCAAgC;QAChC,EAAE;QACF,yFAAyF;YACvF,8DAA8D,YAAY,UAAU;YACpF,4FAA4F;YAC5F,4FAA4F;YAC5F,yFAAyF;YACzF,gBAAgB;QAClB,EAAE;QACF,uDAAuD;QACvD,EAAE;QACF,4FAA4F;YAC1F,yFAAyF;YACzF,0FAA0F;YAC1F,6FAA6F;YAC7F,6FAA6F;YAC7F,4FAA4F;YAC5F,6FAA6F;YAC7F,OAAO;QACT,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAC/C,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IACrC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,8FAA8F;AAC9F,iFAAiF;AACjF,8FAA8F;AAE9F;;+EAE+E;AAC/E,MAAM,UAAU,QAAQ,CAAC,WAAmB;IAC1C,MAAM,UAAU,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;IAE/C,IAAI,OAAoB,CAAC;IACzB,IAAI,CAAC;QACH,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAChE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,GAAG,GAAG,OAAO;SAChB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;SAC3D,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;SAClB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;QACf,IAAI,CAAC;YACH,OAAO,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QAChE,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC,CAAC;SACD,IAAI,EAAE;SACN,OAAO,EAAE,CAAC;IAEb,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;AAChF,CAAC;AAED;+EAC+E;AAC/E,SAAS,gBAAgB,CAAC,UAAkB;IAC1C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IACvE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,MAAM,CAAC,WAAmB,EAAE,IAAY;IACtD,MAAM,UAAU,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,eAAe;IACnD,MAAM,WAAW,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAEjD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACpC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAClE,IAAI,WAAW,KAAK,IAAI;QAAE,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAElD,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,SAAS;QACjC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,CAAC;AACrB,CAAC"}