@metricinsights/pp-dev 1.5.0-beta.3 → 1.5.0-beta.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +200 -145
- package/dist/cjs/auth.provider-fI0tFsf5.js +2 -0
- package/dist/cjs/auth.provider-fI0tFsf5.js.map +1 -0
- package/dist/cjs/cli.js +1 -1
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/index-Ty1d2YCg.js +2 -0
- package/dist/cjs/index-Ty1d2YCg.js.map +1 -0
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/migrate-Gi9k9cLw.js +2 -0
- package/dist/cjs/migrate-Gi9k9cLw.js.map +1 -0
- package/dist/cjs/package.json +2 -135
- package/dist/cjs/plugin.js +1 -1
- package/dist/cjs/plugin.js.map +1 -1
- package/dist/cjs/request-capture.middleware-6DhFLyIz.js +2 -0
- package/dist/cjs/request-capture.middleware-6DhFLyIz.js.map +1 -0
- package/dist/cjs/version-manifest-CVBuIKBS.js +2 -0
- package/dist/cjs/version-manifest-CVBuIKBS.js.map +1 -0
- package/dist/cjs/version-plugin-DBdqn2Rn.js +2 -0
- package/dist/cjs/version-plugin-DBdqn2Rn.js.map +1 -0
- package/dist/client/client.js +278 -126
- package/dist/client/client.js.map +1 -1
- package/dist/client/request-inspector.css +3 -0
- package/dist/client/request-inspector.css.map +1 -0
- package/dist/client/request-inspector.html +87 -0
- package/dist/client/request-inspector.js +549 -0
- package/dist/client/request-inspector.js.map +1 -0
- package/dist/client/variables-editor.css +3 -0
- package/dist/client/variables-editor.css.map +1 -0
- package/dist/client/variables-editor.html +44 -0
- package/dist/client/variables-editor.js +3474 -0
- package/dist/client/variables-editor.js.map +1 -0
- package/dist/esm/auth.provider-DDUsu1H1.js +2 -0
- package/dist/esm/auth.provider-DDUsu1H1.js.map +1 -0
- package/dist/esm/cli.js +1 -1
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/index-tD-QICGk.js +2 -0
- package/dist/esm/index-tD-QICGk.js.map +1 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/migrate-CCBRuVfj.js +2 -0
- package/dist/esm/{migrate-B2gJ62fm.js.map → migrate-CCBRuVfj.js.map} +1 -1
- package/dist/esm/package.json +2 -135
- package/dist/esm/plugin.js +1 -1
- package/dist/esm/plugin.js.map +1 -1
- package/dist/esm/request-capture.middleware-VElwjU1W.js +2 -0
- package/dist/esm/request-capture.middleware-VElwjU1W.js.map +1 -0
- package/dist/esm/version-manifest-CyzmnFOe.js +2 -0
- package/dist/esm/version-manifest-CyzmnFOe.js.map +1 -0
- package/dist/esm/version-plugin-6rxIgQ-I.js +2 -0
- package/dist/esm/version-plugin-6rxIgQ-I.js.map +1 -0
- package/dist/types/helpers.d.ts +29 -0
- package/dist/types/index.d.ts +15 -156
- package/dist/types/plugin.d.ts +8 -0
- package/dist/types/pp-dev-config-D889A-PO.d.ts +189 -0
- package/docs/features.md +2 -1
- package/package.json +26 -35
- package/dist/CHANGELOG.md +0 -442
- package/dist/README.md +0 -724
- package/dist/cjs/index-CCUrjlJE.js +0 -2
- package/dist/cjs/index-CCUrjlJE.js.map +0 -1
- package/dist/cjs/migrate-BYno__sx.js +0 -2
- package/dist/cjs/migrate-BYno__sx.js.map +0 -1
- package/dist/cjs/plugin-D_RXI7ru.js +0 -2
- package/dist/cjs/plugin-D_RXI7ru.js.map +0 -1
- package/dist/cjs/version-plugin-Bf4jLh17.js +0 -2
- package/dist/cjs/version-plugin-Bf4jLh17.js.map +0 -1
- package/dist/esm/index-BazQY12s.js +0 -2
- package/dist/esm/index-BazQY12s.js.map +0 -1
- package/dist/esm/migrate-B2gJ62fm.js +0 -2
- package/dist/esm/plugin-NIWxLreC.js +0 -2
- package/dist/esm/plugin-NIWxLreC.js.map +0 -1
- package/dist/esm/version-plugin-DwuZCHob.js +0 -2
- package/dist/esm/version-plugin-DwuZCHob.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-inspector.js","sources":["../../../src/client/storage.ts","../../../src/client/theme.ts","../../../src/client/request-inspector/format.ts","../../../src/client/request-inspector/render.ts","../../../src/client/request-inspector/inspector.ts","../../../src/client/request-inspector/main.ts"],"sourcesContent":["// localStorage helpers guarded against environments where storage is unavailable\n// (e.g. sandboxed iframes). Keys follow the original `pp-dev-info-closed` naming.\n\nexport const STORAGE_KEYS = {\n closed: 'pp-dev-info-closed',\n position: 'pp-dev-info-position',\n autoHide: 'pp-dev-info-auto-hide',\n hidden: 'pp-dev-info-hidden',\n /** Shared with the standalone Inspector/Variables Editor pages — same key, same values. */\n theme: 'pp-dev-info-theme',\n} as const;\n\nexport function checkLocalStorage() {\n try {\n localStorage.setItem('test', 'test');\n localStorage.removeItem('test');\n\n return true;\n } catch (e) {\n return false;\n }\n}\n\nexport function setStorageItem(key: string, value: string) {\n if (checkLocalStorage()) {\n localStorage.setItem(key, value);\n }\n}\n\nexport function getStorageItem(key: string) {\n if (checkLocalStorage()) {\n return localStorage.getItem(key);\n }\n\n return null;\n}\n\nexport function removeStorageItem(key: string) {\n if (checkLocalStorage()) {\n localStorage.removeItem(key);\n }\n}\n","// Theme override (Auto/Dark/Light), shared across the dev panel and the standalone\n// Inspector/Variables Editor pages via the same localStorage key (see STORAGE_KEYS.theme) and\n// the same `data-pp-dev-theme` attribute convention (prefixed to avoid colliding with a host\n// Portal Page's own theme attribute, since the panel is injected into pages pp-dev doesn't own).\nimport { STORAGE_KEYS, getStorageItem, setStorageItem } from './storage.js';\n\nexport type ThemeChoice = 'auto' | 'dark' | 'light';\n\nconst THEME_ATTR = 'data-pp-dev-theme';\n\nexport function getStoredTheme(): ThemeChoice {\n const value = getStorageItem(STORAGE_KEYS.theme);\n\n return value === 'dark' || value === 'light' ? value : 'auto';\n}\n\nexport function applyTheme(theme: ThemeChoice): void {\n if (theme === 'dark' || theme === 'light') {\n document.documentElement.setAttribute(THEME_ATTR, theme);\n } else {\n document.documentElement.removeAttribute(THEME_ATTR);\n }\n}\n\nexport function setTheme(theme: ThemeChoice): void {\n setStorageItem(STORAGE_KEYS.theme, theme);\n applyTheme(theme);\n}\n\n/** Call once on page load to apply whatever was last chosen (defaults to 'auto', a no-op). */\nexport function initTheme(): void {\n applyTheme(getStoredTheme());\n}\n","// Formatting helpers of the Request Inspector page: pure, so the tests import them directly.\n\n/** Escapes text for HTML content and double-quoted attribute values. */\nexport function esc(value: unknown): string {\n return String(value).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n}\n\nexport function formatBytes(bytes: number | undefined): string {\n const b = bytes || 0;\n\n if (b < 1024) {\n return b + ' B';\n }\n\n if (b < 1024 * 1024) {\n return (b / 1024).toFixed(1) + ' KB';\n }\n\n if (b < 1024 * 1024 * 1024) {\n return (b / (1024 * 1024)).toFixed(1) + ' MB';\n }\n\n return (b / (1024 * 1024 * 1024)).toFixed(2) + ' GB';\n}\n\nexport function formatDur(ms: number): string {\n if (ms < 1000) {\n return ms + 'ms';\n }\n\n return (ms / 1000).toFixed(2) + 's';\n}\n\nconst METHOD_CLASSES: Record<string, string> = {\n GET: 'm-GET',\n POST: 'm-POST',\n PUT: 'm-PUT',\n PATCH: 'm-PATCH',\n DELETE: 'm-DELETE',\n HEAD: 'm-HEAD',\n OPTIONS: 'm-OPTIONS',\n};\n\nexport function methodClass(method: string): string {\n return METHOD_CLASSES[method] || 'm-other';\n}\n\nexport function statusClass(status: number | null | undefined): string {\n if (!status) {\n return 's-pending';\n }\n\n return ['', '', 's-2xx', 's-3xx', 's-4xx', 's-5xx'][Math.floor(status / 100)] || '';\n}\n\nexport function sourceInfo(source: string | undefined): { cls: string; title: string } {\n if (source === 'proxy') {\n return { cls: 'src-proxy', title: 'Backend (live)' };\n }\n\n if (source === 'proxy-cache') {\n return { cls: 'src-proxy-cache', title: 'Backend (cached)' };\n }\n\n return { cls: 'src-local', title: 'Local (dev server)' };\n}\n\nexport function sourceLetter(source: string | undefined): string {\n if (source === 'proxy') {\n return 'P';\n }\n\n if (source === 'proxy-cache') {\n return 'C';\n }\n\n return 'L';\n}\n\nconst FILE_EXTENSIONS: Record<string, string> = {\n 'application/json': 'json',\n 'text/html': 'html',\n 'text/css': 'css',\n 'text/javascript': 'js',\n 'application/javascript': 'js',\n 'text/plain': 'txt',\n 'text/xml': 'xml',\n 'application/xml': 'xml',\n 'image/png': 'png',\n 'image/jpeg': 'jpg',\n 'image/gif': 'gif',\n 'image/svg+xml': 'svg',\n 'image/webp': 'webp',\n 'application/pdf': 'pdf',\n 'application/zip': 'zip',\n 'application/x-www-form-urlencoded': 'txt',\n 'application/octet-stream': 'bin',\n};\n\n/** The file extension a saved body of `contentType` gets. */\nexport function fileExt(contentType: string | undefined): string {\n return FILE_EXTENSIONS[(contentType || '').split(';')[0].trim().toLowerCase()] || 'bin';\n}\n\nexport function decodeBase64(b64: string): Uint8Array {\n return Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));\n}\n\nexport function decodeTextBody(b64: string): string {\n return new TextDecoder('utf-8').decode(decodeBase64(b64));\n}\n\n/** Pretty-prints JSON with highlighting spans; invalid JSON comes back as escaped plain text. */\nexport function syntaxHighlightJson(text: string): string {\n let str: string;\n\n try {\n str = JSON.stringify(JSON.parse(text), null, 2);\n } catch {\n // Invalid JSON can contain arbitrary HTML. It cannot be token-highlighted safely because\n // unmatched text is preserved by the replacement below, so render it as escaped plain text.\n return esc(text);\n }\n\n return str.replace(\n /(\"(\\\\u[a-zA-Z0-9]{4}|\\\\[^u]|[^\\\\\"])*\"\\s*:?|\\b(true|false|null)\\b|-?\\d+(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)/g,\n (m) => {\n if (/^\"/.test(m)) {\n if (/:$/.test(m)) {\n return '<span class=\"body-json-key\">' + esc(m) + '</span>';\n }\n\n return '<span class=\"body-json-str\">' + esc(m) + '</span>';\n }\n\n if (/true|false/.test(m)) {\n return '<span class=\"body-json-bool\">' + m + '</span>';\n }\n\n if (/null/.test(m)) {\n return '<span class=\"body-json-null\">' + m + '</span>';\n }\n\n return '<span class=\"body-json-num\">' + m + '</span>';\n },\n );\n}\n","// HTML of the Request Inspector's list and detail. Buttons say what they do in `data-action`\n// (and which side in `data-type`); main.ts handles the clicks in one place.\nimport {\n decodeTextBody,\n esc,\n formatBytes,\n formatDur,\n methodClass,\n sourceInfo,\n sourceLetter,\n statusClass,\n syntaxHighlightJson,\n} from './format.js';\n\n/** A request in the list (`GET /@api/requests`). */\nexport interface RequestSummary {\n id: string;\n method: string;\n url: string;\n statusCode?: number | null;\n duration?: number | null;\n responseSize?: number;\n source?: string;\n user?: string;\n}\n\ntype Headers = Record<string, string | string[] | number | null | undefined>;\n\n/** A request with its headers and bodies (`GET /@api/requests/:id`); bodies in base64. */\nexport interface RequestEntry extends RequestSummary {\n timestamp: number;\n requestHeaders: Headers;\n requestBody: string | null;\n requestBodySize: number;\n requestBodyTruncated: boolean;\n requestContentType: string;\n responseHeaders: Headers;\n responseBody: string | null;\n responseBodySize: number;\n responseBodyTruncated: boolean;\n responseContentType: string;\n}\n\nexport type Side = 'request' | 'response';\n\nexport function renderListHtml(requests: RequestSummary[], selectedId: string | null): string {\n if (!requests.length) {\n return '<div class=\"empty-state\"><div class=\"empty-icon\">🔍</div><div>No matching requests</div></div>';\n }\n\n return requests\n .map((r) => {\n const sel = r.id === selectedId ? ' selected' : '';\n const dur = r.duration != null ? formatDur(r.duration) : '…';\n const source = r.source || 'local';\n\n return `<div class=\"req-item src-${source}${sel}\" data-id=\"${esc(r.id)}\">\n <span class=\"method-badge ${methodClass(r.method)}\">${esc(r.method)}</span>\n ${r.user ? `<span class=\"user-chip\" title=\"From the tab of user ${esc(r.user)}\">${esc(r.user)}</span>` : ''}\n <span class=\"req-url\" title=\"${esc(r.url)}\">${esc(r.url)}</span>\n <span class=\"req-meta\">\n <span class=\"req-status-row\">\n <span class=\"source-letter src-letter-${source}\">${sourceLetter(r.source)}</span>\n <span class=\"status-badge ${statusClass(r.statusCode)}\">${r.statusCode || '…'}</span>\n </span>\n <span>${dur}</span>\n <span>${formatBytes(r.responseSize || 0)}</span>\n </span>\n </div>`;\n })\n .join('');\n}\n\nexport function renderDetailInfoHtml(e: RequestEntry): string {\n const src = sourceInfo(e.source);\n\n return `\n <div class=\"info-item\"><div class=\"info-label\">Method</div><div class=\"info-value\"><span class=\"method-badge ${methodClass(e.method)}\">${esc(e.method)}</span></div></div>\n <div class=\"info-item\"><div class=\"info-label\">Status</div><div class=\"info-value\"><span class=\"status-badge ${statusClass(e.statusCode)}\">${e.statusCode || '—'}</span></div></div>\n <div class=\"info-item\"><div class=\"info-label\">Source</div><div class=\"info-value\"><span class=\"source-chip ${src.cls}\">${src.title}</span></div></div>\n <div class=\"info-item\"><div class=\"info-label\">User</div><div class=\"info-value\">${e.user ? `<span class=\"user-chip\">${esc(e.user)}</span>` : 'Original'}</div></div>\n <div class=\"info-item\"><div class=\"info-label\">Duration</div><div class=\"info-value\">${e.duration != null ? formatDur(e.duration) : '—'}</div></div>\n <div class=\"info-item\"><div class=\"info-label\">Request</div><div class=\"info-value\">${formatBytes(e.requestBodySize || 0)}</div></div>\n <div class=\"info-item\"><div class=\"info-label\">Response</div><div class=\"info-value\">${formatBytes(e.responseBodySize || 0)}</div></div>\n <div class=\"info-item\"><div class=\"info-label\">Time</div><div class=\"info-value\" style=\"font-size:11px\">${new Date(e.timestamp).toLocaleTimeString()}</div></div>\n `;\n}\n\nexport function renderDetailUrlHtml(e: RequestEntry): string {\n return `<span class=\"info-url-text\" title=\"${esc(e.url)}\">${esc(e.url)}</span><button class=\"section-btn\" data-action=\"copy-url\">Copy link</button>`;\n}\n\nfunction sectionHtml(title: string, badge: string, actions: string, body: string): string {\n return `<div class=\"detail-section\">\n <div class=\"detail-section-hdr\" data-action=\"toggle-section\">\n <span class=\"toggle\">▾</span>\n <span class=\"section-title\">${title}</span>\n ${badge}\n ${actions ? `<div class=\"section-actions\">${actions}</div>` : ''}\n </div>\n <div class=\"detail-section-body\">${body}</div>\n </div>`;\n}\n\nexport function renderHeadersSectionHtml(title: string, headers: Headers | undefined, type: Side): string {\n const entries = Object.entries(headers || {}).filter(([, v]) => v != null);\n const rows = entries\n .map(([k, v]) => `<tr><td>${esc(k)}</td><td>${esc(Array.isArray(v) ? v.join(', ') : String(v))}</td></tr>`)\n .join('');\n const copy = entries.length\n ? `<button class=\"section-btn\" data-action=\"copy-headers\" data-type=\"${type}\">Copy</button>`\n : '';\n\n return sectionHtml(\n title,\n `<span class=\"section-badge\">${entries.length}</span>`,\n copy,\n `<table class=\"kv-table\">${rows}</table>`,\n );\n}\n\n/**\n * A body shown and copied as text: JSON, script, XML (an SVG among them) and text/* types. XML\n * is `application/xml` or a `+xml` suffix: the Office types (`application/vnd.openxmlformats-…`)\n * name XML too, and are ZIP archives.\n */\nfunction isTextType(ct: string): boolean {\n return (\n ct.includes('json') ||\n ct.startsWith('text/') ||\n ct.includes('/javascript') ||\n ct === 'application/xml' ||\n ct.endsWith('+xml') ||\n ct === 'application/x-www-form-urlencoded'\n );\n}\n\nfunction bodyContentHtml(b64: string | null, ct: string, truncated: boolean, size: number): string {\n if (!b64 && !truncated) {\n return '<div class=\"body-binary\">No body</div>';\n }\n\n if (truncated) {\n return `<div class=\"body-binary\">Body too large to capture (${formatBytes(size)})</div>`;\n }\n\n if (ct.includes('json') || ct.includes('/javascript') || ct === 'text/plain') {\n const text = decodeTextBody(b64!);\n\n return ct.includes('json')\n ? `<pre class=\"body-content json\">${syntaxHighlightJson(text)}</pre>`\n : `<pre class=\"body-content\">${esc(text)}</pre>`;\n }\n\n if (ct.startsWith('image/') && size < 1024 * 1024) {\n return `<img class=\"body-image\" src=\"data:${esc(ct)};base64,${b64}\" alt=\"image\"/>`;\n }\n\n if (ct === 'application/x-www-form-urlencoded') {\n const params = new URLSearchParams(decodeTextBody(b64!));\n const rows = [...params.entries()].map(([k, v]) => `<tr><td>${esc(k)}</td><td>${esc(v)}</td></tr>`).join('');\n\n return `<table class=\"kv-table\">${rows}</table>`;\n }\n\n // XML was offered for copying as text, and shown as \"Binary data\".\n if (isTextType(ct)) {\n return `<pre class=\"body-content\">${esc(decodeTextBody(b64!))}</pre>`;\n }\n\n return `<div class=\"body-binary\">Binary data — ${formatBytes(size)} (${esc(ct || 'unknown type')})</div>`;\n}\n\nexport function renderBodySectionHtml(\n title: string,\n b64: string | null,\n contentType: string | undefined,\n truncated: boolean,\n size: number,\n type: Side,\n captureLimit: number,\n): string {\n const ct = (contentType || '').toLowerCase().split(';')[0].trim();\n const copy =\n b64 && isTextType(ct)\n ? `<button class=\"section-btn\" data-action=\"copy-body\" data-type=\"${type}\">Copy</button>`\n : '';\n const save = b64 ? `<button class=\"section-btn\" data-action=\"save-body\" data-type=\"${type}\">Save</button>` : '';\n const note = truncated\n ? `<div class=\"truncated-note\">⚠ Body was larger than the capture limit (${formatBytes(captureLimit)})</div>`\n : '';\n\n return sectionHtml(\n title,\n size ? `<span class=\"section-badge\">${formatBytes(size)}</span>` : '',\n copy + save,\n bodyContentHtml(b64, ct, truncated, size) + note,\n );\n}\n\nexport function renderDetailSectionsHtml(e: RequestEntry, captureLimit: number): string {\n return [\n renderHeadersSectionHtml('Request Headers', e.requestHeaders, 'request'),\n renderBodySectionHtml(\n 'Request Body',\n e.requestBody,\n e.requestContentType,\n e.requestBodyTruncated,\n e.requestBodySize,\n 'request',\n captureLimit,\n ),\n renderHeadersSectionHtml('Response Headers', e.responseHeaders, 'response'),\n renderBodySectionHtml(\n 'Response Body',\n e.responseBody,\n e.responseContentType,\n e.responseBodyTruncated,\n e.responseBodySize,\n 'response',\n captureLimit,\n ),\n ].join('');\n}\n","// The Request Inspector page (`/@pp-dev/inspector`): lists what went through the dev server and\n// shows a request's headers and bodies. main.ts starts it on request-inspector.html.\nimport { getStoredTheme, setTheme, applyTheme, type ThemeChoice } from '../theme.js';\nimport { decodeBase64, decodeTextBody, fileExt, formatBytes } from './format.js';\nimport {\n renderDetailInfoHtml,\n renderDetailSectionsHtml,\n renderDetailUrlHtml,\n renderListHtml,\n type RequestEntry,\n type RequestSummary,\n type Side,\n} from './render.js';\n\n/** Value of the user filter for requests sent as the original user (a saved user's name can't start with \"@\"). */\nconst ORIGINAL_USER = '@original';\nconst DEFAULT_CAPTURE_LIMIT = 10 * 1024 * 1024;\n\ninterface ListResponse {\n requests?: RequestSummary[];\n total: number;\n memoryUsage: number;\n maxMemory: number;\n}\n\nexport interface InspectorOptions {\n /** How often the list is fetched again. */\n pollIntervalMs?: number;\n}\n\n/** Starts the page on the current document; returns a function that stops it (polling and listeners). */\nexport function startInspector({ pollIntervalMs = 2000 }: InspectorOptions = {}): () => void {\n const byId = <T extends HTMLElement>(id: string) => document.getElementById(id) as T;\n\n const captureLimit = Number(document.body.dataset.captureLimit) || DEFAULT_CAPTURE_LIMIT;\n const listEl = byId<HTMLDivElement>('req-list');\n const detailEmpty = byId<HTMLDivElement>('detail-empty');\n const detailPanel = byId<HTMLDivElement>('detail-panel');\n const detailInfo = byId<HTMLDivElement>('detail-info');\n const detailUrl = byId<HTMLDivElement>('detail-url');\n const detailScroll = byId<HTMLDivElement>('detail-scroll');\n const filterBar = byId<HTMLDivElement>('filter-bar');\n const searchInput = byId<HTMLInputElement>('search-input');\n const methodSelect = byId<HTMLSelectElement>('method-select');\n const statusSelect = byId<HTMLSelectElement>('status-select');\n const sourceSelect = byId<HTMLSelectElement>('source-select');\n const userSelect = byId<HTMLSelectElement>('user-select');\n const themeSwitch = byId<HTMLDivElement>('theme-switch');\n\n let allRequests: RequestSummary[] = [];\n let filteredRequests: RequestSummary[] = [];\n let selectedId: string | null = null;\n let currentEntry: RequestEntry | null = null;\n\n // ── Theme (Auto/Dark/Light) ────────────────────────────────────────────────\n // The page's <head> already set the stored theme before first paint; this keeps the buttons in\n // step. Shared with the dev panel and the Variables Editor (see ../theme.ts).\n const showTheme = (theme: ThemeChoice) => {\n applyTheme(theme);\n\n for (const button of Array.from(themeSwitch.children) as HTMLElement[]) {\n const isActive = button.dataset.themeChoice === theme;\n\n button.classList.toggle('active', isActive);\n button.setAttribute('aria-pressed', String(isActive));\n }\n };\n\n // ── List ───────────────────────────────────────────────────────────────────\n const updateStats = (data: Pick<ListResponse, 'total' | 'memoryUsage' | 'maxMemory'>) => {\n const pct = data.maxMemory > 0 ? Math.min(100, (data.memoryUsage / data.maxMemory) * 100) : 0;\n\n byId('req-count').textContent = data.total + ' request' + (data.total !== 1 ? 's' : '');\n byId('mem-fill').style.width = pct + '%';\n byId('mem-text').textContent = formatBytes(data.memoryUsage) + ' / ' + formatBytes(data.maxMemory);\n };\n\n // The user filter only shows up once a request was sent as a saved user.\n const updateUserOptions = () => {\n const names = Array.from(new Set(allRequests.map((r) => r.user).filter((u): u is string => Boolean(u)))).sort();\n const current = userSelect.value;\n\n userSelect.style.display = names.length ? '' : 'none';\n userSelect.replaceChildren(\n new Option('All users', ''),\n new Option('Original', ORIGINAL_USER),\n ...names.map((name) => new Option(name, name)),\n );\n userSelect.value = current === ORIGINAL_USER || names.includes(current) ? current : '';\n };\n\n const renderList = () => {\n const atBottom = listEl.scrollTop + listEl.clientHeight >= listEl.scrollHeight - 16;\n\n listEl.innerHTML = renderListHtml(filteredRequests, selectedId);\n\n if (atBottom && filteredRequests.length) {\n listEl.scrollTop = listEl.scrollHeight;\n }\n };\n\n const applyFilter = () => {\n const search = searchInput.value.toLowerCase();\n const method = methodSelect.value;\n const status = statusSelect.value;\n const source = sourceSelect.value;\n const user = userSelect.value;\n\n filteredRequests = allRequests.filter(\n (r) =>\n !(user && (r.user || ORIGINAL_USER) !== user) &&\n !(method && r.method !== method) &&\n !(status && !String(r.statusCode || '').startsWith(status)) &&\n !(source && r.source !== source) &&\n !(search && !r.url.toLowerCase().includes(search)),\n );\n\n renderList();\n };\n\n const showDetailEmpty = () => {\n detailPanel.style.display = 'none';\n detailEmpty.style.display = 'flex';\n };\n\n const fetchList = async () => {\n try {\n const data = (await (await fetch('/@api/requests')).json()) as ListResponse;\n\n allRequests = data.requests || [];\n updateStats(data);\n updateUserOptions();\n applyFilter();\n\n if (selectedId && !allRequests.find((r) => r.id === selectedId)) {\n selectedId = null;\n showDetailEmpty();\n }\n } catch {\n // The dev server is restarting; the next poll tries again.\n }\n };\n\n // ── Detail ─────────────────────────────────────────────────────────────────\n const selectRequest = async (id: string) => {\n selectedId = id;\n renderList();\n\n detailEmpty.style.display = 'none';\n detailPanel.style.display = 'flex';\n detailPanel.style.flexDirection = 'column';\n detailPanel.style.overflow = 'hidden';\n detailScroll.innerHTML = '<div style=\"padding:20px;color:var(--text3)\">Loading…</div>';\n\n try {\n const response = await fetch('/@api/requests/' + encodeURIComponent(id));\n\n // Another row was clicked meanwhile: this answer, arriving last, was shown under the other\n // row's highlight, and Copy/Save acted on it.\n if (selectedId !== id) {\n return;\n }\n\n if (!response.ok) {\n showDetailEmpty();\n\n return;\n }\n\n const loaded = (await response.json()) as RequestEntry;\n\n if (selectedId !== id) {\n return;\n }\n\n currentEntry = loaded;\n detailInfo.innerHTML = renderDetailInfoHtml(currentEntry);\n detailUrl.innerHTML = renderDetailUrlHtml(currentEntry);\n detailScroll.innerHTML = renderDetailSectionsHtml(currentEntry, captureLimit);\n } catch {\n if (selectedId === id) {\n showDetailEmpty();\n }\n }\n };\n\n const toggleSection = (header: HTMLElement) => {\n const body = header.nextElementSibling;\n const toggle = header.querySelector('.toggle');\n\n if (body && toggle) {\n toggle.textContent = body.classList.toggle('collapsed') ? '▸' : '▾';\n }\n };\n\n const clearAll = async () => {\n await fetch('/@api/requests', { method: 'DELETE' });\n\n allRequests = [];\n filteredRequests = [];\n selectedId = null;\n\n showDetailEmpty();\n renderList();\n updateStats({ total: 0, memoryUsage: 0, maxMemory: 1024 * 1024 * 1024 });\n };\n\n // ── Copy / Save ────────────────────────────────────────────────────────────\n const clipboard = (text: string, button: HTMLElement) => {\n navigator.clipboard\n .writeText(text)\n .then(() => {\n const label = button.textContent;\n\n button.textContent = '✓';\n button.style.color = 'var(--green)';\n setTimeout(() => {\n button.textContent = label;\n button.style.color = '';\n }, 1500);\n })\n .catch(() => {});\n };\n\n const copyHeaders = (type: Side, button: HTMLElement) => {\n const headers = type === 'request' ? currentEntry?.requestHeaders : currentEntry?.responseHeaders;\n\n if (!headers) {\n return;\n }\n\n const text = Object.entries(headers)\n .filter(([, v]) => v != null)\n .map(([k, v]) => k + ': ' + (Array.isArray(v) ? v.join(', ') : String(v)))\n .join('\\n');\n\n clipboard(text, button);\n };\n\n const bodyOf = (type: Side) => (type === 'request' ? currentEntry?.requestBody : currentEntry?.responseBody);\n\n const copyBody = (type: Side, button: HTMLElement) => {\n const b64 = bodyOf(type);\n\n if (!b64) {\n return;\n }\n\n try {\n clipboard(decodeTextBody(b64), button);\n } catch {\n // Not text after all.\n }\n };\n\n const saveBody = (type: Side) => {\n const b64 = bodyOf(type);\n const contentType = type === 'request' ? currentEntry?.requestContentType : currentEntry?.responseContentType;\n\n if (!b64) {\n return;\n }\n\n try {\n const url = URL.createObjectURL(new Blob([decodeBase64(b64) as BlobPart]));\n const link = document.createElement('a');\n\n link.href = url;\n link.download = type + '-body.' + fileExt(contentType);\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n setTimeout(() => URL.revokeObjectURL(url), 1000);\n } catch {\n // Not valid base64.\n }\n };\n\n // ── Events ─────────────────────────────────────────────────────────────────\n // One handler for the whole page: list items carry `data-id`, buttons `data-action` (and\n // `data-type` for request/response), the theme buttons `data-theme-choice`.\n const onClick = (event: MouseEvent) => {\n const target = event.target as HTMLElement;\n const themeButton = target.closest<HTMLElement>('[data-theme-choice]');\n\n if (themeButton) {\n const theme = themeButton.dataset.themeChoice as ThemeChoice;\n\n setTheme(theme);\n showTheme(theme);\n\n return;\n }\n\n const actionEl = target.closest<HTMLElement>('[data-action]');\n const type = actionEl?.dataset.type as Side;\n\n switch (actionEl?.dataset.action) {\n case 'clear':\n void clearAll();\n\n return;\n case 'copy-url':\n clipboard(currentEntry?.url ?? '', actionEl);\n\n return;\n case 'copy-headers':\n copyHeaders(type, actionEl);\n\n return;\n case 'copy-body':\n copyBody(type, actionEl);\n\n return;\n case 'save-body':\n saveBody(type);\n\n return;\n case 'toggle-section':\n toggleSection(actionEl);\n\n return;\n }\n\n const item = target.closest<HTMLElement>('.req-item');\n\n if (item?.dataset.id) {\n void selectRequest(item.dataset.id);\n }\n };\n\n document.addEventListener('click', onClick);\n filterBar.addEventListener('input', applyFilter);\n filterBar.addEventListener('change', applyFilter);\n\n showTheme(getStoredTheme());\n void fetchList();\n\n const poll = setInterval(() => void fetchList(), pollIntervalMs);\n\n return () => {\n clearInterval(poll);\n document.removeEventListener('click', onClick);\n filterBar.removeEventListener('input', applyFilter);\n filterBar.removeEventListener('change', applyFilter);\n };\n}\n","// Entry of the Request Inspector bundle: its styles and page, built next to it in dist/client.\nimport './request-inspector.scss';\nimport './request-inspector.html';\nimport { startInspector } from './inspector.js';\n\nstartInspector();\n"],"names":[],"mappings":"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","x_google_ignoreList":[0,1,2,3,4,5]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}:root,:root[data-pp-dev-theme=light]{--bg: #ffffff;--bg2: #f4f5f7;--bg3: #e9ebef;--bg4: #dbdee3;--border: #d7dae0;--border2: #c2c6cd;--text: #1a1a1e;--text2: #54566b;--text3: #8a8c9c;--accent: #4f46e5;--accent2: #7c3aed;--m-accent: var(--accent);--m-bg2: var(--bg2);--green: #16a34a;--red: #dc2626;--yellow: #a16207;--blue: #2563eb;--btn-primary-fg: #ffffff;--font-mono: 'Cascadia Code', 'Fira Code', 'JetBrains Mono', Consolas, monospace;--font-ui: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif}:root[data-pp-dev-theme=dark]{--bg: #1a1a1e;--bg2: #222228;--bg3: #2a2a32;--bg4: #32323c;--border: #3a3a46;--border2: #4a4a58;--text: #e0e0f0;--text2: #a0a0b8;--text3: #606078;--accent: #6e8efb;--accent2: #a78bfa;--m-accent: var(--accent);--m-bg2: var(--bg2);--green: #4ade80;--red: #f87171;--yellow: #fbbf24;--blue: #60a5fa;--btn-primary-fg: #0d0d10}@media(prefers-color-scheme: dark){:root{--bg: #1a1a1e;--bg2: #222228;--bg3: #2a2a32;--bg4: #32323c;--border: #3a3a46;--border2: #4a4a58;--text: #e0e0f0;--text2: #a0a0b8;--text3: #606078;--accent: #6e8efb;--accent2: #a78bfa;--m-accent: var(--accent);--m-bg2: var(--bg2);--green: #4ade80;--red: #f87171;--yellow: #fbbf24;--blue: #60a5fa;--btn-primary-fg: #0d0d10}}html,body{height:100%;overflow:hidden;background:var(--bg);color:var(--text);font-family:var(--font-ui);font-size:13px;line-height:1.5}.app{display:flex;flex-direction:column;height:100vh}.toolbar{display:flex;align-items:center;gap:8px;padding:8px 12px;background:var(--bg2);border-bottom:1px solid var(--border);flex-shrink:0;flex-wrap:wrap}.toolbar-title{font-weight:600;font-size:14px;margin-right:8px}.tabs{display:flex;gap:4px}.tab{padding:5px 12px;border-radius:4px;border:1px solid rgba(0,0,0,0);background:rgba(0,0,0,0);color:var(--text2);font-size:12px;cursor:pointer}.tab:hover{background:var(--bg3);color:var(--text)}.tab.active{background:var(--bg4);color:var(--text);border-color:var(--border2)}.toolbar-spacer{flex:1}.ve-loading-indicator{display:inline-flex;align-items:center;gap:6px;color:var(--text3);font-size:11px}.ve-loading-dot{width:6px;height:6px;border-radius:50%;background:var(--accent);animation:ve-pulse 1s ease-in-out infinite}.ve-skeleton{padding:16px}.ve-skeleton-row{height:32px;border-radius:4px;background:var(--bg3);margin-bottom:8px;animation:ve-pulse 1.4s ease-in-out infinite}.ve-skeleton-row:nth-child(2){width:92%}.ve-skeleton-row:nth-child(3){width:96%}.ve-skeleton-row:nth-child(4){width:88%}.ve-skeleton-row:nth-child(5){width:94%}@keyframes ve-pulse{0%,100%{opacity:1}50%{opacity:.4}}.theme-switch{display:flex;gap:2px;background:var(--bg3);border:1px solid var(--border);border-radius:4px;padding:2px}.theme-switch button{padding:3px 8px;border:none;border-radius:3px;background:rgba(0,0,0,0);color:var(--text2);font-size:11px;cursor:pointer;font-family:var(--font-ui)}.theme-switch button.active{background:var(--accent);color:var(--btn-primary-fg)}.btn{padding:5px 12px;border-radius:4px;border:1px solid var(--border);background:var(--bg3);color:var(--text);font-size:12px;cursor:pointer;transition:background .1s}.btn:hover{background:var(--bg4);border-color:var(--border2)}.btn-primary{background:var(--accent);border-color:var(--accent);color:var(--btn-primary-fg);font-weight:600}.btn-primary:hover{opacity:.9;background:var(--accent)}.btn-sm{padding:5px 8px;font-size:11px;min-width:30px;min-height:30px}.local-update-btn{position:fixed;right:16px;bottom:16px;z-index:20;box-shadow:0 4px 16px rgba(0,0,0,.25)}.local-update-btn[hidden]{display:none}.content{flex:1;overflow:auto;padding:14px}.banner{margin-bottom:12px;padding:8px 12px;border-radius:4px;font-size:12px}.banner-warning{background:color-mix(in srgb, var(--yellow) 15%, var(--bg));color:var(--yellow);border:1px solid color-mix(in srgb, var(--yellow) 40%, var(--bg))}.banner-error{background:color-mix(in srgb, var(--red) 15%, var(--bg));color:var(--red);border:1px solid color-mix(in srgb, var(--red) 40%, var(--bg))}.banner-success{background:color-mix(in srgb, var(--green) 15%, var(--bg));color:var(--green);border:1px solid color-mix(in srgb, var(--green) 40%, var(--bg))}.banner ul{margin:6px 0 0 18px}table{width:100%;border-collapse:separate;border-spacing:0;font-size:12px}thead{border-radius:6px 6px 0 0;overflow:hidden}thead th{padding:8px 8px 6px}th{text-align:left;padding:6px 8px;color:var(--text2);border-bottom:1px solid var(--border);font-weight:600;font-size:11px;text-transform:uppercase;letter-spacing:.4px;background:var(--bg2)}thead th:first-child{border-radius:6px 0 0 0}thead th:last-child{border-radius:0 6px 0 0}td{padding:12px 8px;vertical-align:top}tr:hover td{background:var(--bg2)}input[type=text],select,textarea{width:100%;background:var(--bg3);border:1px solid var(--border);color:var(--text);padding:4px 6px;border-radius:4px;font-size:12px;font-family:var(--font-mono);outline:none;min-height:30px}input[type=text]:focus,select:focus,textarea:focus{border-color:var(--accent)}input[type=color]{max-width:150px;width:100%;height:30px;padding:0;border:1px solid var(--border);border-radius:4px;background:var(--bg3)}textarea{resize:vertical;min-height:32px}.cell-textarea{min-height:30px;height:30px;resize:none;overflow:hidden;line-height:1.8}.col-name{width:180px}.col-type{width:130px}.col-source{width:110px}.col-actions{width:70px;text-align:right}.col-expand{width:48px;padding-left:0px;padding-right:0 !important}.ve-expand-cell{display:flex;align-items:center;gap:2px}.ve-schema-row-handle{flex-shrink:0;width:18px;height:22px;display:inline-flex;align-items:center;justify-content:center;cursor:grab;color:var(--text3);user-select:none;border:none;background:rgba(0,0,0,0);font-size:20px;line-height:1;padding:0;letter-spacing:-2px}.ve-schema-row-handle:hover{color:var(--text2)}.ve-schema-row-handle:active{cursor:grabbing}tr.schema-row.is-dragging td,tr.details-row.is-dragging td{opacity:.45}tr.schema-row.is-drop-target td,tr.details-row.is-drop-target td{box-shadow:inset 0 2px 0 var(--accent)}.ve-expand-btn{width:30px;height:30px;padding:0;display:inline-flex;align-items:center;justify-content:center;font-size:13px;line-height:1;color:var(--text2)}.ve-expand-btn:hover{color:var(--text)}.raw-toggle{margin-bottom:10px}.raw-editor{width:100%;height:min(60vh,600px);font-family:var(--font-mono);font-size:12px;white-space:pre}.hint{color:var(--text3);font-size:11px}.ve-md p{margin:0 0 4px}.ve-md p:last-child,.ve-md ul:last-child,.ve-md ol:last-child,.ve-md pre:last-child{margin-bottom:0}.ve-md ul,.ve-md ol{margin:0 0 4px;padding-left:18px}.ve-md code{font-family:var(--font-mono, monospace);background:var(--bg4);border-radius:3px;padding:0 3px}.ve-md pre{margin:0 0 4px;padding:6px 8px;background:var(--bg4);border-radius:4px;overflow-x:auto}.ve-md pre code{background:none;padding:0}.ve-md strong{color:var(--text2)}.details-row td{background:var(--bg2);padding:16px}.details-grid{display:grid;grid-template-columns:repeat(auto-fit, minmax(280px, 1fr));gap:12px}.details-grid-item-wrapper{display:flex;gap:12px;grid-column:1/-1}.details-grid label{display:block;font-size:10px;color:var(--text3);font-family:var(--font-mono);margin-bottom:6px}.badge{font-size:10px;padding:1px 6px;border-radius:8px;background:var(--bg4);color:var(--text3);text-transform:uppercase;letter-spacing:.3px;white-space:nowrap}.badge-source-dataset{background:color-mix(in srgb, var(--yellow) 22%, var(--bg));color:var(--yellow)}.badge-source-static{background:var(--bg4);color:var(--text3)}.ve-values-layout{display:flex;gap:16px;align-items:stretch;height:calc(100vh - 115px);min-height:320px}.ve-values-detail>.ve-values-layout{height:100%;min-height:0}.ve-values-nav{width:280px;flex-shrink:0;display:flex;flex-direction:column;gap:8px;min-height:0}.ve-values-nav-list{display:flex;flex-direction:column;gap:6px;overflow:auto;min-height:0}.ve-values-nav-item{display:flex;align-items:center;gap:8px;min-height:30px;padding:6px 10px;border:1px solid var(--border);border-radius:6px;background:var(--bg2);color:var(--text);cursor:pointer;text-align:left;width:100%;font-family:var(--font-ui);font-size:12px}.ve-values-nav-item:hover{border-color:var(--border2);background:var(--bg3)}.ve-values-nav-item.is-active{border-color:var(--m-accent);background:color-mix(in srgb, var(--m-accent) 12%, var(--m-bg2))}.ve-values-nav-dot{width:8px;height:8px;border-radius:50%;background:var(--text3);flex-shrink:0}.ve-values-nav-item.is-active .ve-values-nav-dot{background:var(--m-accent)}.ve-values-nav-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:var(--font-mono)}.ve-values-nav-badges{display:flex;gap:4px;flex-shrink:0;align-items:center}.ve-values-nav-add{border-style:dashed;justify-content:center;background:rgba(0,0,0,0)}.ve-values-nav-add:hover{background:var(--bg3)}.ve-values-detail{flex:1;min-width:0;overflow:auto;padding-right:10px}.ve-values-anchor{scroll-margin-top:12px}.ve-values-anchor.is-active{border-color:var(--accent)}.ve-values-anchor+.ve-values-anchor{margin-top:24px;padding-top:10px}.ve-values-detail-header{display:flex;align-items:center;gap:8px}.ve-values-detail-title{font-family:var(--font-mono);font-size:13px;font-weight:600}.ve-values-detail-header .ve-values-field-label{flex:1;min-width:0}.ve-values-detail-header .btn{margin-left:auto;flex-shrink:0}.ve-values-fields{display:grid;grid-template-columns:repeat(auto-fit, minmax(220px, 1fr));gap:12px}.ve-values-field{display:flex;flex-direction:column;align-items:flex-start;gap:10px;min-width:0}.ve-values-field.is-wide{grid-column:1/-1}.ve-values-field-label{display:flex;align-items:center;gap:6px;font-size:10px;color:var(--text3)}.ve-values-field-label>span:first-child{font-family:var(--font-mono)}.ve-values-field textarea,.ve-values-field input[type=text],.ve-values-field select{min-height:30px;height:30px;resize:none;overflow:hidden}.ve-values-empty{color:var(--text3);padding:24px 0}.ve-values-list-items{display:flex;flex-direction:column;gap:12px}.ve-values-list-item{background:var(--bg);border:1px solid var(--border);border-radius:4px;padding:10px 8px 16px;display:flex;gap:6px;align-items:flex-start;transition:opacity .12s ease,border-color .12s ease,box-shadow .12s ease}.ve-values-list-item.is-dragging{opacity:.45}.ve-values-list-item.is-drop-target{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent)}.ve-values-list-item-handle{flex-shrink:0;width:22px;align-self:stretch;display:inline-flex;align-items:center;justify-content:center;cursor:grab;color:var(--text3);user-select:none;border:none;background:rgba(0,0,0,0);font-size:16px;line-height:1;padding:0;letter-spacing:-2px}.ve-values-list-item-handle:hover{color:var(--text2)}.ve-values-list-item-handle:active{cursor:grabbing}.ve-values-list-item>.ve-values-fields{flex:1;min-width:0}.ve-values-list-item-remove{flex-shrink:0}.checkbox-row{display:flex;flex-wrap:wrap;gap:4px 16px}.details-grid .checkbox-label{display:inline-flex;align-items:center;gap:4px;font-size:11px;color:var(--text2);font-family:var(--font-ui);margin-bottom:0}.checkbox-label input{width:auto}.empty-state{color:var(--text3);text-align:center;padding:40px}.ve-modal-overlay{position:fixed;inset:0;background:rgba(0,0,0,.5);display:flex;align-items:center;justify-content:center;z-index:100}.ve-modal{background:var(--bg2);border:1px solid var(--border2);border-radius:6px;padding:16px;width:min(400px,90vw);box-shadow:0 8px 24px rgba(0,0,0,.4);position:relative}.ve-modal-diff{width:min(860px,94vw);min-width:min(500px,90vw);min-height:min(300px,80vh);max-height:85vh;display:flex;flex-direction:column}.ve-modal-wide{width:min(560px,90vw)}.ve-modal-title{font-size:12px;color:var(--text2);margin-bottom:8px}.ve-modal-title-row{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:12px}.ve-modal-title-row .ve-modal-title{margin-bottom:0;flex:1}.ve-modal-close{width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}.ve-modal-body{font-size:12px;line-height:1.6;max-height:60vh;overflow-y:auto}.ve-modal-diff .ve-modal-body{flex:1;max-height:none;min-height:0;display:flex;flex-direction:column;gap:8px}.ve-diff-nav{display:flex;align-items:center;gap:8px;flex-shrink:0}.ve-diff-nav .btn{min-width:30px;min-height:30px;padding:0;display:inline-flex;align-items:center;justify-content:center}.ve-diff-nav-count{font-size:12px;color:var(--text2);font-variant-numeric:tabular-nums;min-width:4.5em}.ve-diff{background:var(--bg);border:1px solid var(--border);border-radius:6px;overflow:auto;flex:1;min-height:180px;font-family:var(--font-mono);font-size:11px;line-height:1.55}.ve-diff-line{display:flex;gap:8px;padding:1px 8px;white-space:pre-wrap;word-break:break-word}.ve-diff-prefix{flex-shrink:0;width:12px;user-select:none;opacity:.8}.ve-diff-line.is-add{background:color-mix(in srgb, var(--green) 14%, var(--bg));color:var(--text)}.ve-diff-line.is-remove{background:color-mix(in srgb, var(--red) 14%, var(--bg));color:var(--text)}.ve-diff-line.is-add .ve-diff-prefix{color:var(--green)}.ve-diff-line.is-remove .ve-diff-prefix{color:var(--red)}.ve-diff-line.is-current-change{outline:1px solid var(--accent);outline-offset:-1px}.ve-diff-inline-add{background:color-mix(in srgb, var(--green) 35%, transparent);color:var(--green);font-weight:700;border-radius:2px}.ve-diff-inline-remove{background:color-mix(in srgb, var(--red) 35%, transparent);color:color-mix(in srgb, var(--red) 80%, #fff);font-weight:700;border-radius:2px}.ve-diff-empty{padding:24px;color:var(--text3);text-align:center}.ve-modal-body pre{background:var(--bg3);border:1px solid var(--border);border-radius:4px;padding:8px;font-family:var(--font-mono);font-size:11px;white-space:pre-wrap;word-break:break-word}.ve-modal-body code{background:var(--bg3);padding:1px 4px;border-radius:3px;font-family:var(--font-mono)}.ve-modal-actions{display:flex;justify-content:flex-end;align-items:center;gap:8px;margin-top:12px}.ve-modal-actions .hint{margin:0;margin-right:auto;text-align:left}.ve-combo{position:relative}.ve-combo-input{margin-bottom:0}.ve-combo-list{position:absolute;left:0;right:0;top:100%;z-index:10;max-height:220px;overflow-y:auto;background:var(--bg3);border:1px solid var(--border2);border-radius:4px;margin-top:2px;box-shadow:0 4px 12px rgba(0,0,0,.3)}.ve-combo-option{padding:5px 8px;font-size:12px;cursor:pointer}.ve-combo-option:hover{background:var(--bg4)}.ve-combo-chips{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:8px}.ve-chip{display:inline-flex;align-items:center;gap:4px;background:var(--bg3);border:1px solid var(--border2);border-radius:10px;padding:2px 4px 2px 8px;font-size:11px}.ve-chip button{background:none;border:none;color:var(--text3);cursor:pointer;font-size:11px;padding:0 2px}.ve-chip button:hover{color:var(--text)}.ve-list-items{display:flex;flex-direction:column;gap:6px}.ve-list-item{display:flex;gap:6px;align-items:flex-start}.ve-list-item>input[type=text]{flex:1}.ve-list-item-cols{background:var(--bg2);border:1px solid var(--border);border-radius:4px;padding:8px;display:flex;gap:8px;align-items:flex-start}.ve-list-item-fields{display:flex;flex-direction:column;gap:8px;width:100%}.ve-list-field{display:flex;flex-direction:column;gap:6px;max-width:450px;width:100%}.ve-list-field label{font-size:10px;color:var(--text3)}.ve-list-field textarea,.ve-list-field input[type=text],.ve-list-field select{min-height:30px;height:30px;resize:none;overflow:hidden}.ve-list-item-actions{flex-shrink:0}.box-style{border:1px solid var(--border);border-radius:6px;padding:8px;background:var(--bg3)}.ve-ao-columns{display:flex;flex-direction:column;gap:8px;margin-top:8px}.ve-ao-column{background:var(--bg);border:1px solid var(--border);border-radius:4px;padding:10px 8px 16px;display:flex;gap:6px;align-items:flex-start;transition:opacity .12s ease,border-color .12s ease,box-shadow .12s ease}.ve-ao-column.is-dragging{opacity:.45}.ve-ao-column.is-drop-target{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent)}.ve-ao-column-handle{flex-shrink:0;width:22px;align-self:stretch;display:inline-flex;align-items:center;justify-content:center;cursor:grab;color:var(--text3);user-select:none;border:none;background:rgba(0,0,0,0);font-size:16px;line-height:1;padding:0;letter-spacing:-2px}.ve-ao-column-handle:hover{color:var(--text2)}.ve-ao-column-handle:active{cursor:grabbing}.ve-ao-column-fields{flex:1;min-width:0;display:flex;flex-direction:column;gap:6px}.ve-ao-column-top{display:flex;gap:6px;align-items:flex-end}.ve-ao-column-field{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.ve-ao-column-field label{font-size:10px;color:var(--text3);text-transform:none;margin-bottom:0;font-family:var(--font-mono)}.ve-ao-column-name{position:relative;min-width:0}.ve-ao-column-name input{width:100%;padding-right:28px;font-family:var(--font-mono)}.ve-ao-column-remove{position:absolute;right:0px;top:50%;transform:translateY(-50%);width:24px;height:24px;padding:0;display:inline-flex;align-items:center;justify-content:center}.ve-ao-column-bottom{display:flex;gap:6px;align-items:flex-end}.ve-ao-column-bottom>.ve-ao-column-field{flex:1;min-width:0}.ve-json-issues{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}.ve-json-issue-badge{display:inline-flex;align-items:center;gap:4px;background:color-mix(in srgb, var(--yellow) 15%, var(--bg));color:var(--yellow);border:1px solid color-mix(in srgb, var(--yellow) 40%, var(--bg));border-radius:10px;padding:2px 8px;font-size:11px;cursor:default}.ve-modal-back{background:none;border:none;color:var(--accent);font-size:11px;cursor:pointer;padding:0 0 4px;font-family:var(--font-ui);display:block}.ve-import-search{position:relative;margin-bottom:12px}.ve-import-search input{padding-left:28px}.ve-import-search::before{content:"⌕";position:absolute;left:9px;top:50%;transform:translateY(-50%);color:var(--text3);font-size:14px;pointer-events:none}.ve-import-section-title{font-size:10.5px;color:var(--text3);text-transform:uppercase;letter-spacing:.5px;margin:14px 0 6px;font-weight:600}.ve-import-section-title:first-child{margin-top:0}.ve-import-page-list{display:flex;flex-direction:column;gap:5px}.ve-import-page-row{display:flex;align-items:center;gap:10px;width:100%;text-align:left;padding:8px 10px;border:1px solid var(--border);border-radius:6px;background:var(--bg3);color:var(--text);cursor:pointer;font-family:var(--font-ui);font-size:12px}.ve-import-page-row:hover{border-color:var(--accent)}.ve-import-page-name{font-weight:500}.ve-import-page-slug{font-size:11px;color:var(--text3);font-family:var(--font-mono);margin-left:auto;flex-shrink:0}.ve-import-empty{padding:20px 4px;text-align:center;color:var(--text3);font-size:12px}.ve-import-list-head{display:flex;align-items:center;gap:8px;margin-bottom:8px}.ve-import-list-head .badge{background:color-mix(in srgb, var(--green) 18%, var(--bg));color:var(--green)}.ve-import-select-all{margin-left:auto;display:flex;align-items:center;gap:6px;font-size:11.5px;color:var(--text2);cursor:pointer;text-transform:none}.ve-import-list{display:flex;flex-direction:column;gap:6px}.ve-import-row{display:flex;align-items:flex-start;gap:10px;padding:8px 10px;border:1px solid var(--border);border-radius:6px;background:var(--bg3);cursor:pointer}.ve-import-row input[type=checkbox]{margin-top:2px;flex-shrink:0}.ve-import-row-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}.ve-import-row-top{display:flex;align-items:center;gap:8px}.ve-import-row-name{font-family:var(--font-mono);font-size:12px;font-weight:600}.ve-import-row-value{font-size:11.5px;color:var(--text2);font-family:var(--font-mono);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ve-import-swatch{width:12px;height:12px;border-radius:3px;border:1px solid var(--border2);flex-shrink:0;display:inline-block;vertical-align:-1px;margin-right:5px}.ve-import-skip-row{display:flex;align-items:baseline;gap:8px;padding:7px 10px;opacity:.85}.ve-import-skip-row .ve-import-row-name{color:var(--text2)}.ve-import-skip-reason{font-size:11.5px;color:var(--text3)}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:var(--bg)}::-webkit-scrollbar-thumb{background:var(--bg4);border-radius:4px}body[data-template-less=true] .ve-template-only{display:none !important}
|
|
2
|
+
|
|
3
|
+
/*# sourceMappingURL=variables-editor.css.map */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sourceRoot":"","sources":["variables-editor.scss"],"names":[],"mappings":"CACA,qBAGE,sBACA,SACA,UAEF,qCAEE,cACA,eACA,eACA,eACA,kBACA,mBACA,gBACA,iBACA,iBACA,kBACA,mBACA,0BACA,oBACA,iBACA,eACA,kBACA,gBACA,0BACA,iFACA,qEAEF,8BACE,cACA,eACA,eACA,eACA,kBACA,mBACA,gBACA,iBACA,iBACA,kBACA,mBACA,0BACA,oBACA,iBACA,eACA,kBACA,gBACA,0BAEF,mCACE,MACE,cACA,eACA,eACA,eACA,kBACA,mBACA,gBACA,iBACA,iBACA,kBACA,mBACA,0BACA,oBACA,iBACA,eACA,kBACA,gBACA,2BAGJ,UAEE,YACA,gBACA,qBACA,kBACA,2BACA,eACA,gBAEF,KACE,aACA,sBACA,aAEF,SACE,aACA,mBACA,QACA,iBACA,sBACA,sCACA,cACA,eAEF,eACE,gBACA,eACA,iBAEF,MACE,aACA,QAEF,KACE,iBACA,kBACA,+BACA,yBACA,mBACA,eACA,eAEF,WACE,sBACA,kBAEF,YACE,sBACA,kBACA,4BAEF,gBACE,OAEF,sBACE,oBACA,mBACA,QACA,mBACA,eAEF,gBACE,UACA,WACA,kBACA,yBACA,2CAEF,aACE,aAEF,iBACE,YACA,kBACA,sBACA,kBACA,6CAEF,8BACE,UAEF,8BACE,UAEF,8BACE,UAEF,8BACE,UAEF,oBACE,QAEE,UAEF,IACE,YAGJ,cACE,aACA,QACA,sBACA,+BACA,kBACA,YAEF,qBACE,gBACA,YACA,kBACA,yBACA,mBACA,eACA,eACA,2BAEF,4BACE,yBACA,4BAEF,KACE,iBACA,kBACA,+BACA,sBACA,kBACA,eACA,eACA,0BAEF,WACE,sBACA,4BAEF,aACE,yBACA,2BACA,4BACA,gBAEF,mBACE,WACA,yBAEF,QACE,gBACA,eACA,eACA,gBAEF,kBACE,eACA,WACA,YACA,WACA,sCAEF,0BACE,aAEF,SACE,OACA,cACA,aAEF,QACE,mBACA,iBACA,kBACA,eAEF,gBACE,4DACA,oBACA,kEAEF,cACE,yDACA,iBACA,+DAEF,gBACE,2DACA,mBACA,iEAEF,WACE,oBAEF,MACE,WACA,yBACA,iBACA,eAEF,MACE,0BACA,gBAEF,SACE,oBAEF,GACE,gBACA,gBACA,mBACA,sCACA,gBACA,eACA,yBACA,oBACA,sBAEF,qBACE,wBAEF,oBACE,wBAEF,GACE,iBACA,mBAEF,YACE,sBAEF,iCAGE,WACA,sBACA,+BACA,kBACA,gBACA,kBACA,eACA,6BACA,aACA,gBAEF,mDAGE,2BAEF,kBACE,gBACA,WACA,YACA,UACA,+BACA,kBACA,sBAEF,SACE,gBACA,gBAEF,eACE,gBACA,YACA,YACA,gBACA,gBAEF,UACE,YAEF,UACE,YAEF,YACE,YAEF,aACE,WACA,iBAEF,YACE,WACA,iBACA,2BAEF,gBACE,aACA,mBACA,QAEF,sBACE,cACA,WACA,YACA,oBACA,mBACA,uBACA,YACA,mBACA,iBACA,YACA,yBACA,eACA,cACA,UACA,oBAEF,4BACE,mBAEF,6BACE,gBAEF,2DAEE,YAEF,iEAEE,uCAEF,eACE,WACA,YACA,UACA,oBACA,mBACA,uBACA,eACA,cACA,mBAEF,qBACE,kBAEF,YACE,mBAEF,YACE,WACA,uBACA,6BACA,eACA,gBAEF,MACE,mBACA,eAEF,SACE,eAEF,oFAIE,gBAEF,oBAEE,eACA,kBAEF,YACE,wCACA,sBACA,kBACA,cAEF,WACE,eACA,gBACA,sBACA,kBACA,gBAEF,gBACE,gBACA,UAEF,cACE,mBAEF,gBACE,sBACA,aAEF,cACE,aACA,2DACA,SAEF,2BACE,aACA,SACA,iBAEF,oBACE,cACA,eACA,mBACA,6BACA,kBAEF,OACE,eACA,gBACA,kBACA,sBACA,mBACA,yBACA,oBACA,mBAEF,sBACE,4DACA,oBAEF,qBACE,sBACA,mBAEF,kBACE,aACA,SACA,oBACA,2BACA,iBAEF,oCACE,YACA,aAEF,eACE,YACA,cACA,aACA,sBACA,QACA,aAEF,oBACE,aACA,sBACA,QACA,cACA,aAEF,oBACE,aACA,mBACA,QACA,gBACA,iBACA,+BACA,kBACA,sBACA,kBACA,eACA,gBACA,WACA,2BACA,eAEF,0BACE,4BACA,sBAEF,8BACE,6BACA,iEAEF,mBACE,UACA,WACA,kBACA,wBACA,cAEF,iDACE,2BAEF,qBACE,OACA,YACA,gBACA,uBACA,mBACA,6BAEF,sBACE,aACA,QACA,cACA,mBAEF,mBACE,oBACA,uBACA,yBAEF,yBACE,sBAEF,kBACE,OACA,YACA,cACA,mBAEF,kBACE,uBAEF,4BACE,2BAEF,oCACE,gBACA,iBAEF,yBACE,aACA,mBACA,QAEF,wBACE,6BACA,eACA,gBAEF,gDACE,OACA,YAEF,8BACE,iBACA,cAEF,kBACE,aACA,2DACA,SAEF,iBACE,aACA,sBACA,uBACA,SACA,YAEF,yBACE,iBAEF,uBACE,aACA,mBACA,QACA,eACA,mBAEF,wCACE,6BAEF,oFAGE,gBACA,YACA,YACA,gBAEF,iBACE,mBACA,eAEF,sBACE,aACA,sBACA,SAEF,qBACE,qBACA,+BACA,kBACA,sBACA,aACA,QACA,uBACA,WACE,8DAIJ,iCACE,YAEF,oCACE,2BACA,mCAEF,4BACE,cACA,WACA,mBACA,oBACA,mBACA,uBACA,YACA,mBACA,iBACA,YACA,yBACA,eACA,cACA,UACA,oBAEF,kCACE,mBAEF,mCACE,gBAEF,uCACE,OACA,YAEF,4BACE,cAEF,cACE,aACA,eACA,aAEF,8BACE,oBACA,mBACA,QACA,eACA,mBACA,2BACA,gBAEF,sBACE,WAEF,aACE,mBACA,kBACA,aAEF,kBACE,eACA,QACA,0BACA,aACA,mBACA,uBACA,YAEF,UACE,sBACA,gCACA,kBACA,aACA,sBACA,qCACA,kBAEF,eACE,sBACA,0BACA,2BACA,gBACA,aACA,sBAEF,eACE,sBAEF,gBACE,eACA,mBACA,kBAEF,oBACE,aACA,uBACA,8BACA,SACA,mBAEF,oCACE,gBACA,OAEF,gBACE,WACA,YACA,UACA,oBACA,mBACA,uBACA,cAEF,eACE,eACA,gBACA,gBACA,gBAEF,8BACE,OACA,gBACA,aACA,aACA,sBACA,QAEF,aACE,aACA,mBACA,QACA,cAEF,kBACE,eACA,gBACA,UACA,oBACA,mBACA,uBAEF,mBACE,eACA,mBACA,kCACA,gBAEF,SACE,qBACA,+BACA,kBACA,cACA,OACA,iBACA,6BACA,eACA,iBAEF,cACE,aACA,QACA,gBACA,qBACA,sBAEF,gBACE,cACA,WACA,iBACA,WAEF,qBACE,2DACA,kBAEF,wBACE,yDACA,kBAEF,qCACE,mBAEF,wCACE,iBAEF,gCACE,gCACA,oBAEF,oBACE,6DACA,mBACA,gBACA,kBAEF,uBACE,2DACA,+CACA,gBACA,kBAEF,eACE,aACA,mBACA,kBAEF,mBACE,sBACA,+BACA,kBACA,YACA,6BACA,eACA,qBACA,sBAEF,oBACE,sBACA,gBACA,kBACA,6BAEF,kBACE,aACA,yBACA,mBACA,QACA,gBAEF,wBACE,SACA,kBACA,gBAEF,UACE,kBAEF,gBACE,gBAEF,eACE,kBACA,OACA,QACA,SACA,WACA,iBACA,gBACA,sBACA,gCACA,kBACA,eACA,qCAEF,iBACE,gBACA,eACA,eAEF,uBACE,sBAEF,gBACE,aACA,eACA,QACA,kBAEF,SACE,oBACA,mBACA,QACA,sBACA,gCACA,mBACA,wBACA,eAEF,gBACE,gBACA,YACA,mBACA,eACA,eACA,cAEF,sBACE,kBAEF,eACE,aACA,sBACA,QAEF,cACE,aACA,QACA,uBAEF,+BACE,OAEF,mBACE,sBACA,+BACA,kBACA,YACA,aACA,QACA,uBAEF,qBACE,aACA,sBACA,QACA,WAEF,eACE,aACA,sBACA,QACA,gBACA,WAEF,qBACE,eACA,mBAEF,8EAGE,gBACA,YACA,YACA,gBAEF,sBACE,cAEF,WACE,+BACA,kBACA,YACA,sBAEF,eACE,aACA,sBACA,QACA,eAEF,cACE,qBACA,+BACA,kBACA,sBACA,aACA,QACA,uBACA,WACE,8DAIJ,0BACE,YAEF,6BACE,2BACA,mCAEF,qBACE,cACA,WACA,mBACA,oBACA,mBACA,uBACA,YACA,mBACA,iBACA,YACA,yBACA,eACA,cACA,UACA,oBAEF,2BACE,mBAEF,4BACE,gBAEF,qBACE,OACA,YACA,aACA,sBACA,QAEF,kBACE,aACA,QACA,qBAEF,oBACE,OACA,YACA,aACA,sBACA,QAEF,0BACE,eACA,mBACA,oBACA,gBACA,6BAEF,mBACE,kBACA,YAEF,yBACE,WACA,mBACA,6BAEF,qBACE,kBACA,UACA,QACA,2BACA,WACA,YACA,UACA,oBACA,mBACA,uBAEF,qBACE,aACA,QACA,qBAEF,yCACE,OACA,YAEF,gBACE,aACA,eACA,QACA,eAEF,qBACE,oBACA,mBACA,QACA,4DACA,oBACA,kEACA,mBACA,gBACA,eACA,eAEF,eACE,gBACA,YACA,oBACA,eACA,eACA,gBACA,2BACA,cAEF,kBACE,kBACA,mBAEF,wBACE,kBAEF,0BACE,YACA,kBACA,SACA,QACA,2BACA,mBACA,eACA,oBAEF,yBACE,iBACA,mBACA,yBACA,oBACA,kBACA,gBAEF,qCACE,aAEF,qBACE,aACA,sBACA,QAEF,oBACE,aACA,mBACA,SACA,WACA,gBACA,iBACA,+BACA,kBACA,sBACA,kBACA,eACA,2BACA,eAEF,0BACE,2BAEF,qBACE,gBAEF,qBACE,eACA,mBACA,6BACA,iBACA,cAEF,iBACE,iBACA,kBACA,mBACA,eAEF,qBACE,aACA,mBACA,QACA,kBAEF,4BACE,2DACA,mBAEF,sBACE,iBACA,aACA,mBACA,QACA,iBACA,mBACA,eACA,oBAEF,gBACE,aACA,sBACA,QAEF,eACE,aACA,uBACA,SACA,iBACA,+BACA,kBACA,sBACA,eAEF,oCACE,eACA,cAEF,oBACE,OACA,YACA,aACA,sBACA,QAEF,mBACE,aACA,mBACA,QAEF,oBACE,6BACA,eACA,gBAEF,qBACE,iBACA,mBACA,6BACA,mBACA,gBACA,uBAEF,kBACE,WACA,YACA,kBACA,gCACA,cACA,qBACA,oBACA,iBAEF,oBACE,aACA,qBACA,QACA,iBACA,YAEF,wCACE,mBAEF,uBACE,iBACA,mBAEF,oBACE,UACA,WAEF,0BACE,qBAEF,0BACE,sBACA,kBAIF,gDACE","file":"variables-editor.css","sourcesContent":["// The Variables Editor page (moved from the template literal in src/lib/variables-editor.ts).\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n}\n:root,\n:root[data-pp-dev-theme='light'] {\n --bg: #ffffff;\n --bg2: #f4f5f7;\n --bg3: #e9ebef;\n --bg4: #dbdee3;\n --border: #d7dae0;\n --border2: #c2c6cd;\n --text: #1a1a1e;\n --text2: #54566b;\n --text3: #8a8c9c;\n --accent: #4f46e5;\n --accent2: #7c3aed;\n --m-accent: var(--accent);\n --m-bg2: var(--bg2);\n --green: #16a34a;\n --red: #dc2626;\n --yellow: #a16207;\n --blue: #2563eb;\n --btn-primary-fg: #ffffff;\n --font-mono: 'Cascadia Code', 'Fira Code', 'JetBrains Mono', Consolas, monospace;\n --font-ui: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n}\n:root[data-pp-dev-theme='dark'] {\n --bg: #1a1a1e;\n --bg2: #222228;\n --bg3: #2a2a32;\n --bg4: #32323c;\n --border: #3a3a46;\n --border2: #4a4a58;\n --text: #e0e0f0;\n --text2: #a0a0b8;\n --text3: #606078;\n --accent: #6e8efb;\n --accent2: #a78bfa;\n --m-accent: var(--accent);\n --m-bg2: var(--bg2);\n --green: #4ade80;\n --red: #f87171;\n --yellow: #fbbf24;\n --blue: #60a5fa;\n --btn-primary-fg: #0d0d10;\n}\n@media (prefers-color-scheme: dark) {\n :root {\n --bg: #1a1a1e;\n --bg2: #222228;\n --bg3: #2a2a32;\n --bg4: #32323c;\n --border: #3a3a46;\n --border2: #4a4a58;\n --text: #e0e0f0;\n --text2: #a0a0b8;\n --text3: #606078;\n --accent: #6e8efb;\n --accent2: #a78bfa;\n --m-accent: var(--accent);\n --m-bg2: var(--bg2);\n --green: #4ade80;\n --red: #f87171;\n --yellow: #fbbf24;\n --blue: #60a5fa;\n --btn-primary-fg: #0d0d10;\n }\n}\nhtml,\nbody {\n height: 100%;\n overflow: hidden;\n background: var(--bg);\n color: var(--text);\n font-family: var(--font-ui);\n font-size: 13px;\n line-height: 1.5;\n}\n.app {\n display: flex;\n flex-direction: column;\n height: 100vh;\n}\n.toolbar {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n background: var(--bg2);\n border-bottom: 1px solid var(--border);\n flex-shrink: 0;\n flex-wrap: wrap;\n}\n.toolbar-title {\n font-weight: 600;\n font-size: 14px;\n margin-right: 8px;\n}\n.tabs {\n display: flex;\n gap: 4px;\n}\n.tab {\n padding: 5px 12px;\n border-radius: 4px;\n border: 1px solid transparent;\n background: transparent;\n color: var(--text2);\n font-size: 12px;\n cursor: pointer;\n}\n.tab:hover {\n background: var(--bg3);\n color: var(--text);\n}\n.tab.active {\n background: var(--bg4);\n color: var(--text);\n border-color: var(--border2);\n}\n.toolbar-spacer {\n flex: 1;\n}\n.ve-loading-indicator {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n color: var(--text3);\n font-size: 11px;\n}\n.ve-loading-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--accent);\n animation: ve-pulse 1s ease-in-out infinite;\n}\n.ve-skeleton {\n padding: 16px;\n}\n.ve-skeleton-row {\n height: 32px;\n border-radius: 4px;\n background: var(--bg3);\n margin-bottom: 8px;\n animation: ve-pulse 1.4s ease-in-out infinite;\n}\n.ve-skeleton-row:nth-child(2) {\n width: 92%;\n}\n.ve-skeleton-row:nth-child(3) {\n width: 96%;\n}\n.ve-skeleton-row:nth-child(4) {\n width: 88%;\n}\n.ve-skeleton-row:nth-child(5) {\n width: 94%;\n}\n@keyframes ve-pulse {\n 0%,\n 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.4;\n }\n}\n.theme-switch {\n display: flex;\n gap: 2px;\n background: var(--bg3);\n border: 1px solid var(--border);\n border-radius: 4px;\n padding: 2px;\n}\n.theme-switch button {\n padding: 3px 8px;\n border: none;\n border-radius: 3px;\n background: transparent;\n color: var(--text2);\n font-size: 11px;\n cursor: pointer;\n font-family: var(--font-ui);\n}\n.theme-switch button.active {\n background: var(--accent);\n color: var(--btn-primary-fg);\n}\n.btn {\n padding: 5px 12px;\n border-radius: 4px;\n border: 1px solid var(--border);\n background: var(--bg3);\n color: var(--text);\n font-size: 12px;\n cursor: pointer;\n transition: background 0.1s;\n}\n.btn:hover {\n background: var(--bg4);\n border-color: var(--border2);\n}\n.btn-primary {\n background: var(--accent);\n border-color: var(--accent);\n color: var(--btn-primary-fg);\n font-weight: 600;\n}\n.btn-primary:hover {\n opacity: 0.9;\n background: var(--accent);\n}\n.btn-sm {\n padding: 5px 8px;\n font-size: 11px;\n min-width: 30px;\n min-height: 30px;\n}\n.local-update-btn {\n position: fixed;\n right: 16px;\n bottom: 16px;\n z-index: 20;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);\n}\n.local-update-btn[hidden] {\n display: none;\n}\n.content {\n flex: 1;\n overflow: auto;\n padding: 14px;\n}\n.banner {\n margin-bottom: 12px;\n padding: 8px 12px;\n border-radius: 4px;\n font-size: 12px;\n}\n.banner-warning {\n background: color-mix(in srgb, var(--yellow) 15%, var(--bg));\n color: var(--yellow);\n border: 1px solid color-mix(in srgb, var(--yellow) 40%, var(--bg));\n}\n.banner-error {\n background: color-mix(in srgb, var(--red) 15%, var(--bg));\n color: var(--red);\n border: 1px solid color-mix(in srgb, var(--red) 40%, var(--bg));\n}\n.banner-success {\n background: color-mix(in srgb, var(--green) 15%, var(--bg));\n color: var(--green);\n border: 1px solid color-mix(in srgb, var(--green) 40%, var(--bg));\n}\n.banner ul {\n margin: 6px 0 0 18px;\n}\ntable {\n width: 100%;\n border-collapse: separate;\n border-spacing: 0;\n font-size: 12px;\n}\nthead {\n border-radius: 6px 6px 0 0;\n overflow: hidden;\n}\nthead th {\n padding: 8px 8px 6px;\n}\nth {\n text-align: left;\n padding: 6px 8px;\n color: var(--text2);\n border-bottom: 1px solid var(--border);\n font-weight: 600;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.4px;\n background: var(--bg2);\n}\nthead th:first-child {\n border-radius: 6px 0 0 0;\n}\nthead th:last-child {\n border-radius: 0 6px 0 0;\n}\ntd {\n padding: 12px 8px;\n vertical-align: top;\n}\ntr:hover td {\n background: var(--bg2);\n}\ninput[type='text'],\nselect,\ntextarea {\n width: 100%;\n background: var(--bg3);\n border: 1px solid var(--border);\n color: var(--text);\n padding: 4px 6px;\n border-radius: 4px;\n font-size: 12px;\n font-family: var(--font-mono);\n outline: none;\n min-height: 30px;\n}\ninput[type='text']:focus,\nselect:focus,\ntextarea:focus {\n border-color: var(--accent);\n}\ninput[type='color'] {\n max-width: 150px;\n width: 100%;\n height: 30px;\n padding: 0;\n border: 1px solid var(--border);\n border-radius: 4px;\n background: var(--bg3);\n}\ntextarea {\n resize: vertical;\n min-height: 32px;\n}\n.cell-textarea {\n min-height: 30px;\n height: 30px;\n resize: none;\n overflow: hidden;\n line-height: 1.8;\n}\n.col-name {\n width: 180px;\n}\n.col-type {\n width: 130px;\n}\n.col-source {\n width: 110px;\n}\n.col-actions {\n width: 70px;\n text-align: right;\n}\n.col-expand {\n width: 48px;\n padding-left: 0px;\n padding-right: 0 !important;\n}\n.ve-expand-cell {\n display: flex;\n align-items: center;\n gap: 2px;\n}\n.ve-schema-row-handle {\n flex-shrink: 0;\n width: 18px;\n height: 22px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n cursor: grab;\n color: var(--text3);\n user-select: none;\n border: none;\n background: transparent;\n font-size: 20px;\n line-height: 1;\n padding: 0;\n letter-spacing: -2px;\n}\n.ve-schema-row-handle:hover {\n color: var(--text2);\n}\n.ve-schema-row-handle:active {\n cursor: grabbing;\n}\ntr.schema-row.is-dragging td,\ntr.details-row.is-dragging td {\n opacity: 0.45;\n}\ntr.schema-row.is-drop-target td,\ntr.details-row.is-drop-target td {\n box-shadow: inset 0 2px 0 var(--accent);\n}\n.ve-expand-btn {\n width: 30px;\n height: 30px;\n padding: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: 13px;\n line-height: 1;\n color: var(--text2);\n}\n.ve-expand-btn:hover {\n color: var(--text);\n}\n.raw-toggle {\n margin-bottom: 10px;\n}\n.raw-editor {\n width: 100%;\n height: min(60vh, 600px);\n font-family: var(--font-mono);\n font-size: 12px;\n white-space: pre;\n}\n.hint {\n color: var(--text3);\n font-size: 11px;\n}\n.ve-md p {\n margin: 0 0 4px;\n}\n.ve-md p:last-child,\n.ve-md ul:last-child,\n.ve-md ol:last-child,\n.ve-md pre:last-child {\n margin-bottom: 0;\n}\n.ve-md ul,\n.ve-md ol {\n margin: 0 0 4px;\n padding-left: 18px;\n}\n.ve-md code {\n font-family: var(--font-mono, monospace);\n background: var(--bg4);\n border-radius: 3px;\n padding: 0 3px;\n}\n.ve-md pre {\n margin: 0 0 4px;\n padding: 6px 8px;\n background: var(--bg4);\n border-radius: 4px;\n overflow-x: auto;\n}\n.ve-md pre code {\n background: none;\n padding: 0;\n}\n.ve-md strong {\n color: var(--text2);\n}\n.details-row td {\n background: var(--bg2);\n padding: 16px;\n}\n.details-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));\n gap: 12px;\n}\n.details-grid-item-wrapper {\n display: flex;\n gap: 12px;\n grid-column: 1/-1;\n}\n.details-grid label {\n display: block;\n font-size: 10px;\n color: var(--text3);\n font-family: var(--font-mono);\n margin-bottom: 6px;\n}\n.badge {\n font-size: 10px;\n padding: 1px 6px;\n border-radius: 8px;\n background: var(--bg4);\n color: var(--text3);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n white-space: nowrap;\n}\n.badge-source-dataset {\n background: color-mix(in srgb, var(--yellow) 22%, var(--bg));\n color: var(--yellow);\n}\n.badge-source-static {\n background: var(--bg4);\n color: var(--text3);\n}\n.ve-values-layout {\n display: flex;\n gap: 16px;\n align-items: stretch;\n height: calc(100vh - 115px);\n min-height: 320px;\n}\n.ve-values-detail > .ve-values-layout {\n height: 100%;\n min-height: 0;\n}\n.ve-values-nav {\n width: 280px;\n flex-shrink: 0;\n display: flex;\n flex-direction: column;\n gap: 8px;\n min-height: 0;\n}\n.ve-values-nav-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n overflow: auto;\n min-height: 0;\n}\n.ve-values-nav-item {\n display: flex;\n align-items: center;\n gap: 8px;\n min-height: 30px;\n padding: 6px 10px;\n border: 1px solid var(--border);\n border-radius: 6px;\n background: var(--bg2);\n color: var(--text);\n cursor: pointer;\n text-align: left;\n width: 100%;\n font-family: var(--font-ui);\n font-size: 12px;\n}\n.ve-values-nav-item:hover {\n border-color: var(--border2);\n background: var(--bg3);\n}\n.ve-values-nav-item.is-active {\n border-color: var(--m-accent);\n background: color-mix(in srgb, var(--m-accent) 12%, var(--m-bg2));\n}\n.ve-values-nav-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: var(--text3);\n flex-shrink: 0;\n}\n.ve-values-nav-item.is-active .ve-values-nav-dot {\n background: var(--m-accent);\n}\n.ve-values-nav-label {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-family: var(--font-mono);\n}\n.ve-values-nav-badges {\n display: flex;\n gap: 4px;\n flex-shrink: 0;\n align-items: center;\n}\n.ve-values-nav-add {\n border-style: dashed;\n justify-content: center;\n background: transparent;\n}\n.ve-values-nav-add:hover {\n background: var(--bg3);\n}\n.ve-values-detail {\n flex: 1;\n min-width: 0;\n overflow: auto;\n padding-right: 10px;\n}\n.ve-values-anchor {\n scroll-margin-top: 12px;\n}\n.ve-values-anchor.is-active {\n border-color: var(--accent);\n}\n.ve-values-anchor + .ve-values-anchor {\n margin-top: 24px;\n padding-top: 10px;\n}\n.ve-values-detail-header {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.ve-values-detail-title {\n font-family: var(--font-mono);\n font-size: 13px;\n font-weight: 600;\n}\n.ve-values-detail-header .ve-values-field-label {\n flex: 1;\n min-width: 0;\n}\n.ve-values-detail-header .btn {\n margin-left: auto;\n flex-shrink: 0;\n}\n.ve-values-fields {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\n gap: 12px;\n}\n.ve-values-field {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 10px;\n min-width: 0;\n}\n.ve-values-field.is-wide {\n grid-column: 1/-1;\n}\n.ve-values-field-label {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 10px;\n color: var(--text3);\n}\n.ve-values-field-label > span:first-child {\n font-family: var(--font-mono);\n}\n.ve-values-field textarea,\n.ve-values-field input[type='text'],\n.ve-values-field select {\n min-height: 30px;\n height: 30px;\n resize: none;\n overflow: hidden;\n}\n.ve-values-empty {\n color: var(--text3);\n padding: 24px 0;\n}\n.ve-values-list-items {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n.ve-values-list-item {\n background: var(--bg);\n border: 1px solid var(--border);\n border-radius: 4px;\n padding: 10px 8px 16px;\n display: flex;\n gap: 6px;\n align-items: flex-start;\n transition:\n opacity 0.12s ease,\n border-color 0.12s ease,\n box-shadow 0.12s ease;\n}\n.ve-values-list-item.is-dragging {\n opacity: 0.45;\n}\n.ve-values-list-item.is-drop-target {\n border-color: var(--accent);\n box-shadow: 0 0 0 1px var(--accent);\n}\n.ve-values-list-item-handle {\n flex-shrink: 0;\n width: 22px;\n align-self: stretch;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n cursor: grab;\n color: var(--text3);\n user-select: none;\n border: none;\n background: transparent;\n font-size: 16px;\n line-height: 1;\n padding: 0;\n letter-spacing: -2px;\n}\n.ve-values-list-item-handle:hover {\n color: var(--text2);\n}\n.ve-values-list-item-handle:active {\n cursor: grabbing;\n}\n.ve-values-list-item > .ve-values-fields {\n flex: 1;\n min-width: 0;\n}\n.ve-values-list-item-remove {\n flex-shrink: 0;\n}\n.checkbox-row {\n display: flex;\n flex-wrap: wrap;\n gap: 4px 16px;\n}\n.details-grid .checkbox-label {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n color: var(--text2);\n font-family: var(--font-ui);\n margin-bottom: 0;\n}\n.checkbox-label input {\n width: auto;\n}\n.empty-state {\n color: var(--text3);\n text-align: center;\n padding: 40px;\n}\n.ve-modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 100;\n}\n.ve-modal {\n background: var(--bg2);\n border: 1px solid var(--border2);\n border-radius: 6px;\n padding: 16px;\n width: min(400px, 90vw);\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);\n position: relative;\n}\n.ve-modal-diff {\n width: min(860px, 94vw);\n min-width: min(500px, 90vw);\n min-height: min(300px, 80vh);\n max-height: 85vh;\n display: flex;\n flex-direction: column;\n}\n.ve-modal-wide {\n width: min(560px, 90vw);\n}\n.ve-modal-title {\n font-size: 12px;\n color: var(--text2);\n margin-bottom: 8px;\n}\n.ve-modal-title-row {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 12px;\n margin-bottom: 12px;\n}\n.ve-modal-title-row .ve-modal-title {\n margin-bottom: 0;\n flex: 1;\n}\n.ve-modal-close {\n width: 28px;\n height: 28px;\n padding: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n.ve-modal-body {\n font-size: 12px;\n line-height: 1.6;\n max-height: 60vh;\n overflow-y: auto;\n}\n.ve-modal-diff .ve-modal-body {\n flex: 1;\n max-height: none;\n min-height: 0;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.ve-diff-nav {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-shrink: 0;\n}\n.ve-diff-nav .btn {\n min-width: 30px;\n min-height: 30px;\n padding: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n.ve-diff-nav-count {\n font-size: 12px;\n color: var(--text2);\n font-variant-numeric: tabular-nums;\n min-width: 4.5em;\n}\n.ve-diff {\n background: var(--bg);\n border: 1px solid var(--border);\n border-radius: 6px;\n overflow: auto;\n flex: 1;\n min-height: 180px;\n font-family: var(--font-mono);\n font-size: 11px;\n line-height: 1.55;\n}\n.ve-diff-line {\n display: flex;\n gap: 8px;\n padding: 1px 8px;\n white-space: pre-wrap;\n word-break: break-word;\n}\n.ve-diff-prefix {\n flex-shrink: 0;\n width: 12px;\n user-select: none;\n opacity: 0.8;\n}\n.ve-diff-line.is-add {\n background: color-mix(in srgb, var(--green) 14%, var(--bg));\n color: var(--text);\n}\n.ve-diff-line.is-remove {\n background: color-mix(in srgb, var(--red) 14%, var(--bg));\n color: var(--text);\n}\n.ve-diff-line.is-add .ve-diff-prefix {\n color: var(--green);\n}\n.ve-diff-line.is-remove .ve-diff-prefix {\n color: var(--red);\n}\n.ve-diff-line.is-current-change {\n outline: 1px solid var(--accent);\n outline-offset: -1px;\n}\n.ve-diff-inline-add {\n background: color-mix(in srgb, var(--green) 35%, transparent);\n color: var(--green);\n font-weight: 700;\n border-radius: 2px;\n}\n.ve-diff-inline-remove {\n background: color-mix(in srgb, var(--red) 35%, transparent);\n color: color-mix(in srgb, var(--red) 80%, #fff);\n font-weight: 700;\n border-radius: 2px;\n}\n.ve-diff-empty {\n padding: 24px;\n color: var(--text3);\n text-align: center;\n}\n.ve-modal-body pre {\n background: var(--bg3);\n border: 1px solid var(--border);\n border-radius: 4px;\n padding: 8px;\n font-family: var(--font-mono);\n font-size: 11px;\n white-space: pre-wrap;\n word-break: break-word;\n}\n.ve-modal-body code {\n background: var(--bg3);\n padding: 1px 4px;\n border-radius: 3px;\n font-family: var(--font-mono);\n}\n.ve-modal-actions {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n gap: 8px;\n margin-top: 12px;\n}\n.ve-modal-actions .hint {\n margin: 0;\n margin-right: auto;\n text-align: left;\n}\n.ve-combo {\n position: relative;\n}\n.ve-combo-input {\n margin-bottom: 0;\n}\n.ve-combo-list {\n position: absolute;\n left: 0;\n right: 0;\n top: 100%;\n z-index: 10;\n max-height: 220px;\n overflow-y: auto;\n background: var(--bg3);\n border: 1px solid var(--border2);\n border-radius: 4px;\n margin-top: 2px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);\n}\n.ve-combo-option {\n padding: 5px 8px;\n font-size: 12px;\n cursor: pointer;\n}\n.ve-combo-option:hover {\n background: var(--bg4);\n}\n.ve-combo-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n margin-bottom: 8px;\n}\n.ve-chip {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n background: var(--bg3);\n border: 1px solid var(--border2);\n border-radius: 10px;\n padding: 2px 4px 2px 8px;\n font-size: 11px;\n}\n.ve-chip button {\n background: none;\n border: none;\n color: var(--text3);\n cursor: pointer;\n font-size: 11px;\n padding: 0 2px;\n}\n.ve-chip button:hover {\n color: var(--text);\n}\n.ve-list-items {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.ve-list-item {\n display: flex;\n gap: 6px;\n align-items: flex-start;\n}\n.ve-list-item > input[type='text'] {\n flex: 1;\n}\n.ve-list-item-cols {\n background: var(--bg2);\n border: 1px solid var(--border);\n border-radius: 4px;\n padding: 8px;\n display: flex;\n gap: 8px;\n align-items: flex-start;\n}\n.ve-list-item-fields {\n display: flex;\n flex-direction: column;\n gap: 8px;\n width: 100%;\n}\n.ve-list-field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n max-width: 450px;\n width: 100%;\n}\n.ve-list-field label {\n font-size: 10px;\n color: var(--text3);\n}\n.ve-list-field textarea,\n.ve-list-field input[type='text'],\n.ve-list-field select {\n min-height: 30px;\n height: 30px;\n resize: none;\n overflow: hidden;\n}\n.ve-list-item-actions {\n flex-shrink: 0;\n}\n.box-style {\n border: 1px solid var(--border);\n border-radius: 6px;\n padding: 8px;\n background: var(--bg3);\n}\n.ve-ao-columns {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-top: 8px;\n}\n.ve-ao-column {\n background: var(--bg);\n border: 1px solid var(--border);\n border-radius: 4px;\n padding: 10px 8px 16px;\n display: flex;\n gap: 6px;\n align-items: flex-start;\n transition:\n opacity 0.12s ease,\n border-color 0.12s ease,\n box-shadow 0.12s ease;\n}\n.ve-ao-column.is-dragging {\n opacity: 0.45;\n}\n.ve-ao-column.is-drop-target {\n border-color: var(--accent);\n box-shadow: 0 0 0 1px var(--accent);\n}\n.ve-ao-column-handle {\n flex-shrink: 0;\n width: 22px;\n align-self: stretch;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n cursor: grab;\n color: var(--text3);\n user-select: none;\n border: none;\n background: transparent;\n font-size: 16px;\n line-height: 1;\n padding: 0;\n letter-spacing: -2px;\n}\n.ve-ao-column-handle:hover {\n color: var(--text2);\n}\n.ve-ao-column-handle:active {\n cursor: grabbing;\n}\n.ve-ao-column-fields {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.ve-ao-column-top {\n display: flex;\n gap: 6px;\n align-items: flex-end;\n}\n.ve-ao-column-field {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n.ve-ao-column-field label {\n font-size: 10px;\n color: var(--text3);\n text-transform: none;\n margin-bottom: 0;\n font-family: var(--font-mono);\n}\n.ve-ao-column-name {\n position: relative;\n min-width: 0;\n}\n.ve-ao-column-name input {\n width: 100%;\n padding-right: 28px;\n font-family: var(--font-mono);\n}\n.ve-ao-column-remove {\n position: absolute;\n right: 0px;\n top: 50%;\n transform: translateY(-50%);\n width: 24px;\n height: 24px;\n padding: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n.ve-ao-column-bottom {\n display: flex;\n gap: 6px;\n align-items: flex-end;\n}\n.ve-ao-column-bottom > .ve-ao-column-field {\n flex: 1;\n min-width: 0;\n}\n.ve-json-issues {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 8px;\n}\n.ve-json-issue-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n background: color-mix(in srgb, var(--yellow) 15%, var(--bg));\n color: var(--yellow);\n border: 1px solid color-mix(in srgb, var(--yellow) 40%, var(--bg));\n border-radius: 10px;\n padding: 2px 8px;\n font-size: 11px;\n cursor: default;\n}\n.ve-modal-back {\n background: none;\n border: none;\n color: var(--accent);\n font-size: 11px;\n cursor: pointer;\n padding: 0 0 4px;\n font-family: var(--font-ui);\n display: block;\n}\n.ve-import-search {\n position: relative;\n margin-bottom: 12px;\n}\n.ve-import-search input {\n padding-left: 28px;\n}\n.ve-import-search::before {\n content: '⌕';\n position: absolute;\n left: 9px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--text3);\n font-size: 14px;\n pointer-events: none;\n}\n.ve-import-section-title {\n font-size: 10.5px;\n color: var(--text3);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin: 14px 0 6px;\n font-weight: 600;\n}\n.ve-import-section-title:first-child {\n margin-top: 0;\n}\n.ve-import-page-list {\n display: flex;\n flex-direction: column;\n gap: 5px;\n}\n.ve-import-page-row {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n text-align: left;\n padding: 8px 10px;\n border: 1px solid var(--border);\n border-radius: 6px;\n background: var(--bg3);\n color: var(--text);\n cursor: pointer;\n font-family: var(--font-ui);\n font-size: 12px;\n}\n.ve-import-page-row:hover {\n border-color: var(--accent);\n}\n.ve-import-page-name {\n font-weight: 500;\n}\n.ve-import-page-slug {\n font-size: 11px;\n color: var(--text3);\n font-family: var(--font-mono);\n margin-left: auto;\n flex-shrink: 0;\n}\n.ve-import-empty {\n padding: 20px 4px;\n text-align: center;\n color: var(--text3);\n font-size: 12px;\n}\n.ve-import-list-head {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 8px;\n}\n.ve-import-list-head .badge {\n background: color-mix(in srgb, var(--green) 18%, var(--bg));\n color: var(--green);\n}\n.ve-import-select-all {\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 11.5px;\n color: var(--text2);\n cursor: pointer;\n text-transform: none;\n}\n.ve-import-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.ve-import-row {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 8px 10px;\n border: 1px solid var(--border);\n border-radius: 6px;\n background: var(--bg3);\n cursor: pointer;\n}\n.ve-import-row input[type='checkbox'] {\n margin-top: 2px;\n flex-shrink: 0;\n}\n.ve-import-row-main {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 3px;\n}\n.ve-import-row-top {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.ve-import-row-name {\n font-family: var(--font-mono);\n font-size: 12px;\n font-weight: 600;\n}\n.ve-import-row-value {\n font-size: 11.5px;\n color: var(--text2);\n font-family: var(--font-mono);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ve-import-swatch {\n width: 12px;\n height: 12px;\n border-radius: 3px;\n border: 1px solid var(--border2);\n flex-shrink: 0;\n display: inline-block;\n vertical-align: -1px;\n margin-right: 5px;\n}\n.ve-import-skip-row {\n display: flex;\n align-items: baseline;\n gap: 8px;\n padding: 7px 10px;\n opacity: 0.85;\n}\n.ve-import-skip-row .ve-import-row-name {\n color: var(--text2);\n}\n.ve-import-skip-reason {\n font-size: 11.5px;\n color: var(--text3);\n}\n::-webkit-scrollbar {\n width: 8px;\n height: 8px;\n}\n::-webkit-scrollbar-track {\n background: var(--bg);\n}\n::-webkit-scrollbar-thumb {\n background: var(--bg4);\n border-radius: 4px;\n}\n\n// A page without a template has no tabs, Refresh, Save or local update: only the message.\nbody[data-template-less='true'] .ve-template-only {\n display: none !important;\n}\n"]}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
6
|
+
<title>Variables Editor — pp-dev</title>
|
|
7
|
+
<script>
|
|
8
|
+
// Set the stored theme override before first paint, so switching pages/reloading doesn't
|
|
9
|
+
// flash the OS-default theme before settling on the user's explicit choice (see setTheme()).
|
|
10
|
+
try {
|
|
11
|
+
var ppDevStoredTheme = localStorage.getItem('pp-dev-info-theme');
|
|
12
|
+
|
|
13
|
+
if (ppDevStoredTheme === 'dark' || ppDevStoredTheme === 'light') {
|
|
14
|
+
document.documentElement.setAttribute('data-pp-dev-theme', ppDevStoredTheme);
|
|
15
|
+
}
|
|
16
|
+
} catch (e) {}
|
|
17
|
+
</script>
|
|
18
|
+
<link rel="stylesheet" href="/@pp-dev/variables-editor/variables-editor.css">
|
|
19
|
+
<script type="module" src="/@pp-dev/variables-editor/variables-editor.js"></script>
|
|
20
|
+
</head>
|
|
21
|
+
<!-- data-template-less: "true" when the page has no template; the CSS then hides .ve-template-only. -->
|
|
22
|
+
<body data-template-less="{{templateLess}}">
|
|
23
|
+
<div class="app">
|
|
24
|
+
<div class="toolbar">
|
|
25
|
+
<span class="toolbar-title">🧩 Variables Editor</span>
|
|
26
|
+
<div class="tabs ve-template-only">
|
|
27
|
+
<button class="tab" id="tab-schema" data-action="switch-tab" data-tab="schema">Schema</button>
|
|
28
|
+
<button class="tab" id="tab-values" data-action="switch-tab" data-tab="values">Values</button>
|
|
29
|
+
</div>
|
|
30
|
+
<span class="ve-loading-indicator ve-template-only" id="loading-indicator" style="display:none"><span class="ve-loading-dot"></span>Refreshing…</span>
|
|
31
|
+
<div class="toolbar-spacer"></div>
|
|
32
|
+
<button class="btn btn-sm ve-template-only" data-action="refresh">↻ Refresh</button>
|
|
33
|
+
<button class="btn btn-sm btn-primary ve-template-only" id="save-btn" data-action="save">Save</button>
|
|
34
|
+
<div class="theme-switch" id="theme-switch">
|
|
35
|
+
<button data-theme-choice="auto" aria-pressed="false">Auto</button>
|
|
36
|
+
<button data-theme-choice="dark" aria-pressed="false">Dark</button>
|
|
37
|
+
<button data-theme-choice="light" aria-pressed="false">Light</button>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
<div class="content" id="content"></div>
|
|
41
|
+
</div>
|
|
42
|
+
<button class="btn btn-sm btn-primary local-update-btn ve-template-only" id="local-update-btn" hidden data-action="update-local-values"></button>
|
|
43
|
+
</body>
|
|
44
|
+
</html>
|