@jobshimo/browser-link 0.40.0 → 0.42.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.
- package/README.md +27 -12
- package/dist/admin/actions.d.ts +57 -0
- package/dist/admin/actions.js +163 -0
- package/dist/admin/actions.js.map +1 -0
- package/dist/admin/descriptor.d.ts +65 -0
- package/dist/admin/descriptor.js +205 -0
- package/dist/admin/descriptor.js.map +1 -0
- package/dist/admin/i18n.d.ts +90 -0
- package/dist/admin/i18n.js +203 -0
- package/dist/admin/i18n.js.map +1 -0
- package/dist/admin/primary.d.ts +21 -0
- package/dist/admin/primary.js +56 -0
- package/dist/admin/primary.js.map +1 -0
- package/dist/admin/sources.d.ts +22 -0
- package/dist/admin/sources.js +82 -0
- package/dist/admin/sources.js.map +1 -0
- package/dist/bridge/dispatch.js +17 -7
- package/dist/bridge/dispatch.js.map +1 -1
- package/dist/bridge/ws-bridge.d.ts +65 -3
- package/dist/bridge/ws-bridge.js +165 -7
- package/dist/bridge/ws-bridge.js.map +1 -1
- package/dist/cli.js +6 -2
- package/dist/cli.js.map +1 -1
- package/dist/commands/doctor.d.ts +24 -0
- package/dist/commands/doctor.js +62 -1
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/free-port.d.ts +40 -1
- package/dist/commands/free-port.js +72 -7
- package/dist/commands/free-port.js.map +1 -1
- package/dist/extension/admin-view.d.ts +95 -0
- package/dist/extension/admin-view.js +164 -0
- package/dist/extension/admin-view.js.map +1 -0
- package/dist/extension/background.js +176 -8
- package/dist/extension/background.js.map +1 -1
- package/dist/extension/manifest.json +1 -1
- package/dist/extension/popup.html +113 -0
- package/dist/extension/popup.js +282 -1
- package/dist/extension/popup.js.map +1 -1
- package/dist/extension/repair-policy.d.ts +60 -0
- package/dist/extension/repair-policy.js +79 -0
- package/dist/extension/repair-policy.js.map +1 -0
- package/dist/extension/version-status.d.ts +44 -0
- package/dist/extension/version-status.js +60 -0
- package/dist/extension/version-status.js.map +1 -0
- package/dist/lifecycle/election.d.ts +98 -0
- package/dist/lifecycle/election.js +187 -0
- package/dist/lifecycle/election.js.map +1 -0
- package/dist/lifecycle/processes.d.ts +67 -0
- package/dist/lifecycle/processes.js +239 -0
- package/dist/lifecycle/processes.js.map +1 -0
- package/dist/lifecycle/repair.d.ts +48 -0
- package/dist/lifecycle/repair.js +67 -0
- package/dist/lifecycle/repair.js.map +1 -0
- package/dist/lifecycle/version-endpoint.d.ts +16 -0
- package/dist/lifecycle/version-endpoint.js +50 -0
- package/dist/lifecycle/version-endpoint.js.map +1 -0
- package/dist/manual/topics.js +1 -1
- package/dist/manual/topics.js.map +1 -1
- package/dist/messages.d.ts +115 -2
- package/dist/server.js +104 -1
- package/dist/server.js.map +1 -1
- package/dist/tools/browser-dispatch.d.ts +8 -0
- package/dist/tools/browser-dispatch.js +15 -1
- package/dist/tools/browser-dispatch.js.map +1 -1
- package/dist/ui/app.d.ts +4 -1
- package/dist/ui/app.js +55 -42
- package/dist/ui/app.js.map +1 -1
- package/dist/ui/screens/free-port.js +4 -2
- package/dist/ui/screens/free-port.js.map +1 -1
- package/dist/ui/screens/index.d.ts +1 -0
- package/dist/ui/screens/index.js +1 -0
- package/dist/ui/screens/index.js.map +1 -1
- package/dist/ui/screens/menu.d.ts +11 -1
- package/dist/ui/screens/menu.js +12 -4
- package/dist/ui/screens/menu.js.map +1 -1
- package/dist/ui/screens/status.d.ts +19 -0
- package/dist/ui/screens/status.js +67 -0
- package/dist/ui/screens/status.js.map +1 -0
- package/dist/version.d.ts +8 -0
- package/dist/version.js +16 -0
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -59,10 +59,12 @@ The fastest path is the interactive UI — a full-screen [Ink](https://github.co
|
|
|
59
59
|
browser-link
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
-
That opens the welcome screen and then a
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
That opens the welcome screen and then a status view: the running server,
|
|
63
|
+
its ports, multi-agent, the instructions block per client, cdp-direct and
|
|
64
|
+
updates, with the setup menu's entries and hotkeys right below it (Tab opens
|
|
65
|
+
the full menu) to register with **Claude Code**, **OpenCode** or **GitHub
|
|
66
|
+
Copilot CLI**, see the Chrome extension install steps, run a doctor
|
|
67
|
+
diagnose, and manage per-tool permissions.
|
|
66
68
|
|
|
67
69
|
Or drive it directly:
|
|
68
70
|
|
|
@@ -70,7 +72,8 @@ Or drive it directly:
|
|
|
70
72
|
browser-link install # register in every detected client
|
|
71
73
|
browser-link install --client claude # register only in Claude Code
|
|
72
74
|
browser-link extension # show the Chrome extension assets path + steps
|
|
73
|
-
browser-link doctor # diagnose current setup
|
|
75
|
+
browser-link doctor # diagnose current setup (running vs installed version, live processes)
|
|
76
|
+
browser-link stop # stop every live browser-link server, one line per process
|
|
74
77
|
browser-link tools # show which of the 31 MCP tools are enabled
|
|
75
78
|
browser-link tools preset readonly # all | readonly | no-eval | no-map
|
|
76
79
|
browser-link map # list apps the persistent UI map knows about
|
|
@@ -84,11 +87,11 @@ tab you want the agent to reach.
|
|
|
84
87
|
|
|
85
88
|
## The 31 tools, at a glance
|
|
86
89
|
|
|
87
|
-
| Family
|
|
88
|
-
|
|
|
89
|
-
| Browser bridge — read
|
|
90
|
-
| Browser bridge — actions
|
|
91
|
-
| Persistent UI map
|
|
90
|
+
| Family | Count | What it covers |
|
|
91
|
+
| ------------------------ | ----: | ------------------------------------------------------------------------------- |
|
|
92
|
+
| Browser bridge — read | 13 | list/claim tabs, snapshot/find/state, console, network, wait_for(_tab), events |
|
|
93
|
+
| Browser bridge — actions | 12 | navigate, click, type, press, drag, flow, evaluate, dialogs, permissions, reset |
|
|
94
|
+
| Persistent UI map | 6 | recall, save, record_use, forget, rename_app, apps |
|
|
92
95
|
|
|
93
96
|
Every tool can be disabled per machine via `browser-link tools disable
|
|
94
97
|
<name>` or a preset (`all` / `readonly` / `no-eval` / `no-map`). The full
|
|
@@ -99,8 +102,8 @@ this page stays a landing page on purpose.
|
|
|
99
102
|
|
|
100
103
|
## `browser-link map` — inspect and manage the persistent map
|
|
101
104
|
|
|
102
|
-
The 6 map tools above are how an
|
|
103
|
-
works. `browser-link map` is how a
|
|
105
|
+
The 6 map tools above are how an _agent_ reads and writes the map while it
|
|
106
|
+
works. `browser-link map` is how a _human_ looks at the same data from a
|
|
104
107
|
terminal, no agent required:
|
|
105
108
|
|
|
106
109
|
```bash
|
|
@@ -127,6 +130,18 @@ browser-link map import map.json # restore it (merge by default, --re
|
|
|
127
130
|
the same bridge and map. `browser-link multi-agent` shows the current
|
|
128
131
|
state; see [Multi-agent mode](https://github.com/jobshimo/browser-link#multi-agent-mode)
|
|
129
132
|
for how it works.
|
|
133
|
+
- **Updates take effect by themselves**: a newer browser-link that starts
|
|
134
|
+
displaces an older primary (it reads `GET /version` on the bridge port),
|
|
135
|
+
`browser-link stop` stops every live server, `doctor` and `list_tabs`
|
|
136
|
+
show "running X / installed Y", and the extension popup has a "Repair
|
|
137
|
+
connection" button. See
|
|
138
|
+
[Updating while a server is running](https://github.com/jobshimo/browser-link#updating-while-a-server-is-running).
|
|
139
|
+
- **Admin panel**: the console's status view and the extension popup's
|
|
140
|
+
Admin section render the same server-built sections and labels (English
|
|
141
|
+
or Spanish). Every change that writes to disk shows a one-line preview and
|
|
142
|
+
waits for your confirmation; stopping or updating the server stays a
|
|
143
|
+
console command. See
|
|
144
|
+
[Admin panel](https://github.com/jobshimo/browser-link#admin-panel-console-and-popup).
|
|
130
145
|
- **cdp-direct mode** (off by default): an extension-free transport gated
|
|
131
146
|
behind `browser-link config set cdp-direct.enabled true` PLUS a
|
|
132
147
|
time-boxed `browser-link cdp allow` grant — see
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { type BrowserLinkConfig } from '../config.js';
|
|
2
|
+
import { disableTools, enableTools } from '../commands/tools.js';
|
|
3
|
+
import { disableAutoReelect, disableMultiAgent, enableAutoReelect, enableMultiAgent } from '../commands/multi-agent.js';
|
|
4
|
+
import { setCdpDirectEnabled, setCdpDirectGrantTtl } from '../commands/config.js';
|
|
5
|
+
import type { ClientId } from '../installers/index.js';
|
|
6
|
+
import type { AdminActionResult } from '../messages.js';
|
|
7
|
+
import { type AdminInput } from './descriptor.js';
|
|
8
|
+
/**
|
|
9
|
+
* Admin actions (S2). The only way the popup changes server state, and a
|
|
10
|
+
* closed allowlist: an action id must name an actionable item of the state
|
|
11
|
+
* the server builds right now (so a tool outside the catalogue, a client
|
|
12
|
+
* that is not detected, or a readout can never be written), its value is
|
|
13
|
+
* checked against the item's kind and options, a disk write needs an
|
|
14
|
+
* explicit `confirm: true`, and the write itself goes through the SAME
|
|
15
|
+
* helper the CLI uses, never a new write path.
|
|
16
|
+
*/
|
|
17
|
+
export interface AdminActionRequest {
|
|
18
|
+
id: string;
|
|
19
|
+
value?: string | number | boolean;
|
|
20
|
+
confirm?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/** The existing write helpers, injectable so tests can spy on each one. */
|
|
23
|
+
export interface AdminHelpers {
|
|
24
|
+
saveConfig: (patch: Partial<BrowserLinkConfig>) => unknown;
|
|
25
|
+
enableTools: typeof enableTools;
|
|
26
|
+
disableTools: typeof disableTools;
|
|
27
|
+
enableMultiAgent: typeof enableMultiAgent;
|
|
28
|
+
disableMultiAgent: typeof disableMultiAgent;
|
|
29
|
+
enableAutoReelect: typeof enableAutoReelect;
|
|
30
|
+
disableAutoReelect: typeof disableAutoReelect;
|
|
31
|
+
setCdpDirectEnabled: typeof setCdpDirectEnabled;
|
|
32
|
+
setCdpDirectGrantTtl: typeof setCdpDirectGrantTtl;
|
|
33
|
+
installInstructionsFor: (client: ClientId) => {
|
|
34
|
+
ok: boolean;
|
|
35
|
+
message?: string;
|
|
36
|
+
};
|
|
37
|
+
uninstallInstructionsFor: (client: ClientId) => {
|
|
38
|
+
ok: boolean;
|
|
39
|
+
message?: string;
|
|
40
|
+
};
|
|
41
|
+
installFor: (client: ClientId) => {
|
|
42
|
+
installedClient: boolean;
|
|
43
|
+
message: string;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export declare const DEFAULT_ADMIN_HELPERS: AdminHelpers;
|
|
47
|
+
export interface AdminActionDeps {
|
|
48
|
+
/** Fresh facts for the state; called before and after the action. */
|
|
49
|
+
input: () => Promise<AdminInput>;
|
|
50
|
+
/** `runDoctor` + `formatDoctor`, split into lines. Slow: runs only on the button. */
|
|
51
|
+
doctor: () => Promise<string[]>;
|
|
52
|
+
/** A forced update check, formatted into lines (network). */
|
|
53
|
+
checkUpdates: () => Promise<string[]>;
|
|
54
|
+
helpers?: Partial<AdminHelpers>;
|
|
55
|
+
}
|
|
56
|
+
/** Validate, confirm, apply. Never throws: every failure is `ok: false`. */
|
|
57
|
+
export declare function applyAdminAction(req: AdminActionRequest, deps: AdminActionDeps): Promise<AdminActionResult>;
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { saveConfig } from '../config.js';
|
|
2
|
+
import { disableTools, enableTools } from '../commands/tools.js';
|
|
3
|
+
import { disableAutoReelect, disableMultiAgent, enableAutoReelect, enableMultiAgent, } from '../commands/multi-agent.js';
|
|
4
|
+
import { setCdpDirectEnabled, setCdpDirectGrantTtl } from '../commands/config.js';
|
|
5
|
+
import { installInstructionsFor, uninstallInstructionsFor } from '../commands/instructions.js';
|
|
6
|
+
import { installFor } from '../commands/install.js';
|
|
7
|
+
import { adminItems, adminLanguage, buildAdminState } from './descriptor.js';
|
|
8
|
+
import { ADMIN_I18N } from './i18n.js';
|
|
9
|
+
export const DEFAULT_ADMIN_HELPERS = {
|
|
10
|
+
saveConfig,
|
|
11
|
+
enableTools,
|
|
12
|
+
disableTools,
|
|
13
|
+
enableMultiAgent,
|
|
14
|
+
disableMultiAgent,
|
|
15
|
+
enableAutoReelect,
|
|
16
|
+
disableAutoReelect,
|
|
17
|
+
setCdpDirectEnabled,
|
|
18
|
+
setCdpDirectGrantTtl,
|
|
19
|
+
installInstructionsFor,
|
|
20
|
+
uninstallInstructionsFor,
|
|
21
|
+
installFor: (client) => installFor(client),
|
|
22
|
+
};
|
|
23
|
+
/** Toggles whose value is one config key written with `saveConfig`, exactly
|
|
24
|
+
* as the console does for the keys without a dedicated CLI helper. */
|
|
25
|
+
const PLAIN_TOGGLES = [
|
|
26
|
+
'instructionsAutoRefresh',
|
|
27
|
+
'activityEnabled',
|
|
28
|
+
'activityRecordPayloads',
|
|
29
|
+
];
|
|
30
|
+
function isPlainToggle(id) {
|
|
31
|
+
return PLAIN_TOGGLES.includes(id);
|
|
32
|
+
}
|
|
33
|
+
class AdminRefusal extends Error {
|
|
34
|
+
}
|
|
35
|
+
function suffix(id, prefix) {
|
|
36
|
+
return id.startsWith(prefix) ? id.slice(prefix.length) : null;
|
|
37
|
+
}
|
|
38
|
+
function lines(text) {
|
|
39
|
+
return text === undefined || text.length === 0 ? [] : text.split('\n');
|
|
40
|
+
}
|
|
41
|
+
function checkValue(item, value) {
|
|
42
|
+
if (item.kind === 'toggle')
|
|
43
|
+
return typeof value === 'boolean';
|
|
44
|
+
if (item.kind === 'select') {
|
|
45
|
+
if (typeof value !== 'string' && typeof value !== 'number')
|
|
46
|
+
return false;
|
|
47
|
+
return (item.options ?? []).some((o) => o.value === String(value));
|
|
48
|
+
}
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
function preview(item, value, input) {
|
|
52
|
+
const t = ADMIN_I18N[adminLanguage(input.config)];
|
|
53
|
+
const tool = suffix(item.id, 'tools.');
|
|
54
|
+
if (tool !== null)
|
|
55
|
+
return value === true ? t.previewToolOn(tool) : t.previewToolOff(tool);
|
|
56
|
+
if (item.kind === 'toggle')
|
|
57
|
+
return t.previewToggle(item.label, value === true);
|
|
58
|
+
if (item.kind === 'select') {
|
|
59
|
+
const option = item.options?.find((o) => o.value === String(value));
|
|
60
|
+
return t.previewSelect(item.label, option?.label ?? String(value));
|
|
61
|
+
}
|
|
62
|
+
const displayName = (id) => input.instructions.find((s) => s.id === id)?.displayName ??
|
|
63
|
+
input.clients.find((c) => c.id === id)?.displayName ??
|
|
64
|
+
String(id);
|
|
65
|
+
const install = suffix(item.id, 'instructions.install.');
|
|
66
|
+
if (install !== null)
|
|
67
|
+
return t.previewInstall(displayName(install));
|
|
68
|
+
const uninstall = suffix(item.id, 'instructions.uninstall.');
|
|
69
|
+
if (uninstall !== null)
|
|
70
|
+
return t.previewUninstall(displayName(uninstall));
|
|
71
|
+
return t.previewRegister(displayName(suffix(item.id, 'client.register.')));
|
|
72
|
+
}
|
|
73
|
+
/** Runs the write for one validated, confirmed item. Returns output lines;
|
|
74
|
+
* throws an `AdminRefusal` (or the helper's own error) when it refused. */
|
|
75
|
+
async function apply(item, value, input, deps, h) {
|
|
76
|
+
const language = adminLanguage(input.config);
|
|
77
|
+
const on = value === true;
|
|
78
|
+
const { id } = item;
|
|
79
|
+
if (id === 'doctor')
|
|
80
|
+
return deps.doctor();
|
|
81
|
+
if (id === 'updates.check')
|
|
82
|
+
return deps.checkUpdates();
|
|
83
|
+
if (id === 'language') {
|
|
84
|
+
h.saveConfig({ language: value === 'es' ? 'es' : 'en' });
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
const tool = suffix(id, 'tools.');
|
|
88
|
+
if (tool !== null) {
|
|
89
|
+
return lines(on ? h.enableTools([tool], language) : h.disableTools([tool], language));
|
|
90
|
+
}
|
|
91
|
+
if (id === 'multiAgent') {
|
|
92
|
+
return lines(on ? h.enableMultiAgent(language) : h.disableMultiAgent(language));
|
|
93
|
+
}
|
|
94
|
+
if (id === 'autoReelect') {
|
|
95
|
+
return lines(on ? h.enableAutoReelect(language) : h.disableAutoReelect(language));
|
|
96
|
+
}
|
|
97
|
+
if (isPlainToggle(id)) {
|
|
98
|
+
h.saveConfig({ [id]: on });
|
|
99
|
+
return [];
|
|
100
|
+
}
|
|
101
|
+
if (id === 'cdpDirectEnabled')
|
|
102
|
+
return lines(h.setCdpDirectEnabled(String(on), language));
|
|
103
|
+
if (id === 'cdpDirectGrantTtlMinutes') {
|
|
104
|
+
return lines(h.setCdpDirectGrantTtl(String(value), language));
|
|
105
|
+
}
|
|
106
|
+
const install = suffix(id, 'instructions.install.');
|
|
107
|
+
const uninstall = suffix(id, 'instructions.uninstall.');
|
|
108
|
+
if (install !== null || uninstall !== null) {
|
|
109
|
+
const report = install !== null
|
|
110
|
+
? h.installInstructionsFor(install)
|
|
111
|
+
: h.uninstallInstructionsFor(uninstall);
|
|
112
|
+
if (!report.ok)
|
|
113
|
+
throw new AdminRefusal(report.message ?? id);
|
|
114
|
+
return lines(report.message);
|
|
115
|
+
}
|
|
116
|
+
const register = suffix(id, 'client.register.');
|
|
117
|
+
if (register !== null) {
|
|
118
|
+
const report = h.installFor(register);
|
|
119
|
+
if (!report.installedClient)
|
|
120
|
+
throw new AdminRefusal(report.message);
|
|
121
|
+
return lines(report.message);
|
|
122
|
+
}
|
|
123
|
+
// Reaching here means the descriptor offers an actionable item this
|
|
124
|
+
// module does not know: refuse rather than guess.
|
|
125
|
+
throw new AdminRefusal(ADMIN_I18N[language].unknownAction(id));
|
|
126
|
+
}
|
|
127
|
+
/** Validate, confirm, apply. Never throws: every failure is `ok: false`. */
|
|
128
|
+
export async function applyAdminAction(req, deps) {
|
|
129
|
+
try {
|
|
130
|
+
const input = await deps.input();
|
|
131
|
+
const t = ADMIN_I18N[adminLanguage(input.config)];
|
|
132
|
+
const item = adminItems(buildAdminState(input)).find((i) => i.id === req.id);
|
|
133
|
+
if (!item)
|
|
134
|
+
return { ok: false, error: t.unknownAction(req.id) };
|
|
135
|
+
if (item.kind === 'readout' || item.kind === 'link') {
|
|
136
|
+
return { ok: false, error: t.notAnAction(item.id) };
|
|
137
|
+
}
|
|
138
|
+
if (!checkValue(item, req.value))
|
|
139
|
+
return { ok: false, error: t.invalidValue(item.id) };
|
|
140
|
+
if (item.writesDisk && req.confirm !== true) {
|
|
141
|
+
return {
|
|
142
|
+
ok: true,
|
|
143
|
+
applied: false,
|
|
144
|
+
needsConfirm: true,
|
|
145
|
+
preview: preview(item, req.value, input),
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
const helpers = { ...DEFAULT_ADMIN_HELPERS, ...deps.helpers };
|
|
149
|
+
const output = await apply(item, req.value, input, deps, helpers);
|
|
150
|
+
const state = buildAdminState(await deps.input());
|
|
151
|
+
return {
|
|
152
|
+
ok: true,
|
|
153
|
+
applied: true,
|
|
154
|
+
...(item.requiresRestart ? { requiresRestart: true } : {}),
|
|
155
|
+
state,
|
|
156
|
+
...(output.length > 0 ? { output } : {}),
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
return { ok: false, error: error instanceof Error ? error.message : String(error) };
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=actions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../../src/admin/actions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { type BrowserLinkConfig } from '../config.js';
|
|
2
|
+
import type { ClientInstructionsStatus } from '../manual/status.js';
|
|
3
|
+
import type { ClientId } from '../installers/index.js';
|
|
4
|
+
import type { DoctorServerStatus } from '../commands/doctor.js';
|
|
5
|
+
import type { Language } from '../commands/welcome.js';
|
|
6
|
+
import type { AdminItem, AdminState } from '../messages.js';
|
|
7
|
+
/**
|
|
8
|
+
* The admin descriptor (S1): one source of truth for what the console's
|
|
9
|
+
* status view and the popup's Admin section show. `buildAdminState` is pure:
|
|
10
|
+
* every fact arrives in `AdminInput`, gathered by `admin/sources.ts` in the
|
|
11
|
+
* primary (in process) or in the console (out of process, through the
|
|
12
|
+
* primary's `/version`). Every string is localised here.
|
|
13
|
+
*
|
|
14
|
+
* Process-ending operations (`stop`/free-port, self-update) are never
|
|
15
|
+
* actions: they would end the very primary that answers the popup, so they
|
|
16
|
+
* are readouts carrying the console command instead.
|
|
17
|
+
*/
|
|
18
|
+
export declare const REPO_URL = "https://github.com/jobshimo/browser-link";
|
|
19
|
+
export declare const STOP_COMMAND = "browser-link stop";
|
|
20
|
+
export declare const SELF_UPDATE_COMMAND = "npm install -g @jobshimo/browser-link@latest";
|
|
21
|
+
export interface AdminClient {
|
|
22
|
+
id: ClientId;
|
|
23
|
+
displayName: string;
|
|
24
|
+
/** The client's config exists on this machine. */
|
|
25
|
+
installed: boolean;
|
|
26
|
+
/** browser-link is already registered in it. */
|
|
27
|
+
registered: boolean;
|
|
28
|
+
}
|
|
29
|
+
export interface AdminInput {
|
|
30
|
+
config: BrowserLinkConfig;
|
|
31
|
+
/** Epoch ms used for `generatedAt` and the uptime. */
|
|
32
|
+
now: number;
|
|
33
|
+
/** The version of the process building the state. */
|
|
34
|
+
version: string;
|
|
35
|
+
/** Running primary (from `/version` or in process) against the version on disk. */
|
|
36
|
+
server: DoctorServerStatus;
|
|
37
|
+
/** `null` when unknown: the console runs out of process. */
|
|
38
|
+
tabsConnected: number | null;
|
|
39
|
+
ports: {
|
|
40
|
+
ws: number;
|
|
41
|
+
ipc: number;
|
|
42
|
+
};
|
|
43
|
+
extension: {
|
|
44
|
+
path: string | null;
|
|
45
|
+
connectedVersion: string | null;
|
|
46
|
+
};
|
|
47
|
+
instructions: readonly ClientInstructionsStatus[];
|
|
48
|
+
clients: readonly AdminClient[];
|
|
49
|
+
cdpGrant: {
|
|
50
|
+
live: boolean;
|
|
51
|
+
remainingMs: number | null;
|
|
52
|
+
};
|
|
53
|
+
/** Cached update check; `null` when none ran yet. */
|
|
54
|
+
update: {
|
|
55
|
+
latest: string | null;
|
|
56
|
+
isNewer: boolean;
|
|
57
|
+
} | null;
|
|
58
|
+
toolNames: readonly string[];
|
|
59
|
+
downloadsDir: string;
|
|
60
|
+
}
|
|
61
|
+
export declare function adminLanguage(config: BrowserLinkConfig): Language;
|
|
62
|
+
export declare function formatUptime(ms: number): string;
|
|
63
|
+
export declare function buildAdminState(input: AdminInput): AdminState;
|
|
64
|
+
/** Every item of a state, in display order. */
|
|
65
|
+
export declare function adminItems(state: AdminState): AdminItem[];
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { DEFAULT_CDP_DIRECT_PORT, DEFAULT_GRANT_TTL_MINUTES, } from '../config.js';
|
|
2
|
+
import { ADMIN_I18N } from './i18n.js';
|
|
3
|
+
/**
|
|
4
|
+
* The admin descriptor (S1): one source of truth for what the console's
|
|
5
|
+
* status view and the popup's Admin section show. `buildAdminState` is pure:
|
|
6
|
+
* every fact arrives in `AdminInput`, gathered by `admin/sources.ts` in the
|
|
7
|
+
* primary (in process) or in the console (out of process, through the
|
|
8
|
+
* primary's `/version`). Every string is localised here.
|
|
9
|
+
*
|
|
10
|
+
* Process-ending operations (`stop`/free-port, self-update) are never
|
|
11
|
+
* actions: they would end the very primary that answers the popup, so they
|
|
12
|
+
* are readouts carrying the console command instead.
|
|
13
|
+
*/
|
|
14
|
+
export const REPO_URL = 'https://github.com/jobshimo/browser-link';
|
|
15
|
+
export const STOP_COMMAND = 'browser-link stop';
|
|
16
|
+
export const SELF_UPDATE_COMMAND = 'npm install -g @jobshimo/browser-link@latest';
|
|
17
|
+
/** Common lifetimes for the cdp-direct grant select; `0` = never expires. */
|
|
18
|
+
const GRANT_TTL_CHOICES = [15, 30, 60, 240, 1440, 0];
|
|
19
|
+
export function adminLanguage(config) {
|
|
20
|
+
return config.language === 'es' ? 'es' : 'en';
|
|
21
|
+
}
|
|
22
|
+
function readout(id, label, value, extra = {}) {
|
|
23
|
+
return { id, kind: 'readout', label, value, writesDisk: false, ...extra };
|
|
24
|
+
}
|
|
25
|
+
function toggle(id, label, value, requiresRestart = false) {
|
|
26
|
+
return {
|
|
27
|
+
id,
|
|
28
|
+
kind: 'toggle',
|
|
29
|
+
label,
|
|
30
|
+
value,
|
|
31
|
+
writesDisk: true,
|
|
32
|
+
...(requiresRestart ? { requiresRestart: true } : {}),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export function formatUptime(ms) {
|
|
36
|
+
const totalMinutes = Math.max(0, Math.floor(ms / 60_000));
|
|
37
|
+
const days = Math.floor(totalMinutes / 1440);
|
|
38
|
+
const hours = Math.floor((totalMinutes % 1440) / 60);
|
|
39
|
+
const minutes = totalMinutes % 60;
|
|
40
|
+
if (days > 0)
|
|
41
|
+
return `${days}d ${hours}h ${minutes}m`;
|
|
42
|
+
if (hours > 0)
|
|
43
|
+
return `${hours}h ${minutes}m`;
|
|
44
|
+
return `${minutes}m`;
|
|
45
|
+
}
|
|
46
|
+
function statusSection(input, t) {
|
|
47
|
+
const { server, config } = input;
|
|
48
|
+
const running = server.running;
|
|
49
|
+
const startedAt = running ? Date.parse(running.startedAt) : NaN;
|
|
50
|
+
const items = [
|
|
51
|
+
readout('status.server', t.server, running ? t.serverRunning(running.version) : t.serverNotRunning, running ? {} : { hint: t.serverNotRunningHint }),
|
|
52
|
+
readout('status.installed', t.installed, server.installed === null
|
|
53
|
+
? t.unknown
|
|
54
|
+
: server.outdated
|
|
55
|
+
? t.installedOutdated(server.installed)
|
|
56
|
+
: server.installed, server.outdated ? { hint: STOP_COMMAND } : {}),
|
|
57
|
+
readout('status.pid', t.pid, running ? running.pid : null),
|
|
58
|
+
readout('status.uptime', t.uptime, running && Number.isFinite(startedAt) ? formatUptime(input.now - startedAt) : null),
|
|
59
|
+
readout('status.tabs', t.tabs, input.tabsConnected, input.tabsConnected === null ? { hint: t.tabsUnknownHint } : {}),
|
|
60
|
+
readout('status.ports', t.ports, `WS ${input.ports.ws} · IPC ${input.ports.ipc}`),
|
|
61
|
+
readout('status.multiAgent', t.multiAgentStatus, config.multiAgent === false ? t.off : t.on),
|
|
62
|
+
readout('status.extension', t.extension,
|
|
63
|
+
// Out of process the console cannot see the tabs, so it cannot know.
|
|
64
|
+
input.tabsConnected === null
|
|
65
|
+
? t.unknown
|
|
66
|
+
: input.extension.connectedVersion === null
|
|
67
|
+
? t.extensionNotConnected
|
|
68
|
+
: input.extension.connectedVersion === input.version
|
|
69
|
+
? t.extensionAligned(input.extension.connectedVersion)
|
|
70
|
+
: t.extensionMismatch(input.extension.connectedVersion, input.version)),
|
|
71
|
+
...input.instructions.map((s) => readout(`status.instructions.${s.id}`, t.instructionsFor(s.displayName), t.instructionsState(s.state))),
|
|
72
|
+
readout('status.cdpDirect', t.cdpDirect, config.cdpDirectEnabled !== true
|
|
73
|
+
? t.off
|
|
74
|
+
: input.cdpGrant.live
|
|
75
|
+
? t.cdpDirectGranted(input.cdpGrant.remainingMs === null
|
|
76
|
+
? null
|
|
77
|
+
: Math.ceil(input.cdpGrant.remainingMs / 60_000))
|
|
78
|
+
: t.cdpDirectNoGrant),
|
|
79
|
+
readout('status.update', t.update, input.update === null || input.update.latest === null
|
|
80
|
+
? t.unknown
|
|
81
|
+
: input.update.isNewer
|
|
82
|
+
? t.updateAvailable(input.update.latest)
|
|
83
|
+
: t.upToDate, input.update?.isNewer === true ? { hint: SELF_UPDATE_COMMAND } : {}),
|
|
84
|
+
readout('status.activity', t.activity, config.activityEnabled === false ? t.off : t.on),
|
|
85
|
+
];
|
|
86
|
+
return { id: 'status', title: t.sections.status, items };
|
|
87
|
+
}
|
|
88
|
+
function grantTtlOptions(current, t) {
|
|
89
|
+
const values = [...GRANT_TTL_CHOICES];
|
|
90
|
+
if (!values.includes(current))
|
|
91
|
+
values.unshift(current);
|
|
92
|
+
return values.map((n) => ({ value: String(n), label: n === 0 ? t.never : t.minutes(n) }));
|
|
93
|
+
}
|
|
94
|
+
function setupSection(input, t) {
|
|
95
|
+
const { config } = input;
|
|
96
|
+
const disabled = new Set(config.disabledTools ?? []);
|
|
97
|
+
const grantTtl = config.cdpDirectGrantTtlMinutes ?? DEFAULT_GRANT_TTL_MINUTES;
|
|
98
|
+
const items = [
|
|
99
|
+
{
|
|
100
|
+
id: 'language',
|
|
101
|
+
kind: 'select',
|
|
102
|
+
label: t.language,
|
|
103
|
+
value: adminLanguage(config),
|
|
104
|
+
options: [
|
|
105
|
+
{ value: 'en', label: 'English' },
|
|
106
|
+
{ value: 'es', label: 'Español' },
|
|
107
|
+
],
|
|
108
|
+
writesDisk: true,
|
|
109
|
+
},
|
|
110
|
+
...input.toolNames.map((name) => toggle(`tools.${name}`, t.tool(name), !disabled.has(name))),
|
|
111
|
+
toggle('multiAgent', t.multiAgent, config.multiAgent !== false, true),
|
|
112
|
+
toggle('autoReelect', t.autoReelect, config.autoReelect === true, true),
|
|
113
|
+
toggle('instructionsAutoRefresh', t.instructionsAutoRefresh, config.instructionsAutoRefresh !== false, true),
|
|
114
|
+
toggle('cdpDirectEnabled', t.cdpDirectEnabled, config.cdpDirectEnabled === true),
|
|
115
|
+
readout('cdpDirectPort', t.cdpDirectPort, config.cdpDirectPort ?? DEFAULT_CDP_DIRECT_PORT, {
|
|
116
|
+
hint: 'browser-link config set cdp-direct.port <port>',
|
|
117
|
+
}),
|
|
118
|
+
{
|
|
119
|
+
id: 'cdpDirectGrantTtlMinutes',
|
|
120
|
+
kind: 'select',
|
|
121
|
+
label: t.cdpDirectGrantTtl,
|
|
122
|
+
value: String(grantTtl),
|
|
123
|
+
options: grantTtlOptions(grantTtl, t),
|
|
124
|
+
writesDisk: true,
|
|
125
|
+
},
|
|
126
|
+
// Read once when the primary wires the trail, so a change needs a restart.
|
|
127
|
+
toggle('activityEnabled', t.activityEnabled, config.activityEnabled !== false, true),
|
|
128
|
+
toggle('activityRecordPayloads', t.activityRecordPayloads, config.activityRecordPayloads !== false, true),
|
|
129
|
+
readout('downloadsDir', t.downloadsDir, input.downloadsDir, {
|
|
130
|
+
hint: 'browser-link config set downloads.dir <absolute-path|default>',
|
|
131
|
+
}),
|
|
132
|
+
// These two keep their timestamped `settings.update` path (popup and
|
|
133
|
+
// `config set`), so the admin panel only shows them.
|
|
134
|
+
readout('idleTtl', t.idleTtl, config.idleTtlMinutes === undefined
|
|
135
|
+
? t.popupDefault
|
|
136
|
+
: config.idleTtlMinutes === 0
|
|
137
|
+
? t.never
|
|
138
|
+
: t.minutes(config.idleTtlMinutes), { hint: t.idleTtlHint }),
|
|
139
|
+
readout('flowRecording', t.flowRecording, config.flowRecordingEnabled === undefined
|
|
140
|
+
? t.popupDefault
|
|
141
|
+
: config.flowRecordingEnabled
|
|
142
|
+
? t.on
|
|
143
|
+
: t.off, { hint: t.flowRecordingHint }),
|
|
144
|
+
];
|
|
145
|
+
return { id: 'setup', title: t.sections.setup, items };
|
|
146
|
+
}
|
|
147
|
+
function button(id, label, writesDisk, description) {
|
|
148
|
+
return { id, kind: 'button', label, writesDisk, ...(description ? { description } : {}) };
|
|
149
|
+
}
|
|
150
|
+
function diagnoseSection(input, t) {
|
|
151
|
+
const items = [
|
|
152
|
+
button('doctor', t.doctor, false),
|
|
153
|
+
button('updates.check', t.updatesCheck, false),
|
|
154
|
+
];
|
|
155
|
+
for (const s of input.instructions) {
|
|
156
|
+
// A corrupt file is the CLI's business: the installers refuse to touch it.
|
|
157
|
+
if (s.state.kind === 'corrupt')
|
|
158
|
+
continue;
|
|
159
|
+
items.push(button(`instructions.install.${s.id}`, t.instructionsInstall(s.displayName), true));
|
|
160
|
+
if (s.state.kind === 'installed' || s.state.kind === 'installed-outdated') {
|
|
161
|
+
items.push(button(`instructions.uninstall.${s.id}`, t.instructionsUninstall(s.displayName), true));
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
for (const c of input.clients) {
|
|
165
|
+
if (!c.installed)
|
|
166
|
+
continue;
|
|
167
|
+
items.push(button(`client.register.${c.id}`, t.register(c.displayName), true, c.registered ? t.registered : t.notRegistered));
|
|
168
|
+
}
|
|
169
|
+
items.push(readout('stop', t.stop, STOP_COMMAND, { description: t.stopDescription }));
|
|
170
|
+
items.push(readout('selfUpdate', t.selfUpdate, SELF_UPDATE_COMMAND, {
|
|
171
|
+
description: t.selfUpdateDescription,
|
|
172
|
+
}));
|
|
173
|
+
return { id: 'diagnose', title: t.sections.diagnose, items };
|
|
174
|
+
}
|
|
175
|
+
function referenceSection(input, t) {
|
|
176
|
+
return {
|
|
177
|
+
id: 'reference',
|
|
178
|
+
title: t.sections.reference,
|
|
179
|
+
items: [
|
|
180
|
+
readout('about', t.about, t.aboutText),
|
|
181
|
+
{ id: 'repo', kind: 'link', label: t.repo, value: REPO_URL, writesDisk: false },
|
|
182
|
+
readout('extension.path', t.extensionPath, input.extension.path ?? t.extensionNotFound),
|
|
183
|
+
],
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
export function buildAdminState(input) {
|
|
187
|
+
const language = adminLanguage(input.config);
|
|
188
|
+
const t = ADMIN_I18N[language];
|
|
189
|
+
return {
|
|
190
|
+
version: 1,
|
|
191
|
+
generatedAt: new Date(input.now).toISOString(),
|
|
192
|
+
sections: [
|
|
193
|
+
statusSection(input, t),
|
|
194
|
+
setupSection(input, t),
|
|
195
|
+
diagnoseSection(input, t),
|
|
196
|
+
referenceSection(input, t),
|
|
197
|
+
],
|
|
198
|
+
ui: { language, ...t.ui },
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
/** Every item of a state, in display order. */
|
|
202
|
+
export function adminItems(state) {
|
|
203
|
+
return state.sections.flatMap((s) => s.items);
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=descriptor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"descriptor.js","sourceRoot":"","sources":["../../src/admin/descriptor.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,yBAAyB,GAE1B,MAAM,cAAc,CAAC;AAMtB,OAAO,EAAE,UAAU,EAAkB,MAAM,WAAW,CAAC;AAEvD;;;;;;;;;;GAUG;AAEH,MAAM,CAAC,MAAM,QAAQ,GAAG,0CAA0C,CAAC;AACnE,MAAM,CAAC,MAAM,YAAY,GAAG,mBAAmB,CAAC;AAChD,MAAM,CAAC,MAAM,mBAAmB,GAAG,8CAA8C,CAAC;AAElF,6EAA6E;AAC7E,MAAM,iBAAiB,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAU,CAAC;AAgC9D,MAAM,UAAU,aAAa,CAAC,MAAyB;IACrD,OAAO,MAAM,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAChD,CAAC;AAED,SAAS,OAAO,CACd,EAAU,EACV,KAAa,EACb,KAAyB,EACzB,QAA4B,EAAE;IAE9B,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,CAAC;AAC5E,CAAC;AAED,SAAS,MAAM,CAAC,EAAU,EAAE,KAAa,EAAE,KAAc,EAAE,eAAe,GAAG,KAAK;IAChF,OAAO;QACL,EAAE;QACF,IAAI,EAAE,QAAQ;QACd,KAAK;QACL,KAAK;QACL,UAAU,EAAE,IAAI;QAChB,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACtD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,EAAU;IACrC,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC;IAC1D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,YAAY,GAAG,EAAE,CAAC;IAClC,IAAI,IAAI,GAAG,CAAC;QAAE,OAAO,GAAG,IAAI,KAAK,KAAK,KAAK,OAAO,GAAG,CAAC;IACtD,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,GAAG,KAAK,KAAK,OAAO,GAAG,CAAC;IAC9C,OAAO,GAAG,OAAO,GAAG,CAAC;AACvB,CAAC;AAED,SAAS,aAAa,CAAC,KAAiB,EAAE,CAAY;IACpD,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IACjC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;IAC/B,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAChE,MAAM,KAAK,GAAgB;QACzB,OAAO,CACL,eAAe,EACf,CAAC,CAAC,MAAM,EACR,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,EAC/D,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,oBAAoB,EAAE,CAChD;QACD,OAAO,CACL,kBAAkB,EAClB,CAAC,CAAC,SAAS,EACX,MAAM,CAAC,SAAS,KAAK,IAAI;YACvB,CAAC,CAAC,CAAC,CAAC,OAAO;YACX,CAAC,CAAC,MAAM,CAAC,QAAQ;gBACf,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC;gBACvC,CAAC,CAAC,MAAM,CAAC,SAAS,EACtB,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAC9C;QACD,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;QAC1D,OAAO,CACL,eAAe,EACf,CAAC,CAAC,MAAM,EACR,OAAO,IAAI,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CACnF;QACD,OAAO,CACL,aAAa,EACb,CAAC,CAAC,IAAI,EACN,KAAK,CAAC,aAAa,EACnB,KAAK,CAAC,aAAa,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAChE;QACD,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,KAAK,CAAC,KAAK,CAAC,EAAE,UAAU,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QACjF,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC,gBAAgB,EAAE,MAAM,CAAC,UAAU,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5F,OAAO,CACL,kBAAkB,EAClB,CAAC,CAAC,SAAS;QACX,qEAAqE;QACrE,KAAK,CAAC,aAAa,KAAK,IAAI;YAC1B,CAAC,CAAC,CAAC,CAAC,OAAO;YACX,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,gBAAgB,KAAK,IAAI;gBACzC,CAAC,CAAC,CAAC,CAAC,qBAAqB;gBACzB,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,gBAAgB,KAAK,KAAK,CAAC,OAAO;oBAClD,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,SAAS,CAAC,gBAAgB,CAAC;oBACtD,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,KAAK,CAAC,SAAS,CAAC,gBAAgB,EAAE,KAAK,CAAC,OAAO,CAAC,CAC7E;QACD,GAAG,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAC9B,OAAO,CACL,uBAAuB,CAAC,CAAC,EAAE,EAAE,EAC7B,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,WAAW,CAAC,EAChC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,KAAK,CAAC,CAC7B,CACF;QACD,OAAO,CACL,kBAAkB,EAClB,CAAC,CAAC,SAAS,EACX,MAAM,CAAC,gBAAgB,KAAK,IAAI;YAC9B,CAAC,CAAC,CAAC,CAAC,GAAG;YACP,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI;gBACnB,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAChB,KAAK,CAAC,QAAQ,CAAC,WAAW,KAAK,IAAI;oBACjC,CAAC,CAAC,IAAI;oBACN,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,GAAG,MAAM,CAAC,CACnD;gBACH,CAAC,CAAC,CAAC,CAAC,gBAAgB,CACzB;QACD,OAAO,CACL,eAAe,EACf,CAAC,CAAC,MAAM,EACR,KAAK,CAAC,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,KAAK,IAAI;YACnD,CAAC,CAAC,CAAC,CAAC,OAAO;YACX,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO;gBACpB,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;gBACxC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAChB,KAAK,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,CAAC,CAAC,EAAE,CACpE;QACD,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,eAAe,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KACxF,CAAC;IACF,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC;AAC3D,CAAC;AAED,SAAS,eAAe,CAAC,OAAe,EAAE,CAAY;IACpD,MAAM,MAAM,GAAa,CAAC,GAAG,iBAAiB,CAAC,CAAC;IAChD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACvD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC5F,CAAC;AAED,SAAS,YAAY,CAAC,KAAiB,EAAE,CAAY;IACnD,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IACzB,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,MAAM,CAAC,wBAAwB,IAAI,yBAAyB,CAAC;IAC9E,MAAM,KAAK,GAAgB;QACzB;YACE,EAAE,EAAE,UAAU;YACd,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,CAAC,CAAC,QAAQ;YACjB,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC;YAC5B,OAAO,EAAE;gBACP,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE;gBACjC,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE;aAClC;YACD,UAAU,EAAE,IAAI;SACjB;QACD,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;QAC5F,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,KAAK,KAAK,EAAE,IAAI,CAAC;QACrE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,WAAW,EAAE,MAAM,CAAC,WAAW,KAAK,IAAI,EAAE,IAAI,CAAC;QACvE,MAAM,CACJ,yBAAyB,EACzB,CAAC,CAAC,uBAAuB,EACzB,MAAM,CAAC,uBAAuB,KAAK,KAAK,EACxC,IAAI,CACL;QACD,MAAM,CAAC,kBAAkB,EAAE,CAAC,CAAC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,KAAK,IAAI,CAAC;QAChF,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,uBAAuB,EAAE;YACzF,IAAI,EAAE,gDAAgD;SACvD,CAAC;QACF;YACE,EAAE,EAAE,0BAA0B;YAC9B,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,CAAC,CAAC,iBAAiB;YAC1B,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC;YACvB,OAAO,EAAE,eAAe,CAAC,QAAQ,EAAE,CAAC,CAAC;YACrC,UAAU,EAAE,IAAI;SACjB;QACD,2EAA2E;QAC3E,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,eAAe,EAAE,MAAM,CAAC,eAAe,KAAK,KAAK,EAAE,IAAI,CAAC;QACpF,MAAM,CACJ,wBAAwB,EACxB,CAAC,CAAC,sBAAsB,EACxB,MAAM,CAAC,sBAAsB,KAAK,KAAK,EACvC,IAAI,CACL;QACD,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,YAAY,EAAE,KAAK,CAAC,YAAY,EAAE;YAC1D,IAAI,EAAE,+DAA+D;SACtE,CAAC;QACF,qEAAqE;QACrE,qDAAqD;QACrD,OAAO,CACL,SAAS,EACT,CAAC,CAAC,OAAO,EACT,MAAM,CAAC,cAAc,KAAK,SAAS;YACjC,CAAC,CAAC,CAAC,CAAC,YAAY;YAChB,CAAC,CAAC,MAAM,CAAC,cAAc,KAAK,CAAC;gBAC3B,CAAC,CAAC,CAAC,CAAC,KAAK;gBACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,EACtC,EAAE,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CACxB;QACD,OAAO,CACL,eAAe,EACf,CAAC,CAAC,aAAa,EACf,MAAM,CAAC,oBAAoB,KAAK,SAAS;YACvC,CAAC,CAAC,CAAC,CAAC,YAAY;YAChB,CAAC,CAAC,MAAM,CAAC,oBAAoB;gBAC3B,CAAC,CAAC,CAAC,CAAC,EAAE;gBACN,CAAC,CAAC,CAAC,CAAC,GAAG,EACX,EAAE,IAAI,EAAE,CAAC,CAAC,iBAAiB,EAAE,CAC9B;KACF,CAAC;IACF,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC;AACzD,CAAC;AAED,SAAS,MAAM,CAAC,EAAU,EAAE,KAAa,EAAE,UAAmB,EAAE,WAAoB;IAClF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AAC5F,CAAC;AAED,SAAS,eAAe,CAAC,KAAiB,EAAE,CAAY;IACtD,MAAM,KAAK,GAAgB;QACzB,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC;QACjC,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,YAAY,EAAE,KAAK,CAAC;KAC/C,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;QACnC,2EAA2E;QAC3E,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS;YAAE,SAAS;QACzC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,wBAAwB,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;QAC/F,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,oBAAoB,EAAE,CAAC;YAC1E,KAAK,CAAC,IAAI,CACR,MAAM,CAAC,0BAA0B,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,IAAI,CAAC,CACvF,CAAC;QACJ,CAAC;IACH,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAC9B,IAAI,CAAC,CAAC,CAAC,SAAS;YAAE,SAAS;QAC3B,KAAK,CAAC,IAAI,CACR,MAAM,CACJ,mBAAmB,CAAC,CAAC,EAAE,EAAE,EACzB,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,EACzB,IAAI,EACJ,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAC9C,CACF,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,YAAY,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;IACtF,KAAK,CAAC,IAAI,CACR,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,UAAU,EAAE,mBAAmB,EAAE;QACvD,WAAW,EAAE,CAAC,CAAC,qBAAqB;KACrC,CAAC,CACH,CAAC;IACF,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC;AAC/D,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAiB,EAAE,CAAY;IACvD,OAAO;QACL,EAAE,EAAE,WAAW;QACf,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,SAAS;QAC3B,KAAK,EAAE;YACL,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,SAAS,CAAC;YACtC,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE;YAC/E,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,aAAa,EAAE,KAAK,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,CAAC,iBAAiB,CAAC;SACxF;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAiB;IAC/C,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC/B,OAAO;QACL,OAAO,EAAE,CAAC;QACV,WAAW,EAAE,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE;QAC9C,QAAQ,EAAE;YACR,aAAa,CAAC,KAAK,EAAE,CAAC,CAAC;YACvB,YAAY,CAAC,KAAK,EAAE,CAAC,CAAC;YACtB,eAAe,CAAC,KAAK,EAAE,CAAC,CAAC;YACzB,gBAAgB,CAAC,KAAK,EAAE,CAAC,CAAC;SAC3B;QACD,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC,EAAE,EAAE;KAC1B,CAAC;AACJ,CAAC;AAED,+CAA+C;AAC/C,MAAM,UAAU,UAAU,CAAC,KAAiB;IAC1C,OAAO,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AAChD,CAAC"}
|