@brutalist/mcp 1.13.0 → 1.14.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 (54) hide show
  1. package/README.md +57 -31
  2. package/dist/brutalist-server.js +9 -9
  3. package/dist/brutalist-server.js.map +1 -1
  4. package/dist/cli-adapters/agy-adapter.d.ts +30 -0
  5. package/dist/cli-adapters/agy-adapter.d.ts.map +1 -0
  6. package/dist/cli-adapters/agy-adapter.js +280 -0
  7. package/dist/cli-adapters/agy-adapter.js.map +1 -0
  8. package/dist/cli-adapters/index.d.ts +8 -12
  9. package/dist/cli-adapters/index.d.ts.map +1 -1
  10. package/dist/cli-adapters/index.js +2 -2
  11. package/dist/cli-adapters/index.js.map +1 -1
  12. package/dist/cli-agents.d.ts +6 -29
  13. package/dist/cli-agents.d.ts.map +1 -1
  14. package/dist/cli-agents.js +30 -129
  15. package/dist/cli-agents.js.map +1 -1
  16. package/dist/debate/debate-orchestrator.d.ts +2 -4
  17. package/dist/debate/debate-orchestrator.d.ts.map +1 -1
  18. package/dist/debate/debate-orchestrator.js.map +1 -1
  19. package/dist/domains/argument-space.d.ts +8 -8
  20. package/dist/domains/argument-space.js +3 -3
  21. package/dist/domains/argument-space.js.map +1 -1
  22. package/dist/domains/critic-persona.d.ts +2 -1
  23. package/dist/domains/critic-persona.d.ts.map +1 -1
  24. package/dist/domains/critic-persona.js.map +1 -1
  25. package/dist/handlers/tool-handler.js.map +1 -1
  26. package/dist/mcp-registry.d.ts +0 -6
  27. package/dist/mcp-registry.d.ts.map +1 -1
  28. package/dist/mcp-registry.js +0 -35
  29. package/dist/mcp-registry.js.map +1 -1
  30. package/dist/metrics/registry.d.ts +2 -2
  31. package/dist/metrics/registry.js +2 -2
  32. package/dist/metrics/types.d.ts +1 -1
  33. package/dist/metrics/types.js +1 -1
  34. package/dist/model-resolver.d.ts +1 -13
  35. package/dist/model-resolver.d.ts.map +1 -1
  36. package/dist/model-resolver.js +12 -7
  37. package/dist/model-resolver.js.map +1 -1
  38. package/dist/streaming/output-parser.d.ts +1 -1
  39. package/dist/streaming/output-parser.d.ts.map +1 -1
  40. package/dist/streaming/output-parser.js +0 -17
  41. package/dist/streaming/output-parser.js.map +1 -1
  42. package/dist/streaming/streaming-orchestrator.js +1 -1
  43. package/dist/streaming/streaming-orchestrator.js.map +1 -1
  44. package/dist/types/brutalist.d.ts +3 -3
  45. package/dist/types/brutalist.d.ts.map +1 -1
  46. package/dist/types/tool-config.d.ts +4 -4
  47. package/dist/types/tool-config.d.ts.map +1 -1
  48. package/dist/types/tool-config.js +7 -6
  49. package/dist/types/tool-config.js.map +1 -1
  50. package/package.json +4 -3
  51. package/dist/cli-adapters/gemini-adapter.d.ts +0 -84
  52. package/dist/cli-adapters/gemini-adapter.d.ts.map +0 -1
  53. package/dist/cli-adapters/gemini-adapter.js +0 -305
  54. package/dist/cli-adapters/gemini-adapter.js.map +0 -1
