tauri-agent-tools 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.
- package/.agents/skills/tauri-agent-tools/SKILL.md +104 -0
- package/.agents/skills/tauri-bridge-setup/SKILL.md +95 -0
- package/AGENTS.md +30 -0
- package/LICENSE +21 -0
- package/README.md +338 -0
- package/dist/bridge/client.d.ts +15 -0
- package/dist/bridge/client.js +119 -0
- package/dist/bridge/client.js.map +1 -0
- package/dist/bridge/tokenDiscovery.d.ts +3 -0
- package/dist/bridge/tokenDiscovery.js +77 -0
- package/dist/bridge/tokenDiscovery.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +49 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/consoleMonitor.d.ts +2 -0
- package/dist/commands/consoleMonitor.js +133 -0
- package/dist/commands/consoleMonitor.js.map +1 -0
- package/dist/commands/dom.d.ts +2 -0
- package/dist/commands/dom.js +186 -0
- package/dist/commands/dom.js.map +1 -0
- package/dist/commands/eval.d.ts +2 -0
- package/dist/commands/eval.js +27 -0
- package/dist/commands/eval.js.map +1 -0
- package/dist/commands/info.d.ts +3 -0
- package/dist/commands/info.js +28 -0
- package/dist/commands/info.js.map +1 -0
- package/dist/commands/ipcMonitor.d.ts +2 -0
- package/dist/commands/ipcMonitor.js +122 -0
- package/dist/commands/ipcMonitor.js.map +1 -0
- package/dist/commands/listWindows.d.ts +3 -0
- package/dist/commands/listWindows.js +58 -0
- package/dist/commands/listWindows.js.map +1 -0
- package/dist/commands/pageState.d.ts +2 -0
- package/dist/commands/pageState.js +43 -0
- package/dist/commands/pageState.js.map +1 -0
- package/dist/commands/screenshot.d.ts +3 -0
- package/dist/commands/screenshot.js +81 -0
- package/dist/commands/screenshot.js.map +1 -0
- package/dist/commands/shared.d.ts +7 -0
- package/dist/commands/shared.js +27 -0
- package/dist/commands/shared.js.map +1 -0
- package/dist/commands/storage.d.ts +2 -0
- package/dist/commands/storage.js +110 -0
- package/dist/commands/storage.js.map +1 -0
- package/dist/commands/wait.d.ts +3 -0
- package/dist/commands/wait.js +63 -0
- package/dist/commands/wait.js.map +1 -0
- package/dist/platform/detect.d.ts +11 -0
- package/dist/platform/detect.js +73 -0
- package/dist/platform/detect.js.map +1 -0
- package/dist/platform/macos.d.ts +8 -0
- package/dist/platform/macos.js +111 -0
- package/dist/platform/macos.js.map +1 -0
- package/dist/platform/wayland.d.ts +10 -0
- package/dist/platform/wayland.js +98 -0
- package/dist/platform/wayland.js.map +1 -0
- package/dist/platform/x11.d.ts +8 -0
- package/dist/platform/x11.js +78 -0
- package/dist/platform/x11.js.map +1 -0
- package/dist/types.d.ts +32 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/util/exec.d.ts +9 -0
- package/dist/util/exec.js +31 -0
- package/dist/util/exec.js.map +1 -0
- package/dist/util/image.d.ts +10 -0
- package/dist/util/image.js +23 -0
- package/dist/util/image.js.map +1 -0
- package/examples/tauri-bridge/Cargo.toml +13 -0
- package/examples/tauri-bridge/src/dev_bridge.rs +146 -0
- package/examples/tauri-bridge/src/main.rs +16 -0
- package/package.json +70 -0
- package/rust-bridge/README.md +80 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
export class BridgeClient {
|
|
2
|
+
baseUrl;
|
|
3
|
+
token;
|
|
4
|
+
constructor(config) {
|
|
5
|
+
this.baseUrl = `http://127.0.0.1:${config.port}`;
|
|
6
|
+
this.token = config.token;
|
|
7
|
+
}
|
|
8
|
+
async eval(js, timeout = 5000) {
|
|
9
|
+
const res = await fetch(`${this.baseUrl}/eval`, {
|
|
10
|
+
method: 'POST',
|
|
11
|
+
headers: { 'Content-Type': 'application/json' },
|
|
12
|
+
body: JSON.stringify({ js, token: this.token }),
|
|
13
|
+
signal: AbortSignal.timeout(timeout),
|
|
14
|
+
});
|
|
15
|
+
if (!res.ok) {
|
|
16
|
+
const text = await res.text().catch(() => '');
|
|
17
|
+
if (res.status === 401 || res.status === 403) {
|
|
18
|
+
throw new Error('Bridge authentication failed — check your token');
|
|
19
|
+
}
|
|
20
|
+
throw new Error(`Bridge error (${res.status}): ${text}`);
|
|
21
|
+
}
|
|
22
|
+
const data = await res.json();
|
|
23
|
+
return data.result;
|
|
24
|
+
}
|
|
25
|
+
async getElementRect(selector) {
|
|
26
|
+
const escaped = selector.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
|
27
|
+
const js = `(() => {
|
|
28
|
+
const el = document.querySelector('${escaped}');
|
|
29
|
+
if (!el) return null;
|
|
30
|
+
const r = el.getBoundingClientRect();
|
|
31
|
+
return JSON.stringify({ x: r.x, y: r.y, width: r.width, height: r.height });
|
|
32
|
+
})()`;
|
|
33
|
+
const result = await this.eval(js);
|
|
34
|
+
if (result === null || result === undefined)
|
|
35
|
+
return null;
|
|
36
|
+
return JSON.parse(String(result));
|
|
37
|
+
}
|
|
38
|
+
async getViewportSize() {
|
|
39
|
+
const js = `JSON.stringify({ width: window.innerWidth, height: window.innerHeight })`;
|
|
40
|
+
const result = await this.eval(js);
|
|
41
|
+
return JSON.parse(String(result));
|
|
42
|
+
}
|
|
43
|
+
async getDocumentTitle() {
|
|
44
|
+
const result = await this.eval('document.title');
|
|
45
|
+
return String(result ?? '');
|
|
46
|
+
}
|
|
47
|
+
async getAccessibilityTree(selector = 'body', depth = 10) {
|
|
48
|
+
const escaped = selector.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
|
49
|
+
const js = `(() => {
|
|
50
|
+
function getRole(el) {
|
|
51
|
+
return el.computedRole || el.getAttribute('role') || el.tagName.toLowerCase();
|
|
52
|
+
}
|
|
53
|
+
function getLabel(el) {
|
|
54
|
+
if (el.computedLabel) return el.computedLabel;
|
|
55
|
+
var label = el.getAttribute('aria-label');
|
|
56
|
+
if (label) return label;
|
|
57
|
+
var labelledBy = el.getAttribute('aria-labelledby');
|
|
58
|
+
if (labelledBy) {
|
|
59
|
+
var ref = document.getElementById(labelledBy);
|
|
60
|
+
if (ref) return ref.textContent.trim();
|
|
61
|
+
}
|
|
62
|
+
if (['button','a','label','th','td','caption','legend','figcaption'].indexOf(el.tagName.toLowerCase()) !== -1) {
|
|
63
|
+
var t = el.textContent.trim();
|
|
64
|
+
if (t.length <= 80) return t;
|
|
65
|
+
return t.slice(0, 77) + '...';
|
|
66
|
+
}
|
|
67
|
+
var alt = el.getAttribute('alt') || el.getAttribute('title') || el.getAttribute('placeholder');
|
|
68
|
+
if (alt) return alt;
|
|
69
|
+
return '';
|
|
70
|
+
}
|
|
71
|
+
function getState(el) {
|
|
72
|
+
var s = {};
|
|
73
|
+
if (el.disabled) s.disabled = true;
|
|
74
|
+
if (el.checked) s.checked = true;
|
|
75
|
+
if (el.getAttribute('aria-expanded')) s.expanded = el.getAttribute('aria-expanded') === 'true';
|
|
76
|
+
if (el.getAttribute('aria-selected')) s.selected = el.getAttribute('aria-selected') === 'true';
|
|
77
|
+
if (el.required) s.required = true;
|
|
78
|
+
if (el.getAttribute('aria-current')) s.current = el.getAttribute('aria-current');
|
|
79
|
+
if (el.getAttribute('aria-level')) s.level = parseInt(el.getAttribute('aria-level'));
|
|
80
|
+
if (el.tagName.match(/^H[1-6]$/)) s.level = parseInt(el.tagName[1]);
|
|
81
|
+
return Object.keys(s).length ? s : undefined;
|
|
82
|
+
}
|
|
83
|
+
function walk(el, d, maxD) {
|
|
84
|
+
var role = getRole(el);
|
|
85
|
+
var label = getLabel(el);
|
|
86
|
+
var state = getState(el);
|
|
87
|
+
var node = { role: role };
|
|
88
|
+
if (label) node.name = label;
|
|
89
|
+
if (state) node.state = state;
|
|
90
|
+
if (d < maxD) {
|
|
91
|
+
var kids = [];
|
|
92
|
+
for (var i = 0; i < el.children.length; i++) {
|
|
93
|
+
var child = walk(el.children[i], d + 1, maxD);
|
|
94
|
+
if (child) kids.push(child);
|
|
95
|
+
}
|
|
96
|
+
if (kids.length) node.children = kids;
|
|
97
|
+
}
|
|
98
|
+
return node;
|
|
99
|
+
}
|
|
100
|
+
var root = document.querySelector('${escaped}');
|
|
101
|
+
if (!root) return null;
|
|
102
|
+
return JSON.stringify(walk(root, 0, ${depth}));
|
|
103
|
+
})()`;
|
|
104
|
+
const result = await this.eval(js);
|
|
105
|
+
if (result === null || result === undefined)
|
|
106
|
+
return null;
|
|
107
|
+
return JSON.parse(String(result));
|
|
108
|
+
}
|
|
109
|
+
async ping() {
|
|
110
|
+
try {
|
|
111
|
+
await this.eval('1', 2000);
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/bridge/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { readdir, readFile, unlink } from 'node:fs/promises';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
const TOKEN_DIR = tmpdir();
|
|
4
|
+
const TOKEN_PREFIX = 'tauri-dev-bridge-';
|
|
5
|
+
const TOKEN_SUFFIX = '.token';
|
|
6
|
+
function isPidAlive(pid) {
|
|
7
|
+
try {
|
|
8
|
+
process.kill(pid, 0);
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export async function discoverBridge() {
|
|
16
|
+
let files;
|
|
17
|
+
try {
|
|
18
|
+
files = await readdir(TOKEN_DIR);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
const tokenFiles = files.filter((f) => f.startsWith(TOKEN_PREFIX) && f.endsWith(TOKEN_SUFFIX));
|
|
24
|
+
let found = null;
|
|
25
|
+
for (const file of tokenFiles) {
|
|
26
|
+
const filePath = `${TOKEN_DIR}/${file}`;
|
|
27
|
+
try {
|
|
28
|
+
const content = await readFile(filePath, 'utf-8');
|
|
29
|
+
const data = JSON.parse(content);
|
|
30
|
+
if (!data.port || !data.token || !data.pid)
|
|
31
|
+
continue;
|
|
32
|
+
if (!isPidAlive(data.pid)) {
|
|
33
|
+
// Clean stale token files from dead processes
|
|
34
|
+
await unlink(filePath).catch(() => { });
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (!found) {
|
|
38
|
+
found = { port: data.port, token: data.token };
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// Skip malformed files
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return found;
|
|
47
|
+
}
|
|
48
|
+
export async function discoverBridgesByPid() {
|
|
49
|
+
const result = new Map();
|
|
50
|
+
let files;
|
|
51
|
+
try {
|
|
52
|
+
files = await readdir(TOKEN_DIR);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
const tokenFiles = files.filter((f) => f.startsWith(TOKEN_PREFIX) && f.endsWith(TOKEN_SUFFIX));
|
|
58
|
+
for (const file of tokenFiles) {
|
|
59
|
+
const filePath = `${TOKEN_DIR}/${file}`;
|
|
60
|
+
try {
|
|
61
|
+
const content = await readFile(filePath, 'utf-8');
|
|
62
|
+
const data = JSON.parse(content);
|
|
63
|
+
if (!data.port || !data.token || !data.pid)
|
|
64
|
+
continue;
|
|
65
|
+
if (!isPidAlive(data.pid)) {
|
|
66
|
+
await unlink(filePath).catch(() => { });
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
result.set(data.pid, { port: data.port, token: data.token });
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=tokenDiscovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenDiscovery.js","sourceRoot":"","sources":["../../src/bridge/tokenDiscovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAGjC,MAAM,SAAS,GAAG,MAAM,EAAE,CAAC;AAC3B,MAAM,YAAY,GAAG,mBAAmB,CAAC;AACzC,MAAM,YAAY,GAAG,QAAQ,CAAC;AAQ9B,SAAS,UAAU,CAAC,GAAW;IAC7B,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,IAAI,KAAe,CAAC;IACpB,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAC7B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,CAC9D,CAAC;IAEF,IAAI,KAAK,GAAwB,IAAI,CAAC;IAEtC,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,GAAG,SAAS,IAAI,IAAI,EAAE,CAAC;QACxC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAClD,MAAM,IAAI,GAAc,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAE5C,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,GAAG;gBAAE,SAAS;YAErD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC1B,8CAA8C;gBAC9C,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;gBACvC,SAAS;YACX,CAAC;YAED,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,KAAK,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;YACjD,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,uBAAuB;YACvB,SAAS;QACX,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAwB,CAAC;IAE/C,IAAI,KAAe,CAAC;IACpB,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAC7B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,CAC9D,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,GAAG,SAAS,IAAI,IAAI,EAAE,CAAC;QACxC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAClD,MAAM,IAAI,GAAc,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAE5C,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,GAAG;gBAAE,SAAS;YAErD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC1B,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;gBACvC,SAAS;YACX,CAAC;YAED,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QAC/D,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { detectDisplayServer, ensureTools } from './platform/detect.js';
|
|
4
|
+
import { X11Adapter } from './platform/x11.js';
|
|
5
|
+
import { WaylandAdapter } from './platform/wayland.js';
|
|
6
|
+
import { MacOSAdapter } from './platform/macos.js';
|
|
7
|
+
import { registerScreenshot } from './commands/screenshot.js';
|
|
8
|
+
import { registerInfo } from './commands/info.js';
|
|
9
|
+
import { registerDom } from './commands/dom.js';
|
|
10
|
+
import { registerEval } from './commands/eval.js';
|
|
11
|
+
import { registerWait } from './commands/wait.js';
|
|
12
|
+
import { registerListWindows } from './commands/listWindows.js';
|
|
13
|
+
import { registerIpcMonitor } from './commands/ipcMonitor.js';
|
|
14
|
+
import { registerPageState } from './commands/pageState.js';
|
|
15
|
+
import { registerStorage } from './commands/storage.js';
|
|
16
|
+
import { registerConsoleMonitor } from './commands/consoleMonitor.js';
|
|
17
|
+
const program = new Command()
|
|
18
|
+
.name('tauri-agent-tools')
|
|
19
|
+
.description('Agent-driven inspection toolkit for Tauri desktop apps')
|
|
20
|
+
.version('0.1.0');
|
|
21
|
+
let checkedTools = null;
|
|
22
|
+
async function getAdapter() {
|
|
23
|
+
const ds = detectDisplayServer();
|
|
24
|
+
if (ds === 'unknown') {
|
|
25
|
+
throw new Error('Could not detect display server. Set DISPLAY (X11) or WAYLAND_DISPLAY (Wayland).');
|
|
26
|
+
}
|
|
27
|
+
if (checkedTools !== ds) {
|
|
28
|
+
await ensureTools(ds);
|
|
29
|
+
checkedTools = ds;
|
|
30
|
+
}
|
|
31
|
+
if (ds === 'darwin')
|
|
32
|
+
return new MacOSAdapter();
|
|
33
|
+
return ds === 'x11' ? new X11Adapter() : new WaylandAdapter();
|
|
34
|
+
}
|
|
35
|
+
registerScreenshot(program, getAdapter);
|
|
36
|
+
registerInfo(program, getAdapter);
|
|
37
|
+
registerDom(program);
|
|
38
|
+
registerEval(program);
|
|
39
|
+
registerWait(program, getAdapter);
|
|
40
|
+
registerListWindows(program, getAdapter);
|
|
41
|
+
registerIpcMonitor(program);
|
|
42
|
+
registerPageState(program);
|
|
43
|
+
registerStorage(program);
|
|
44
|
+
registerConsoleMonitor(program);
|
|
45
|
+
program.parseAsync().catch((err) => {
|
|
46
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
47
|
+
process.exitCode = 1;
|
|
48
|
+
});
|
|
49
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAEtE,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE;KAC1B,IAAI,CAAC,mBAAmB,CAAC;KACzB,WAAW,CAAC,wDAAwD,CAAC;KACrE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,IAAI,YAAY,GAAyB,IAAI,CAAC;AAE9C,KAAK,UAAU,UAAU;IACvB,MAAM,EAAE,GAAG,mBAAmB,EAAE,CAAC;IACjC,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CACb,kFAAkF,CACnF,CAAC;IACJ,CAAC;IAED,IAAI,YAAY,KAAK,EAAE,EAAE,CAAC;QACxB,MAAM,WAAW,CAAC,EAAE,CAAC,CAAC;QACtB,YAAY,GAAG,EAAE,CAAC;IACpB,CAAC;IAED,IAAI,EAAE,KAAK,QAAQ;QAAE,OAAO,IAAI,YAAY,EAAE,CAAC;IAC/C,OAAO,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,cAAc,EAAE,CAAC;AAChE,CAAC;AAED,kBAAkB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AACxC,YAAY,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AAClC,WAAW,CAAC,OAAO,CAAC,CAAC;AACrB,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,YAAY,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AAClC,mBAAmB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AACzC,kBAAkB,CAAC,OAAO,CAAC,CAAC;AAC5B,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAC3B,eAAe,CAAC,OAAO,CAAC,CAAC;AACzB,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAEhC,OAAO,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IAC1C,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAChE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { addBridgeOptions, resolveBridge } from './shared.js';
|
|
3
|
+
const PATCH_SCRIPT = `(() => {
|
|
4
|
+
if (window.__tauriDevToolsConsolePatched) return 'already_patched';
|
|
5
|
+
window.__tauriDevToolsOriginalConsole = {
|
|
6
|
+
log: console.log,
|
|
7
|
+
warn: console.warn,
|
|
8
|
+
error: console.error,
|
|
9
|
+
info: console.info,
|
|
10
|
+
debug: console.debug
|
|
11
|
+
};
|
|
12
|
+
window.__tauriDevToolsConsoleLogs = [];
|
|
13
|
+
['log', 'warn', 'error', 'info', 'debug'].forEach(function(level) {
|
|
14
|
+
console[level] = function() {
|
|
15
|
+
var args = Array.prototype.slice.call(arguments);
|
|
16
|
+
var message = args.map(function(a) {
|
|
17
|
+
return typeof a === 'object' ? JSON.stringify(a) : String(a);
|
|
18
|
+
}).join(' ');
|
|
19
|
+
window.__tauriDevToolsConsoleLogs.push({
|
|
20
|
+
level: level,
|
|
21
|
+
message: message,
|
|
22
|
+
timestamp: Date.now()
|
|
23
|
+
});
|
|
24
|
+
window.__tauriDevToolsOriginalConsole[level].apply(console, arguments);
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
window.__tauriDevToolsConsolePatched = true;
|
|
28
|
+
return 'patched';
|
|
29
|
+
})()`;
|
|
30
|
+
const DRAIN_SCRIPT = `(() => {
|
|
31
|
+
var log = window.__tauriDevToolsConsoleLogs || [];
|
|
32
|
+
window.__tauriDevToolsConsoleLogs = [];
|
|
33
|
+
return JSON.stringify(log);
|
|
34
|
+
})()`;
|
|
35
|
+
const CLEANUP_SCRIPT = `(() => {
|
|
36
|
+
if (window.__tauriDevToolsOriginalConsole) {
|
|
37
|
+
['log', 'warn', 'error', 'info', 'debug'].forEach(function(level) {
|
|
38
|
+
console[level] = window.__tauriDevToolsOriginalConsole[level];
|
|
39
|
+
});
|
|
40
|
+
delete window.__tauriDevToolsOriginalConsole;
|
|
41
|
+
delete window.__tauriDevToolsConsoleLogs;
|
|
42
|
+
delete window.__tauriDevToolsConsolePatched;
|
|
43
|
+
}
|
|
44
|
+
return 'cleaned';
|
|
45
|
+
})()`;
|
|
46
|
+
function matchesLevel(entry, level) {
|
|
47
|
+
if (!level)
|
|
48
|
+
return true;
|
|
49
|
+
return entry.level === level;
|
|
50
|
+
}
|
|
51
|
+
function matchesTextFilter(message, filter) {
|
|
52
|
+
if (!filter)
|
|
53
|
+
return true;
|
|
54
|
+
const regex = new RegExp(filter);
|
|
55
|
+
return regex.test(message);
|
|
56
|
+
}
|
|
57
|
+
function formatConsoleEntry(entry) {
|
|
58
|
+
const time = new Date(entry.timestamp).toISOString().slice(11, 23);
|
|
59
|
+
return `[${time}] [${entry.level.toUpperCase()}] ${entry.message}`;
|
|
60
|
+
}
|
|
61
|
+
async function cleanup(bridge) {
|
|
62
|
+
try {
|
|
63
|
+
await bridge.eval(CLEANUP_SCRIPT);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// Best-effort cleanup
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
export function registerConsoleMonitor(program) {
|
|
70
|
+
const cmd = new Command('console-monitor')
|
|
71
|
+
.description('Monitor console output (log/warn/error/info/debug) in real-time')
|
|
72
|
+
.option('--level <level>', 'Filter by level (log, warn, error, info, debug)')
|
|
73
|
+
.option('--filter <regex>', 'Filter messages by regex pattern')
|
|
74
|
+
.option('--interval <ms>', 'Poll interval in milliseconds', parseInt, 500)
|
|
75
|
+
.option('--duration <ms>', 'Auto-stop after N milliseconds', parseInt)
|
|
76
|
+
.option('--json', 'Output one JSON object per line');
|
|
77
|
+
addBridgeOptions(cmd);
|
|
78
|
+
cmd.action(async (opts) => {
|
|
79
|
+
if (opts.level && !['log', 'warn', 'error', 'info', 'debug'].includes(opts.level)) {
|
|
80
|
+
throw new Error(`Invalid level: ${opts.level}. Must be one of: log, warn, error, info, debug`);
|
|
81
|
+
}
|
|
82
|
+
const bridge = await resolveBridge(opts);
|
|
83
|
+
const patchResult = await bridge.eval(PATCH_SCRIPT);
|
|
84
|
+
if (patchResult === 'already_patched') {
|
|
85
|
+
// Already patched, continue monitoring
|
|
86
|
+
}
|
|
87
|
+
let stopped = false;
|
|
88
|
+
const onSignal = () => {
|
|
89
|
+
stopped = true;
|
|
90
|
+
};
|
|
91
|
+
process.on('SIGINT', onSignal);
|
|
92
|
+
process.on('SIGTERM', onSignal);
|
|
93
|
+
let timer;
|
|
94
|
+
if (opts.duration) {
|
|
95
|
+
timer = setTimeout(() => {
|
|
96
|
+
stopped = true;
|
|
97
|
+
}, opts.duration);
|
|
98
|
+
}
|
|
99
|
+
if (!opts.json) {
|
|
100
|
+
console.error('Monitoring console output... (Ctrl+C to stop)');
|
|
101
|
+
}
|
|
102
|
+
try {
|
|
103
|
+
while (!stopped) {
|
|
104
|
+
await new Promise((resolve) => setTimeout(resolve, opts.interval));
|
|
105
|
+
if (stopped)
|
|
106
|
+
break;
|
|
107
|
+
const raw = await bridge.eval(DRAIN_SCRIPT);
|
|
108
|
+
const entries = JSON.parse(String(raw));
|
|
109
|
+
for (const entry of entries) {
|
|
110
|
+
if (!matchesLevel(entry, opts.level))
|
|
111
|
+
continue;
|
|
112
|
+
if (!matchesTextFilter(entry.message, opts.filter))
|
|
113
|
+
continue;
|
|
114
|
+
if (opts.json) {
|
|
115
|
+
console.log(JSON.stringify(entry));
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
console.log(formatConsoleEntry(entry));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
finally {
|
|
124
|
+
if (timer)
|
|
125
|
+
clearTimeout(timer);
|
|
126
|
+
process.off('SIGINT', onSignal);
|
|
127
|
+
process.off('SIGTERM', onSignal);
|
|
128
|
+
await cleanup(bridge);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
program.addCommand(cmd);
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=consoleMonitor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consoleMonitor.js","sourceRoot":"","sources":["../../src/commands/consoleMonitor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { addBridgeOptions, resolveBridge } from './shared.js';
|
|
3
|
+
function formatA11yLine(node, indent) {
|
|
4
|
+
let line = ' '.repeat(indent);
|
|
5
|
+
line += `[${node.role}]`;
|
|
6
|
+
if (node.name) {
|
|
7
|
+
const truncated = node.name.length > 50 ? node.name.slice(0, 47) + '...' : node.name;
|
|
8
|
+
line += ` "${truncated}"`;
|
|
9
|
+
}
|
|
10
|
+
if (node.state) {
|
|
11
|
+
const parts = [];
|
|
12
|
+
for (const [key, value] of Object.entries(node.state)) {
|
|
13
|
+
if (key === 'level') {
|
|
14
|
+
parts.push(`level=${value}`);
|
|
15
|
+
}
|
|
16
|
+
else if (key === 'current') {
|
|
17
|
+
parts.push(`current`);
|
|
18
|
+
}
|
|
19
|
+
else if (value === true) {
|
|
20
|
+
parts.push(key);
|
|
21
|
+
}
|
|
22
|
+
else if (value === false) {
|
|
23
|
+
parts.push(`not ${key}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (parts.length)
|
|
27
|
+
line += ` (${parts.join(', ')})`;
|
|
28
|
+
}
|
|
29
|
+
return line;
|
|
30
|
+
}
|
|
31
|
+
function printA11yTree(node, indent, maxDepth) {
|
|
32
|
+
const lines = [formatA11yLine(node, indent)];
|
|
33
|
+
if (indent < maxDepth && node.children) {
|
|
34
|
+
for (const child of node.children) {
|
|
35
|
+
lines.push(...printA11yTree(child, indent + 1, maxDepth));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return lines;
|
|
39
|
+
}
|
|
40
|
+
function formatTreeLine(node, indent) {
|
|
41
|
+
let line = ' '.repeat(indent);
|
|
42
|
+
line += node.tag;
|
|
43
|
+
if (node.id)
|
|
44
|
+
line += `#${node.id}`;
|
|
45
|
+
if (node.classes?.length)
|
|
46
|
+
line += `.${node.classes.join('.')}`;
|
|
47
|
+
if (node.text) {
|
|
48
|
+
const truncated = node.text.length > 30 ? node.text.slice(0, 27) + '...' : node.text;
|
|
49
|
+
line += ` "${truncated}"`;
|
|
50
|
+
}
|
|
51
|
+
if (node.rect) {
|
|
52
|
+
const w = Math.round(node.rect.width);
|
|
53
|
+
const h = Math.round(node.rect.height);
|
|
54
|
+
line += ` (${w}x${h})`;
|
|
55
|
+
if (h === 0)
|
|
56
|
+
line += ' [hidden]';
|
|
57
|
+
}
|
|
58
|
+
return line;
|
|
59
|
+
}
|
|
60
|
+
function printTree(node, indent, maxDepth) {
|
|
61
|
+
const lines = [formatTreeLine(node, indent)];
|
|
62
|
+
if (indent < maxDepth && node.children) {
|
|
63
|
+
for (const child of node.children) {
|
|
64
|
+
lines.push(...printTree(child, indent + 1, maxDepth));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return lines;
|
|
68
|
+
}
|
|
69
|
+
function buildSerializerScript(selector, depth, includeStyles) {
|
|
70
|
+
return `(() => {
|
|
71
|
+
function serialize(el, d, maxD, styles) {
|
|
72
|
+
const r = el.getBoundingClientRect();
|
|
73
|
+
const node = {
|
|
74
|
+
tag: el.tagName.toLowerCase(),
|
|
75
|
+
rect: { width: r.width, height: r.height },
|
|
76
|
+
};
|
|
77
|
+
if (el.id) node.id = el.id;
|
|
78
|
+
const cls = Array.from(el.classList);
|
|
79
|
+
if (cls.length) node.classes = cls;
|
|
80
|
+
const txt = Array.from(el.childNodes)
|
|
81
|
+
.filter(n => n.nodeType === 3)
|
|
82
|
+
.map(n => n.textContent.trim())
|
|
83
|
+
.filter(Boolean)
|
|
84
|
+
.join(' ');
|
|
85
|
+
if (txt) node.text = txt;
|
|
86
|
+
const attrs = {};
|
|
87
|
+
for (const a of el.attributes) {
|
|
88
|
+
if (a.name !== 'id' && a.name !== 'class' && a.name !== 'style') {
|
|
89
|
+
attrs[a.name] = a.value;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (Object.keys(attrs).length) node.attributes = attrs;
|
|
93
|
+
if (styles) {
|
|
94
|
+
const cs = window.getComputedStyle(el);
|
|
95
|
+
node.styles = {
|
|
96
|
+
display: cs.display,
|
|
97
|
+
visibility: cs.visibility,
|
|
98
|
+
opacity: cs.opacity,
|
|
99
|
+
position: cs.position,
|
|
100
|
+
overflow: cs.overflow,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
if (d < maxD) {
|
|
104
|
+
const kids = [];
|
|
105
|
+
for (const c of el.children) {
|
|
106
|
+
kids.push(serialize(c, d + 1, maxD, styles));
|
|
107
|
+
}
|
|
108
|
+
if (kids.length) node.children = kids;
|
|
109
|
+
}
|
|
110
|
+
return node;
|
|
111
|
+
}
|
|
112
|
+
const root = document.querySelector('${selector.replace(/'/g, "\\'")}');
|
|
113
|
+
if (!root) return null;
|
|
114
|
+
return JSON.stringify(serialize(root, 0, ${depth}, ${includeStyles}));
|
|
115
|
+
})()`;
|
|
116
|
+
}
|
|
117
|
+
export function registerDom(program) {
|
|
118
|
+
const cmd = new Command('dom')
|
|
119
|
+
.description('Query DOM structure from the Tauri app')
|
|
120
|
+
.argument('[selector]', 'Root element to explore', 'body')
|
|
121
|
+
.option('-s, --selector <css>', 'Root element to explore (alternative)')
|
|
122
|
+
.option('--mode <mode>', 'Output mode: dom (default) or accessibility', 'dom')
|
|
123
|
+
.option('--depth <number>', 'Max child depth', parseInt, 3)
|
|
124
|
+
.option('--tree', 'Compact tree view (default)')
|
|
125
|
+
.option('--styles', 'Include computed styles')
|
|
126
|
+
.option('--count', 'Just output match count')
|
|
127
|
+
.option('--first', 'Only return first match')
|
|
128
|
+
.option('--json', 'Full structured JSON output');
|
|
129
|
+
addBridgeOptions(cmd);
|
|
130
|
+
cmd.action(async (selectorArg, opts) => {
|
|
131
|
+
const selector = opts.selector ?? selectorArg;
|
|
132
|
+
const bridge = await resolveBridge(opts);
|
|
133
|
+
if (opts.mode === 'accessibility') {
|
|
134
|
+
const tree = await bridge.getAccessibilityTree(selector, opts.depth);
|
|
135
|
+
if (!tree) {
|
|
136
|
+
throw new Error(`Element not found: ${selector}`);
|
|
137
|
+
}
|
|
138
|
+
if (opts.json) {
|
|
139
|
+
console.log(JSON.stringify(tree, null, 2));
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
const lines = printA11yTree(tree, 0, opts.depth);
|
|
143
|
+
console.log(lines.join('\n'));
|
|
144
|
+
}
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const escaped = selector.replace(/'/g, "\\'");
|
|
148
|
+
if (opts.count) {
|
|
149
|
+
const js = `document.querySelectorAll('${escaped}').length`;
|
|
150
|
+
const result = await bridge.eval(js);
|
|
151
|
+
console.log(String(result));
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (opts.first) {
|
|
155
|
+
// Return only the first match, depth 0 (just the element itself)
|
|
156
|
+
const script = buildSerializerScript(selector, 0, !!opts.styles);
|
|
157
|
+
const result = await bridge.eval(script);
|
|
158
|
+
if (result === null || result === undefined) {
|
|
159
|
+
throw new Error(`Element not found: ${selector}`);
|
|
160
|
+
}
|
|
161
|
+
const node = JSON.parse(String(result));
|
|
162
|
+
if (opts.json) {
|
|
163
|
+
console.log(JSON.stringify(node, null, 2));
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
console.log(formatTreeLine(node, 0));
|
|
167
|
+
}
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const script = buildSerializerScript(selector, opts.depth, !!opts.styles);
|
|
171
|
+
const result = await bridge.eval(script);
|
|
172
|
+
if (result === null || result === undefined) {
|
|
173
|
+
throw new Error(`Element not found: ${selector}`);
|
|
174
|
+
}
|
|
175
|
+
const tree = JSON.parse(String(result));
|
|
176
|
+
if (opts.json) {
|
|
177
|
+
console.log(JSON.stringify(tree, null, 2));
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
const lines = printTree(tree, 0, opts.depth);
|
|
181
|
+
console.log(lines.join('\n'));
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
program.addCommand(cmd);
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=dom.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dom.js","sourceRoot":"","sources":["../../src/commands/dom.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { addBridgeOptions, resolveBridge } from './shared.js';
|
|
3
|
+
export function registerEval(program) {
|
|
4
|
+
const cmd = new Command('eval')
|
|
5
|
+
.description('Evaluate a JavaScript expression in the Tauri app')
|
|
6
|
+
.argument('<expression>', 'JavaScript expression to evaluate');
|
|
7
|
+
addBridgeOptions(cmd);
|
|
8
|
+
cmd.action(async (expression, opts) => {
|
|
9
|
+
const bridge = await resolveBridge(opts);
|
|
10
|
+
const result = await bridge.eval(expression);
|
|
11
|
+
if (typeof result === 'string') {
|
|
12
|
+
// Try to pretty-print if it's JSON
|
|
13
|
+
try {
|
|
14
|
+
const parsed = JSON.parse(result);
|
|
15
|
+
console.log(JSON.stringify(parsed, null, 2));
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
console.log(result);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
console.log(JSON.stringify(result, null, 2));
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
program.addCommand(cmd);
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=eval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eval.js","sourceRoot":"","sources":["../../src/commands/eval.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE9D,MAAM,UAAU,YAAY,CAAC,OAAgB;IAC3C,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;SAC5B,WAAW,CAAC,mDAAmD,CAAC;SAChE,QAAQ,CAAC,cAAc,EAAE,mCAAmC,CAAC,CAAC;IAEjE,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAEtB,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,UAAkB,EAAE,IAAuC,EAAE,EAAE;QAC/E,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAE7C,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC/B,mCAAmC;YACnC,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBAClC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC/C,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACtB,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC"}
|