@winstonfassett/webdev-gateway 0.1.0-alpha.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/CHANGELOG.md +16 -0
- package/LICENSE +21 -0
- package/README.md +78 -0
- package/dist/adapter-helpers.d.ts +64 -0
- package/dist/adapter-helpers.d.ts.map +1 -0
- package/dist/adapter-helpers.js +297 -0
- package/dist/adapter-helpers.js.map +1 -0
- package/dist/admin/assets/index-DEDI8OIx.css +2 -0
- package/dist/admin/assets/index-DaI40ww1.js +70 -0
- package/dist/admin/assets/tinykeys.module-CjuTRcEz.js +1 -0
- package/dist/admin/index.html +13 -0
- package/dist/admin-rpc.d.ts +27 -0
- package/dist/admin-rpc.d.ts.map +1 -0
- package/dist/admin-rpc.js +147 -0
- package/dist/admin-rpc.js.map +1 -0
- package/dist/admin.d.ts +10 -0
- package/dist/admin.d.ts.map +1 -0
- package/dist/admin.js +202 -0
- package/dist/admin.js.map +1 -0
- package/dist/auto-register.d.ts +10 -0
- package/dist/auto-register.d.ts.map +1 -0
- package/dist/auto-register.js +145 -0
- package/dist/auto-register.js.map +1 -0
- package/dist/cdp-relay.d.ts +110 -0
- package/dist/cdp-relay.d.ts.map +1 -0
- package/dist/cdp-relay.js +616 -0
- package/dist/cdp-relay.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +95 -0
- package/dist/cli.js.map +1 -0
- package/dist/doctor.d.ts +6 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +149 -0
- package/dist/doctor.js.map +1 -0
- package/dist/element-grab-client.js +305 -0
- package/dist/element-grab.d.ts +15 -0
- package/dist/element-grab.d.ts.map +1 -0
- package/dist/element-grab.js +102 -0
- package/dist/element-grab.js.map +1 -0
- package/dist/gateway.d.ts +5 -0
- package/dist/gateway.d.ts.map +1 -0
- package/dist/gateway.js +534 -0
- package/dist/gateway.js.map +1 -0
- package/dist/installer.d.ts +48 -0
- package/dist/installer.d.ts.map +1 -0
- package/dist/installer.js +637 -0
- package/dist/installer.js.map +1 -0
- package/dist/libs/element-source.js +35 -0
- package/dist/libs/modern-screenshot.js +14 -0
- package/dist/log-reader.d.ts +30 -0
- package/dist/log-reader.d.ts.map +1 -0
- package/dist/log-reader.js +174 -0
- package/dist/log-reader.js.map +1 -0
- package/dist/mcp-server.d.ts +22 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +115 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/mcp-tools-core.d.ts +30 -0
- package/dist/mcp-tools-core.d.ts.map +1 -0
- package/dist/mcp-tools-core.js +375 -0
- package/dist/mcp-tools-core.js.map +1 -0
- package/dist/mcp-tools-full.d.ts +4 -0
- package/dist/mcp-tools-full.d.ts.map +1 -0
- package/dist/mcp-tools-full.js +141 -0
- package/dist/mcp-tools-full.js.map +1 -0
- package/dist/playwright-commands.d.ts +33 -0
- package/dist/playwright-commands.d.ts.map +1 -0
- package/dist/playwright-commands.js +356 -0
- package/dist/playwright-commands.js.map +1 -0
- package/dist/registry.d.ts +83 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +205 -0
- package/dist/registry.js.map +1 -0
- package/dist/rpc-server.d.ts +54 -0
- package/dist/rpc-server.d.ts.map +1 -0
- package/dist/rpc-server.js +207 -0
- package/dist/rpc-server.js.map +1 -0
- package/dist/session.d.ts +13 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +61 -0
- package/dist/session.js.map +1 -0
- package/dist/types.d.ts +76 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/webdev-client.js +20 -0
- package/dist/writers/base.d.ts +24 -0
- package/dist/writers/base.d.ts.map +1 -0
- package/dist/writers/base.js +98 -0
- package/dist/writers/base.js.map +1 -0
- package/dist/writers/console.d.ts +8 -0
- package/dist/writers/console.d.ts.map +1 -0
- package/dist/writers/console.js +14 -0
- package/dist/writers/console.js.map +1 -0
- package/dist/writers/dev-events.d.ts +28 -0
- package/dist/writers/dev-events.d.ts.map +1 -0
- package/dist/writers/dev-events.js +53 -0
- package/dist/writers/dev-events.js.map +1 -0
- package/dist/writers/errors.d.ts +8 -0
- package/dist/writers/errors.d.ts.map +1 -0
- package/dist/writers/errors.js +14 -0
- package/dist/writers/errors.js.map +1 -0
- package/dist/writers/network.d.ts +9 -0
- package/dist/writers/network.d.ts.map +1 -0
- package/dist/writers/network.js +17 -0
- package/dist/writers/network.js.map +1 -0
- package/dist/writers/server-console.d.ts +8 -0
- package/dist/writers/server-console.d.ts.map +1 -0
- package/dist/writers/server-console.js +14 -0
- package/dist/writers/server-console.js.map +1 -0
- package/package.json +79 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { startGateway } from './gateway.js';
|
|
4
|
+
import { runInit } from './installer.js';
|
|
5
|
+
import { runDoctor } from './doctor.js';
|
|
6
|
+
const program = new Command();
|
|
7
|
+
program
|
|
8
|
+
.name('npx webdev')
|
|
9
|
+
.description('MCP gateway for web development — proxy any dev server with live browser observability for AI agents');
|
|
10
|
+
program
|
|
11
|
+
.command('start', { isDefault: true })
|
|
12
|
+
.description('Start the gateway (default command)')
|
|
13
|
+
.option('-p, --port <port>', 'Gateway port', (v) => parseInt(v, 10))
|
|
14
|
+
.option('--network', 'Capture fetch/XHR requests')
|
|
15
|
+
.option('--https', 'Enable HTTPS with self-signed cert')
|
|
16
|
+
.option('--cert <path>', 'Custom TLS certificate (use with --key)')
|
|
17
|
+
.option('--key <path>', 'Custom TLS private key (use with --cert)')
|
|
18
|
+
.option('--auto-register', 'Register MCP URL in .mcp.json, .cursor/, .windsurf/ then exit')
|
|
19
|
+
.option('--global', 'With --auto-register: write to user-level configs (~/.claude/, ~/.cursor/)')
|
|
20
|
+
.action(async (opts) => {
|
|
21
|
+
if (opts.autoRegister) {
|
|
22
|
+
const { autoRegister, autoRegisterGlobal } = await import('./auto-register.js');
|
|
23
|
+
const port = opts.port ?? 3333;
|
|
24
|
+
const mcpUrl = `http://localhost:${port}/__mcp/sse`;
|
|
25
|
+
if (opts.global) {
|
|
26
|
+
const registered = autoRegisterGlobal(mcpUrl);
|
|
27
|
+
for (const path of registered) {
|
|
28
|
+
console.log(` Auto-registered (global): ${path}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
const registered = autoRegister(process.cwd(), mcpUrl);
|
|
33
|
+
for (const path of registered) {
|
|
34
|
+
console.log(` Auto-registered: ${path}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
process.exit(0);
|
|
38
|
+
}
|
|
39
|
+
await startGateway({
|
|
40
|
+
port: opts.port,
|
|
41
|
+
network: opts.network,
|
|
42
|
+
https: opts.https,
|
|
43
|
+
cert: opts.cert,
|
|
44
|
+
key: opts.key,
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
program
|
|
48
|
+
.command('init')
|
|
49
|
+
.description('Install webdev into the current project (detect framework, wire config, install deps, register MCP)')
|
|
50
|
+
.option('--cwd <dir>', 'Project directory (default: current)', process.cwd())
|
|
51
|
+
.option('-p, --port <port>', 'Gateway port to register with MCP clients (default: 3333)', (v) => parseInt(v, 10), 3333)
|
|
52
|
+
.option('--skip-install', 'Skip npm install of adapter + gateway packages')
|
|
53
|
+
.option('--skip-mcp', 'Skip writing MCP client config files')
|
|
54
|
+
.option('-y, --yes', 'Auto-accept all prompts (non-interactive / CI)')
|
|
55
|
+
.action(async (opts) => {
|
|
56
|
+
await runInit({
|
|
57
|
+
cwd: opts.cwd,
|
|
58
|
+
port: opts.port,
|
|
59
|
+
skipInstall: opts.skipInstall,
|
|
60
|
+
skipMcp: opts.skipMcp,
|
|
61
|
+
yes: opts.yes,
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
program
|
|
65
|
+
.command('doctor')
|
|
66
|
+
.description('Verify setup: gateway reachable, framework wired, adapter installed, MCP registered')
|
|
67
|
+
.option('--cwd <dir>', 'Project directory (default: current)', process.cwd())
|
|
68
|
+
.option('-p, --port <port>', 'Gateway port (default: 3333)', (v) => parseInt(v, 10), 3333)
|
|
69
|
+
.action(async (opts) => {
|
|
70
|
+
await runDoctor({ cwd: opts.cwd, port: opts.port });
|
|
71
|
+
});
|
|
72
|
+
program
|
|
73
|
+
.command('register')
|
|
74
|
+
.description('Register MCP URL with agent clients (.mcp.json, .cursor/, .windsurf/, .vscode/)')
|
|
75
|
+
.option('-p, --port <port>', 'Gateway port', (v) => parseInt(v, 10), 3333)
|
|
76
|
+
.option('--global', 'Write to user-level configs (~/.claude/, ~/.cursor/) instead of project-level')
|
|
77
|
+
.action(async (opts) => {
|
|
78
|
+
const { autoRegister, autoRegisterGlobal } = await import('./auto-register.js');
|
|
79
|
+
const mcpUrl = `http://localhost:${opts.port}/__mcp/sse`;
|
|
80
|
+
if (opts.global) {
|
|
81
|
+
const registered = autoRegisterGlobal(mcpUrl);
|
|
82
|
+
for (const path of registered)
|
|
83
|
+
console.log(` Registered (global): ${path}`);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
const registered = autoRegister(process.cwd(), mcpUrl);
|
|
87
|
+
for (const path of registered)
|
|
88
|
+
console.log(` Registered: ${path}`);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
program.parseAsync().catch((err) => {
|
|
92
|
+
console.error('Failed:', err);
|
|
93
|
+
process.exit(1);
|
|
94
|
+
});
|
|
95
|
+
//# 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":"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"}
|
package/dist/doctor.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"AAcA,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA8GlE"}
|
package/dist/doctor.js
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join, dirname } from 'node:path';
|
|
3
|
+
import http from 'node:http';
|
|
4
|
+
import { intro, outro, log, note } from '@clack/prompts';
|
|
5
|
+
import pc from 'picocolors';
|
|
6
|
+
import { detectFrameworksIn, isWired, relPath, ADAPTER_PACKAGES, GATEWAY_PKG, } from './installer.js';
|
|
7
|
+
export async function runDoctor(opts) {
|
|
8
|
+
intro(pc.cyan('webdev doctor'));
|
|
9
|
+
let pass = 0;
|
|
10
|
+
let fail = 0;
|
|
11
|
+
let warn = 0;
|
|
12
|
+
// 1. Gateway reachable
|
|
13
|
+
const gatewayOk = await checkGatewayReachable(opts.port);
|
|
14
|
+
if (gatewayOk) {
|
|
15
|
+
log.success(`Gateway responding at ${pc.dim(`http://localhost:${opts.port}`)}`);
|
|
16
|
+
pass++;
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
log.error(`Gateway not responding at ${pc.dim(`http://localhost:${opts.port}`)} — start it with ${pc.cyan('npm run dev')} (adapter auto-spawns) or ${pc.cyan('npx webdev')}`);
|
|
20
|
+
fail++;
|
|
21
|
+
}
|
|
22
|
+
// 2. Detect framework + check wiring + check adapter installed
|
|
23
|
+
const frameworks = await detectFrameworksIn(opts.cwd);
|
|
24
|
+
if (frameworks.length === 0) {
|
|
25
|
+
log.warn(`No supported framework config in ${pc.dim(opts.cwd)}. Skipping wiring + adapter checks. (Run ${pc.cyan('init')} from the directory containing your framework config.)`);
|
|
26
|
+
warn++;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
for (const fw of frameworks) {
|
|
30
|
+
const rel = relPath(opts.cwd, fw.configPath);
|
|
31
|
+
if (isWired(fw)) {
|
|
32
|
+
log.success(`${fw.name}: config wired ${pc.dim(`(${rel})`)}`);
|
|
33
|
+
pass++;
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
log.error(`${fw.name}: config NOT wired ${pc.dim(`(${rel})`)} — run ${pc.cyan('npx webdev init')}`);
|
|
37
|
+
fail++;
|
|
38
|
+
}
|
|
39
|
+
const adapterPkg = ADAPTER_PACKAGES[fw.name];
|
|
40
|
+
if (adapterPkg) {
|
|
41
|
+
if (isPackageInstalled(fw.projectDir, adapterPkg)) {
|
|
42
|
+
log.success(`${adapterPkg} installed ${pc.dim(`(${relPath(opts.cwd, fw.projectDir) || '.'})`)}`);
|
|
43
|
+
pass++;
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
log.error(`${adapterPkg} NOT installed in ${pc.dim(relPath(opts.cwd, fw.projectDir) || '.')} — run ${pc.cyan(`npm i -D ${adapterPkg}`)}`);
|
|
47
|
+
fail++;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (!isPackageInstalled(fw.projectDir, GATEWAY_PKG)) {
|
|
51
|
+
log.warn(`${GATEWAY_PKG} not in ${relPath(opts.cwd, fw.projectDir) || '.'} package.json (OK if you use ${pc.cyan('npx webdev')} — won't auto-spawn from the adapter)`);
|
|
52
|
+
warn++;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// 3. MCP client configs — check for ANY entry pointing at our gateway URL
|
|
57
|
+
// (user may have registered under a custom key like 'my-mcp' instead of 'webdev')
|
|
58
|
+
const gatewayUrl = `http://localhost:${opts.port}/__mcp/sse`;
|
|
59
|
+
const mcpRels = [
|
|
60
|
+
{ path: '.mcp.json', serversKey: 'mcpServers' },
|
|
61
|
+
{ path: '.cursor/mcp.json', serversKey: 'mcpServers' },
|
|
62
|
+
{ path: '.windsurf/mcp.json', serversKey: 'mcpServers' },
|
|
63
|
+
{ path: '.vscode/mcp.json', serversKey: 'servers' },
|
|
64
|
+
];
|
|
65
|
+
let anyMcpFound = false;
|
|
66
|
+
let anyMcpPointsHere = false;
|
|
67
|
+
for (const { path, serversKey } of mcpRels) {
|
|
68
|
+
const full = join(opts.cwd, path);
|
|
69
|
+
if (!existsSync(full))
|
|
70
|
+
continue;
|
|
71
|
+
anyMcpFound = true;
|
|
72
|
+
try {
|
|
73
|
+
const config = JSON.parse(readFileSync(full, 'utf-8'));
|
|
74
|
+
const servers = (config[serversKey] ?? {});
|
|
75
|
+
const matchingEntry = Object.entries(servers).find(([_k, v]) => v?.url === gatewayUrl);
|
|
76
|
+
if (matchingEntry) {
|
|
77
|
+
const [key] = matchingEntry;
|
|
78
|
+
const keyHint = key === 'webdev' ? '' : pc.dim(` (key: ${key})`);
|
|
79
|
+
log.success(`MCP registered in ${pc.dim(path)}${keyHint}`);
|
|
80
|
+
pass++;
|
|
81
|
+
anyMcpPointsHere = true;
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
log.warn(`${path} exists but no entry points to ${pc.dim(gatewayUrl)}`);
|
|
85
|
+
warn++;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
log.warn(`Could not parse ${pc.dim(path)} — ${err.message}`);
|
|
90
|
+
warn++;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (!anyMcpFound) {
|
|
94
|
+
log.warn(`No MCP client config files found. Run ${pc.cyan('npx webdev register')} to create them.`);
|
|
95
|
+
warn++;
|
|
96
|
+
}
|
|
97
|
+
else if (!anyMcpPointsHere) {
|
|
98
|
+
log.error(`MCP files exist but none point to ${pc.dim(gatewayUrl)}. Run ${pc.cyan('npx webdev register')}.`);
|
|
99
|
+
fail++;
|
|
100
|
+
}
|
|
101
|
+
// Summary
|
|
102
|
+
const summary = [
|
|
103
|
+
`${pc.green(`✓ ${pass} passed`)}`,
|
|
104
|
+
warn > 0 ? `${pc.yellow(`▲ ${warn} warning${warn !== 1 ? 's' : ''}`)}` : null,
|
|
105
|
+
fail > 0 ? `${pc.red(`✗ ${fail} failed`)}` : null,
|
|
106
|
+
]
|
|
107
|
+
.filter(Boolean)
|
|
108
|
+
.join(' · ');
|
|
109
|
+
note(summary, 'doctor');
|
|
110
|
+
if (fail > 0) {
|
|
111
|
+
outro(pc.red('Some checks failed.'));
|
|
112
|
+
process.exitCode = 1;
|
|
113
|
+
}
|
|
114
|
+
else if (warn > 0) {
|
|
115
|
+
outro(pc.yellow('All required checks passed (warnings noted).'));
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
outro(pc.green('All checks passed.'));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
async function checkGatewayReachable(port) {
|
|
122
|
+
return new Promise((resolve) => {
|
|
123
|
+
const req = http.request({ host: 'localhost', port, path: '/', method: 'HEAD', timeout: 1500 }, (res) => {
|
|
124
|
+
// Any HTTP response means the gateway is up.
|
|
125
|
+
res.resume();
|
|
126
|
+
resolve(true);
|
|
127
|
+
});
|
|
128
|
+
req.on('error', () => resolve(false));
|
|
129
|
+
req.on('timeout', () => {
|
|
130
|
+
req.destroy();
|
|
131
|
+
resolve(false);
|
|
132
|
+
});
|
|
133
|
+
req.end();
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
function isPackageInstalled(projectDir, pkg) {
|
|
137
|
+
// Cheap check: package dir in node_modules. Workspace-hoisted deps may live
|
|
138
|
+
// in a parent node_modules — walk up until found or filesystem root.
|
|
139
|
+
let dir = projectDir;
|
|
140
|
+
while (true) {
|
|
141
|
+
if (existsSync(join(dir, 'node_modules', pkg, 'package.json')))
|
|
142
|
+
return true;
|
|
143
|
+
const parent = dirname(dir);
|
|
144
|
+
if (parent === dir)
|
|
145
|
+
return false;
|
|
146
|
+
dir = parent;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAA;AACxD,OAAO,EAAE,MAAM,YAAY,CAAA;AAC3B,OAAO,EACL,kBAAkB,EAClB,OAAO,EACP,OAAO,EACP,gBAAgB,EAChB,WAAW,GAEZ,MAAM,gBAAgB,CAAA;AAOvB,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAmB;IACjD,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAA;IAE/B,IAAI,IAAI,GAAG,CAAC,CAAA;IACZ,IAAI,IAAI,GAAG,CAAC,CAAA;IACZ,IAAI,IAAI,GAAG,CAAC,CAAA;IAEZ,uBAAuB;IACvB,MAAM,SAAS,GAAG,MAAM,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACxD,IAAI,SAAS,EAAE,CAAC;QACd,GAAG,CAAC,OAAO,CAAC,yBAAyB,EAAE,CAAC,GAAG,CAAC,oBAAoB,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAA;QAC/E,IAAI,EAAE,CAAA;IACR,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,KAAK,CAAC,6BAA6B,EAAE,CAAC,GAAG,CAAC,oBAAoB,IAAI,CAAC,IAAI,EAAE,CAAC,oBAAoB,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,6BAA6B,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAA;QAC7K,IAAI,EAAE,CAAA;IACR,CAAC;IAED,+DAA+D;IAC/D,MAAM,UAAU,GAAG,MAAM,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACrD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,GAAG,CAAC,IAAI,CAAC,oCAAoC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,4CAA4C,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,wDAAwD,CAAC,CAAA;QACjL,IAAI,EAAE,CAAA;IACR,CAAC;SAAM,CAAC;QACN,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;YAC5B,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,CAAA;YAC5C,IAAI,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;gBAChB,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,kBAAkB,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC,CAAA;gBAC7D,IAAI,EAAE,CAAA;YACR,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,sBAAsB,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAA;gBACnG,IAAI,EAAE,CAAA;YACR,CAAC;YAED,MAAM,UAAU,GAAG,gBAAgB,CAAC,EAAE,CAAC,IAAI,CAAC,CAAA;YAC5C,IAAI,UAAU,EAAE,CAAC;gBACf,IAAI,kBAAkB,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC,EAAE,CAAC;oBAClD,GAAG,CAAC,OAAO,CAAC,GAAG,UAAU,cAAc,EAAE,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC,CAAA;oBAChG,IAAI,EAAE,CAAA;gBACR,CAAC;qBAAM,CAAC;oBACN,GAAG,CAAC,KAAK,CAAC,GAAG,UAAU,qBAAqB,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,YAAY,UAAU,EAAE,CAAC,EAAE,CAAC,CAAA;oBACzI,IAAI,EAAE,CAAA;gBACR,CAAC;YACH,CAAC;YACD,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,UAAU,EAAE,WAAW,CAAC,EAAE,CAAC;gBACpD,GAAG,CAAC,IAAI,CAAC,GAAG,WAAW,WAAW,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,GAAG,gCAAgC,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,uCAAuC,CAAC,CAAA;gBACtK,IAAI,EAAE,CAAA;YACR,CAAC;QACH,CAAC;IACH,CAAC;IAED,0EAA0E;IAC1E,kFAAkF;IAClF,MAAM,UAAU,GAAG,oBAAoB,IAAI,CAAC,IAAI,YAAY,CAAA;IAC5D,MAAM,OAAO,GAAgD;QAC3D,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE;QAC/C,EAAE,IAAI,EAAE,kBAAkB,EAAE,UAAU,EAAE,YAAY,EAAE;QACtD,EAAE,IAAI,EAAE,oBAAoB,EAAE,UAAU,EAAE,YAAY,EAAE;QACxD,EAAE,IAAI,EAAE,kBAAkB,EAAE,UAAU,EAAE,SAAS,EAAE;KACpD,CAAA;IACD,IAAI,WAAW,GAAG,KAAK,CAAA;IACvB,IAAI,gBAAgB,GAAG,KAAK,CAAA;IAC5B,KAAK,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,OAAO,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;QACjC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,SAAQ;QAC/B,WAAW,GAAG,IAAI,CAAA;QAClB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAA;YACtD,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,CAAqC,CAAA;YAC9E,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,UAAU,CAAC,CAAA;YACtF,IAAI,aAAa,EAAE,CAAC;gBAClB,MAAM,CAAC,GAAG,CAAC,GAAG,aAAa,CAAA;gBAC3B,MAAM,OAAO,GAAG,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC,CAAA;gBAChE,GAAG,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,OAAO,EAAE,CAAC,CAAA;gBAC1D,IAAI,EAAE,CAAA;gBACN,gBAAgB,GAAG,IAAI,CAAA;YACzB,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,kCAAkC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;gBACvE,IAAI,EAAE,CAAA;YACR,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,MAAO,GAAa,CAAC,OAAO,EAAE,CAAC,CAAA;YACvE,IAAI,EAAE,CAAA;QACR,CAAC;IACH,CAAC;IACD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,GAAG,CAAC,IAAI,CAAC,yCAAyC,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,kBAAkB,CAAC,CAAA;QACnG,IAAI,EAAE,CAAA;IACR,CAAC;SAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC7B,GAAG,CAAC,KAAK,CAAC,qCAAqC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAA;QAC5G,IAAI,EAAE,CAAA;IACR,CAAC;IAED,UAAU;IACV,MAAM,OAAO,GAAG;QACd,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,IAAI,SAAS,CAAC,EAAE;QACjC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,IAAI,WAAW,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI;QAC7E,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,IAAI,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI;KAClD;SACE,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,OAAO,CAAC,CAAA;IAChB,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;IAEvB,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;QACb,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC,CAAA;QACpC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;IACtB,CAAC;SAAM,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;QACpB,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,8CAA8C,CAAC,CAAC,CAAA;IAClE,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAA;IACvC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,qBAAqB,CAAC,IAAY;IAC/C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CACtB,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,EACrE,CAAC,GAAG,EAAE,EAAE;YACN,6CAA6C;YAC7C,GAAG,CAAC,MAAM,EAAE,CAAA;YACZ,OAAO,CAAC,IAAI,CAAC,CAAA;QACf,CAAC,CACF,CAAA;QACD,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAA;QACrC,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;YACrB,GAAG,CAAC,OAAO,EAAE,CAAA;YACb,OAAO,CAAC,KAAK,CAAC,CAAA;QAChB,CAAC,CAAC,CAAA;QACF,GAAG,CAAC,GAAG,EAAE,CAAA;IACX,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,UAAkB,EAAE,GAAW;IACzD,4EAA4E;IAC5E,qEAAqE;IACrE,IAAI,GAAG,GAAG,UAAU,CAAA;IACpB,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,cAAc,CAAC,CAAC;YAAE,OAAO,IAAI,CAAA;QAC3E,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;QAC3B,IAAI,MAAM,KAAK,GAAG;YAAE,OAAO,KAAK,CAAA;QAChC,GAAG,GAAG,MAAM,CAAA;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
"use strict";(()=>{var K="data-element-grab";var ve=e=>{let t=document.querySelector(`[${K}]`);if(t){let s=t.shadowRoot?.querySelector(`[${K}]`);if(s instanceof HTMLDivElement&&t.shadowRoot)return s}let n=document.createElement("div");n.setAttribute(K,"true"),n.style.zIndex=String(2147483647),n.style.position="fixed",n.style.inset="0",n.style.pointerEvents="none";let o=n.attachShadow({mode:"open"});if(e){let s=document.createElement("style");s.textContent=e,o.appendChild(s)}let i=document.createElement("div");i.setAttribute(K,"true"),o.appendChild(i);let r=document.body??document.documentElement;return r.appendChild(n),setTimeout(()=>r.appendChild(n),1e3),i};var k=(e,t,n)=>e+(t-e)*n;var G=null,ht=()=>{if(G!==null)return G;try{G=window.matchMedia("(color-gamut: p3)").matches}catch{G=!1}return G},ft="210, 57, 192",gt="0.84 0.19 0.78",R=e=>ht()?`color(display-p3 ${gt} / ${e})`:`rgba(${ft}, ${e})`;var Ae="c",Le=!0;var Ce=32;var Z=.95,Re=.7,Y=.5,Oe=.01,Te=2,Ne=R(.4),Se=R(.05),se=R(.5),ae=R(.08),Ie=R(.3),Me=R(.04),De=R(.15),Pe=50,H=1500,le=100,ce=100,de=8,ke=4,He=.2,Be=50,pe=16,O=4,T=8,Xe=100,$e=15;var Fe=95;var ue=2147483647,q=2147483645;var me=16;var W={selection:{borderColor:se,fillColor:ae,lerpFactor:Z},drag:{borderColor:Ne,fillColor:Se,lerpFactor:Re},grabbed:{borderColor:se,fillColor:ae,lerpFactor:Z},inspect:{borderColor:Ie,fillColor:Me,lerpFactor:Z}},Ve=e=>{let t=e.match(/^(\d+(?:\.\d+)?)/);return t?parseFloat(t[1]):0},z=(e,t,n)=>({id:e,current:{x:t.x,y:t.y,width:t.width,height:t.height},target:{x:t.x,y:t.y,width:t.width,height:t.height},borderRadius:Ve(t.borderRadius),opacity:n?.opacity??1,targetOpacity:n?.targetOpacity??n?.opacity??1,createdAt:n?.createdAt,initialized:!0}),J=(e,t,n)=>{e.target={x:t.x,y:t.y,width:t.width,height:t.height},e.borderRadius=Ve(t.borderRadius),n!==void 0&&(e.targetOpacity=n)},Q=(e,t,n=!1)=>{let o=k(e.current.x,e.target.x,t),i=k(e.current.y,e.target.y,t),r=k(e.current.width,e.target.width,t),s=k(e.current.height,e.target.height,t),a=Math.abs(o-e.target.x)<Y&&Math.abs(i-e.target.y)<Y&&Math.abs(r-e.target.width)<Y&&Math.abs(s-e.target.height)<Y;e.current.x=a?e.target.x:o,e.current.y=a?e.target.y:i,e.current.width=a?e.target.width:r,e.current.height=a?e.target.height:s;let p=!0;if(n){let d=k(e.opacity,e.targetOpacity,t);p=Math.abs(d-e.targetOpacity)<Oe,e.opacity=p?e.targetOpacity:d}return!a||!p},yt=(e,t,n,o,i,r,s,a,p=1)=>{if(o<=0||i<=0)return;let d=Math.min(r,o/2,i/2);e.globalAlpha=p,e.beginPath(),d>0?e.roundRect(t,n,o,i,d):e.rect(t,n,o,i),e.fillStyle=s,e.fill(),e.strokeStyle=a,e.lineWidth=1,e.stroke(),e.globalAlpha=1},ee=class{canvas;mainCtx=null;w=0;h=0;dpr=1;frameId=null;layers={selection:{canvas:null,ctx:null},drag:{canvas:null,ctx:null},grabbed:{canvas:null,ctx:null},inspect:{canvas:null,ctx:null}};selectionAnims=[];dragAnim=null;grabbedAnims=[];inspectAnims=[];selectionVisible=!1;selectionFading=!1;dragVisible=!1;constructor(t){this.canvas=document.createElement("canvas"),this.canvas.setAttribute("data-element-grab-canvas",""),this.canvas.style.position="fixed",this.canvas.style.top="0",this.canvas.style.left="0",this.canvas.style.pointerEvents="none",this.canvas.style.zIndex=String(q),t.appendChild(this.canvas),this.init(),window.addEventListener("resize",()=>this.init())}init(){let t=typeof window<"u"&&window.matchMedia?.("(color-gamut: p3)")?.matches?"display-p3":"srgb";this.dpr=Math.max(window.devicePixelRatio||1,Te),this.w=window.innerWidth,this.h=window.innerHeight,this.canvas.width=this.w*this.dpr,this.canvas.height=this.h*this.dpr,this.canvas.style.width=`${this.w}px`,this.canvas.style.height=`${this.h}px`,this.mainCtx=this.canvas.getContext("2d",{colorSpace:t}),this.mainCtx&&this.mainCtx.scale(this.dpr,this.dpr);for(let n of Object.keys(this.layers)){let o=new OffscreenCanvas(this.w*this.dpr,this.h*this.dpr),i=o.getContext("2d",{colorSpace:t});i&&i.scale(this.dpr,this.dpr),this.layers[n]={canvas:o,ctx:i}}}setSelection(t,n=!1){if(!t){this.selectionAnims=[],this.schedule();return}this.selectionAnims.length>0?(J(this.selectionAnims[0],t),n&&(this.selectionAnims[0].current={...this.selectionAnims[0].target})):this.selectionAnims=[z("sel-0",t)],this.schedule()}setSelectionMultiple(t,n=!1){this.selectionAnims=t.map((o,i)=>{let r=`sel-${i}`,s=this.selectionAnims.find(a=>a.id===r);return s?(J(s,o),n&&(s.current={...s.target}),s):z(r,o)}),this.schedule()}setDrag(t){if(!t){this.dragAnim=null,this.schedule();return}this.dragAnim?J(this.dragAnim,t):this.dragAnim=z("drag",t),this.schedule()}addGrabbed(t,n){this.grabbedAnims.find(o=>o.id===t)||this.grabbedAnims.push(z(t,n,{createdAt:Date.now()})),this.schedule()}setInspect(t){this.inspectAnims=t.map((n,o)=>{let i=`inspect-${o}`,r=this.inspectAnims.find(s=>s.id===i);return r?(J(r,n),r):z(i,n)}),this.schedule()}clearInspect(){this.inspectAnims=[],this.schedule()}destroy(){this.frameId!==null&&cancelAnimationFrame(this.frameId),this.canvas.remove(),window.removeEventListener("resize",()=>this.init())}schedule(){this.frameId===null&&(this.frameId=requestAnimationFrame(()=>this.tick()))}tick(){this.frameId=null;let t=!1;for(let o of this.selectionAnims)o.initialized&&Q(o,W.selection.lerpFactor)&&(t=!0);this.dragAnim?.initialized&&Q(this.dragAnim,W.drag.lerpFactor)&&(t=!0);let n=Date.now();this.grabbedAnims=this.grabbedAnims.filter(o=>{if(o.initialized&&Q(o,W.grabbed.lerpFactor)&&(t=!0),o.createdAt){let i=n-o.createdAt;return i>=H+ce?!1:(i>H&&(o.opacity=1-(i-H)/ce,t=!0),!0)}return o.opacity>0});for(let o of this.inspectAnims)o.initialized&&Q(o,W.inspect.lerpFactor)&&(t=!0);this.composite(),t&&(this.frameId=requestAnimationFrame(()=>this.tick()))}renderLayer(t,n,o){let i=this.layers[t];if(!i.ctx)return;i.ctx.clearRect(0,0,this.w,this.h);let r=W[t];for(let s of n){let a=o?.fading?0:s.opacity;yt(i.ctx,s.current.x,s.current.y,s.current.width,s.current.height,s.borderRadius,r.fillColor,r.borderColor,a)}}composite(){if(!this.mainCtx)return;this.mainCtx.setTransform(1,0,0,1,0,0),this.mainCtx.clearRect(0,0,this.canvas.width,this.canvas.height),this.mainCtx.setTransform(this.dpr,0,0,this.dpr,0,0),this.renderLayer("inspect",this.inspectAnims),this.renderLayer("drag",this.dragAnim?[this.dragAnim]:[]),this.renderLayer("selection",this.selectionAnims,{fading:this.selectionFading}),this.renderLayer("grabbed",this.grabbedAnims);let t=["inspect","drag","selection","grabbed"];for(let n of t){let o=this.layers[n].canvas;o&&this.mainCtx.drawImage(o,0,0,this.w,this.h)}}};var bt=["data-testid","data-test-id","data-test","data-cy","data-qa","aria-label","role","name","title","alt"];var Ge=e=>typeof CSS<"u"&&CSS.escape?CSS.escape(e):e.replace(/[^a-zA-Z0-9_-]/g,t=>`\\${t}`),he=(e,t)=>{try{let n=e.ownerDocument.querySelectorAll(t);return n.length===1&&n[0]===e}catch{return!1}},Ye=e=>{if(e instanceof HTMLElement&&e.id){let i=`#${Ge(e.id)}`;if(he(e,i))return i}for(let i of bt){let r=e.getAttribute(i);if(!r||r.length>120)continue;let s=JSON.stringify(r),a=`[${i}=${s}]`;if(he(e,a))return a;let p=`${e.tagName.toLowerCase()}${a}`;if(he(e,p))return p}let t=e.ownerDocument.body??e.ownerDocument.documentElement,n=[],o=e;for(;o;){if(o instanceof HTMLElement&&o.id){n.unshift(`#${Ge(o.id)}`);break}let i=o.parentElement;if(!i){n.unshift(o.tagName.toLowerCase());break}let s=Array.from(i.children).indexOf(o)+1;if(n.unshift(`${o.tagName.toLowerCase()}:nth-child(${s})`),i===t){n.unshift(t.tagName.toLowerCase());break}o=i}return n.join(" > ")};function Et(e){try{let t=Object.keys(e).find(i=>i.startsWith("__reactFiber$")||i.startsWith("__reactInternalInstance$"));if(!t)return null;let o=e[t];for(;o;){if(o.type&&typeof o.type=="function"){let i=o.type.displayName||o.type.name;if(i&&i.length>1&&i[0]===i[0].toUpperCase()&&i!=="Fragment"&&i!=="Suspense"){let r=o._debugSource;return{component:i,file:r?.fileName??null,line:r?.lineNumber??null,column:r?.columnNumber??null}}}o=o.return}}catch{}return null}function _t(e){try{let t=e.getAttribute("data-v-inspector");if(t){let o=t.split(":");if(o.length>=2){let i=o.slice(0,-2).join(":")||o[0],r=parseInt(o[o.length-2],10),s=parseInt(o[o.length-1],10);return{component:We(e),file:i,line:isNaN(r)?null:r,column:isNaN(s)?null:s}}}let n=We(e);if(n)return{component:n,file:null,line:null,column:null}}catch{}return null}function We(e){let t=e;for(;t;){let n=t.__vueParentComponent;if(n){let o=n.type;if(o){let i=o.name||o.__name;if(i&&i!=="Fragment")return i}}t=t.parentElement}return null}function xt(e){try{let t=e;for(;t;){let n=t.__svelte_meta;if(n?.loc){let o=n.loc,i=typeof o.file=="string"?o.file:null,r=typeof o.line=="number"?o.line:null,s=typeof o.column=="number"?o.column+1:null,a=null,p=n.parent;for(;p;){if(typeof p.componentTag=="string"){a=p.componentTag;break}p=p.parent}return{component:a,file:i,line:r,column:s}}t=t.parentElement}}catch{}return null}function wt(e){try{let t=e.__c||e._component;if(t){let n=t.constructor?.displayName||t.constructor?.name,o=t.__v?.__source||t.props?.__source;return{component:n&&n!=="Fragment"?n:null,file:o?.fileName??null,line:o?.lineNumber??null,column:o?.columnNumber??null}}}catch{}return null}var U;async function ze(){if(U!==void 0)return U;try{let t=await import((window.__WEBDEV_ORIGIN__||window.location.origin)+"/__libs/element-source.js");return U=t,t}catch{return U=null,null}}ze();async function vt(e){let t=U;if(!t)return null;try{let n=await t.resolveElementInfo(e);return n?{component:n.componentName??null,file:n.source?.filePath??null,line:n.source?.lineNumber??null,column:n.source?.columnNumber??null}:null}catch{return null}}var At=[Et,_t,xt,wt];function fe(e){for(let t of At){let n=t(e);if(n)return n}return null}async function Ue(e){if(await ze()){let n=await vt(e);if(n)return n}return fe(e)}function je(e){if(!e.file)return null;let t=e.file;return e.line!=null&&(t+=":"+e.line),e.column!=null&&(t+=":"+e.column),t}var Ke=(e,t)=>e.length>t?e.slice(0,t)+"\u2026":e,ge=e=>fe(e)?.component??null,Lt=e=>{let t=e.tagName.toLowerCase(),n=e instanceof HTMLElement?e.innerText?.trim()??e.textContent?.trim()??"":e.textContent?.trim()??"",o="";for(let{name:r,value:s}of e.attributes)o+=` ${r}="${Ke(s,$e)}"`;let i=Ke(n,Xe);return i.length>0?`<${t}${o}>
|
|
2
|
+
${i}
|
|
3
|
+
</${t}>`:`<${t}${o} />`},te=async e=>{let t=Lt(e),n=Ye(e),o=await Ue(e),i=o?.component??null,r=o?je(o):null,s=o?.file?{file:o.file,line:o.line??void 0,column:o.column??void 0}:void 0,a=r?`src: ${r}`:"";return{html:t,stack:a,component:i,selector:n,source:s}},ne=e=>{let t=[];if(e.component?t.push(`<${e.component}> (${e.html.match(/^<(\w+)/)?.[1]??"?"})`):t.push(e.html.split(`
|
|
4
|
+
`)[0]),e.source?.file){let n=e.source.file;e.source.line&&(n+=`:${e.source.line}`),e.source.column&&(n+=`:${e.source.column}`),t.push(`src: ${n}`)}return t.push(`sel: ${e.selector}`),t.push("Live ref: window.__LAST_GRABBED__.element"),t.join(`
|
|
5
|
+
`)};var Ze=async(e,t)=>{let n=new URLSearchParams({file:e});t&&n.set("line",String(t)),n.set("column","1");try{if((await fetch(`/__open-in-editor?${n}`)).ok)return}catch{}try{let i=new URLSearchParams({file:e});if(t&&i.set("line1",String(t)),i.set("column1","1"),(await fetch(`/__nextjs_launch-editor?${i}`)).ok)return}catch{}let o=t?`:${t}`:"";window.open(`vscode://file/${e}${o}`,"_blank","noopener,noreferrer")};function qe(e,t){let n=document.createElement("div");n.className="eg-label",n.style.display="none",e.appendChild(n);let o=document.createElement("div");o.className="eg-arrow";let i=document.createElement("div");i.className="eg-panel",i.style.padding="6px 8px";let r=document.createElement("div");r.className="eg-tag";let s=document.createElement("span");s.className="eg-tag-name";let a=document.createElement("span");a.className="eg-tag-component";let p=document.createElement("span");p.className="eg-tag-suffix",s.appendChild(a),s.appendChild(p),r.appendChild(s),i.appendChild(r),n.appendChild(o),n.appendChild(i);let d={visible:!1,tagName:"",bounds:null,mouseX:0,status:"hovering"},f="none",m=()=>{let c=d.bounds;if(!c)return;let x=n.offsetWidth||100,v=n.offsetHeight||30,b=Math.max(ke,Math.min(de,x*He)),y=window.visualViewport?.width??window.innerWidth,I=window.visualViewport?.height??window.innerHeight,E=window.visualViewport?.offsetLeft??0,re=window.visualViewport?.offsetTop??0,$=d.mouseX||c.x+c.width/2,F=0,C=x/2;$+C>E+y-T&&(F=E+y-T-($+C)),$-C+F<E+T&&(F=E+T-($-C));let V=c.y+c.height+b+O,ct=V+v<=re+I-T,we="bottom";ct||(V=c.y-v-b-O,we="top"),V<re+T&&(V=re+T);let dt=C-F,pt=Math.min(pe,C),ut=Math.max(x-pe,C),mt=Math.max(pt,Math.min(ut,dt))-C;n.style.top=`${V}px`,n.style.left=`${$}px`,n.style.transform=`translateX(calc(-50% + ${F}px))`,n.style.zIndex=String(ue),n.style.opacity=d.status==="fading"?"0":"1",n.style.pointerEvents=d.status==="frozen"||d.status==="copying"?"auto":"none",o.style.left=`calc(${Be}% + ${mt}px)`,we==="bottom"?(o.style.top="0",o.style.bottom="",o.style.transform="translateX(-50%) translateY(-100%)",o.style.borderBottom=`${b}px solid white`,o.style.borderTop=""):(o.style.top="",o.style.bottom="0",o.style.transform="translateX(-50%) translateY(100%)",o.style.borderTop=`${b}px solid white`,o.style.borderBottom=""),o.style.borderLeft=`${b}px solid transparent`,o.style.borderRight=`${b}px solid transparent`},w=()=>{d.componentName?(a.textContent=d.componentName,p.textContent=`.${d.tagName}`):(a.textContent=d.tagName,p.textContent="")},S=()=>{f!=="hover"&&(f="hover",n.innerHTML="",i.innerHTML="",i.style.padding="6px 8px",i.className="eg-panel animate-pop-in",i.appendChild(r),n.appendChild(o),n.appendChild(i))},l=()=>{f="frozen",n.innerHTML="",i.innerHTML="",i.style.padding="0",i.className="eg-panel";let c=document.createElement("div");Object.assign(c.style,{display:"flex",flexDirection:"column",alignItems:"flex-start",minWidth:"150px",maxWidth:"280px"});let x=document.createElement("div");Object.assign(x.style,{display:"flex",alignItems:"center",gap:"4px",padding:"6px 8px 4px 8px"}),x.appendChild(r),c.appendChild(x);let v=document.createElement("div");v.className="eg-bottom-section";let b=document.createElement("div");Object.assign(b.style,{display:"flex",justifyContent:"space-between",alignItems:"flex-end",width:"100%",minHeight:"16px"});let y=document.createElement("textarea");y.className="eg-input",y.placeholder="Add context",y.rows=1,y.style.maxHeight=`${Fe}px`,queueMicrotask(()=>y.focus({preventScroll:!0})),y.addEventListener("keydown",E=>{E.stopImmediatePropagation(),E.code==="Enter"&&!E.shiftKey?(E.preventDefault(),t.onsubmit(y.value)):E.code==="Escape"&&(E.preventDefault(),t.ondismiss())});let I=document.createElement("button");I.className="eg-circle-btn eg-interactive-scale",I.setAttribute("aria-label","Submit"),I.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="white" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5"><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></svg>',I.addEventListener("click",E=>{E.stopImmediatePropagation(),t.onsubmit(y.value)}),b.appendChild(y),b.appendChild(I),v.appendChild(b),c.appendChild(v),i.appendChild(c),n.appendChild(o),n.appendChild(i)},A=()=>{f="copying",n.innerHTML="",i.innerHTML="",i.style.padding="6px 8px",i.className="eg-panel";let c=document.createElement("span");c.className="eg-status shimmer-text",c.textContent="Grabbing\u2026",i.appendChild(c),n.appendChild(o),n.appendChild(i)},u=()=>{f="copied",n.innerHTML="",i.innerHTML="",i.style.padding="6px 8px",i.className="eg-panel animate-success-pop";let c=document.createElement("span");c.className="eg-status",c.style.color="black",c.textContent="Copied",i.appendChild(c),n.appendChild(o),n.appendChild(i)},g=()=>{if(!d.visible||!d.bounds){n.style.display="none";return}switch(n.style.display="",d.status){case"hovering":S(),w();break;case"frozen":f!=="frozen"&&(l(),w());break;case"copying":f!=="copying"&&A();break;case"copied":f!=="copied"&&u();break}m()};return{update(c){let x=c.tagName!==void 0&&c.tagName!==d.tagName,v=c.componentName!==void 0&&c.componentName!==d.componentName;if(Object.assign(d,c),d.status==="hovering"&&f==="hover"&&d.visible&&d.bounds){(x||v)&&w(),m();return}g()},hide(){d.visible=!1,d.status="hovering",f="none",n.style.display="none"},getPromptValue(){return n.querySelector("textarea")?.value?.trim()||""}}}function Je(e,t){let n="element-grab-toolbar",r="right",s=.5,a=!1,p=0,d=0,f=!1;try{let l=JSON.parse(localStorage.getItem(n)||"{}");l.edge&&(r=l.edge),typeof l.ratio=="number"&&(s=l.ratio)}catch{}let m=document.createElement("div");m.className="eg-toolbar-pill",m.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z"/><path d="M13 13l6 6"/></svg><div class="eg-toolbar-dot" style="display:none"></div>',e.appendChild(m);let w=m.querySelector(".eg-toolbar-dot"),S=()=>{let l=window.innerWidth,A=window.innerHeight,u=me,g,c;switch(r){case"right":g=l-40-u,c=u+s*(A-32-2*u);break;case"left":g=u,c=u+s*(A-32-2*u);break;case"top":g=u+s*(l-40-2*u),c=u;break;case"bottom":g=u+s*(l-40-2*u),c=A-32-u;break}m.style.left=`${g}px`,m.style.top=`${c}px`};return m.addEventListener("pointerdown",l=>{a=!0,f=!1,p=l.clientX,d=l.clientY;try{m.setPointerCapture(l.pointerId)}catch{}l.preventDefault()}),m.addEventListener("pointermove",l=>{if(!a)return;(Math.abs(l.clientX-p)>5||Math.abs(l.clientY-d)>5)&&(f=!0);let A=window.innerWidth,u=window.innerHeight,g=me,c=A-l.clientX,x=l.clientX,v=l.clientY,b=u-l.clientY,y=Math.min(c,x,v,b);r=y===c?"right":y===x?"left":y===v?"top":"bottom",s=r==="left"||r==="right"?Math.max(0,Math.min(1,(l.clientY-g)/(u-2*g))):Math.max(0,Math.min(1,(l.clientX-g)/(A-2*g))),S()}),m.addEventListener("pointerup",l=>{if(a){a=!1;try{m.releasePointerCapture(l.pointerId)}catch{}try{localStorage.setItem(n,JSON.stringify({edge:r,ratio:s}))}catch{}f||t.ontoggle()}}),S(),{setActive(l){m.classList.toggle("active",l),w.style.display=l?"":"none"},destroy(){m.remove()}}}function Qe(e){let t=document.createElement("div");t.className="eg-label",t.style.display="none",t.style.pointerEvents="auto",e.appendChild(t);let n=null,o=a=>{a.key==="Escape"&&(a.preventDefault(),s())},i=a=>{t.contains(a.target)||s()},r=a=>{n=a.ondismiss;let p=a.componentName?`<span class="eg-tag-component">${B(a.componentName)}</span><span class="eg-tag-suffix">.${B(a.tagName)}</span>`:`<span class="eg-tag-component">${B(a.tagName)}</span>`,d=a.actions.map(l=>`<button class="eg-menu-item" data-action="${B(l.label)}">${B(l.label)}${l.shortcut?`<span class="eg-menu-item-shortcut">${B(l.shortcut)}</span>`:""}</button>`).join("");t.innerHTML=`<div class="eg-panel" style="flex-direction:column;align-items:flex-start;min-width:100px;padding:0"><div style="display:flex;align-items:center;gap:4px;padding:6px 8px 4px 8px"><span class="eg-tag-name">${p}</span></div><div class="eg-bottom-section" style="padding:4px 0">${d}</div></div>`;let f=de,m=Math.max(O,Math.min(a.position.x-60,window.innerWidth-140)),w=a.bounds.y+a.bounds.height+f+O;t.style.display="";let S=t.offsetHeight;w+S>window.innerHeight&&(w=a.bounds.y-S-f-O),w<O&&(w=O),t.style.left=`${m}px`,t.style.top=`${w}px`,t.style.zIndex=String(ue),t.querySelectorAll(".eg-menu-item").forEach(l=>{let A=l.getAttribute("data-action"),u=a.actions.find(g=>g.label===A);l.addEventListener("click",g=>{g.stopImmediatePropagation(),u?.action(),s()})}),window.addEventListener("keydown",o,!0),window.addEventListener("pointerdown",i,!0)},s=()=>{t.style.display="none",t.innerHTML="",window.removeEventListener("keydown",o,!0),window.removeEventListener("pointerdown",i,!0),n?.(),n=null};return{show:r,hide:s}}var B=e=>e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""");var et=`:host {
|
|
6
|
+
all: initial;
|
|
7
|
+
direction: ltr;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
@keyframes shake {
|
|
11
|
+
0%, 100% { transform: translateX(0); }
|
|
12
|
+
15% { transform: translateX(-3px); }
|
|
13
|
+
30% { transform: translateX(3px); }
|
|
14
|
+
45% { transform: translateX(-3px); }
|
|
15
|
+
60% { transform: translateX(3px); }
|
|
16
|
+
75% { transform: translateX(-2px); }
|
|
17
|
+
90% { transform: translateX(2px); }
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@keyframes pop-in {
|
|
21
|
+
0% { opacity: 0; transform: scale(0.9); }
|
|
22
|
+
70% { opacity: 1; transform: scale(1.02); }
|
|
23
|
+
100% { opacity: 1; transform: scale(1); }
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@keyframes pop-out {
|
|
27
|
+
from { opacity: 1; transform: scale(1); }
|
|
28
|
+
to { opacity: 0; transform: scale(0.95); }
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@keyframes slide-in-bottom {
|
|
32
|
+
from { opacity: 0; transform: translateY(8px); }
|
|
33
|
+
to { opacity: 1; transform: translateY(0); }
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@keyframes slide-in-top {
|
|
37
|
+
from { opacity: 0; transform: translateY(-8px); }
|
|
38
|
+
to { opacity: 1; transform: translateY(0); }
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@keyframes success-pop {
|
|
42
|
+
0% { transform: scale(0.9); opacity: 0; }
|
|
43
|
+
60% { transform: scale(1.1); opacity: 1; }
|
|
44
|
+
80% { transform: scale(0.95); }
|
|
45
|
+
100% { transform: scale(1); opacity: 1; }
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@keyframes icon-loader-spin {
|
|
49
|
+
0% { opacity: 1; }
|
|
50
|
+
50% { opacity: 0.5; }
|
|
51
|
+
100% { opacity: 0.2; }
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@keyframes shimmer {
|
|
55
|
+
0% { background-position: 200% 0; }
|
|
56
|
+
100% { background-position: -200% 0; }
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@keyframes tooltip-fade-in {
|
|
60
|
+
from { opacity: 0; transform: scale(0.97); }
|
|
61
|
+
to { opacity: 1; transform: scale(1); }
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.icon-loader-bar {
|
|
65
|
+
animation: icon-loader-spin 0.5s linear infinite;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.shimmer-text {
|
|
69
|
+
background: linear-gradient(90deg, #71717a 0%, #a1a1aa 25%, #71717a 50%, #a1a1aa 75%, #71717a 100%);
|
|
70
|
+
background-size: 200% 100%;
|
|
71
|
+
-webkit-background-clip: text;
|
|
72
|
+
background-clip: text;
|
|
73
|
+
color: transparent;
|
|
74
|
+
animation: shimmer 2.5s linear infinite;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.animate-shake { animation: shake 0.3s ease-out; will-change: transform; }
|
|
78
|
+
.animate-pop-in { animation: pop-in 150ms ease-out; will-change: transform, opacity; }
|
|
79
|
+
.animate-pop-out { animation: pop-out 150ms ease-out forwards; will-change: transform, opacity; }
|
|
80
|
+
.animate-slide-in-bottom { animation: slide-in-bottom 200ms ease-out; will-change: transform, opacity; }
|
|
81
|
+
.animate-slide-in-top { animation: slide-in-top 200ms ease-out; will-change: transform, opacity; }
|
|
82
|
+
.animate-success-pop { animation: success-pop 250ms ease-out; will-change: transform, opacity; }
|
|
83
|
+
.animate-tooltip-fade-in { animation: tooltip-fade-in 100ms ease-out; will-change: transform, opacity; }
|
|
84
|
+
|
|
85
|
+
/* --- Base styles for element-grab UI --- */
|
|
86
|
+
|
|
87
|
+
.eg-label {
|
|
88
|
+
position: fixed;
|
|
89
|
+
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
|
|
90
|
+
font-size: 13px;
|
|
91
|
+
font-weight: 500;
|
|
92
|
+
-webkit-font-smoothing: antialiased;
|
|
93
|
+
-moz-osx-font-smoothing: grayscale;
|
|
94
|
+
filter: drop-shadow(0px 1px 2px #51515140);
|
|
95
|
+
user-select: none;
|
|
96
|
+
z-index: 2147483647;
|
|
97
|
+
transition: opacity 100ms ease-out;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.eg-panel {
|
|
101
|
+
display: flex;
|
|
102
|
+
align-items: center;
|
|
103
|
+
gap: 5px;
|
|
104
|
+
background: white;
|
|
105
|
+
border-radius: 10px;
|
|
106
|
+
padding: 0;
|
|
107
|
+
width: fit-content;
|
|
108
|
+
height: fit-content;
|
|
109
|
+
font-synthesis: none;
|
|
110
|
+
/* superellipse corners \u2014 degrades gracefully */
|
|
111
|
+
corner-shape: superellipse(1.25);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.eg-tag {
|
|
115
|
+
display: flex;
|
|
116
|
+
align-items: center;
|
|
117
|
+
gap: 4px;
|
|
118
|
+
max-width: 280px;
|
|
119
|
+
overflow: hidden;
|
|
120
|
+
flex-shrink: 0;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.eg-tag-name {
|
|
124
|
+
font-size: 13px;
|
|
125
|
+
line-height: 16px;
|
|
126
|
+
font-weight: 500;
|
|
127
|
+
overflow: hidden;
|
|
128
|
+
text-overflow: ellipsis;
|
|
129
|
+
white-space: nowrap;
|
|
130
|
+
min-width: 0;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.eg-tag-component { color: black; }
|
|
134
|
+
.eg-tag-suffix { color: rgba(0,0,0,0.5); }
|
|
135
|
+
|
|
136
|
+
.eg-tag-open-icon {
|
|
137
|
+
color: black;
|
|
138
|
+
transition: all 100ms;
|
|
139
|
+
flex-shrink: 0;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.eg-tag-open-icon.visible { opacity: 1; transform: scale(1); }
|
|
143
|
+
.eg-tag-open-icon.hidden { opacity: 0; transform: scale(0.75); margin-left: -2px; width: 0; }
|
|
144
|
+
|
|
145
|
+
.eg-bottom-section {
|
|
146
|
+
font-synthesis: none;
|
|
147
|
+
flex-shrink: 0;
|
|
148
|
+
display: flex;
|
|
149
|
+
flex-direction: column;
|
|
150
|
+
align-items: flex-start;
|
|
151
|
+
padding: 6px 8px;
|
|
152
|
+
width: auto;
|
|
153
|
+
height: fit-content;
|
|
154
|
+
align-self: stretch;
|
|
155
|
+
border-top: 0.5px solid #D9D9D9;
|
|
156
|
+
-webkit-font-smoothing: antialiased;
|
|
157
|
+
border-radius: 0 0 6px 6px;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.eg-arrow {
|
|
161
|
+
position: absolute;
|
|
162
|
+
width: 0;
|
|
163
|
+
height: 0;
|
|
164
|
+
z-index: 10;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/* Interactive utilities */
|
|
168
|
+
.eg-interactive-scale {
|
|
169
|
+
transition: transform 150ms cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
170
|
+
}
|
|
171
|
+
.eg-interactive-scale:hover { transform: scale(1.05); }
|
|
172
|
+
.eg-interactive-scale:active { transform: scale(0.97); }
|
|
173
|
+
|
|
174
|
+
.eg-press-scale {
|
|
175
|
+
transition: transform 100ms ease-out;
|
|
176
|
+
}
|
|
177
|
+
.eg-press-scale:active { transform: scale(0.97); }
|
|
178
|
+
|
|
179
|
+
/* Prompt input */
|
|
180
|
+
.eg-input {
|
|
181
|
+
color: black;
|
|
182
|
+
font-size: 13px;
|
|
183
|
+
line-height: 16px;
|
|
184
|
+
font-weight: 500;
|
|
185
|
+
background: transparent;
|
|
186
|
+
border: none;
|
|
187
|
+
outline: none;
|
|
188
|
+
resize: none;
|
|
189
|
+
flex: 1;
|
|
190
|
+
padding: 0;
|
|
191
|
+
margin: 0;
|
|
192
|
+
overflow-wrap: break-word;
|
|
193
|
+
overflow-y: auto;
|
|
194
|
+
field-sizing: content;
|
|
195
|
+
min-height: 16px;
|
|
196
|
+
scrollbar-width: none;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.eg-input::placeholder { color: rgba(0,0,0,0.4); }
|
|
200
|
+
|
|
201
|
+
/* Submit/abort buttons */
|
|
202
|
+
.eg-circle-btn {
|
|
203
|
+
flex-shrink: 0;
|
|
204
|
+
display: flex;
|
|
205
|
+
align-items: center;
|
|
206
|
+
justify-content: center;
|
|
207
|
+
width: 16px;
|
|
208
|
+
height: 16px;
|
|
209
|
+
border-radius: 50%;
|
|
210
|
+
background: black;
|
|
211
|
+
cursor: pointer;
|
|
212
|
+
margin-left: 4px;
|
|
213
|
+
border: none;
|
|
214
|
+
padding: 0;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/* Status text with shimmer */
|
|
218
|
+
.eg-status {
|
|
219
|
+
font-size: 13px;
|
|
220
|
+
line-height: 16px;
|
|
221
|
+
font-weight: 500;
|
|
222
|
+
height: fit-content;
|
|
223
|
+
font-variant-numeric: tabular-nums;
|
|
224
|
+
overflow: hidden;
|
|
225
|
+
text-overflow: ellipsis;
|
|
226
|
+
white-space: nowrap;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/* Context menu */
|
|
230
|
+
.eg-menu-item {
|
|
231
|
+
position: relative;
|
|
232
|
+
z-index: 1;
|
|
233
|
+
display: flex;
|
|
234
|
+
align-items: center;
|
|
235
|
+
justify-content: space-between;
|
|
236
|
+
width: 100%;
|
|
237
|
+
padding: 4px 8px;
|
|
238
|
+
cursor: pointer;
|
|
239
|
+
text-align: left;
|
|
240
|
+
border: none;
|
|
241
|
+
background: transparent;
|
|
242
|
+
font-size: 13px;
|
|
243
|
+
line-height: 16px;
|
|
244
|
+
font-weight: 500;
|
|
245
|
+
color: black;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.eg-menu-item:disabled { opacity: 0.4; cursor: default; }
|
|
249
|
+
.eg-menu-item-shortcut { font-size: 11px; color: rgba(0,0,0,0.5); margin-left: 16px; }
|
|
250
|
+
|
|
251
|
+
/* Toolbar pill */
|
|
252
|
+
.eg-toolbar-pill {
|
|
253
|
+
position: fixed;
|
|
254
|
+
pointer-events: auto;
|
|
255
|
+
cursor: grab;
|
|
256
|
+
display: flex;
|
|
257
|
+
align-items: center;
|
|
258
|
+
justify-content: center;
|
|
259
|
+
gap: 4px;
|
|
260
|
+
width: 40px;
|
|
261
|
+
height: 32px;
|
|
262
|
+
background: white;
|
|
263
|
+
border-radius: 10px;
|
|
264
|
+
box-shadow: 0 1px 4px rgba(0,0,0,0.15), 0 0 0 0.5px rgba(0,0,0,0.06);
|
|
265
|
+
transition: background 150ms ease, box-shadow 150ms ease, transform 150ms ease;
|
|
266
|
+
user-select: none;
|
|
267
|
+
-webkit-user-select: none;
|
|
268
|
+
touch-action: none;
|
|
269
|
+
color: rgba(0,0,0,0.5);
|
|
270
|
+
}
|
|
271
|
+
.eg-toolbar-pill:hover {
|
|
272
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.18), 0 0 0 0.5px rgba(0,0,0,0.08);
|
|
273
|
+
color: rgba(0,0,0,0.8);
|
|
274
|
+
transform: scale(1.05);
|
|
275
|
+
}
|
|
276
|
+
.eg-toolbar-pill:active { transform: scale(0.97); }
|
|
277
|
+
.eg-toolbar-pill.active {
|
|
278
|
+
background: #6366f1;
|
|
279
|
+
color: white;
|
|
280
|
+
box-shadow: 0 2px 8px rgba(99,102,241,0.4), 0 0 0 0.5px rgba(99,102,241,0.3);
|
|
281
|
+
}
|
|
282
|
+
.eg-toolbar-pill.active:hover {
|
|
283
|
+
background: #5558e6;
|
|
284
|
+
box-shadow: 0 2px 12px rgba(99,102,241,0.5), 0 0 0 0.5px rgba(99,102,241,0.4);
|
|
285
|
+
}
|
|
286
|
+
.eg-toolbar-dot {
|
|
287
|
+
width: 6px;
|
|
288
|
+
height: 6px;
|
|
289
|
+
border-radius: 50%;
|
|
290
|
+
background: white;
|
|
291
|
+
opacity: 0.8;
|
|
292
|
+
flex-shrink: 0;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
.eg-menu-highlight {
|
|
296
|
+
pointer-events: none;
|
|
297
|
+
position: absolute;
|
|
298
|
+
background: rgba(0,0,0,0.05);
|
|
299
|
+
opacity: 0;
|
|
300
|
+
transition: top 75ms ease-out, left 75ms ease-out, width 75ms ease-out, height 75ms ease-out, opacity 75ms ease-out;
|
|
301
|
+
}
|
|
302
|
+
`;var L=!1,_=null,j=null,h=null,M=null,be="",N=null,X=null,oe=null,D=null,Rt=e=>{let t=e.getRootNode();return!!(t instanceof ShadowRoot&&t.host.hasAttribute("data-element-grab")||e.hasAttribute?.("data-element-grab"))},tt=e=>{if(Rt(e)||e===document.body||e===document.documentElement)return!1;let t=e.getBoundingClientRect();if(t.width/window.innerWidth>.9&&t.height/window.innerHeight>.9){let n=getComputedStyle(e);if(n.pointerEvents==="none"||n.backgroundColor==="transparent"||n.backgroundColor==="rgba(0, 0, 0, 0)")return!1}return!0},Ot=(e,t)=>{let n=document.elementFromPoint(e,t);if(n&&tt(n))return n;let o=document.elementsFromPoint(e,t);for(let i of o)if(tt(i))return i;return null},ie=null,nt=0,ot=0,it=2,Ee=()=>{if(M)return;be=window.__WEBDEV_ORIGIN__||window.location.origin,M=ve(et),_=new ee(M),N=qe(M,{onsubmit:Tt,onopen:st,ondismiss:P});let e=()=>!!document.querySelector("vite-devtools-dock-embedded, vite-devtools-dock-standalone");if(!e()){X=Je(M,{ontoggle:()=>{L?P():xe()}});let t=new MutationObserver(()=>{X&&e()&&(X.destroy(),X=null,t.disconnect())});t.observe(document.documentElement,{childList:!0,subtree:!0})}oe=Qe(M),D=document.createElement("div"),Object.assign(D.style,{position:"fixed",top:"0",right:"0",bottom:"0",left:"0",pointerEvents:"none",zIndex:String(q),opacity:"0",transition:`opacity ${le}ms ease-out`,willChange:"opacity",contain:"strict",transform:"translateZ(0)",boxShadow:`inset 0 0 ${Pe}px ${De}`}),M.appendChild(D),document.addEventListener("contextmenu",t=>{if(!h||!oe)return;t.preventDefault();let n=h.getBoundingClientRect();oe.show({position:{x:t.clientX,y:t.clientY},bounds:{x:n.x,y:n.y,width:n.width,height:n.height},tagName:h.tagName.toLowerCase(),componentName:ge(h)||void 0,actions:[{label:"Copy",shortcut:"\u2318C",action:()=>{let o=window.__LAST_GRABBED__?.card;o&&navigator.clipboard.writeText(o).catch(()=>{})}},{label:"Copy HTML",action:()=>{h&&navigator.clipboard.writeText(h.outerHTML).catch(()=>{})}},{label:"Copy Styles",action:()=>{if(!h)return;let o=getComputedStyle(h),i=Array.from(o).filter(r=>o.getPropertyValue(r)!=="").map(r=>`${r}: ${o.getPropertyValue(r)};`).join(`
|
|
303
|
+
`);navigator.clipboard.writeText(i).catch(()=>{})}},{label:"Open in editor",shortcut:"\u2318O",action:st}],ondismiss:()=>{}})},!0),console.log("[element-grab] Ready \u2014 hold Cmd+Shift+C to activate")},_e=e=>{let t=e.getBoundingClientRect(),n=getComputedStyle(e);return{x:t.x,y:t.y,width:t.width,height:t.height,borderRadius:n.borderRadius||"0"}},rt=0,at=e=>{if(!L||h)return;let t=Date.now();if(t-rt<Ce||(rt=t,ie&&Math.abs(e.clientX-nt)<it&&Math.abs(e.clientY-ot)<it))return;nt=e.clientX,ot=e.clientY;let n=Ot(e.clientX,e.clientY);if(!n)return;ie=n,j=n;let o=_e(n);_&&(_.selectionVisible=!0,_.selectionFading=!1,_.setSelection(o)),N?.update({visible:!0,tagName:n.tagName.toLowerCase(),componentName:ge(n)||void 0,bounds:{x:o.x,y:o.y,width:o.width,height:o.height},mouseX:e.clientX,status:"hovering"})},lt=async e=>{if(!L||!j)return;e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation();let t=j;h=t,D&&(D.style.opacity="1");let n=_e(t);N?.update({status:"frozen",bounds:{x:n.x,y:n.y,width:n.width,height:n.height}});let o=await te(t),i=ne(o);window.__LAST_GRABBED__={element:t,selector:o.selector,component:o.component,source:o.source,card:i}},Tt=async e=>{if(!h)return;let t=e?.trim()||N?.getPromptValue()||"";N?.update({status:"copying"});let n=await te(h),o=ne(n);t&&(o+=`
|
|
304
|
+
prompt: ${t}`),window.__LAST_GRABBED__={element:h,selector:n.selector,component:n.component,source:n.source,card:o};try{await fetch(`${be}/__element-grab/selection`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({payload:{card:o,timestamp:Date.now(),url:window.location.href},browserId:sessionStorage.getItem("__webdev_browser_id__")})})}catch{}try{await navigator.clipboard.writeText(o)}catch{}_&&_.addGrabbed(`grab-${Date.now()}`,_e(h)),N?.update({status:"copied"}),console.log(`[element-grab] Grabbed:
|
|
305
|
+
`+o),setTimeout(()=>{N?.update({status:"fading"}),setTimeout(()=>P(),le)},H)},st=()=>{let e=window.__LAST_GRABBED__;e?.source?.file&&Ze(e.source.file,e.source.line)},xe=()=>{L||(Ee(),L=!0,h=null,ie=null,document.addEventListener("mousemove",at,!0),document.addEventListener("click",lt,!0),document.body.style.cursor="crosshair",_&&(_.selectionVisible=!0,_.selectionFading=!1),X?.setActive(!0))},P=()=>{L=!1,j=null,h=null,ie=null,document.removeEventListener("mousemove",at,!0),document.removeEventListener("click",lt,!0),document.body.style.cursor="",_&&(_.selectionVisible=!1,_.setSelection(null)),N?.hide(),oe?.hide(),X?.setActive(!1),D&&(D.style.opacity="0")},ye=!1,Nt=e=>{if(e.key==="Meta"||e.key==="Control"){ye=!0;return}ye&&e.key.toLowerCase()===Ae&&(!Le||e.shiftKey)&&(e.preventDefault(),L||xe()),e.key==="Escape"&&L&&(e.preventDefault(),P())},St=e=>{(e.key==="Meta"||e.key==="Control")&&(ye=!1,L&&!h&&P())};document.addEventListener("keydown",Nt,!0);document.addEventListener("keyup",St,!0);Ee();window.__elementGrab={activate:xe,deactivate:P,isActive:()=>L,async grabBySelector(e){Ee();let t=document.querySelector(e);if(!t)return null;j=t,h=t;let n=await te(t),o=ne(n);window.__LAST_GRABBED__={element:t,selector:n.selector,component:n.component,source:n.source,card:o};try{await fetch(`${be}/__element-grab/selection`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({payload:{card:o,timestamp:Date.now(),url:window.location.href},browserId:sessionStorage.getItem("__webdev_browser_id__")})})}catch{}return P(),o}};})();
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
3
|
+
interface ElementSelection {
|
|
4
|
+
card: string;
|
|
5
|
+
timestamp: number;
|
|
6
|
+
url: string;
|
|
7
|
+
browserId?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function pushSelection(sel: ElementSelection): void;
|
|
10
|
+
export declare function getLatestSelection(): ElementSelection | null;
|
|
11
|
+
export declare function getAllSelections(): ElementSelection[];
|
|
12
|
+
export declare function registerElementGrabTool(mcp: McpServer): void;
|
|
13
|
+
export declare function handleElementGrabRequest(req: IncomingMessage, res: ServerResponse, url: string): boolean;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=element-grab.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"element-grab.d.ts","sourceRoot":"","sources":["../src/element-grab.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAIhE,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,GAAG,EAAE,MAAM,CAAA;IACX,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAaD,wBAAgB,aAAa,CAAC,GAAG,EAAE,gBAAgB,QAIlD;AAED,wBAAgB,kBAAkB,IAAI,gBAAgB,GAAG,IAAI,CAG5D;AAED,wBAAgB,gBAAgB,IAAI,gBAAgB,EAAE,CAGrD;AAGD,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,SAAS,QAiCrD;AAGD,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CA+CxG"}
|