@@ -1,305 +0,0 @@
1
- /**
2
- * Gemini CLI Adapter
3
- *
4
- * Encapsulates Gemini-specific CLI configuration, command construction,
5
- * and output decoding (JSON response field extraction).
6
- *
7
- * Pattern A (integrate-observability): logger is threaded via
8
- * CLIAgentOptions.log (buildCommand) and the optional `log` parameter on
9
- * decodeOutput. Falls back to the root logger singleton when absent so
10
- * legacy test proxies keep working.
11
- */
12
- import { logger as rootLogger } from '../logger.js';
13
- import { resolveServers, listRegisteredServers, ensureGeminiMCPServers, } from '../mcp-registry.js';
14
- /**
15
- * Cycle 4 Task T19 (F10 — security): pre-filter caller-supplied MCP
16
- * server names against the registry-known set BEFORE handing them to
17
- * `resolveServers`. Unknown names must not reach
18
- * `mcp-registry.ts:75` where they would be interpolated raw into the
19
- * warning message. Emits only bounded metadata (counts) via the
20
- * adapter's scoped logger — never the unknown-name strings
21
- * themselves, which crossed the trust boundary from the MCP tool
22
- * caller.
23
- *
24
- * Guarded via `typeof listRegisteredServers === 'function'` so that
25
- * test harnesses which mock the mcp-registry module with a narrower
26
- * surface (omitting listRegisteredServers) fall through the filter
27
- * transparently. In production, `listRegisteredServers` is always a
28
- * function, and the filter runs as intended.
29
- */
30
- function sanitizeMcpServerNames(requested, log) {
31
- if (typeof listRegisteredServers !== 'function') {
32
- return requested;
33
- }
34
- const known = new Set(listRegisteredServers());
35
- const kept = [];
36
- let droppedCount = 0;
37
- for (const name of requested) {
38
- if (known.has(name)) {
39
- kept.push(name);
40
- }
41
- else {
42
- droppedCount++;
43
- }
44
- }
45
- if (droppedCount > 0) {
46
- log.warn('Unknown MCP servers skipped', {
47
- unknownCount: droppedCount,
48
- knownCount: kept.length,
49
- });
50
- }
51
- return kept;
52
- }
53
- const GEMINI_CONFIG = {
54
- command: 'gemini',
55
- defaultArgs: ['--output-format', 'json'],
56
- modelArgName: '--model',
57
- envExtras: { TERM: 'dumb', NO_COLOR: '1', CI: 'true' },
58
- mpcEnvCleanup: ['GEMINI_MCP_CONFIG', 'MCP_ENABLED'],
59
- mcpSupport: {
60
- configMethod: 'server-whitelist',
61
- whitelistFlag: '--allowed-mcp-server-names',
62
- writeProtection: {
63
- method: 'approval-mode',
64
- flag: '--approval-mode',
65
- value: 'plan',
66
- },
67
- },
68
- };
69
- /**
70
- * Frontier Gemini model chain.
71
- *
72
- * Ordered by preference: newest pro preview → previous pro preview →
73
- * 3-series flash preview. The orchestrator rotates through this chain
74
- * on saturation/access failures (429 / "No capacity available" / 403),
75
- * trading "freshest capability" for "delivered response" as the
76
- * preview tiers exhaust.
77
- *
78
- * Rationale: Gemini CLI's default Auto routing resolves to
79
- * `gemini-2.5-flash-lite` for prompts the router classifies as "simple" —
80
- * a classification our full adversarial verification protocol apparently
81
- * does not escape. flash-lite lacks the capacity to maintain URL/quote
82
- * source-provenance across 5+ citation verification loads, so it
83
- * fabricates. Pinning specific frontier models trades the Auto router's
84
- * variable downselect for predictable capacity; rotation handles the
85
- * preview tier's availability.
86
- *
87
- * Why `gemini-3-flash-preview` as the floor (not `gemini-2.5-pro`):
88
- * Gemini 3 Flash ships with "Pro-grade reasoning at Flash-level speed
89
- * and lower cost" per Google's docs, and unlike 2.5-flash-lite it has
90
- * the capacity for our verification protocol. It's also priced an
91
- * order of magnitude below the pro tiers, so when both pro previews
92
- * are unavailable, 3-flash is a substantively better fallback than
93
- * dropping a generation back to 2.5-pro.
94
- *
95
- * Probe-tested in Gemini CLI: the strings below are the canonical
96
- * preview identifiers. `gemini-3-pro`, `gemini-3.1-pro`,
97
- * `gemini-3.0-pro`, `gemini-3-flash` (no `-preview`),
98
- * `gemini-3-pro-exp`, `gemini-3-pro-002`, and `gemini-pro-3` all
99
- * return ModelNotFoundError. The `-preview` suffix is required for
100
- * the 3.x tier.
101
- *
102
- * Override the whole chain with a single model via
103
- * `BRUTALIST_GEMINI_MODEL=...` (disables rotation — operator takes
104
- * responsibility for availability; this is the path for users who
105
- * still want `gemini-2.5-pro` as their pin). Passing `models.gemini`
106
- * on a tool call similarly disables rotation.
107
- */
108
- export const GEMINI_FRONTIER_CHAIN = Object.freeze([
109
- 'gemini-3.1-pro-preview', // newest pro frontier, preview (capacity-limited)
110
- 'gemini-3-pro-preview', // previous pro frontier, preview
111
- 'gemini-3-flash-preview', // 3-series flash, pro-grade reasoning at flash cost
112
- ]);
113
- const GEMINI_FRONTIER_MODEL = process.env.BRUTALIST_GEMINI_MODEL || GEMINI_FRONTIER_CHAIN[0];
114
- export class GeminiAdapter {
115
- name = 'gemini';
116
- getConfig() {
117
- return GEMINI_CONFIG;
118
- }
119
- async buildCommand(userPrompt, systemPrompt, options, modelResolver, secureEnv) {
120
- const log = options.log ?? rootLogger;
121
- const config = GEMINI_CONFIG;
122
- const mcpEnabled = options.mcpServers && options.mcpServers.length > 0;
123
- // Build args
124
- const args = [...config.defaultArgs];
125
- // Priority: caller-specified > env override > frontier default.
126
- // We always pass --model to prevent Gemini CLI's Auto router from
127
- // silently downselecting to flash-lite under verification load.
128
- const resolvedModel = modelResolver.resolveModel('gemini', options.models?.gemini) || GEMINI_FRONTIER_MODEL;
129
- args.push(config.modelArgName, resolvedModel);
130
- // MCP configuration
131
- if (mcpEnabled && config.mcpSupport) {
132
- // Pre-filter via sanitizeMcpServerNames — unknown names are
133
- // dropped before they reach `mcp-registry.ts:75`
134
- // (Cycle 4 Task T19 / F10).
135
- const sanitizedNames = sanitizeMcpServerNames(options.mcpServers, log);
136
- const servers = resolveServers(sanitizedNames);
137
- const serverNames = Object.keys(servers);
138
- if (serverNames.length > 0) {
139
- const mcp = config.mcpSupport;
140
- // Gemini: --allowed-mcp-server-names <names> --approval-mode plan
141
- await ensureGeminiMCPServers(servers);
142
- args.push(mcp.whitelistFlag, ...serverNames);
143
- args.push(mcp.writeProtection.flag, mcp.writeProtection.value);
144
- log.info(`\u{1F50C} MCP enabled for gemini: [${serverNames.join(', ')}]`);
145
- }
146
- }
147
- // Build prompt -- no promptWrapper for Gemini
148
- const combinedPrompt = `${systemPrompt}\n\n${userPrompt}`;
149
- // Add CLI-specific env extras
150
- const env = { ...secureEnv };
151
- if (config.envExtras) {
152
- Object.assign(env, config.envExtras);
153
- }
154
- // Add required API keys
155
- const apiKeys = ['GOOGLE_API_KEY', 'GEMINI_API_KEY'];
156
- for (const key of apiKeys) {
157
- if (process.env[key])
158
- env[key] = process.env[key];
159
- }
160
- // Clean up MPC env vars that could cause deadlock -- SKIP when MCP is enabled
161
- if (!mcpEnabled && config.mpcEnvCleanup) {
162
- for (const envVar of config.mpcEnvCleanup) {
163
- delete env[envVar];
164
- }
165
- }
166
- env.BRUTALIST_SUBPROCESS = '1';
167
- return { command: config.command, args, input: combinedPrompt, env, model: resolvedModel };
168
- }
169
- /**
170
- * Extract response text from Gemini --output-format json output.
171
- * Parses a single JSON object and returns the `response` field.
172
- */
173
- decodeOutput(rawOutput, args, log) {
174
- // Legacy text-only API.
175
- const result = this.decode(rawOutput, '', args, log);
176
- return result.kind === 'ok' ? result.text : '';
177
- }
178
- decode(stdout, stderr, args, log) {
179
- // Only structured-decode if Gemini was run with --output-format json
180
- if (!(args.includes('--output-format') && args.includes('json'))) {
181
- return { kind: 'ok', text: stdout };
182
- }
183
- return this.decodeJson(stdout, stderr, log ?? rootLogger);
184
- }
185
- /**
186
- * Structured decode of Gemini --output-format json output.
187
- *
188
- * Gemini exits 0 on quota and bakes the refusal text into the
189
- * `response` field itself — there is no envelope-level signal in the
190
- * stdout JSON to distinguish a real answer from a refusal. So:
191
- * - parse stdout; non-empty `response` → ok (best-effort; we can't
192
- * tell the difference here without prose matching, which we
193
- * explicitly refuse to do)
194
- * - empty/missing `response`, or unparseable stdout, AND stderr
195
- * matches anchored Google API quota markers → refused (quota)
196
- * - empty + no anchored markers → error (empty/malformed)
197
- *
198
- * Per the user direction for Phase 2: anchored stderr markers only.
199
- * No fallback to loose patterns. The honest residual is that a
200
- * gemini quota that prints ONLY to `response` (no stderr signal)
201
- * passes through as a normal response — surfaced to the caller as
202
- * agent output. That is documented and accepted.
203
- */
204
- decodeJson(jsonOutput, stderr, log) {
205
- if (!jsonOutput || !jsonOutput.trim()) {
206
- // Stdout empty — check stderr for anchored quota markers before
207
- // declaring this an empty error.
208
- if (classifyGeminiStderrReason(stderr) === 'quota') {
209
- return { kind: 'refused', reason: 'quota' };
210
- }
211
- log.debug('extractGeminiResponse: empty input');
212
- return { kind: 'error', reason: 'empty' };
213
- }
214
- try {
215
- const parsed = JSON.parse(jsonOutput);
216
- if (parsed.response && typeof parsed.response === 'string') {
217
- log.info(`✅ extractGeminiResponse: extracted response with ${parsed.response.length} chars`);
218
- return { kind: 'ok', text: parsed.response };
219
- }
220
- log.warn('extractGeminiResponse: no response field in JSON output', {
221
- keys: Object.keys(parsed)
222
- });
223
- // No response field — check anchored stderr markers before
224
- // treating as error.
225
- if (classifyGeminiStderrReason(stderr) === 'quota') {
226
- return { kind: 'refused', reason: 'quota' };
227
- }
228
- return { kind: 'error', reason: 'empty' };
229
- }
230
- catch (e) {
231
- // Redacted: raw jsonOutput is never emitted — only its length plus
232
- // the parse error reason. Prevents prompt / response leakage
233
- // through log aggregators.
234
- log.warn('extractGeminiResponse: failed to parse JSON', {
235
- error: e instanceof Error ? e.message : String(e),
236
- length: jsonOutput.length
237
- });
238
- if (classifyGeminiStderrReason(stderr) === 'quota') {
239
- return { kind: 'refused', reason: 'quota' };
240
- }
241
- return { kind: 'error', reason: 'malformed' };
242
- }
243
- }
244
- extractGeminiResponse(jsonOutput, log) {
245
- if (!jsonOutput || !jsonOutput.trim()) {
246
- log.debug('extractGeminiResponse: empty input');
247
- return '';
248
- }
249
- try {
250
- const parsed = JSON.parse(jsonOutput);
251
- if (parsed.response && typeof parsed.response === 'string') {
252
- log.info(`\u2705 extractGeminiResponse: extracted response with ${parsed.response.length} chars`);
253
- return parsed.response;
254
- }
255
- log.warn('extractGeminiResponse: no response field in JSON output', {
256
- keys: Object.keys(parsed)
257
- });
258
- return '';
259
- }
260
- catch (e) {
261
- // Redacted: raw jsonOutput is never emitted — only its length plus
262
- // the parse error reason. Prevents prompt / response leakage
263
- // through log aggregators.
264
- log.warn('extractGeminiResponse: failed to parse JSON, returning raw output', {
265
- error: e instanceof Error ? e.message : String(e),
266
- length: jsonOutput.length
267
- });
268
- return '';
269
- }
270
- }
271
- }
272
- /**
273
- * Classify Gemini stderr against anchored Google API quota markers.
274
- * Operates only on stderr, never on the `response` field or any other
275
- * assistant-author surface.
276
- *
277
- * Anchored markers chosen against the literal strings Google's API and
278
- * gemini-cli surface on quota:
279
- * - "RESOURCE_EXHAUSTED" — gRPC / Google API status code
280
- * - "Quota exceeded for quota metric" — Google API canonical phrase
281
- * - "Quota exhausted" — alt phrasing
282
- * - "rateLimitExceeded" — Google API error reason
283
- * - "userRateLimitExceeded" — per-user variant
284
- * - "429" — HTTP status
285
- *
286
- * No loose `rate limit` / `usage limit` / `plan.*limit` patterns. The
287
- * known residual: a quota state that prints only to gemini's `response`
288
- * field (no stderr signal) passes through as a normal answer. We
289
- * document and accept that — gemini's protocol gives us no honest way
290
- * to distinguish that case from a real reply.
291
- */
292
- function classifyGeminiStderrReason(stderr) {
293
- if (!stderr)
294
- return 'unknown';
295
- const markers = [
296
- /RESOURCE_EXHAUSTED/,
297
- /Quota exceeded for quota metric/i,
298
- /Quota exhausted/i,
299
- /rateLimitExceeded/i,
300
- /userRateLimitExceeded/i,
301
- /\b429\b/,
302
- ];
303
- return markers.some((p) => p.test(stderr)) ? 'quota' : 'unknown';
304
- }
305
- //# sourceMappingURL=gemini-adapter.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"gemini-adapter.js","sourceRoot":"","sources":["../../src/cli-adapters/gemini-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,cAAc,CAAC;AAKpD,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;;;;;;;;;GAeG;AACH,SAAS,sBAAsB,CAC7B,SAAmB,EACnB,GAAqB;IAErB,IAAI,OAAO,qBAAqB,KAAK,UAAU,EAAE,CAAC;QAChD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,qBAAqB,EAAE,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACpB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,YAAY,EAAE,CAAC;QACjB,CAAC;IACH,CAAC;IACD,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;QACrB,GAAG,CAAC,IAAI,CAAC,6BAA6B,EAAE;YACtC,YAAY,EAAE,YAAY;YAC1B,UAAU,EAAE,IAAI,CAAC,MAAM;SACxB,CAAC,CAAC;IACL,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,aAAa,GAAqB;IACtC,OAAO,EAAE,QAAQ;IACjB,WAAW,EAAE,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACxC,YAAY,EAAE,SAAS;IACvB,SAAS,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE;IACtD,aAAa,EAAE,CAAC,mBAAmB,EAAE,aAAa,CAAC;IACnD,UAAU,EAAE;QACV,YAAY,EAAE,kBAAkB;QAChC,aAAa,EAAE,4BAA4B;QAC3C,eAAe,EAAE;YACf,MAAM,EAAE,eAAe;YACvB,IAAI,EAAE,iBAAiB;YACvB,KAAK,EAAE,MAAM;SACd;KACF;CACF,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAsB,MAAM,CAAC,MAAM,CAAC;IACpE,wBAAwB,EAAG,kDAAkD;IAC7E,sBAAsB,EAAK,iCAAiC;IAC5D,wBAAwB,EAAG,oDAAoD;CAChF,CAAC,CAAC;AAEH,MAAM,qBAAqB,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,qBAAqB,CAAC,CAAC,CAAC,CAAC;AAE7F,MAAM,OAAO,aAAa;IACf,IAAI,GAAY,QAAQ,CAAC;IAElC,SAAS;QACP,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,YAAY,CAChB,UAAkB,EAClB,YAAoB,EACpB,OAAwB,EACxB,aAA4B,EAC5B,SAAiC;QASjC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,UAAU,CAAC;QACtC,MAAM,MAAM,GAAG,aAAa,CAAC;QAC7B,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;QAEvE,aAAa;QACb,MAAM,IAAI,GAAG,CAAC,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;QACrC,gEAAgE;QAChE,kEAAkE;QAClE,gEAAgE;QAChE,MAAM,aAAa,GAAG,aAAa,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,qBAAqB,CAAC;QAC5G,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;QAE9C,oBAAoB;QACpB,IAAI,UAAU,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACpC,4DAA4D;YAC5D,iDAAiD;YACjD,4BAA4B;YAC5B,MAAM,cAAc,GAAG,sBAAsB,CAAC,OAAO,CAAC,UAAW,EAAE,GAAG,CAAC,CAAC;YACxE,MAAM,OAAO,GAAG,cAAc,CAAC,cAAc,CAAC,CAAC;YAC/C,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAEzC,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3B,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC;gBAE9B,kEAAkE;gBAClE,MAAM,sBAAsB,CAAC,OAAO,CAAC,CAAC;gBACtC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,aAAc,EAAE,GAAG,WAAW,CAAC,CAAC;gBAC9C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;gBAE/D,GAAG,CAAC,IAAI,CAAC,sCAAsC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC5E,CAAC;QACH,CAAC;QAED,8CAA8C;QAC9C,MAAM,cAAc,GAAG,GAAG,YAAY,OAAO,UAAU,EAAE,CAAC;QAE1D,8BAA8B;QAC9B,MAAM,GAAG,GAAG,EAAE,GAAG,SAAS,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;YACrB,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;QACvC,CAAC;QAED,wBAAwB;QACxB,MAAM,OAAO,GAAG,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,CAAC;QACrD,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,GAAG,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC;QACrD,CAAC;QAED,8EAA8E;QAC9E,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;YACxC,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;gBAC1C,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;QAED,GAAG,CAAC,oBAAoB,GAAG,GAAG,CAAC;QAE/B,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;IAC7F,CAAC;IAED;;;OAGG;IACH,YAAY,CAAC,SAAiB,EAAE,IAAc,EAAE,GAAsB;QACpE,wBAAwB;QACxB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;QACrD,OAAO,MAAM,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACjD,CAAC;IAED,MAAM,CACJ,MAAc,EACd,MAAc,EACd,IAAc,EACd,GAAsB;QAEtB,qEAAqE;QACrE,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;YACjE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QACtC,CAAC;QACD,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,UAAU,CAAC,CAAC;IAC5D,CAAC;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACK,UAAU,CAChB,UAAkB,EAClB,MAAc,EACd,GAAqB;QAErB,IAAI,CAAC,UAAU,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC;YACtC,gEAAgE;YAChE,iCAAiC;YACjC,IAAI,0BAA0B,CAAC,MAAM,CAAC,KAAK,OAAO,EAAE,CAAC;gBACnD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;YAC9C,CAAC;YACD,GAAG,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;YAChD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;QAC5C,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YACtC,IAAI,MAAM,CAAC,QAAQ,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC3D,GAAG,CAAC,IAAI,CAAC,oDAAoD,MAAM,CAAC,QAAQ,CAAC,MAAM,QAAQ,CAAC,CAAC;gBAC7F,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;YAC/C,CAAC;YACD,GAAG,CAAC,IAAI,CAAC,yDAAyD,EAAE;gBAClE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;aAC1B,CAAC,CAAC;YACH,2DAA2D;YAC3D,qBAAqB;YACrB,IAAI,0BAA0B,CAAC,MAAM,CAAC,KAAK,OAAO,EAAE,CAAC;gBACnD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;YAC9C,CAAC;YACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;QAC5C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,mEAAmE;YACnE,6DAA6D;YAC7D,2BAA2B;YAC3B,GAAG,CAAC,IAAI,CAAC,6CAA6C,EAAE;gBACtD,KAAK,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;gBACjD,MAAM,EAAE,UAAU,CAAC,MAAM;aAC1B,CAAC,CAAC;YACH,IAAI,0BAA0B,CAAC,MAAM,CAAC,KAAK,OAAO,EAAE,CAAC;gBACnD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;YAC9C,CAAC;YACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;QAChD,CAAC;IACH,CAAC;IAEO,qBAAqB,CAAC,UAAkB,EAAE,GAAqB;QACrE,IAAI,CAAC,UAAU,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC;YACtC,GAAG,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;YAChD,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YACtC,IAAI,MAAM,CAAC,QAAQ,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC3D,GAAG,CAAC,IAAI,CAAC,yDAAyD,MAAM,CAAC,QAAQ,CAAC,MAAM,QAAQ,CAAC,CAAC;gBAClG,OAAO,MAAM,CAAC,QAAQ,CAAC;YACzB,CAAC;YACD,GAAG,CAAC,IAAI,CAAC,yDAAyD,EAAE;gBAClE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;aAC1B,CAAC,CAAC;YACH,OAAO,EAAE,CAAC;QACZ,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,mEAAmE;YACnE,6DAA6D;YAC7D,2BAA2B;YAC3B,GAAG,CAAC,IAAI,CAAC,mEAAmE,EAAE;gBAC5E,KAAK,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;gBACjD,MAAM,EAAE,UAAU,CAAC,MAAM;aAC1B,CAAC,CAAC;YACH,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;CACF;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,SAAS,0BAA0B,CAAC,MAA0B;IAC5D,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAC9B,MAAM,OAAO,GAAG;QACd,oBAAoB;QACpB,kCAAkC;QAClC,kBAAkB;QAClB,oBAAoB;QACpB,wBAAwB;QACxB,SAAS;KACV,CAAC;IACF,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AACnE,CAAC"}