yoke-mcp 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.
@@ -0,0 +1,606 @@
1
+ // A stdio MCP server for the browser you are already signed in to.
2
+ //
3
+ // Register this with any MCP client and it gets browser automation against your
4
+ // real Chrome profile, with no tab-group boundary: every tab in every window is
5
+ // addressable, not only the ones inside some managed group.
6
+ //
7
+ // Three processes, because Chrome's rules say so:
8
+ //
9
+ // extension --connectNative--> native-host --unix socket--> this server
10
+ //
11
+ // Chrome will only ever spawn the native host itself, so a client cannot talk to
12
+ // the extension directly and the socket in between is not optional.
13
+ import { createInterface } from 'node:readline';
14
+ import { ask, ExtensionUnavailable } from './socket-client.js';
15
+ export const SERVER_NAME = 'yoke';
16
+ export const SERVER_VERSION = '0.1.0';
17
+ export const PROTOCOL_VERSION = '2024-11-05';
18
+ /**
19
+ * The label on the group holding tabs yoke opened.
20
+ *
21
+ * Decided here rather than in the extension because it is policy, and policy
22
+ * belongs where it can be changed and tested without reloading a browser. The
23
+ * extension keeps the same value as a fallback, for a caller that names nothing.
24
+ */
25
+ export const DEFAULT_GROUP_TITLE = 'yoke';
26
+ /** origin and path only, so a tab listing never leaks a token in a query string. */
27
+ export function shownUrl(url, full = false) {
28
+ if (full) {
29
+ return url;
30
+ }
31
+ try {
32
+ const parsed = new URL(url);
33
+ // A wrapper scheme's path can itself be a URL with credentials in it, so
34
+ // anything that is not plain http shows only its scheme.
35
+ if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
36
+ return parsed.protocol;
37
+ }
38
+ return `${parsed.origin}${parsed.pathname === '/' ? '' : parsed.pathname}`;
39
+ }
40
+ catch {
41
+ return '(unparseable url)';
42
+ }
43
+ }
44
+ export const TOOLS = [
45
+ {
46
+ name: 'list_tabs',
47
+ description: 'List every open tab in the browser, across all windows, with its id, title and URL. '
48
+ + 'Unlike a tab-group-scoped bridge this sees the whole browser, so any tab it returns can '
49
+ + 'be passed straight to the other tools. URLs are reduced to origin and path by default, '
50
+ + 'because a raw URL can carry credentials, a session token or a query string; pass '
51
+ + 'full_urls to opt out.',
52
+ inputSchema: {
53
+ type: 'object',
54
+ properties: {
55
+ full_urls: {
56
+ type: 'boolean',
57
+ default: false,
58
+ description: 'Return raw URLs instead of origin and path.',
59
+ },
60
+ },
61
+ },
62
+ },
63
+ {
64
+ name: 'list_tab_groups',
65
+ description: "List the browser's tab groups with their ids, titles and colours, including groups that "
66
+ + 'hold no tabs, which nothing outside an extension can see.',
67
+ inputSchema: { type: 'object', properties: {} },
68
+ },
69
+ {
70
+ name: 'navigate',
71
+ description: 'Navigate one tab to a URL and wait for it to finish loading. The tab is named by id, '
72
+ + 'never implied: there is no acting on "the active tab", because that is whatever the '
73
+ + 'person happens to be looking at. Returns once the load reports complete, so a caller '
74
+ + 'is not left racing the page it just asked for.',
75
+ inputSchema: {
76
+ type: 'object',
77
+ required: ['tab_id', 'url'],
78
+ properties: {
79
+ tab_id: { type: 'number', description: 'From list_tabs.' },
80
+ url: { type: 'string', description: 'http and https only.' },
81
+ timeout_ms: { type: 'number', description: 'How long to wait for the load. Default 20000.' },
82
+ },
83
+ },
84
+ },
85
+ {
86
+ name: 'open_tab',
87
+ description: 'Open a new tab, optionally at a URL. Opens in the background by default, because a '
88
+ + 'script should not pull focus away from what someone is doing. The new tab joins a named '
89
+ + 'group, created if absent and reused if present, so the tab strip shows which tabs an '
90
+ + 'automation is working in. Tabs you already had are never moved into it.',
91
+ inputSchema: {
92
+ type: 'object',
93
+ properties: {
94
+ url: { type: 'string' },
95
+ active: { type: 'boolean', default: false, description: 'Focus the new tab.' },
96
+ group_title: {
97
+ type: 'string',
98
+ default: 'yoke',
99
+ description: 'The label on the group. Defaults to yoke, so the tab strip names what is driving it.',
100
+ },
101
+ },
102
+ },
103
+ },
104
+ {
105
+ name: 'close_tab',
106
+ description: 'Close one tab by id.',
107
+ inputSchema: {
108
+ type: 'object',
109
+ required: ['tab_id'],
110
+ properties: { tab_id: { type: 'number' } },
111
+ },
112
+ },
113
+ {
114
+ name: 'read_page',
115
+ description: 'The interactive elements of a page: links, buttons, inputs, each with a ref, a role and a '
116
+ + 'name. Call this before clicking or typing, and act by ref rather than by coordinate. A '
117
+ + 'coordinate is a guess that one reflow invalidates, and afterwards you cannot tell whether '
118
+ + 'you hit what you meant; a ref resolves to the element that was described. Refs are only '
119
+ + 'valid until the page navigates or re-renders.',
120
+ inputSchema: {
121
+ type: 'object',
122
+ required: ['tab_id'],
123
+ properties: {
124
+ tab_id: { type: 'number' },
125
+ max_elements: { type: 'number', description: 'Default 200.' },
126
+ },
127
+ },
128
+ },
129
+ {
130
+ name: 'find',
131
+ description: 'The elements of a page whose name or role matches some text. A filtered read_page, for '
132
+ + 'when you know what you are looking for.',
133
+ inputSchema: {
134
+ type: 'object',
135
+ required: ['tab_id', 'text'],
136
+ properties: { tab_id: { type: 'number' }, text: { type: 'string' } },
137
+ },
138
+ },
139
+ {
140
+ name: 'click',
141
+ description: 'Click an element by ref from read_page. Produces a real, trusted click through the '
142
+ + 'DevTools Protocol, which pages cannot tell from a person; a synthesised event from page '
143
+ + 'JavaScript arrives with isTrusted false and many sites ignore it. Attaching the debugger '
144
+ + 'shows Chrome\'s "started debugging this browser" bar on the tab, and Chrome allows one '
145
+ + 'debugger client per tab, so a tab with DevTools open cannot be driven.',
146
+ inputSchema: {
147
+ type: 'object',
148
+ required: ['tab_id', 'ref'],
149
+ properties: {
150
+ tab_id: { type: 'number' },
151
+ ref: { type: 'string', description: 'From read_page.' },
152
+ button: { type: 'string', enum: ['left', 'right', 'middle'], default: 'left' },
153
+ click_count: { type: 'number', default: 1, description: '2 for a double click.' },
154
+ },
155
+ },
156
+ },
157
+ {
158
+ name: 'type_text',
159
+ description: 'Type into the page. Pass a ref to click it first, which is how you focus a field. Inserts '
160
+ + 'the text in one operation rather than a keystroke at a time, so it also handles '
161
+ + 'characters no single key produces.',
162
+ inputSchema: {
163
+ type: 'object',
164
+ required: ['tab_id', 'text'],
165
+ properties: {
166
+ tab_id: { type: 'number' },
167
+ text: { type: 'string' },
168
+ ref: { type: 'string', description: 'Focus this element first.' },
169
+ press_enter: { type: 'boolean', default: false },
170
+ },
171
+ },
172
+ },
173
+ {
174
+ name: 'press_key',
175
+ description: 'Press one named key: Enter, Tab, Escape, Backspace or an arrow.',
176
+ inputSchema: {
177
+ type: 'object',
178
+ required: ['tab_id', 'key'],
179
+ properties: {
180
+ tab_id: { type: 'number' },
181
+ key: { type: 'string' },
182
+ ref: { type: 'string', description: 'Focus this element first.' },
183
+ },
184
+ },
185
+ },
186
+ {
187
+ name: 'scroll',
188
+ description: 'Scroll a page, or scroll an element into view by ref.',
189
+ inputSchema: {
190
+ type: 'object',
191
+ required: ['tab_id'],
192
+ properties: {
193
+ tab_id: { type: 'number' },
194
+ dy: { type: 'number', default: 400, description: 'Positive scrolls down.' },
195
+ dx: { type: 'number', default: 0 },
196
+ ref: { type: 'string' },
197
+ },
198
+ },
199
+ },
200
+ {
201
+ name: 'screenshot',
202
+ description: 'A screenshot of a tab, returned as an image. Works on a background tab, which '
203
+ + 'chrome.tabs.captureVisibleTab cannot do: it only photographs the active tab of a window.',
204
+ inputSchema: {
205
+ type: 'object',
206
+ required: ['tab_id'],
207
+ properties: {
208
+ tab_id: { type: 'number' },
209
+ format: { type: 'string', enum: ['png', 'jpeg'], default: 'png' },
210
+ quality: { type: 'number', description: 'JPEG only, 0 to 100.' },
211
+ },
212
+ },
213
+ },
214
+ {
215
+ name: 'run_javascript',
216
+ description: "Evaluate an expression in the page's own world, so it sees the page's variables, and "
217
+ + 'return the value. Top-level await works. A thrown error comes back as the result rather '
218
+ + 'than as a transport failure.',
219
+ inputSchema: {
220
+ type: 'object',
221
+ required: ['tab_id', 'expression'],
222
+ properties: { tab_id: { type: 'number' }, expression: { type: 'string' } },
223
+ },
224
+ },
225
+ {
226
+ name: 'read_console',
227
+ description: 'Console messages and uncaught exceptions for a tab. Only what happened since the tab was '
228
+ + 'first driven: attaching is what starts the recording, so a message from before that is '
229
+ + 'gone. The reply says whether this call was the attachment.',
230
+ inputSchema: {
231
+ type: 'object',
232
+ required: ['tab_id'],
233
+ properties: { tab_id: { type: 'number' }, limit: { type: 'number', default: 100 } },
234
+ },
235
+ },
236
+ {
237
+ name: 'read_network',
238
+ description: 'Network requests for a tab, with their statuses. Same recording rule as read_console: '
239
+ + 'history begins when the tab was first driven.',
240
+ inputSchema: {
241
+ type: 'object',
242
+ required: ['tab_id'],
243
+ properties: { tab_id: { type: 'number' }, limit: { type: 'number', default: 100 } },
244
+ },
245
+ },
246
+ {
247
+ name: 'group_tabs',
248
+ description: 'Put tabs into a named tab group, so it is visible in the tab strip which tabs an agent is '
249
+ + 'working in. Reuses an existing group with the same title rather than making a second one, '
250
+ + 'which is how a tab strip ends up with identical pills nobody can tell apart. Purely '
251
+ + 'cosmetic: nothing addresses a tab through its group, so grouping and ungrouping are '
252
+ + 'always safe and never lose track of a tab.',
253
+ inputSchema: {
254
+ type: 'object',
255
+ required: ['tab_ids'],
256
+ properties: {
257
+ tab_ids: { type: 'array', items: { type: 'number' } },
258
+ title: { type: 'string', description: 'The group label. Defaults to yoke.' },
259
+ color: {
260
+ type: 'string',
261
+ enum: ['grey', 'blue', 'red', 'yellow', 'green', 'pink', 'purple', 'cyan', 'orange'],
262
+ },
263
+ },
264
+ },
265
+ },
266
+ {
267
+ name: 'ungroup_tabs',
268
+ description: 'Take tabs out of their group, leaving the tabs open. Removes the pill when the group '
269
+ + 'empties. This is also how to clear a leftover group from any extension, including ones '
270
+ + 'the Claude bridge stranded.',
271
+ inputSchema: {
272
+ type: 'object',
273
+ required: ['tab_ids'],
274
+ properties: { tab_ids: { type: 'array', items: { type: 'number' } } },
275
+ },
276
+ },
277
+ {
278
+ name: 'release_tab',
279
+ description: 'Stop driving a tab: detaches the debugger, which removes the "started debugging" bar and '
280
+ + 'frees the tab for DevTools. Console and network history for that tab is dropped.',
281
+ inputSchema: {
282
+ type: 'object',
283
+ required: ['tab_id'],
284
+ properties: { tab_id: { type: 'number' } },
285
+ },
286
+ },
287
+ {
288
+ name: 'get_page_text',
289
+ description: 'The visible text of a page, by tab id. Uses innerText rather than textContent, so it is '
290
+ + 'what a reader would see: no script or style bodies, and layout respected. Chrome\'s own '
291
+ + 'pages and the Web Store cannot be read, and say so rather than returning nothing.',
292
+ inputSchema: {
293
+ type: 'object',
294
+ required: ['tab_id'],
295
+ properties: {
296
+ tab_id: { type: 'number' },
297
+ max_chars: { type: 'number', description: 'Truncate beyond this. Default 200000.' },
298
+ },
299
+ },
300
+ },
301
+ ];
302
+ const text = (value) => ({ content: [{ type: 'text', text: value }] });
303
+ const failed = (value) => ({ content: [{ type: 'text', text: value }], isError: true });
304
+ /**
305
+ * A tab id, or a refusal naming what arrived instead.
306
+ *
307
+ * An MCP client hands over whatever the model produced, so a string, a float or
308
+ * nothing at all are all realistic. Passing those through would fail somewhere
309
+ * deeper with a worse message.
310
+ */
311
+ function asTabId(value) {
312
+ if (typeof value !== 'number' || !Number.isInteger(value)) {
313
+ throw new Error(`tab_id must be an integer from list_tabs, got ${JSON.stringify(value)}`);
314
+ }
315
+ return value;
316
+ }
317
+ export async function callTool(name, args) {
318
+ if (name === 'list_tabs') {
319
+ const { tabs } = await ask('listTabs');
320
+ if (tabs.length === 0) {
321
+ return text('No tabs reported, which should not happen while a browser is open.');
322
+ }
323
+ const full = args['full_urls'] === true;
324
+ const lines = tabs.map((tab) => `${tab.id}\t${shownUrl(tab.url, full)}\t${tab.title.slice(0, 80)}`);
325
+ return text(`${tabs.length} open tab(s), every window included.\nid\turl\ttitle\n${lines.join('\n')}`);
326
+ }
327
+ if (name === 'list_tab_groups') {
328
+ const [{ groups }, { tabs }] = await Promise.all([ask('listGroups'), ask('listTabs')]);
329
+ if (groups.length === 0) {
330
+ return text('No tab groups.');
331
+ }
332
+ const lines = groups.map((group) => {
333
+ const members = tabs.filter((tab) => tab.groupId === group.id).length;
334
+ return `${group.id}\t${JSON.stringify(group.title)}\t${group.color}\t${members} tab(s)`;
335
+ });
336
+ return text(`${groups.length} group(s).\nid\ttitle\tcolour\tmembers\n${lines.join('\n')}`);
337
+ }
338
+ if (name === 'navigate') {
339
+ const tabId = asTabId(args['tab_id']);
340
+ const url = String(args['url'] ?? '');
341
+ // Refused here rather than in the extension, because the reason is a policy
342
+ // and policy belongs where it can be tested without a browser.
343
+ if (!/^https?:\/\//i.test(url)) {
344
+ return failed(`navigate takes an http or https URL, not ${JSON.stringify(url)}`);
345
+ }
346
+ const timeoutMs = typeof args['timeout_ms'] === 'number' ? args['timeout_ms'] : undefined;
347
+ const moved = await ask('navigate', {
348
+ tabId,
349
+ url,
350
+ ...(timeoutMs === undefined ? {} : { timeoutMs }),
351
+ });
352
+ return moved.status === 'complete'
353
+ ? text(`Navigated tab ${moved.tabId} to ${shownUrl(moved.url)}\n${moved.title}`)
354
+ : text(`Tab ${moved.tabId} is at ${shownUrl(moved.url)} but did not report finishing loading `
355
+ + 'within the timeout. The page may still be working.');
356
+ }
357
+ if (name === 'open_tab') {
358
+ const url = args['url'] === undefined ? undefined : String(args['url']);
359
+ if (url !== undefined && !/^https?:\/\//i.test(url)) {
360
+ return failed(`open_tab takes an http or https URL, not ${JSON.stringify(url)}`);
361
+ }
362
+ const groupTitle = args['group_title'] === undefined
363
+ ? DEFAULT_GROUP_TITLE
364
+ : String(args['group_title']);
365
+ const opened = await ask('openTab', {
366
+ ...(url === undefined ? {} : { url }),
367
+ active: args['active'] === true,
368
+ groupTitle,
369
+ });
370
+ // Three outcomes, not two. A reply with no groupId at all comes from an
371
+ // extension build older than this server, and saying so beats printing the
372
+ // word "undefined" at whoever is reading.
373
+ const where = typeof opened.groupId !== 'number'
374
+ ? ' (grouping unknown: the loaded extension predates it, so reload it at chrome://extensions)'
375
+ : opened.groupId === -1
376
+ ? ' (not grouped: Chrome refused, which does not affect the tab)'
377
+ : ` in group ${JSON.stringify(opened.groupTitle)}`;
378
+ return text(`Opened tab ${opened.tab.id} at ${shownUrl(opened.tab.url)}${where}\n${opened.tab.title}`);
379
+ }
380
+ if (name === 'close_tab') {
381
+ const { closed } = await ask('closeTab', { tabId: asTabId(args['tab_id']) });
382
+ return text(`Closed tab ${closed}.`);
383
+ }
384
+ if (name === 'get_page_text') {
385
+ const maxChars = typeof args['max_chars'] === 'number' ? args['max_chars'] : undefined;
386
+ const page = await ask('getPageText', {
387
+ tabId: asTabId(args['tab_id']),
388
+ ...(maxChars === undefined ? {} : { maxChars }),
389
+ });
390
+ const note = page.truncated ? '\n\n[truncated]' : '';
391
+ return text(`${page.title}\n${shownUrl(page.url)}\n---\n${page.text}${note}`);
392
+ }
393
+ if (name === 'read_page' || name === 'find') {
394
+ const maxElements = typeof args['max_elements'] === 'number' ? args['max_elements'] : undefined;
395
+ const page = await ask('readPage', {
396
+ tabId: asTabId(args['tab_id']),
397
+ ...(maxElements === undefined ? {} : { maxElements }),
398
+ });
399
+ const needle = name === 'find' ? String(args['text'] ?? '').toLowerCase() : null;
400
+ const shown = needle === null
401
+ ? page.elements
402
+ : page.elements.filter((e) => `${e.name} ${e.role} ${e.tag}`.toLowerCase().includes(needle));
403
+ if (shown.length === 0) {
404
+ return text(needle === null
405
+ ? 'No interactive elements found on this page.'
406
+ : `Nothing on this page matches ${JSON.stringify(args['text'])}.`);
407
+ }
408
+ const rows = shown.map((e) => {
409
+ const extra = [e.value ? `value=${JSON.stringify(e.value)}` : '', e.disabled ? 'disabled' : '']
410
+ .filter(Boolean).join(' ');
411
+ return `${e.ref}\t${e.role}\t${e.name.slice(0, 70)}${extra ? `\t${extra}` : ''}`;
412
+ });
413
+ const note = page.truncated ? '\n[truncated; raise max_elements]' : '';
414
+ return text(`${page.title}\n${shownUrl(page.url)}\n${shown.length} element(s)\nref\trole\tname\n${rows.join('\n')}${note}`);
415
+ }
416
+ if (name === 'click') {
417
+ const button = args['button'];
418
+ const clickCount = typeof args['click_count'] === 'number' ? args['click_count'] : undefined;
419
+ const result = await ask('click', {
420
+ tabId: asTabId(args['tab_id']),
421
+ ref: String(args['ref'] ?? ''),
422
+ ...(button === 'left' || button === 'right' || button === 'middle' ? { button } : {}),
423
+ ...(clickCount === undefined ? {} : { clickCount }),
424
+ });
425
+ // Reported rather than asserted. A click that was dispatched underneath an
426
+ // overlay used to read exactly like one that worked.
427
+ if (result.hit === 'covered') {
428
+ return text(`Dispatched a click at ${result.ref}, but ${result.topmost ?? 'another element'} was on top `
429
+ + 'of it at that point and most likely received it instead. Call read_page again and act on '
430
+ + 'what is actually in front, which is often a cookie or consent banner.');
431
+ }
432
+ if (result.hit === 'nothing') {
433
+ return text(`Dispatched a click at ${result.ref}, but nothing was hit-testable at that point, so it `
434
+ + 'probably went nowhere. The element may be scrolled out of view or covered by a full '
435
+ + 'page overlay.');
436
+ }
437
+ return text(`Clicked ${result.ref}.`);
438
+ }
439
+ if (name === 'type_text') {
440
+ const ref = args['ref'] === undefined ? undefined : String(args['ref']);
441
+ const typed = await ask('typeText', {
442
+ tabId: asTabId(args['tab_id']),
443
+ text: String(args['text'] ?? ''),
444
+ ...(ref === undefined ? {} : { ref }),
445
+ pressEnter: args['press_enter'] === true,
446
+ });
447
+ return text(`Typed ${typed.typed} character(s)${args['press_enter'] === true ? ' and pressed Enter' : ''}.`);
448
+ }
449
+ if (name === 'press_key') {
450
+ const ref = args['ref'] === undefined ? undefined : String(args['ref']);
451
+ const pressed = await ask('pressKey', {
452
+ tabId: asTabId(args['tab_id']),
453
+ key: String(args['key'] ?? ''),
454
+ ...(ref === undefined ? {} : { ref }),
455
+ });
456
+ return text(`Pressed ${pressed.key}.`);
457
+ }
458
+ if (name === 'scroll') {
459
+ const ref = args['ref'] === undefined ? undefined : String(args['ref']);
460
+ const dx = typeof args['dx'] === 'number' ? args['dx'] : undefined;
461
+ const dy = typeof args['dy'] === 'number' ? args['dy'] : undefined;
462
+ const moved = await ask('scroll', {
463
+ tabId: asTabId(args['tab_id']),
464
+ ...(dx === undefined ? {} : { dx }),
465
+ ...(dy === undefined ? {} : { dy }),
466
+ ...(ref === undefined ? {} : { ref }),
467
+ });
468
+ return text(`Scrolled by ${moved.dx}, ${moved.dy}.`);
469
+ }
470
+ if (name === 'screenshot') {
471
+ const format = args['format'] === 'jpeg' ? 'jpeg' : 'png';
472
+ const quality = typeof args['quality'] === 'number' ? args['quality'] : undefined;
473
+ const shot = await ask('screenshot', {
474
+ tabId: asTabId(args['tab_id']),
475
+ format,
476
+ ...(quality === undefined ? {} : { quality }),
477
+ }, { timeoutMs: 30_000 });
478
+ // An image part, not base64 in a text blob: a client that can show an image
479
+ // should get one, and a text field would be unreadable either way.
480
+ return {
481
+ content: [
482
+ { type: 'text', text: `Screenshot of tab ${shot.tabId}, ${shot.format}, ${shot.bytes} bytes.` },
483
+ ],
484
+ images: [{ format: shot.format, base64: shot.base64 }],
485
+ };
486
+ }
487
+ if (name === 'run_javascript') {
488
+ const outcome = await ask('evaluate', {
489
+ tabId: asTabId(args['tab_id']),
490
+ expression: String(args['expression'] ?? ''),
491
+ }, { timeoutMs: 30_000 });
492
+ // A thrown error is the answer, not a transport failure: the caller asked
493
+ // what the page would do, and this is what it did.
494
+ return outcome.threw
495
+ ? text(`threw: ${outcome.value}`)
496
+ : text(`${outcome.type}: ${outcome.value}`);
497
+ }
498
+ if (name === 'read_console') {
499
+ const limit = typeof args['limit'] === 'number' ? args['limit'] : undefined;
500
+ const seen = await ask('consoleMessages', {
501
+ tabId: asTabId(args['tab_id']),
502
+ ...(limit === undefined ? {} : { limit }),
503
+ });
504
+ const preface = seen.attachedNow
505
+ ? 'Recording started with this call, so nothing from before it exists.\n'
506
+ : '';
507
+ if (seen.messages.length === 0) {
508
+ return text(`${preface}No console messages.`);
509
+ }
510
+ const rows = seen.messages.map((m) => `${m.level}\t${m.text.slice(0, 200)}`);
511
+ return text(`${preface}${seen.messages.length} message(s)\nlevel\ttext\n${rows.join('\n')}`);
512
+ }
513
+ if (name === 'read_network') {
514
+ const limit = typeof args['limit'] === 'number' ? args['limit'] : undefined;
515
+ const seen = await ask('networkRequests', {
516
+ tabId: asTabId(args['tab_id']),
517
+ ...(limit === undefined ? {} : { limit }),
518
+ });
519
+ const preface = seen.attachedNow
520
+ ? 'Recording started with this call, so nothing from before it exists.\n'
521
+ : '';
522
+ if (seen.requests.length === 0) {
523
+ return text(`${preface}No requests recorded.`);
524
+ }
525
+ const rows = seen.requests.map((r) => `${r.status ?? '...'}\t${r.method}\t${shownUrl(r.url)}`);
526
+ return text(`${preface}${seen.requests.length} request(s)\nstatus\tmethod\turl\n${rows.join('\n')}`);
527
+ }
528
+ if (name === 'group_tabs' || name === 'ungroup_tabs') {
529
+ const raw = args['tab_ids'];
530
+ if (!Array.isArray(raw) || raw.length === 0) {
531
+ return failed('tab_ids must be a non-empty array of tab ids from list_tabs');
532
+ }
533
+ const tabIds = raw.map((value) => asTabId(value));
534
+ if (name === 'ungroup_tabs') {
535
+ await ask('ungroupTabs', { tabIds });
536
+ return text(`Ungrouped ${tabIds.length} tab(s). They are still open.`);
537
+ }
538
+ const title = args['title'] === undefined ? DEFAULT_GROUP_TITLE : String(args['title']);
539
+ const color = args['color'] === undefined ? undefined : String(args['color']);
540
+ const grouped = await ask('groupTabs', {
541
+ tabIds,
542
+ ...(title === undefined ? {} : { title }),
543
+ ...(color === undefined ? {} : { color }),
544
+ });
545
+ return text(`${tabIds.length} tab(s) are now in group ${grouped.groupId} `
546
+ + `${JSON.stringify(grouped.title)}.`);
547
+ }
548
+ if (name === 'release_tab') {
549
+ const released = await ask('release', { tabId: asTabId(args['tab_id']) });
550
+ return text(released.released
551
+ ? `Released tab ${released.tabId}: the debugging bar is gone and DevTools can attach again.`
552
+ : `Tab ${released.tabId} was not being driven.`);
553
+ }
554
+ return failed(`unknown tool: ${name}`);
555
+ }
556
+ export async function handle(request) {
557
+ if (request.method === 'initialize') {
558
+ return {
559
+ protocolVersion: PROTOCOL_VERSION,
560
+ capabilities: { tools: {} },
561
+ serverInfo: { name: SERVER_NAME, version: SERVER_VERSION },
562
+ };
563
+ }
564
+ if (request.method === 'tools/list') {
565
+ return { tools: TOOLS };
566
+ }
567
+ if (request.method === 'tools/call') {
568
+ const params = request.params ?? {};
569
+ return callTool(params.name ?? '', params.arguments ?? {});
570
+ }
571
+ throw new Error(`unknown method: ${request.method}`);
572
+ }
573
+ export function main() {
574
+ const lines = createInterface({ input: process.stdin, terminal: false });
575
+ const send = (object) => { process.stdout.write(`${JSON.stringify(object)}\n`); };
576
+ lines.on('line', (raw) => {
577
+ const line = raw.trim();
578
+ if (!line) {
579
+ return;
580
+ }
581
+ let request;
582
+ try {
583
+ request = JSON.parse(line);
584
+ }
585
+ catch {
586
+ return;
587
+ }
588
+ // A notification carries no id and must never be answered.
589
+ if (request.id === undefined) {
590
+ return;
591
+ }
592
+ const id = request.id;
593
+ handle(request)
594
+ .then((result) => { send({ jsonrpc: '2.0', id, result }); })
595
+ .catch((thrown) => {
596
+ // An unreachable extension is a condition to report, not a crash: the
597
+ // client should be told to install or load it rather than see a dead
598
+ // server.
599
+ const message = thrown instanceof ExtensionUnavailable || thrown instanceof Error
600
+ ? thrown.message
601
+ : String(thrown);
602
+ send({ jsonrpc: '2.0', id, error: { code: -32000, message } });
603
+ });
604
+ });
605
+ }
606
+ //# sourceMappingURL=mcp-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,EAAE;AACF,gFAAgF;AAChF,gFAAgF;AAChF,4DAA4D;AAC5D,EAAE;AACF,kDAAkD;AAClD,EAAE;AACF,8EAA8E;AAC9E,EAAE;AACF,iFAAiF;AACjF,oEAAoE;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,EAAE,GAAG,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE/D,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC;AAClC,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC;AACtC,MAAM,CAAC,MAAM,gBAAgB,GAAG,YAAY,CAAC;AAE7C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC;AAgB1C,oFAAoF;AACpF,MAAM,UAAU,QAAQ,CAAC,GAAW,EAAE,IAAI,GAAG,KAAK;IAChD,IAAI,IAAI,EAAE,CAAC;QAAC,OAAO,GAAG,CAAC;IAAC,CAAC;IACzB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,yEAAyE;QACzE,yDAAyD;QACzD,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAAC,OAAO,MAAM,CAAC,QAAQ,CAAC;QAAC,CAAC;QAC5F,OAAO,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,QAAQ,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;IAC7E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,mBAAmB,CAAC;IAC7B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB;QACE,IAAI,EAAE,WAAW;QACjB,WAAW,EACT,sFAAsF;cACpF,0FAA0F;cAC1F,yFAAyF;cACzF,mFAAmF;cACnF,uBAAuB;QAC3B,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,SAAS,EAAE;oBACT,IAAI,EAAE,SAAS;oBACf,OAAO,EAAE,KAAK;oBACd,WAAW,EAAE,6CAA6C;iBAC3D;aACF;SACF;KACF;IACD;QACE,IAAI,EAAE,iBAAiB;QACvB,WAAW,EACT,0FAA0F;cACxF,2DAA2D;QAC/D,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE;KAChD;IACD;QACE,IAAI,EAAE,UAAU;QAChB,WAAW,EACT,uFAAuF;cACrF,sFAAsF;cACtF,uFAAuF;cACvF,gDAAgD;QACpD,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC;YAC3B,UAAU,EAAE;gBACV,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,iBAAiB,EAAE;gBAC1D,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sBAAsB,EAAE;gBAC5D,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,+CAA+C,EAAE;aAC7F;SACF;KACF;IACD;QACE,IAAI,EAAE,UAAU;QAChB,WAAW,EACT,qFAAqF;cACnF,0FAA0F;cAC1F,uFAAuF;cACvF,yEAAyE;QAC7E,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBACvB,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,oBAAoB,EAAE;gBAC9E,WAAW,EAAE;oBACX,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,MAAM;oBACf,WAAW,EAAE,sFAAsF;iBACpG;aACF;SACF;KACF;IACD;QACE,IAAI,EAAE,WAAW;QACjB,WAAW,EAAE,sBAAsB;QACnC,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,CAAC,QAAQ,CAAC;YACpB,UAAU,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;SAC3C;KACF;IACD;QACE,IAAI,EAAE,WAAW;QACjB,WAAW,EACT,4FAA4F;cAC1F,yFAAyF;cACzF,4FAA4F;cAC5F,0FAA0F;cAC1F,+CAA+C;QACnD,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,CAAC,QAAQ,CAAC;YACpB,UAAU,EAAE;gBACV,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAC1B,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE;aAC9D;SACF;KACF;IACD;QACE,IAAI,EAAE,MAAM;QACZ,WAAW,EACT,yFAAyF;cACvF,yCAAyC;QAC7C,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC;YAC5B,UAAU,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;SACrE;KACF;IACD;QACE,IAAI,EAAE,OAAO;QACb,WAAW,EACT,qFAAqF;cACnF,0FAA0F;cAC1F,2FAA2F;cAC3F,yFAAyF;cACzF,wEAAwE;QAC5E,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC;YAC3B,UAAU,EAAE;gBACV,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAC1B,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,iBAAiB,EAAE;gBACvD,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE;gBAC9E,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,EAAE,WAAW,EAAE,uBAAuB,EAAE;aAClF;SACF;KACF;IACD;QACE,IAAI,EAAE,WAAW;QACjB,WAAW,EACT,4FAA4F;cAC1F,kFAAkF;cAClF,oCAAoC;QACxC,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC;YAC5B,UAAU,EAAE;gBACV,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAC1B,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBACxB,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,2BAA2B,EAAE;gBACjE,WAAW,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;aACjD;SACF;KACF;IACD;QACE,IAAI,EAAE,WAAW;QACjB,WAAW,EAAE,iEAAiE;QAC9E,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC;YAC3B,UAAU,EAAE;gBACV,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAC1B,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBACvB,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,2BAA2B,EAAE;aAClE;SACF;KACF;IACD;QACE,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,uDAAuD;QACpE,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,CAAC,QAAQ,CAAC;YACpB,UAAU,EAAE;gBACV,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAC1B,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,wBAAwB,EAAE;gBAC3E,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,EAAE;gBAClC,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;aACxB;SACF;KACF;IACD;QACE,IAAI,EAAE,YAAY;QAClB,WAAW,EACT,gFAAgF;cAC9E,0FAA0F;QAC9F,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,CAAC,QAAQ,CAAC;YACpB,UAAU,EAAE;gBACV,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAC1B,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE;gBACjE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sBAAsB,EAAE;aACjE;SACF;KACF;IACD;QACE,IAAI,EAAE,gBAAgB;QACtB,WAAW,EACT,uFAAuF;cACrF,0FAA0F;cAC1F,8BAA8B;QAClC,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,CAAC,QAAQ,EAAE,YAAY,CAAC;YAClC,UAAU,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;SAC3E;KACF;IACD;QACE,IAAI,EAAE,cAAc;QACpB,WAAW,EACT,2FAA2F;cACzF,yFAAyF;cACzF,4DAA4D;QAChE,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,CAAC,QAAQ,CAAC;YACpB,UAAU,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE;SACpF;KACF;IACD;QACE,IAAI,EAAE,cAAc;QACpB,WAAW,EACT,wFAAwF;cACtF,+CAA+C;QACnD,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,CAAC,QAAQ,CAAC;YACpB,UAAU,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE;SACpF;KACF;IACD;QACE,IAAI,EAAE,YAAY;QAClB,WAAW,EACT,4FAA4F;cAC1F,4FAA4F;cAC5F,sFAAsF;cACtF,sFAAsF;cACtF,4CAA4C;QAChD,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,CAAC,SAAS,CAAC;YACrB,UAAU,EAAE;gBACV,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;gBACrD,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oCAAoC,EAAE;gBAC5E,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;iBACrF;aACF;SACF;KACF;IACD;QACE,IAAI,EAAE,cAAc;QACpB,WAAW,EACT,uFAAuF;cACrF,yFAAyF;cACzF,6BAA6B;QACjC,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,CAAC,SAAS,CAAC;YACrB,UAAU,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE;SACtE;KACF;IACD;QACE,IAAI,EAAE,aAAa;QACnB,WAAW,EACT,2FAA2F;cACzF,kFAAkF;QACtF,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,CAAC,QAAQ,CAAC;YACpB,UAAU,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;SAC3C;KACF;IACD;QACE,IAAI,EAAE,eAAe;QACrB,WAAW,EACT,0FAA0F;cACxF,0FAA0F;cAC1F,mFAAmF;QACvF,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,CAAC,QAAQ,CAAC;YACpB,UAAU,EAAE;gBACV,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAC1B,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,uCAAuC,EAAE;aACpF;SACF;KACF;CACO,CAAC;AAEX,MAAM,IAAI,GAAG,CAAC,KAAa,EAAc,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;AAC3F,MAAM,MAAM,GAAG,CAAC,KAAa,EAAc,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;AAE5G;;;;;;GAMG;AACH,SAAS,OAAO,CAAC,KAAc;IAC7B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CAAC,iDAAiD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC5F,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAY,EAAE,IAA6B;IACxE,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;QACzB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,CAAC;QACvC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC,oEAAoE,CAAC,CAAC;QACpF,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,EAAE,KAAK,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;QACpG,OAAO,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,yDAAyD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzG,CAAC;IAED,IAAI,IAAI,KAAK,iBAAiB,EAAE,CAAC;QAC/B,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACvF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAAC,OAAO,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAAC,CAAC;QAC3D,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YACjC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC;YACtE,OAAO,GAAG,KAAK,CAAC,EAAE,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,KAAK,KAAK,OAAO,SAAS,CAAC;QAC1F,CAAC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,2CAA2C,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7F,CAAC;IAED,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;QACtC,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QACtC,4EAA4E;QAC5E,+DAA+D;QAC/D,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/B,OAAO,MAAM,CAAC,4CAA4C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACnF,CAAC;QACD,MAAM,SAAS,GAAG,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC1F,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,UAAU,EAAE;YAClC,KAAK;YACL,GAAG;YACH,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC;SAClD,CAAC,CAAC;QACH,OAAO,KAAK,CAAC,MAAM,KAAK,UAAU;YAChC,CAAC,CAAC,IAAI,CAAC,iBAAiB,KAAK,CAAC,KAAK,OAAO,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,KAAK,EAAE,CAAC;YAChF,CAAC,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,KAAK,UAAU,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,wCAAwC;kBAC1F,oDAAoD,CAAC,CAAC;IAC9D,CAAC;IAED,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QACxE,IAAI,GAAG,KAAK,SAAS,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACpD,OAAO,MAAM,CAAC,4CAA4C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACnF,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,SAAS;YAClD,CAAC,CAAC,mBAAmB;YACrB,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;QAChC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,SAAS,EAAE;YAClC,GAAG,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC;YACrC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI;YAC/B,UAAU;SACX,CAAC,CAAC;QACH,wEAAwE;QACxE,2EAA2E;QAC3E,0CAA0C;QAC1C,MAAM,KAAK,GAAG,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ;YAC9C,CAAC,CAAC,4FAA4F;YAC9F,CAAC,CAAC,MAAM,CAAC,OAAO,KAAK,CAAC,CAAC;gBACrB,CAAC,CAAC,+DAA+D;gBACjE,CAAC,CAAC,aAAa,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;QACvD,OAAO,IAAI,CAAC,cAAc,MAAM,CAAC,GAAG,CAAC,EAAE,OAAO,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,KAAK,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;IACzG,CAAC;IAED,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;QACzB,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC;QAC7E,OAAO,IAAI,CAAC,cAAc,MAAM,GAAG,CAAC,CAAC;IACvC,CAAC;IAED,IAAI,IAAI,KAAK,eAAe,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACvF,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,aAAa,EAAE;YACpC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC9B,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC;SAChD,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC;QACrD,OAAO,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,IAAI,CAAC,IAAI,GAAG,IAAI,EAAE,CAAC,CAAC;IAChF,CAAC;IAED,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QAC5C,MAAM,WAAW,GAAG,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAChG,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,UAAU,EAAE;YACjC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC9B,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;SACtD,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACjF,MAAM,KAAK,GAAG,MAAM,KAAK,IAAI;YAC3B,CAAC,CAAC,IAAI,CAAC,QAAQ;YACf,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QAC/F,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC,MAAM,KAAK,IAAI;gBACzB,CAAC,CAAC,6CAA6C;gBAC/C,CAAC,CAAC,gCAAgC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;QACvE,CAAC;QACD,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YAC3B,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;iBAC5F,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC7B,OAAO,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACnF,CAAC,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,mCAAmC,CAAC,CAAC,CAAC,EAAE,CAAC;QACvE,OAAO,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,MAAM,iCAAiC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;IAC9H,CAAC;IAED,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;QACrB,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9B,MAAM,UAAU,GAAG,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC7F,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,OAAO,EAAE;YAChC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC9B,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YAC9B,GAAG,CAAC,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,OAAO,IAAI,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrF,GAAG,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC;SACpD,CAAC,CAAC;QACH,2EAA2E;QAC3E,qDAAqD;QACrD,IAAI,MAAM,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;YAC7B,OAAO,IAAI,CACT,yBAAyB,MAAM,CAAC,GAAG,SAAS,MAAM,CAAC,OAAO,IAAI,iBAAiB,cAAc;kBAC3F,2FAA2F;kBAC3F,uEAAuE,CAAC,CAAC;QAC/E,CAAC;QACD,IAAI,MAAM,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;YAC7B,OAAO,IAAI,CACT,yBAAyB,MAAM,CAAC,GAAG,sDAAsD;kBACvF,sFAAsF;kBACtF,eAAe,CAAC,CAAC;QACvB,CAAC;QACD,OAAO,IAAI,CAAC,WAAW,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QACxE,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,UAAU,EAAE;YAClC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC9B,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YAChC,GAAG,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC;YACrC,UAAU,EAAE,IAAI,CAAC,aAAa,CAAC,KAAK,IAAI;SACzC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,KAAK,CAAC,KAAK,gBAAgB,IAAI,CAAC,aAAa,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC/G,CAAC;IAED,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QACxE,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,UAAU,EAAE;YACpC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC9B,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YAC9B,GAAG,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC;SACtC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,WAAW,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC;IACzC,CAAC;IAED,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QACxE,MAAM,EAAE,GAAG,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACnE,MAAM,EAAE,GAAG,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACnE,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,QAAQ,EAAE;YAChC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC9B,GAAG,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC;YACnC,GAAG,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC;YACnC,GAAG,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC;SACtC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,eAAe,KAAK,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;IACvD,CAAC;IAED,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;QAC1D,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAClF,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,YAAY,EAAE;YACnC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC9B,MAAM;YACN,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;SAC9C,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;QAC1B,4EAA4E;QAC5E,mEAAmE;QACnE,OAAO;YACL,OAAO,EAAE;gBACP,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,qBAAqB,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,KAAK,SAAS,EAAE;aAChG;YACD,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;SACzC,CAAC;IAClB,CAAC;IAED,IAAI,IAAI,KAAK,gBAAgB,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,UAAU,EAAE;YACpC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC9B,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;SAC7C,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;QAC1B,0EAA0E;QAC1E,mDAAmD;QACnD,OAAO,OAAO,CAAC,KAAK;YAClB,CAAC,CAAC,IAAI,CAAC,UAAU,OAAO,CAAC,KAAK,EAAE,CAAC;YACjC,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC5E,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,iBAAiB,EAAE;YACxC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC9B,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;SAC1C,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW;YAC9B,CAAC,CAAC,uEAAuE;YACzE,CAAC,CAAC,EAAE,CAAC;QACP,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAAC,OAAO,IAAI,CAAC,GAAG,OAAO,sBAAsB,CAAC,CAAC;QAAC,CAAC;QAClF,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7E,OAAO,IAAI,CAAC,GAAG,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,6BAA6B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC/F,CAAC;IAED,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC5E,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,iBAAiB,EAAE;YACxC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC9B,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;SAC1C,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW;YAC9B,CAAC,CAAC,uEAAuE;YACzE,CAAC,CAAC,EAAE,CAAC;QACP,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAAC,OAAO,IAAI,CAAC,GAAG,OAAO,uBAAuB,CAAC,CAAC;QAAC,CAAC;QACnF,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,IAAI,KAAK,KAAK,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC/F,OAAO,IAAI,CAAC,GAAG,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,qCAAqC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACvG,CAAC;IAED,IAAI,IAAI,KAAK,YAAY,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;QACrD,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5C,OAAO,MAAM,CAAC,6DAA6D,CAAC,CAAC;QAC/E,CAAC;QACD,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QAClD,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;YAC5B,MAAM,GAAG,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;YACrC,OAAO,IAAI,CAAC,aAAa,MAAM,CAAC,MAAM,+BAA+B,CAAC,CAAC;QACzE,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QACxF,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QAC9E,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,WAAW,EAAE;YACrC,MAAM;YACN,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;YACzC,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;SAC1C,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,4BAA4B,OAAO,CAAC,OAAO,GAAG;cACtE,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3C,CAAC;IAED,IAAI,IAAI,KAAK,aAAa,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC;QAC1E,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ;YAC3B,CAAC,CAAC,gBAAgB,QAAQ,CAAC,KAAK,4DAA4D;YAC5F,CAAC,CAAC,OAAO,QAAQ,CAAC,KAAK,wBAAwB,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,MAAM,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,OAAuB;IAClD,IAAI,OAAO,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;QACpC,OAAO;YACL,eAAe,EAAE,gBAAgB;YACjC,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;YAC3B,UAAU,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,EAAE;SAC3D,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;QAAC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAAC,CAAC;IACjE,IAAI,OAAO,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;QACpC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;QACpC,OAAO,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,EAAE,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;IAC7D,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,mBAAmB,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,IAAI;IAClB,MAAM,KAAK,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IACzE,MAAM,IAAI,GAAG,CAAC,MAAe,EAAQ,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAEjG,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,GAAW,EAAE,EAAE;QAC/B,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QACxB,IAAI,CAAC,IAAI,EAAE,CAAC;YAAC,OAAO;QAAC,CAAC;QAEtB,IAAI,OAAuB,CAAC;QAC5B,IAAI,CAAC;YAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAmB,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,OAAO;QAAC,CAAC;QACvE,2DAA2D;QAC3D,IAAI,OAAO,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;YAAC,OAAO;QAAC,CAAC;QACzC,MAAM,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC;QAEtB,MAAM,CAAC,OAAO,CAAC;aACZ,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,GAAG,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;aAC3D,KAAK,CAAC,CAAC,MAAe,EAAE,EAAE;YACzB,sEAAsE;YACtE,qEAAqE;YACrE,UAAU;YACV,MAAM,OAAO,GAAG,MAAM,YAAY,oBAAoB,IAAI,MAAM,YAAY,KAAK;gBAC/E,CAAC,CAAC,MAAM,CAAC,OAAO;gBAChB,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACnB,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export declare function main(): void;