From d2806164a2cddd556b98e6d0d41d082c4f8dc6af Mon Sep 17 00:00:00 2001 From: Nexmoe <16796652+nexmoe@users.noreply.github.com> Date: Sun, 11 Jan 2026 00:05:46 +0800 Subject: [PATCH] feat(extension): integrate local video info API (#67) * feat(extension): integrate local video info API * chore(repo): clean up popup styles * feat(extension): revamp popup UI * chore(repo): revert docs and drop content script --- .gitignore | 2 + extension/.gitignore | 26 + extension/README.md | 3 + extension/assets/content.css | 163 + extension/entrypoints/background.ts | 203 ++ extension/entrypoints/popup/App.css | 291 ++ extension/entrypoints/popup/App.tsx | 415 +++ extension/entrypoints/popup/index.html | 13 + extension/entrypoints/popup/main.tsx | 13 + extension/package.json | 28 + extension/pnpm-lock.yaml | 3541 ++++++++++++++++++++ extension/public/_locales/en/messages.json | 8 + extension/public/icon/128.png | Bin 0 -> 7022 bytes extension/public/icon/16.png | Bin 0 -> 924 bytes extension/public/icon/32.png | Bin 0 -> 1830 bytes extension/public/icon/48.png | Bin 0 -> 2693 bytes extension/public/icon/icon-loading-128.png | Bin 0 -> 7416 bytes extension/public/icon/icon-loading-16.png | Bin 0 -> 744 bytes extension/public/icon/icon-loading-32.png | Bin 0 -> 1777 bytes extension/public/icon/icon-loading-48.png | Bin 0 -> 2696 bytes extension/public/icon/icon-success-128.png | Bin 0 -> 7443 bytes extension/public/icon/icon-success-16.png | Bin 0 -> 751 bytes extension/public/icon/icon-success-32.png | Bin 0 -> 1780 bytes extension/public/icon/icon-success-48.png | Bin 0 -> 2707 bytes extension/tsconfig.json | 7 + extension/wxt.config.ts | 11 + src/main/index.ts | 4 + src/main/local-api.ts | 191 ++ 28 files changed, 4919 insertions(+) create mode 100644 extension/.gitignore create mode 100644 extension/README.md create mode 100644 extension/assets/content.css create mode 100644 extension/entrypoints/background.ts create mode 100644 extension/entrypoints/popup/App.css create mode 100644 extension/entrypoints/popup/App.tsx create mode 100644 extension/entrypoints/popup/index.html create mode 100644 extension/entrypoints/popup/main.tsx create mode 100644 extension/package.json create mode 100644 extension/pnpm-lock.yaml create mode 100644 extension/public/_locales/en/messages.json create mode 100644 extension/public/icon/128.png create mode 100644 extension/public/icon/16.png create mode 100644 extension/public/icon/32.png create mode 100644 extension/public/icon/48.png create mode 100644 extension/public/icon/icon-loading-128.png create mode 100644 extension/public/icon/icon-loading-16.png create mode 100644 extension/public/icon/icon-loading-32.png create mode 100644 extension/public/icon/icon-loading-48.png create mode 100644 extension/public/icon/icon-success-128.png create mode 100644 extension/public/icon/icon-success-16.png create mode 100644 extension/public/icon/icon-success-32.png create mode 100644 extension/public/icon/icon-success-48.png create mode 100644 extension/tsconfig.json create mode 100644 extension/wxt.config.ts create mode 100644 src/main/local-api.ts diff --git a/.gitignore b/.gitignore index 5f89311..c82e942 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ node_modules /dist out .conductor/ +.wxt +.output .DS_Store .eslintcache *.log* diff --git a/extension/.gitignore b/extension/.gitignore new file mode 100644 index 0000000..a256953 --- /dev/null +++ b/extension/.gitignore @@ -0,0 +1,26 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +.output +stats.html +stats-*.json +.wxt +web-ext.config.ts + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/extension/README.md b/extension/README.md new file mode 100644 index 0000000..78cf194 --- /dev/null +++ b/extension/README.md @@ -0,0 +1,3 @@ +# WXT + React + +This template should help get you started developing with React in WXT. diff --git a/extension/assets/content.css b/extension/assets/content.css new file mode 100644 index 0000000..5fc9804 --- /dev/null +++ b/extension/assets/content.css @@ -0,0 +1,163 @@ +.vidbee-download-container { + position: fixed; + bottom: 16px; + right: 16px; + z-index: 9999; + transition: all 0.2s ease; + overflow: visible; +} + +.vidbee-download-container.vidbee-hidden { + opacity: 0; + pointer-events: none; + transform: scale(0); +} + +.vidbee-download-button { + position: relative; + display: flex; + align-items: center; + justify-content: center; + width: 36px; + height: 36px; + padding: 0; + background: rgba(0, 0, 0, 0.5); + backdrop-filter: blur(8px); + -webkit-backdrop-filter: blur(8px); + color: rgba(255, 255, 255, 0.8); + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 50%; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2); + cursor: pointer; + font-size: 0; + transition: all 0.2s ease; + opacity: 0.6; + overflow: visible; +} + +.vidbee-download-button:hover { + opacity: 1; + background: rgba(0, 0, 0, 0.7); + border-color: rgba(255, 255, 255, 0.2); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); + transform: scale(1.1); +} + +.vidbee-download-button:active { + transform: scale(0.95); +} + +.vidbee-download-button svg { + flex-shrink: 0; + stroke: currentColor; + width: 16px; + height: 16px; +} + +.vidbee-tooltip { + position: absolute; + right: calc(100% + 8px); + top: 50%; + padding: 6px 10px; + background: rgba(0, 0, 0, 0.9); + backdrop-filter: blur(8px); + -webkit-backdrop-filter: blur(8px); + color: white; + font-size: 12px; + font-weight: 500; + white-space: nowrap; + border-radius: 4px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); + opacity: 0; + pointer-events: none; + transition: opacity 0.2s ease, transform 0.2s ease; + transform: translateY(-50%) translateX(4px); + z-index: 10000; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, + sans-serif; + line-height: 1; +} + +.vidbee-tooltip::after { + content: ''; + position: absolute; + left: 100%; + top: 50%; + transform: translateY(-50%); + border: 4px solid transparent; + border-left-color: rgba(0, 0, 0, 0.9); +} + +.vidbee-download-button:hover .vidbee-tooltip { + opacity: 1; + transform: translateY(-50%) translateX(0); +} + +.vidbee-close-button { + position: absolute; + top: -6px; + right: -6px; + display: flex; + align-items: center; + justify-content: center; + width: 18px; + height: 18px; + padding: 0; + background: rgba(255, 77, 77, 0.9); + backdrop-filter: blur(4px); + -webkit-backdrop-filter: blur(4px); + color: white; + border: 1px solid rgba(255, 255, 255, 0.2); + border-radius: 50%; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); + cursor: pointer; + font-size: 0; + transition: all 0.2s ease; + z-index: 1; + opacity: 0; + pointer-events: none; + overflow: visible; +} + +.vidbee-download-container:hover .vidbee-close-button { + opacity: 1; + pointer-events: auto; +} + +.vidbee-close-button:hover { + background: rgba(255, 77, 77, 1); + transform: scale(1.15); + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.4); +} + +.vidbee-close-button:active { + transform: scale(0.9); +} + +.vidbee-close-button svg { + flex-shrink: 0; + stroke: currentColor; + width: 10px; + height: 10px; +} + +.vidbee-close-button .vidbee-tooltip { + right: calc(100% + 6px); + top: 50%; + left: auto; + transform: translateY(-50%) translateX(4px); +} + +.vidbee-close-button .vidbee-tooltip::after { + left: 100%; + top: 50%; + right: auto; + transform: translateY(-50%); + border-left-color: rgba(0, 0, 0, 0.9); + border-top-color: transparent; +} + +.vidbee-download-container:hover .vidbee-close-button:hover .vidbee-tooltip { + opacity: 1; + transform: translateY(-50%) translateX(0); +} diff --git a/extension/entrypoints/background.ts b/extension/entrypoints/background.ts new file mode 100644 index 0000000..2b2a7f7 --- /dev/null +++ b/extension/entrypoints/background.ts @@ -0,0 +1,203 @@ +type VideoFormat = { + format_id?: string + ext?: string + format_note?: string + resolution?: string + width?: number + height?: number + fps?: number + vcodec?: string + acodec?: string + filesize?: number + filesize_approx?: number + tbr?: number +} + +type VideoInfo = { + title?: string + thumbnail?: string + duration?: number + formats?: VideoFormat[] +} + +type VideoInfoCacheEntry = { + url: string + status: 'pending' | 'ready' | 'error' + fetchedAt: number + info?: VideoInfo + error?: string +} + +const PORT_RANGE_START = 27100 +const PORT_RANGE_END = 27120 +const STATUS_TIMEOUT_MS = 800 +const INFO_TIMEOUT_MS = 60000 +const CACHE_TTL_MS = 5 * 60 * 1000 + +const pendingRequests = new Map>() +const defaultIconPaths = { + 16: 'icon/16.png', + 32: 'icon/32.png', + 48: 'icon/48.png', + 128: 'icon/128.png' +} +const loadingIconPaths = { + 16: 'icon/icon-loading-16.png', + 32: 'icon/icon-loading-32.png', + 48: 'icon/icon-loading-48.png', + 128: 'icon/icon-loading-128.png' +} +const successIconPaths = { + 16: 'icon/icon-success-16.png', + 32: 'icon/icon-success-32.png', + 48: 'icon/icon-success-48.png', + 128: 'icon/icon-success-128.png' +} + +const setActionIcon = (status: 'default' | 'loading' | 'success', tabId?: number): void => { + const paths = + status === 'loading' + ? loadingIconPaths + : status === 'success' + ? successIconPaths + : defaultIconPaths + const options = tabId ? { path: paths, tabId } : { path: paths } + void browser.action.setIcon(options) +} + +const fetchJson = async (url: string, timeoutMs: number): Promise => { + const controller = new AbortController() + const timeoutId = setTimeout(() => controller.abort('timeout'), timeoutMs) + + try { + const response = await fetch(url, { signal: controller.signal }) + const data = (await response.json().catch(() => null)) as (T & { error?: string }) | null + if (!response.ok) { + const message = data && typeof data === 'object' && 'error' in data ? data.error : null + const details = data && typeof data === 'object' && 'details' in data ? data.details : null + const combined = [message, details].filter(Boolean).join('\n\n') + throw new Error(combined || `Request failed: ${response.status}`) + } + return data as T + } catch (error) { + if (error instanceof DOMException && error.name === 'AbortError') { + throw new Error('Request timed out.') + } + if (error instanceof Error && error.message.includes('signal is aborted')) { + throw new Error('Request timed out.') + } + if (error instanceof Error && error.message.includes('Failed to fetch')) { + throw new Error('VidBee app not responding on this port.') + } + throw error + } finally { + clearTimeout(timeoutId) + } +} + +const findAvailablePort = async (): Promise => { + for (let port = PORT_RANGE_START; port <= PORT_RANGE_END; port += 1) { + const baseUrl = `http://127.0.0.1:${port}` + try { + await fetchJson<{ ok: boolean }>(`${baseUrl}/status`, STATUS_TIMEOUT_MS) + return port + } catch { + // Keep scanning. + } + } + return null +} + +const requestVideoInfo = async (targetUrl: string): Promise => { + const port = await findAvailablePort() + if (!port) { + throw new Error('VidBee app not found on localhost.') + } + + const baseUrl = `http://127.0.0.1:${port}` + const tokenResponse = await fetchJson<{ token?: string }>(`${baseUrl}/token`, STATUS_TIMEOUT_MS) + if (!tokenResponse.token) { + throw new Error('Failed to acquire token from VidBee.') + } + + return fetchJson( + `${baseUrl}/video-info?url=${encodeURIComponent(targetUrl)}&token=${encodeURIComponent( + tokenResponse.token + )}`, + INFO_TIMEOUT_MS + ) +} + +const getCacheMap = async (): Promise> => { + const data = await browser.storage.local.get('videoInfoCacheByUrl') + const map = data.videoInfoCacheByUrl as Record | undefined + if (!map) return {} + return map +} + +const pruneCache = (map: Record): void => { + const now = Date.now() + for (const [key, entry] of Object.entries(map)) { + if (now - entry.fetchedAt > CACHE_TTL_MS) { + delete map[key] + } + } +} + +const loadCache = async (url: string): Promise => { + const map = await getCacheMap() + pruneCache(map) + const cache = map[url] + if (!cache) return null + return cache +} + +const saveCacheEntry = async (cache: VideoInfoCacheEntry): Promise => { + const map = await getCacheMap() + pruneCache(map) + map[cache.url] = cache + await browser.storage.local.set({ videoInfoCacheByUrl: map }) +} + +const fetchAndCache = async (url: string, tabId?: number): Promise => { + if (pendingRequests.has(url)) { + return pendingRequests.get(url) as Promise + } + + const task = (async () => { + const existing = await loadCache(url) + if (existing?.status === 'ready') { + setActionIcon('success', tabId) + return + } + + setActionIcon('loading', tabId) + await saveCacheEntry({ url, status: 'pending', fetchedAt: Date.now() }) + + try { + const info = await requestVideoInfo(url) + await saveCacheEntry({ url, status: 'ready', fetchedAt: Date.now(), info }) + setActionIcon('success', tabId) + } catch (error) { + const message = error instanceof Error ? error.message : 'Failed to fetch video info.' + await saveCacheEntry({ url, status: 'error', fetchedAt: Date.now(), error: message }) + setActionIcon('default', tabId) + } + })() + + pendingRequests.set(url, task) + try { + await task + } finally { + pendingRequests.delete(url) + } +} + +export default defineBackground(() => { + browser.runtime.onMessage.addListener((message: { type?: string; url?: string }, sender) => { + if (message.type !== 'video-info:fetch' || !message.url) { + return + } + void fetchAndCache(message.url, sender.tab?.id) + }) +}) diff --git a/extension/entrypoints/popup/App.css b/extension/entrypoints/popup/App.css new file mode 100644 index 0000000..9c8e3b6 --- /dev/null +++ b/extension/entrypoints/popup/App.css @@ -0,0 +1,291 @@ +:root { + --bg: #ffffff; + --fg: #111111; + --fg-secondary: #757575; + --border: #f0f0f0; + --accent: #000000; + --error: #e00000; + --success: #00c853; + --warning: #ffd600; +} + +body { + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; + -webkit-font-smoothing: antialiased; + background: var(--bg); + color: var(--fg); +} + +#root { + width: 360px; + min-height: 200px; + padding: 24px; + box-sizing: border-box; +} + +.app { + display: flex; + flex-direction: column; + gap: 24px; +} + +header { + display: flex; + justify-content: space-between; + align-items: center; +} + +h1 { + font-size: 13px; + font-weight: 600; + margin: 0; + letter-spacing: -0.01em; + color: var(--fg); +} + +.status-indicator { + font-size: 11px; + font-weight: 500; + color: var(--fg-secondary); + display: flex; + align-items: center; + gap: 6px; +} + +.status-dot { + width: 6px; + height: 6px; + border-radius: 50%; + background-color: var(--border); +} +.status-dot.loading { background-color: var(--warning); box-shadow: 0 0 4px var(--warning); } +.status-dot.ok { background-color: var(--success); } +.status-dot.error { background-color: var(--error); } + +.video-info { + display: grid; + grid-template-columns: 1fr 90px; + gap: 20px; + align-items: start; +} + +.video-details h2 { + font-size: 15px; + font-weight: 500; + line-height: 1.4; + margin: 0 0 8px 0; + color: var(--fg); +} + +.meta-row { + font-size: 12px; + color: var(--fg-secondary); + margin: 0 0 4px 0; + display: flex; + align-items: center; + gap: 8px; +} + +.thumbnail { + width: 90px; + height: 50px; + background: var(--border); + object-fit: cover; + border-radius: 6px; + display: block; +} + +.formats-section { + display: flex; + flex-direction: column; + gap: 20px; +} + +.format-group { + display: flex; + flex-direction: column; + gap: 8px; +} + +/* Sticky headers for long lists */ +.sticky-title { + position: sticky; + top: 0; + background: var(--bg); + padding: 4px 0; + z-index: 10; +} + +.group-title { + font-size: 11px; + text-transform: uppercase; + letter-spacing: 0.05em; + color: var(--fg-secondary); + font-weight: 600; + border-bottom: 2px solid var(--border); + padding-bottom: 4px; +} + +.format-table { + width: 100%; + border-collapse: collapse; + font-size: 12px; + table-layout: fixed; +} + +.format-table th { + text-align: left; + font-weight: 400; + color: var(--fg-secondary); + padding-bottom: 6px; + border-bottom: 1px solid var(--border); + font-size: 10px; + text-transform: uppercase; + padding-top: 6px; +} + +.format-table td { + padding: 6px 0; + border-bottom: 1px solid var(--border); + color: var(--fg); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.format-table tr:last-child td { + border-bottom: none; +} + +.col-id { width: 50px; color: var(--fg-secondary); } +.col-ext { width: 50px; } +.col-size { width: 60px; text-align: right; } +.format-table th.col-size { text-align: right; } + +.empty-state { + font-size: 12px; + color: var(--fg-secondary); + padding: 12px 0; + font-style: italic; + text-align: center; +} + +.error-banner { + font-size: 12px; + color: var(--error); + line-height: 1.5; + background: rgba(224, 0, 0, 0.05); + padding: 12px; + border-radius: 6px; +} + +.primary-button { + background: var(--fg); + color: var(--bg); + border: none; + border-radius: 8px; + padding: 12px; + font-size: 13px; + font-weight: 500; + cursor: pointer; + width: 100%; + transition: opacity 0.2s; +} + +.primary-button:hover { + opacity: 0.9; +} + +.primary-button:active { + transform: scale(0.98); +} + + +.error-container { + display: flex; + flex-direction: column; + gap: 12px; +} + +.troubleshoot-box { + background: var(--border); + padding: 12px; + border-radius: 6px; + display: flex; + flex-direction: column; + gap: 8px; +} + +.troubleshoot-title { + font-size: 11px; + font-weight: 600; + color: var(--fg-secondary); + margin: 0; + text-transform: uppercase; + letter-spacing: 0.05em; +} + +.troubleshoot-actions { + display: flex; + align-items: center; + gap: 8px; + font-size: 13px; +} + +.link-button { + background: none; + border: none; + padding: 0; + color: var(--accent); + text-decoration: none; + font-weight: 500; + cursor: pointer; + font-family: inherit; + font-size: inherit; +} + +.link-button:hover { + text-decoration: underline; +} + +.divider { + color: var(--fg-secondary); +} + + +.loading-container { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + min-height: 200px; + gap: 16px; + flex: 1; + width: 100%; +} + +.spinner { + width: 24px; + height: 24px; + border: 2.5px solid var(--border); + border-top-color: var(--fg); + border-radius: 50%; + animation: spin 0.8s linear infinite; +} + +.loading-text { + font-size: 13px; + font-weight: 500; + color: var(--fg-secondary); + animation: pulse 1.5s ease-in-out infinite; +} + +@keyframes spin { + to { transform: rotate(360deg); } +} + +@keyframes pulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.6; } +} diff --git a/extension/entrypoints/popup/App.tsx b/extension/entrypoints/popup/App.tsx new file mode 100644 index 0000000..dd074b3 --- /dev/null +++ b/extension/entrypoints/popup/App.tsx @@ -0,0 +1,415 @@ +import { useEffect, useMemo, useState } from 'react' +import './App.css' + +type VideoFormat = { + format_id?: string + ext?: string + format_note?: string + resolution?: string + width?: number + height?: number + fps?: number + vcodec?: string + acodec?: string + filesize?: number + filesize_approx?: number + tbr?: number +} + +type VideoInfo = { + title?: string + thumbnail?: string + duration?: number + formats?: VideoFormat[] +} + +const CACHE_TTL_MS = 60 * 60 * 1000 + +const isValidHttpUrl = (value?: string): boolean => { + if (!value) return false + return value.startsWith('http://') || value.startsWith('https://') +} + +const formatDuration = (value?: number): string => { + if (!value || value <= 0) return 'Unknown' + const totalSeconds = Math.round(value) + const hours = Math.floor(totalSeconds / 3600) + const minutes = Math.floor((totalSeconds % 3600) / 60) + const seconds = totalSeconds % 60 + const paddedMinutes = hours > 0 ? String(minutes).padStart(2, '0') : String(minutes) + const paddedSeconds = String(seconds).padStart(2, '0') + return hours > 0 ? `${hours}:${paddedMinutes}:${paddedSeconds}` : `${minutes}:${paddedSeconds}` +} + +const formatBytes = (value?: number): string => { + if (!value || value <= 0) return '-' + const units = ['B', 'KB', 'MB', 'GB'] + let size = value + let unitIndex = 0 + while (size >= 1024 && unitIndex < units.length - 1) { + size /= 1024 + unitIndex += 1 + } + return `${size.toFixed(size >= 100 || unitIndex === 0 ? 0 : 1)} ${units[unitIndex]}` +} + +const isVideoFormat = (format: VideoFormat): boolean => { + if (format.vcodec && format.vcodec !== 'none') { + return true + } + return Boolean(format.resolution || format.width || format.height) +} + +const isAudioFormat = (format: VideoFormat): boolean => { + return Boolean(format.acodec && format.acodec !== 'none' && !isVideoFormat(format)) +} + +type VideoInfoCacheEntry = { + url: string + status: 'pending' | 'ready' | 'error' + fetchedAt: number + info?: VideoInfo + error?: string +} + +type VideoGroup = { + label: string + height: number + formats: VideoFormat[] +} + +const loadCachedInfo = async (url: string): Promise => { + const data = await browser.storage.local.get('videoInfoCacheByUrl') + const map = data.videoInfoCacheByUrl as Record | undefined + if (!map) return null + const cached = map[url] + if (!cached) return null + if (Date.now() - cached.fetchedAt > CACHE_TTL_MS) return null + return cached +} + +const sanitizeError = (error: string): string => { + const message = error.toLowerCase() + if ( + message.includes('localhost') || + message.includes('fetch') || + message.includes('network') || + message.includes('connect') || + message.includes('failed to request') + ) { + return 'Client connection failed' + } + return error +} + +function App() { + const [info, setInfo] = useState(null) + const [error, setError] = useState(null) + const [loading, setLoading] = useState(false) + const [currentUrl, setCurrentUrl] = useState('') + const [retryTrigger, setRetryTrigger] = useState(0) + + useEffect(() => { + let active = true + const targetState = { url: '' } + + const handleStorageChange = ( + changes: Record, + areaName: string + ) => { + if (!active || areaName !== 'local') return + const change = changes.videoInfoCacheByUrl + if (!change?.newValue) return + + const map = change.newValue as Record + const next = map[targetState.url] + if (!next) return + + if (next.status === 'ready' && next.info) { + setInfo(next.info) + setError(null) + setLoading(false) + } else if (next.status === 'error' && next.error) { + setError(sanitizeError(next.error)) + setInfo(null) + setLoading(false) + } else if (next.status === 'pending') { + setLoading(true) + } + } + + browser.storage.onChanged.addListener(handleStorageChange) + + const loadInfo = async () => { + setLoading(true) + setError(null) + setInfo(null) + + const [tab] = await browser.tabs.query({ active: true, currentWindow: true }) + if (!isValidHttpUrl(tab?.url)) { + setError('Please open a valid video page first.') + setLoading(false) + return + } + + const targetUrl = tab.url as string + targetState.url = targetUrl + setCurrentUrl(targetUrl) + + const cached = await loadCachedInfo(targetUrl) + const shouldBypassCache = retryTrigger > 0 + if (cached && !shouldBypassCache) { + if (cached.status === 'ready' && cached.info) { + setInfo(cached.info) + setLoading(false) + return + } + if (cached.status === 'error' && cached.error) { + setError(sanitizeError(cached.error)) + setLoading(false) + return + } + } + + try { + await browser.runtime.sendMessage({ + type: 'video-info:fetch', + url: targetUrl + }) + } catch (err) { + const message = err instanceof Error ? err.message : 'Failed to request video info.' + setError(sanitizeError(message)) + setLoading(false) + } + + const latest = await loadCachedInfo(targetUrl) + if (latest && latest.status === 'ready' && latest.info) { + setInfo(latest.info) + setError(null) + setLoading(false) + } else if (latest && latest.status === 'error' && latest.error) { + setError(sanitizeError(latest.error)) + setInfo(null) + setLoading(false) + } + } + + void loadInfo() + + return () => { + active = false + browser.storage.onChanged.removeListener(handleStorageChange) + } + }, [retryTrigger]) + + const formats = useMemo(() => info?.formats ?? [], [info]) + const groupedFormats = useMemo(() => { + const video: VideoFormat[] = [] + const audio: VideoFormat[] = [] + const other: VideoFormat[] = [] + + for (const format of formats) { + if (isVideoFormat(format)) { + video.push(format) + } else if (isAudioFormat(format)) { + audio.push(format) + } else { + other.push(format) + } + } + + return { video, audio, other } + }, [formats]) + + const groupedVideoFormats = useMemo(() => { + const raw = groupedFormats.video + if (!raw.length) return [] + + const groups: Record = {} + const noHeight: VideoFormat[] = [] + + for (const f of raw) { + const h = f.height || f.resolution?.match(/x(\d+)/)?.[1] + const heightVal = h ? Number(h) : 0 + + if (heightVal > 0) { + if (!groups[heightVal]) groups[heightVal] = [] + groups[heightVal].push(f) + } else { + noHeight.push(f) + } + } + + const sortedLabels = Object.keys(groups) + .map(Number) + .sort((a, b) => b - a) + + const result: VideoGroup[] = sortedLabels.map((h) => ({ + label: `${h}p`, + height: h, + formats: groups[h].sort((a, b) => { + const sa = a.filesize || a.filesize_approx || 0 + const sb = b.filesize || b.filesize_approx || 0 + return sb - sa + }) + })) + + if (noHeight.length > 0) { + result.push({ + label: 'Other', + height: 0, + formats: noHeight + }) + } + + return result + }, [groupedFormats.video]) + + const handleOpenClient = () => { + if (!currentUrl) return + const deepLink = `vidbee://download?url=${encodeURIComponent(currentUrl)}` + window.location.href = deepLink + } + + const renderStatus = () => { + // if (loading) return null + if (error) + return ( + +
Error + + ) + if (info) + return ( + +
Ready + + ) + return ( + +
Idle + + ) + } + + return ( +
+
+

VidBee

+ {renderStatus()} +
+ {loading && ( +
+
+
Analyzing video...
+
+ )} + + {!loading && error && ( +
+
{error}
+
+

Having trouble?

+
+ + + + Download + +
+
+
+ )} + + {!loading && !error && info && ( + <> +
+
+

{info.title || 'Untitled video'}

+
+ {formatDuration(info.duration)} + + {formats.length} formats +
+
+ {info.thumbnail && } +
+ + + +
+ {groupedVideoFormats.map((group) => ( +
+
{group.label}
+ + + + + + + + + + {group.formats.map((f) => ( + + + + + + ))} + +
IDExtSize
{f.format_id || '-'}{f.ext || '-'}{formatBytes(f.filesize || f.filesize_approx)}
+
+ ))} + + {groupedVideoFormats.length === 0 && groupedFormats.audio.length === 0 && ( +
No compatible formats.
+ )} + + {groupedFormats.audio.length > 0 && ( +
+
Audio Only
+ + + + + + + + + + {groupedFormats.audio.map((f) => ( + + + + + + ))} + +
IDExtSize
{f.format_id || '-'}{f.ext || '-'}{formatBytes(f.filesize || f.filesize_approx)}
+
+ )} +
+ + )} +
+ ) +} + +export default App diff --git a/extension/entrypoints/popup/index.html b/extension/entrypoints/popup/index.html new file mode 100644 index 0000000..ed4cb94 --- /dev/null +++ b/extension/entrypoints/popup/index.html @@ -0,0 +1,13 @@ + + + + + + Default Popup Title + + + +
+ + + diff --git a/extension/entrypoints/popup/main.tsx b/extension/entrypoints/popup/main.tsx new file mode 100644 index 0000000..dac9d4a --- /dev/null +++ b/extension/entrypoints/popup/main.tsx @@ -0,0 +1,13 @@ +import React from 'react' +import ReactDOM from 'react-dom/client' +import App from './App.tsx' + +const root = document.getElementById('root') + +if (root) { + ReactDOM.createRoot(root).render( + + + + ) +} diff --git a/extension/package.json b/extension/package.json new file mode 100644 index 0000000..980316c --- /dev/null +++ b/extension/package.json @@ -0,0 +1,28 @@ +{ + "name": "wxt-react-starter", + "description": "manifest.json description", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "wxt", + "dev:firefox": "wxt -b firefox", + "build": "wxt build", + "build:firefox": "wxt build -b firefox", + "zip": "wxt zip", + "zip:firefox": "wxt zip -b firefox", + "compile": "tsc --noEmit", + "postinstall": "wxt prepare" + }, + "dependencies": { + "react": "^19.2.3", + "react-dom": "^19.2.3" + }, + "devDependencies": { + "@types/react": "^19.2.7", + "@types/react-dom": "^19.2.3", + "@wxt-dev/module-react": "^1.1.5", + "typescript": "^5.9.3", + "wxt": "^0.20.6" + } +} diff --git a/extension/pnpm-lock.yaml b/extension/pnpm-lock.yaml new file mode 100644 index 0000000..53cb139 --- /dev/null +++ b/extension/pnpm-lock.yaml @@ -0,0 +1,3541 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + react: + specifier: ^19.2.3 + version: 19.2.3 + react-dom: + specifier: ^19.2.3 + version: 19.2.3(react@19.2.3) + devDependencies: + '@types/react': + specifier: ^19.2.7 + version: 19.2.7 + '@types/react-dom': + specifier: ^19.2.3 + version: 19.2.3(@types/react@19.2.7) + '@wxt-dev/module-react': + specifier: ^1.1.5 + version: 1.1.5(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1))(wxt@0.20.13(@types/node@25.0.3)(jiti@2.6.1)(rollup@4.54.0)) + typescript: + specifier: ^5.9.3 + version: 5.9.3 + wxt: + specifier: ^0.20.6 + version: 0.20.13(@types/node@25.0.3)(jiti@2.6.1)(rollup@4.54.0) + +packages: + + '@1natsu/wait-element@4.1.2': + resolution: {integrity: sha512-qWxSJD+Q5b8bKOvESFifvfZ92DuMsY+03SBNjTO34ipJLP6mZ9yK4bQz/vlh48aEQXoJfaZBqUwKL5BdI5iiWw==} + + '@aklinker1/rollup-plugin-visualizer@5.12.0': + resolution: {integrity: sha512-X24LvEGw6UFmy0lpGJDmXsMyBD58XmX1bbwsaMLhNoM+UMQfQ3b2RtC+nz4b/NoRK5r6QJSKJHBNVeUdwqybaQ==} + engines: {node: '>=14'} + hasBin: true + peerDependencies: + rollup: 2.x || 3.x || 4.x + peerDependenciesMeta: + rollup: + optional: true + + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.28.5': + resolution: {integrity: sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.28.5': + resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.28.5': + resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.27.2': + resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.27.1': + resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.3': + resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.28.4': + resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.28.5': + resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-transform-react-jsx-self@7.27.1': + resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-source@7.27.1': + resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime@7.28.2': + resolution: {integrity: sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.27.2': + resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.28.5': + resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.28.5': + resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + engines: {node: '>=6.9.0'} + + '@devicefarmer/adbkit-logcat@2.1.3': + resolution: {integrity: sha512-yeaGFjNBc/6+svbDeul1tNHtNChw6h8pSHAt5D+JsedUrMTN7tla7B15WLDyekxsuS2XlZHRxpuC6m92wiwCNw==} + engines: {node: '>= 4'} + + '@devicefarmer/adbkit-monkey@1.2.1': + resolution: {integrity: sha512-ZzZY/b66W2Jd6NHbAhLyDWOEIBWC11VizGFk7Wx7M61JZRz7HR9Cq5P+65RKWUU7u6wgsE8Lmh9nE4Mz+U2eTg==} + engines: {node: '>= 0.10.4'} + + '@devicefarmer/adbkit@3.3.8': + resolution: {integrity: sha512-7rBLLzWQnBwutH2WZ0EWUkQdihqrnLYCUMaB44hSol9e0/cdIhuNFcqZO0xNheAU6qqHVA8sMiLofkYTgb+lmw==} + engines: {node: '>= 0.10.4'} + hasBin: true + + '@esbuild/aix-ppc64@0.27.2': + resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.27.2': + resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.27.2': + resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.27.2': + resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.27.2': + resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.27.2': + resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.27.2': + resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.27.2': + resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.27.2': + resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.27.2': + resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.27.2': + resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.27.2': + resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.27.2': + resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.27.2': + resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.27.2': + resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.27.2': + resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.27.2': + resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.27.2': + resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.27.2': + resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.27.2': + resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.27.2': + resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.27.2': + resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.27.2': + resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.27.2': + resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.27.2': + resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.27.2': + resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@isaacs/balanced-match@4.0.1': + resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} + engines: {node: 20 || >=22} + + '@isaacs/brace-expansion@5.0.0': + resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} + engines: {node: 20 || >=22} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@pnpm/config.env-replace@1.1.0': + resolution: {integrity: sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==} + engines: {node: '>=12.22.0'} + + '@pnpm/network.ca-file@1.0.2': + resolution: {integrity: sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==} + engines: {node: '>=12.22.0'} + + '@pnpm/npm-conf@2.3.1': + resolution: {integrity: sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==} + engines: {node: '>=12'} + + '@rolldown/pluginutils@1.0.0-beta.53': + resolution: {integrity: sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==} + + '@rollup/rollup-android-arm-eabi@4.54.0': + resolution: {integrity: sha512-OywsdRHrFvCdvsewAInDKCNyR3laPA2mc9bRYJ6LBp5IyvF3fvXbbNR0bSzHlZVFtn6E0xw2oZlyjg4rKCVcng==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.54.0': + resolution: {integrity: sha512-Skx39Uv+u7H224Af+bDgNinitlmHyQX1K/atIA32JP3JQw6hVODX5tkbi2zof/E69M1qH2UoN3Xdxgs90mmNYw==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.54.0': + resolution: {integrity: sha512-k43D4qta/+6Fq+nCDhhv9yP2HdeKeP56QrUUTW7E6PhZP1US6NDqpJj4MY0jBHlJivVJD5P8NxrjuobZBJTCRw==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.54.0': + resolution: {integrity: sha512-cOo7biqwkpawslEfox5Vs8/qj83M/aZCSSNIWpVzfU2CYHa2G3P1UN5WF01RdTHSgCkri7XOlTdtk17BezlV3A==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.54.0': + resolution: {integrity: sha512-miSvuFkmvFbgJ1BevMa4CPCFt5MPGw094knM64W9I0giUIMMmRYcGW/JWZDriaw/k1kOBtsWh1z6nIFV1vPNtA==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.54.0': + resolution: {integrity: sha512-KGXIs55+b/ZfZsq9aR026tmr/+7tq6VG6MsnrvF4H8VhwflTIuYh+LFUlIsRdQSgrgmtM3fVATzEAj4hBQlaqQ==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.54.0': + resolution: {integrity: sha512-EHMUcDwhtdRGlXZsGSIuXSYwD5kOT9NVnx9sqzYiwAc91wfYOE1g1djOEDseZJKKqtHAHGwnGPQu3kytmfaXLQ==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.54.0': + resolution: {integrity: sha512-+pBrqEjaakN2ySv5RVrj/qLytYhPKEUwk+e3SFU5jTLHIcAtqh2rLrd/OkbNuHJpsBgxsD8ccJt5ga/SeG0JmA==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.54.0': + resolution: {integrity: sha512-NSqc7rE9wuUaRBsBp5ckQ5CVz5aIRKCwsoa6WMF7G01sX3/qHUw/z4pv+D+ahL1EIKy6Enpcnz1RY8pf7bjwng==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.54.0': + resolution: {integrity: sha512-gr5vDbg3Bakga5kbdpqx81m2n9IX8M6gIMlQQIXiLTNeQW6CucvuInJ91EuCJ/JYvc+rcLLsDFcfAD1K7fMofg==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.54.0': + resolution: {integrity: sha512-gsrtB1NA3ZYj2vq0Rzkylo9ylCtW/PhpLEivlgWe0bpgtX5+9j9EZa0wtZiCjgu6zmSeZWyI/e2YRX1URozpIw==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.54.0': + resolution: {integrity: sha512-y3qNOfTBStmFNq+t4s7Tmc9hW2ENtPg8FeUD/VShI7rKxNW7O4fFeaYbMsd3tpFlIg1Q8IapFgy7Q9i2BqeBvA==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.54.0': + resolution: {integrity: sha512-89sepv7h2lIVPsFma8iwmccN7Yjjtgz0Rj/Ou6fEqg3HDhpCa+Et+YSufy27i6b0Wav69Qv4WBNl3Rs6pwhebQ==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.54.0': + resolution: {integrity: sha512-ZcU77ieh0M2Q8Ur7D5X7KvK+UxbXeDHwiOt/CPSBTI1fBmeDMivW0dPkdqkT4rOgDjrDDBUed9x4EgraIKoR2A==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.54.0': + resolution: {integrity: sha512-2AdWy5RdDF5+4YfG/YesGDDtbyJlC9LHmL6rZw6FurBJ5n4vFGupsOBGfwMRjBYH7qRQowT8D/U4LoSvVwOhSQ==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.54.0': + resolution: {integrity: sha512-WGt5J8Ij/rvyqpFexxk3ffKqqbLf9AqrTBbWDk7ApGUzaIs6V+s2s84kAxklFwmMF/vBNGrVdYgbblCOFFezMQ==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.54.0': + resolution: {integrity: sha512-JzQmb38ATzHjxlPHuTH6tE7ojnMKM2kYNzt44LO/jJi8BpceEC8QuXYA908n8r3CNuG/B3BV8VR3Hi1rYtmPiw==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openharmony-arm64@4.54.0': + resolution: {integrity: sha512-huT3fd0iC7jigGh7n3q/+lfPcXxBi+om/Rs3yiFxjvSxbSB6aohDFXbWvlspaqjeOh+hx7DDHS+5Es5qRkWkZg==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.54.0': + resolution: {integrity: sha512-c2V0W1bsKIKfbLMBu/WGBz6Yci8nJ/ZJdheE0EwB73N3MvHYKiKGs3mVilX4Gs70eGeDaMqEob25Tw2Gb9Nqyw==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.54.0': + resolution: {integrity: sha512-woEHgqQqDCkAzrDhvDipnSirm5vxUXtSKDYTVpZG3nUdW/VVB5VdCYA2iReSj/u3yCZzXID4kuKG7OynPnB3WQ==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.54.0': + resolution: {integrity: sha512-dzAc53LOuFvHwbCEOS0rPbXp6SIhAf2txMP5p6mGyOXXw5mWY8NGGbPMPrs4P1WItkfApDathBj/NzMLUZ9rtQ==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.54.0': + resolution: {integrity: sha512-hYT5d3YNdSh3mbCU1gwQyPgQd3T2ne0A3KG8KSBdav5TiBg6eInVmV+TeR5uHufiIgSFg0XsOWGW5/RhNcSvPg==} + cpu: [x64] + os: [win32] + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/filesystem@0.0.36': + resolution: {integrity: sha512-vPDXOZuannb9FZdxgHnqSwAG/jvdGM8Wq+6N4D/d80z+D4HWH+bItqsZaVRQykAn6WEVeEkLm2oQigyHtgb0RA==} + + '@types/filewriter@0.0.33': + resolution: {integrity: sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g==} + + '@types/har-format@1.2.16': + resolution: {integrity: sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A==} + + '@types/minimatch@3.0.5': + resolution: {integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==} + + '@types/node@25.0.3': + resolution: {integrity: sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==} + + '@types/react-dom@19.2.3': + resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} + peerDependencies: + '@types/react': ^19.2.0 + + '@types/react@19.2.7': + resolution: {integrity: sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==} + + '@vitejs/plugin-react@5.1.2': + resolution: {integrity: sha512-EcA07pHJouywpzsoTUqNh5NwGayl2PPVEJKUSinGGSxFGYn+shYbqMGBg6FXDqgXum9Ou/ecb+411ssw8HImJQ==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + + '@webext-core/fake-browser@1.3.4': + resolution: {integrity: sha512-nZcVWr3JpwpS5E6hKpbAwAMBM/AXZShnfW0F76udW8oLd6Kv0nbW6vFS07md4Na/0ntQonk3hFnlQYGYBAlTrA==} + + '@webext-core/isolated-element@1.1.3': + resolution: {integrity: sha512-rbtnReIGdiVQb2UhK3MiECU6JqsiIo2K/luWvOdOw57Ot770Iw4KLCEPXUQMITIH5V5er2jfVK8hSWXaEOQGNQ==} + + '@webext-core/match-patterns@1.0.3': + resolution: {integrity: sha512-NY39ACqCxdKBmHgw361M9pfJma8e4AZo20w9AY+5ZjIj1W2dvXC8J31G5fjfOGbulW9w4WKpT8fPooi0mLkn9A==} + + '@wxt-dev/browser@0.1.32': + resolution: {integrity: sha512-jvfSppeLzlH4sOkIvMBJoA1pKoI+U5gTkjDwMKdkTWh0P/fj+KDyze3lzo3S6372viCm8tXUKNez+VKyVz2ZDw==} + + '@wxt-dev/module-react@1.1.5': + resolution: {integrity: sha512-KgsUrsgH5rBT8MwiipnDEOHBXmLvTIdFICrI7KjngqSf9DpVRn92HsKmToxY0AYpkP19hHWta2oNYFTzmmm++g==} + peerDependencies: + wxt: '>=0.19.16' + + '@wxt-dev/storage@1.2.6': + resolution: {integrity: sha512-f6AknnpJvhNHW4s0WqwSGCuZAj0fjP3EVNPBO5kB30pY+3Zt/nqZGqJN6FgBLCSkYjPJ8VL1hNX5LMVmvxQoDw==} + + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + + adm-zip@0.5.16: + resolution: {integrity: sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==} + engines: {node: '>=12.0'} + + ansi-align@3.0.1: + resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} + + ansi-escapes@7.2.0: + resolution: {integrity: sha512-g6LhBsl+GBPRWGWsBtutpzBYuIIdBkLEvad5C/va/74Db018+5TZiyA26cZJAr3Rft5lprVqOIPxf5Vid6tqAw==} + engines: {node: '>=18'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + + array-differ@4.0.0: + resolution: {integrity: sha512-Q6VPTLMsmXZ47ENG3V+wQyZS1ZxXMxFyYzA+Z/GMrJ6yIutAIEf9wTyroTzmGjNfox9/h3GdGBCVh43GVFx4Uw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + array-union@3.0.1: + resolution: {integrity: sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw==} + engines: {node: '>=12'} + + async-mutex@0.5.0: + resolution: {integrity: sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==} + + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + + atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} + + atomically@2.1.0: + resolution: {integrity: sha512-+gDffFXRW6sl/HCwbta7zK4uNqbPjv4YJEAdz7Vu+FLQHe77eZ4bvbJGi4hE0QPeJlMYMA3piXEr1UL3dAwx7Q==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + baseline-browser-mapping@2.9.11: + resolution: {integrity: sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==} + hasBin: true + + bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + boxen@8.0.1: + resolution: {integrity: sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==} + engines: {node: '>=18'} + + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.28.1: + resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} + + c12@3.3.3: + resolution: {integrity: sha512-750hTRvgBy5kcMNPdh95Qo+XUBeGo8C7nsKSmedDmaQI+E0r82DwHeM6vBewDe4rGFbnxoa4V9pw+sPh5+Iz8Q==} + peerDependencies: + magicast: '*' + peerDependenciesMeta: + magicast: + optional: true + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + camelcase@8.0.0: + resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==} + engines: {node: '>=16'} + + caniuse-lite@1.0.30001762: + resolution: {integrity: sha512-PxZwGNvH7Ak8WX5iXzoK1KPZttBXNPuaOvI2ZYU7NrlM+d9Ov+TUvlLOBNGzVXAntMSMMlJPd+jY6ovrVjSmUw==} + + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + + chrome-launcher@1.2.0: + resolution: {integrity: sha512-JbuGuBNss258bvGil7FT4HKdC3SC2K7UAEUqiPy3ACS3Yxo3hAW6bvFpCu2HsIJLgTqxgEX6BkujvzZfLpUD0Q==} + engines: {node: '>=12.13.0'} + hasBin: true + + ci-info@4.3.1: + resolution: {integrity: sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==} + engines: {node: '>=8'} + + citty@0.1.6: + resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} + + cli-boxes@3.0.0: + resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} + engines: {node: '>=10'} + + cli-cursor@5.0.0: + resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} + engines: {node: '>=18'} + + cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} + + cli-truncate@4.0.0: + resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} + engines: {node: '>=18'} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + + commander@2.9.0: + resolution: {integrity: sha512-bmkUukX8wAOjHdN26xj5c4ctEV22TQ7dQYhSmuckKhToXrkUn0iIaolHdIxYYqD55nhpSPA9zPQ1yP57GdXP2A==} + engines: {node: '>= 0.6.x'} + + commander@9.5.0: + resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} + engines: {node: ^12.20.0 || >=14} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + concat-stream@1.6.2: + resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} + engines: {'0': node >= 0.8} + + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + + confbox@0.2.2: + resolution: {integrity: sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==} + + config-chain@1.1.13: + resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} + + configstore@7.1.0: + resolution: {integrity: sha512-N4oog6YJWbR9kGyXvS7jEykLDXIE2C0ILYqNBZBp9iwiJpoCBWYsuAdW6PPFn6w06jjnC+3JstVvWHO4cZqvRg==} + engines: {node: '>=18'} + + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + css-select@5.2.2: + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} + + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + engines: {node: '>= 6'} + + cssom@0.5.0: + resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + debounce@1.2.1: + resolution: {integrity: sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==} + + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + + default-browser-id@5.0.1: + resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} + engines: {node: '>=18'} + + default-browser@5.4.0: + resolution: {integrity: sha512-XDuvSq38Hr1MdN47EDvYtx3U0MTqpCEn+F6ft8z2vYDzMrvQhVp0ui9oQdqW3MvK3vqUETglt1tVGgjLuJ5izg==} + engines: {node: '>=18'} + + define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + + dot-prop@9.0.0: + resolution: {integrity: sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==} + engines: {node: '>=18'} + + dotenv-expand@12.0.3: + resolution: {integrity: sha512-uc47g4b+4k/M/SeaW1y4OApx+mtLWl92l5LMPP0GNXctZqELk+YGgOPIIC5elYmUH4OuoK3JLhuRUYegeySiFA==} + engines: {node: '>=12'} + + dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} + engines: {node: '>=12'} + + dotenv@17.2.3: + resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==} + engines: {node: '>=12'} + + electron-to-chromium@1.5.267: + resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==} + + emoji-regex@10.6.0: + resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + + environment@1.1.0: + resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} + engines: {node: '>=18'} + + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + + es6-error@4.1.1: + resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} + + esbuild@0.27.2: + resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-goat@4.0.0: + resolution: {integrity: sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==} + engines: {node: '>=12'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + + exsolve@1.0.8: + resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-redact@3.5.0: + resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} + engines: {node: '>=6'} + + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + filesize@11.0.13: + resolution: {integrity: sha512-mYJ/qXKvREuO0uH8LTQJ6v7GsUvVOguqxg2VTwQUkyTPXXRRWPdjuUPVqdBrJQhvci48OHlNGRnux+Slr2Rnvw==} + engines: {node: '>= 10.8.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + firefox-profile@4.7.0: + resolution: {integrity: sha512-aGApEu5bfCNbA4PGUZiRJAIU6jKmghV2UVdklXAofnNtiDjqYw0czLS46W7IfFqVKgKhFB8Ao2YoNGHY4BoIMQ==} + engines: {node: '>=18'} + hasBin: true + + form-data-encoder@4.1.0: + resolution: {integrity: sha512-G6NsmEW15s0Uw9XnCg+33H3ViYRyiM0hMrMhhqQOR8NFc5GhYrI+6I3u7OTw7b91J2g8rtvMBZJDbcGb2YUniw==} + engines: {node: '>= 18'} + + formdata-node@6.0.3: + resolution: {integrity: sha512-8e1++BCiTzUno9v5IZ2J6bv4RU+3UKDmqWUQD0MIMVCd9AdhWkO1gw57oo1mNEX1dMq2EGI+FbWz4B92pscSQg==} + engines: {node: '>= 18'} + + fs-extra@11.3.3: + resolution: {integrity: sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==} + engines: {node: '>=14.14'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + fx-runner@1.4.0: + resolution: {integrity: sha512-rci1g6U0rdTg6bAaBboP7XdRu01dzTAaKXxFf+PUqGuCv6Xu7o8NZdY1D5MvKGIjb6EdS1g3VlXOgksir1uGkg==} + hasBin: true + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-east-asian-width@1.4.0: + resolution: {integrity: sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==} + engines: {node: '>=18'} + + get-port-please@3.2.0: + resolution: {integrity: sha512-I9QVvBw5U/hw3RmWpYKRumUeaDgxTPd401x364rLmWBJcOQ753eov1eTgzDqRG9bqFIfDc7gfzcQEWrUri3o1A==} + + giget@2.0.0: + resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==} + hasBin: true + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + + global-directory@4.0.1: + resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} + engines: {node: '>=18'} + + graceful-fs@4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graceful-readlink@1.0.1: + resolution: {integrity: sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w==} + + growly@1.3.0: + resolution: {integrity: sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw==} + + hookable@5.5.3: + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + + html-escaper@3.0.3: + resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==} + + htmlparser2@10.0.0: + resolution: {integrity: sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==} + + immediate@3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + + import-meta-resolve@4.2.0: + resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + ini@4.1.1: + resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + ini@4.1.3: + resolution: {integrity: sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + is-absolute@0.1.7: + resolution: {integrity: sha512-Xi9/ZSn4NFapG8RP98iNPMOeaV3mXPisxKxzKtHVqr3g56j/fBn+yZmnxSVAA8lmZbl2J9b/a4kJvfU3hqQYgA==} + engines: {node: '>=0.10.0'} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-fullwidth-code-point@4.0.0: + resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} + engines: {node: '>=12'} + + is-fullwidth-code-point@5.1.0: + resolution: {integrity: sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==} + engines: {node: '>=18'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-in-ci@1.0.0: + resolution: {integrity: sha512-eUuAjybVTHMYWm/U+vBO1sY/JOCgoPCXRxzdju0K+K0BiGW0SChEL1MLC0PoCIR1OlPo5YAp8HuQoUlsWEICwg==} + engines: {node: '>=18'} + hasBin: true + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + + is-installed-globally@1.0.0: + resolution: {integrity: sha512-K55T22lfpQ63N4KEN57jZUAaAYqYHEe8veb/TycJRk9DdSCLLcovXz/mL6mOnhQaZsQGwPhuFopdQIlqGSEjiQ==} + engines: {node: '>=18'} + + is-interactive@2.0.0: + resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} + engines: {node: '>=12'} + + is-npm@6.1.0: + resolution: {integrity: sha512-O2z4/kNgyjhQwVR1Wpkbfc19JIhggF97NZNCpWTnjH7kVcZMUrnut9XSN7txI7VdyIYk5ZatOq3zvSuWpU8hoA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-path-inside@4.0.0: + resolution: {integrity: sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==} + engines: {node: '>=12'} + + is-plain-object@2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} + + is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + + is-primitive@3.0.1: + resolution: {integrity: sha512-GljRxhWvlCNRfZyORiH77FwdFwGcMO620o37EOYC0ORWdq+WYNVqW0w2Juzew4M+L81l6/QS3t5gkkihyRqv9w==} + engines: {node: '>=0.10.0'} + + is-relative@0.1.3: + resolution: {integrity: sha512-wBOr+rNM4gkAZqoLRJI4myw5WzzIdQosFAAbnvfXP5z1LyzgAI3ivOKehC5KfqlQJZoihVhirgtCBj378Eg8GA==} + engines: {node: '>=0.10.0'} + + is-unicode-supported@1.3.0: + resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} + engines: {node: '>=12'} + + is-unicode-supported@2.1.0: + resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} + engines: {node: '>=18'} + + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + + is-wsl@3.1.0: + resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} + engines: {node: '>=16'} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isexe@1.1.2: + resolution: {integrity: sha512-d2eJzK691yZwPHcv1LbeAOa91yMJ9QmfTgSO1oXB65ezVhXQsxBac2vEB4bMVms9cGzaA99n6V2viHMq82VLDw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isobject@3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} + + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + hasBin: true + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-tokens@9.0.1: + resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-parse-even-better-errors@3.0.2: + resolution: {integrity: sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonfile@6.2.0: + resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} + + jszip@3.10.1: + resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + ky@1.14.2: + resolution: {integrity: sha512-q3RBbsO5A5zrPhB6CaCS8ZUv+NWCXv6JJT4Em0i264G9W0fdPB8YRfnnEi7Dm7X7omAkBIPojzYJ2D1oHTHqug==} + engines: {node: '>=18'} + + latest-version@9.0.0: + resolution: {integrity: sha512-7W0vV3rqv5tokqkBAFV1LbR7HPOWzXQDpDgEuib/aJ1jsZZx6x3c2mBI+TJhJzOhkGeaLbCKEHXEXLfirtG2JA==} + engines: {node: '>=18'} + + lie@3.3.0: + resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} + + lighthouse-logger@2.0.2: + resolution: {integrity: sha512-vWl2+u5jgOQuZR55Z1WM0XDdrJT6mzMP8zHUct7xTlWhuQs+eV0g+QL0RQdFjT54zVmbhLCP8vIVpy1wGn/gCg==} + + lines-and-columns@2.0.4: + resolution: {integrity: sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + linkedom@0.18.12: + resolution: {integrity: sha512-jalJsOwIKuQJSeTvsgzPe9iJzyfVaEJiEXl+25EkKevsULHvMJzpNqwvj1jOESWdmgKDiXObyjOYwlUqG7wo1Q==} + engines: {node: '>=16'} + peerDependencies: + canvas: '>= 2' + peerDependenciesMeta: + canvas: + optional: true + + listr2@8.3.3: + resolution: {integrity: sha512-LWzX2KsqcB1wqQ4AHgYb4RsDXauQiqhjLk+6hjbaeHG4zpjjVAB6wC/gz6X0l+Du1cN3pUB5ZlrvTbhGSNnUQQ==} + engines: {node: '>=18.0.0'} + + local-pkg@1.1.2: + resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==} + engines: {node: '>=14'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + log-symbols@6.0.0: + resolution: {integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==} + engines: {node: '>=18'} + + log-update@6.1.0: + resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==} + engines: {node: '>=18'} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + magicast@0.3.5: + resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + many-keys-map@2.0.1: + resolution: {integrity: sha512-DHnZAD4phTbZ+qnJdjoNEVU1NecYoSdbOOoVmTDH46AuxDkEVh3MxTVpXq10GtcTC6mndN9dkv1rNfpjRcLnOw==} + + marky@1.3.0: + resolution: {integrity: sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mimic-function@5.0.1: + resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} + engines: {node: '>=18'} + + minimatch@10.1.1: + resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} + engines: {node: 20 || >=22} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + mlly@1.8.0: + resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + multimatch@6.0.0: + resolution: {integrity: sha512-I7tSVxHGPlmPN/enE3mS1aOSo6bWBfls+3HmuEeCUBCE7gWnm3cBXCBkpurzFjVRwC6Kld8lLaZ1Iv5vOcjvcQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + nano-spawn@1.0.3: + resolution: {integrity: sha512-jtpsQDetTnvS2Ts1fiRdci5rx0VYws5jGyC+4IYOTnIQ/wwdf6JdomlHBwqC3bJYOvaKu0C2GSZ1A60anrYpaA==} + engines: {node: '>=20.17'} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + node-fetch-native@1.6.7: + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + + node-forge@1.3.3: + resolution: {integrity: sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==} + engines: {node: '>= 6.13.0'} + + node-notifier@10.0.1: + resolution: {integrity: sha512-YX7TSyDukOZ0g+gmzjB6abKu+hTGvO8+8+gIFDsRCU2t8fLV/P2unmt+LGFaIa4y64aX98Qksa97rgz4vMNeLQ==} + + node-releases@2.0.27: + resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + nypm@0.6.2: + resolution: {integrity: sha512-7eM+hpOtrKrBDCh7Ypu2lJ9Z7PNZBdi/8AT3AX8xoCj43BBVHD0hPSTEvMtkMpfs8FCqBGhxB+uToIQimA111g==} + engines: {node: ^14.16.0 || >=16.10.0} + hasBin: true + + obug@2.1.1: + resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + + ofetch@1.5.1: + resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} + + ohash@2.0.11: + resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} + + on-exit-leak-free@2.1.2: + resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} + engines: {node: '>=14.0.0'} + + onetime@7.0.0: + resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} + engines: {node: '>=18'} + + open@10.2.0: + resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==} + engines: {node: '>=18'} + + open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} + + ora@8.2.0: + resolution: {integrity: sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==} + engines: {node: '>=18'} + + os-shim@0.1.3: + resolution: {integrity: sha512-jd0cvB8qQ5uVt0lvCIexBaROw1KyKm5sbulg2fWOHjETisuCzWyt+eTZKEMs8v6HwzoGs8xik26jg7eCM6pS+A==} + engines: {node: '>= 0.4.0'} + + package-json@10.0.1: + resolution: {integrity: sha512-ua1L4OgXSBdsu1FPb7F3tYH0F48a6kxvod4pLUlGY9COeJAJQNX/sNH2IiEmsxw7lqYiAwrdHMjz1FctOsyDQg==} + engines: {node: '>=18'} + + pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + + parse-json@7.1.1: + resolution: {integrity: sha512-SgOTCX/EZXtZxBE5eJ97P4yGM5n37BwRU+YMsH4vNzFqJV/oWFXXCmwFlgWUM4PrakybVOueJJ6pwHqSVhTFDw==} + engines: {node: '>=16'} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + perfect-debounce@2.0.0: + resolution: {integrity: sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + pino-abstract-transport@2.0.0: + resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==} + + pino-std-serializers@7.0.0: + resolution: {integrity: sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==} + + pino@9.7.0: + resolution: {integrity: sha512-vnMCM6xZTb1WDmLvtG2lE/2p+t9hDEIvTWJsu6FejkE62vB7gDhvzrpFR4Cw2to+9JNQxVnkAKVPA1KPB98vWg==} + hasBin: true + + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + + pkg-types@2.3.0: + resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} + + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + engines: {node: ^10 || ^12 || >=14} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + process-warning@5.0.0: + resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==} + + promise-toolbox@0.21.0: + resolution: {integrity: sha512-NV8aTmpwrZv+Iys54sSFOBx3tuVaOBvvrft5PNppnxy9xpU/akHbaWIril22AB22zaPgrgwKdD0KsrM0ptUtpg==} + engines: {node: '>=6'} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + proto-list@1.2.4: + resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + + publish-browser-extension@3.0.3: + resolution: {integrity: sha512-cBINZCkLo7YQaGoUvEHthZ0sDzgJQht28IS+SFMT2omSNhGsPiVNRkWir3qLiTrhGhW9Ci2KVHpA1QAMoBdL2g==} + hasBin: true + + pupa@3.3.0: + resolution: {integrity: sha512-LjgDO2zPtoXP2wJpDjZrGdojii1uqO0cnwKoIoUzkfS98HDmbeiGmYiXo3lXeFlq2xvne1QFQhwYXSUCLKtEuA==} + engines: {node: '>=12.20'} + + quansync@0.2.11: + resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + + rc9@2.1.2: + resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==} + + rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + + react-dom@19.2.3: + resolution: {integrity: sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==} + peerDependencies: + react: ^19.2.3 + + react-refresh@0.18.0: + resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==} + engines: {node: '>=0.10.0'} + + react@19.2.3: + resolution: {integrity: sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==} + engines: {node: '>=0.10.0'} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + readdirp@5.0.0: + resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} + engines: {node: '>= 20.19.0'} + + real-require@0.2.0: + resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} + engines: {node: '>= 12.13.0'} + + registry-auth-token@5.1.0: + resolution: {integrity: sha512-GdekYuwLXLxMuFTwAPg5UKGLW/UXzQrZvH/Zj791BQif5T05T0RsaLfHc9q3ZOKi7n+BoprPD9mJ0O0k4xzUlw==} + engines: {node: '>=14'} + + registry-url@6.0.1: + resolution: {integrity: sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==} + engines: {node: '>=12'} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + restore-cursor@5.1.0: + resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} + engines: {node: '>=18'} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + + rollup@4.54.0: + resolution: {integrity: sha512-3nk8Y3a9Ea8szgKhinMlGMhGMw89mqule3KWczxhIzqudyHdCIOHw8WJlj/r329fACjKLEh13ZSk7oE22kyeIw==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + run-applescript@7.1.0: + resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} + engines: {node: '>=18'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + engines: {node: '>=10'} + + sax@1.4.3: + resolution: {integrity: sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==} + + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + + scule@1.3.0: + resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.3: + resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} + engines: {node: '>=10'} + hasBin: true + + set-value@4.1.0: + resolution: {integrity: sha512-zTEg4HL0RwVrqcWs3ztF+x1vkxfm0lP+MQQFPiMJTKVceBwEV0A569Ou8l9IYQG8jOZdMVI1hGsc0tmeD2o/Lw==} + engines: {node: '>=11.0'} + + setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + + shell-quote@1.7.3: + resolution: {integrity: sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==} + + shellwords@0.1.1: + resolution: {integrity: sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + slice-ansi@5.0.0: + resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} + engines: {node: '>=12'} + + slice-ansi@7.1.2: + resolution: {integrity: sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==} + engines: {node: '>=18'} + + sonic-boom@4.2.0: + resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + + spawn-sync@1.0.15: + resolution: {integrity: sha512-9DWBgrgYZzNghseho0JOuh+5fg9u6QWhAWa51QC7+U5rCheZ/j1DrEZnyE0RBBRqZ9uEXGPgSSM0nky6burpVw==} + + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + + split@1.0.1: + resolution: {integrity: sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==} + + stdin-discarder@0.2.2: + resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} + engines: {node: '>=18'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.2: + resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} + engines: {node: '>=12'} + + strip-bom@5.0.0: + resolution: {integrity: sha512-p+byADHF7SzEcVnLvc/r3uognM1hUhObuHXxJcgLCfD194XAkaLbjq3Wzb0N5G2tgIjH0dgT708Z51QxMeu60A==} + engines: {node: '>=12'} + + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + + strip-json-comments@5.0.2: + resolution: {integrity: sha512-4X2FR3UwhNUE9G49aIsJW5hRRR3GXGTBTZRMfv568O60ojM8HcWjV/VxAxCDW3SUND33O6ZY66ZuRcdkj73q2g==} + engines: {node: '>=14.16'} + + strip-literal@3.1.0: + resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} + + stubborn-fs@2.0.0: + resolution: {integrity: sha512-Y0AvSwDw8y+nlSNFXMm2g6L51rBGdAQT20J3YSOqxC53Lo3bjWRtr2BKcfYoAf352WYpsZSTURrA0tqhfgudPA==} + + stubborn-utils@1.0.2: + resolution: {integrity: sha512-zOh9jPYI+xrNOyisSelgym4tolKTJCQd5GBhK0+0xJvcYDcwlOoxF/rnFKQ2KRZknXSG9jWAp66fwP6AxN9STg==} + + thread-stream@3.1.0: + resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} + + through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + + tinyexec@1.0.2: + resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} + engines: {node: '>=18'} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + tmp@0.2.5: + resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} + engines: {node: '>=14.14'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + type-fest@3.13.1: + resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==} + engines: {node: '>=14.16'} + + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + + typedarray@0.0.6: + resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.6.1: + resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} + + uhyphen@0.2.0: + resolution: {integrity: sha512-qz3o9CHXmJJPGBdqzab7qAYuW8kQGKNEuoHFYrBwV6hWIMcpAmxDLXojcHfFr9US1Pe6zUswEIJIbLI610fuqA==} + + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + + unimport@5.6.0: + resolution: {integrity: sha512-8rqAmtJV8o60x46kBAJKtHpJDJWkA2xcBqWKPI14MgUb05o1pnpnCnXSxedUXyeq7p8fR5g3pTo2BaswZ9lD9A==} + engines: {node: '>=18.12.0'} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + unplugin-utils@0.3.1: + resolution: {integrity: sha512-5lWVjgi6vuHhJ526bI4nlCOmkCIF3nnfXkCMDeMJrtdvxTs6ZFCM8oNufGTsDbKv/tJ/xj8RpvXjRuPBZJuJog==} + engines: {node: '>=20.19.0'} + + unplugin@2.3.11: + resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} + engines: {node: '>=18.12.0'} + + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + update-notifier@7.3.1: + resolution: {integrity: sha512-+dwUY4L35XFYEzE+OAL3sarJdUioVovq+8f7lcIJ7wnmnYQV5UD1Y/lcwaMSyaQ6Bj3JMj1XSTjZbNLHn/19yA==} + engines: {node: '>=18'} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + + vite-node@5.2.0: + resolution: {integrity: sha512-7UT39YxUukIA97zWPXUGb0SGSiLexEGlavMwU3HDE6+d/HJhKLjLqu4eX2qv6SQiocdhKLRcusroDwXHQ6CnRQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + vite@7.3.0: + resolution: {integrity: sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + watchpack@2.4.4: + resolution: {integrity: sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==} + engines: {node: '>=10.13.0'} + + web-ext-run@0.2.4: + resolution: {integrity: sha512-rQicL7OwuqWdQWI33JkSXKcp7cuv1mJG8u3jRQwx/8aDsmhbTHs9ZRmNYOL+LX0wX8edIEQX8jj4bB60GoXtKA==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + + when-exit@2.1.5: + resolution: {integrity: sha512-VGkKJ564kzt6Ms1dbgPP/yuIoQCrsFAnRbptpC5wOEsDaNsbCB2bnfnaA8i/vRs5tjUSEOtIuvl9/MyVsvQZCg==} + + when@3.7.7: + resolution: {integrity: sha512-9lFZp/KHoqH6bPKjbWqa+3Dg/K/r2v0X/3/G2x4DBGchVS2QX2VXL3cZV994WQVnTM1/PD71Az25nAzryEUugw==} + + which@1.2.4: + resolution: {integrity: sha512-zDRAqDSBudazdfM9zpiI30Fu9ve47htYXcGi3ln0wfKu2a7SmrT6F3VDoYONu//48V8Vz4TdCRNPjtvyRO3yBA==} + hasBin: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + widest-line@5.0.0: + resolution: {integrity: sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==} + engines: {node: '>=18'} + + winreg@0.0.12: + resolution: {integrity: sha512-typ/+JRmi7RqP1NanzFULK36vczznSNN8kWVA9vIqXyv8GhghUlwhGp1Xj3Nms1FsPcNnsQrJOR10N58/nQ9hQ==} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@9.0.2: + resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} + engines: {node: '>=18'} + + wsl-utils@0.1.0: + resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==} + engines: {node: '>=18'} + + wxt@0.20.13: + resolution: {integrity: sha512-FwQEk+0a4/pYha6rTKGl5iicU6kRYDBDiElJf55CFEfoJKqvGzBTZpphafurQfqU1X0hvAm9w5GEWC0thXI6wQ==} + hasBin: true + + xdg-basedir@5.1.0: + resolution: {integrity: sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==} + engines: {node: '>=12'} + + xml2js@0.6.2: + resolution: {integrity: sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==} + engines: {node: '>=4.0.0'} + + xmlbuilder@11.0.1: + resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} + engines: {node: '>=4.0'} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + zip-dir@2.0.0: + resolution: {integrity: sha512-uhlsJZWz26FLYXOD6WVuq+fIcZ3aBPGo/cFdiLlv3KNwpa52IF3ISV8fLhQLiqVu5No3VhlqlgthN6gehil1Dg==} + + zod@4.3.4: + resolution: {integrity: sha512-Zw/uYiiyF6pUT1qmKbZziChgNPRu+ZRneAsMUDU6IwmXdWt5JwcUfy2bvLOCUtz5UniaN/Zx5aFttZYbYc7O/A==} + +snapshots: + + '@1natsu/wait-element@4.1.2': + dependencies: + defu: 6.1.4 + many-keys-map: 2.0.1 + + '@aklinker1/rollup-plugin-visualizer@5.12.0(rollup@4.54.0)': + dependencies: + open: 8.4.2 + picomatch: 2.3.1 + source-map: 0.7.6 + yargs: 17.7.2 + optionalDependencies: + rollup: 4.54.0 + + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.28.5': {} + + '@babel/core@7.28.5': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/helpers': 7.28.4 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.28.5': + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-compilation-targets@7.27.2': + dependencies: + '@babel/compat-data': 7.28.5 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.1 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-module-imports@7.27.1': + dependencies: + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-plugin-utils@7.27.1': {} + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.28.4': + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 + + '@babel/parser@7.28.5': + dependencies: + '@babel/types': 7.28.5 + + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/runtime@7.28.2': {} + + '@babel/template@7.27.2': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + + '@babel/traverse@7.28.5': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.28.5': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@devicefarmer/adbkit-logcat@2.1.3': {} + + '@devicefarmer/adbkit-monkey@1.2.1': {} + + '@devicefarmer/adbkit@3.3.8': + dependencies: + '@devicefarmer/adbkit-logcat': 2.1.3 + '@devicefarmer/adbkit-monkey': 1.2.1 + bluebird: 3.7.2 + commander: 9.5.0 + debug: 4.3.7 + node-forge: 1.3.3 + split: 1.0.1 + transitivePeerDependencies: + - supports-color + + '@esbuild/aix-ppc64@0.27.2': + optional: true + + '@esbuild/android-arm64@0.27.2': + optional: true + + '@esbuild/android-arm@0.27.2': + optional: true + + '@esbuild/android-x64@0.27.2': + optional: true + + '@esbuild/darwin-arm64@0.27.2': + optional: true + + '@esbuild/darwin-x64@0.27.2': + optional: true + + '@esbuild/freebsd-arm64@0.27.2': + optional: true + + '@esbuild/freebsd-x64@0.27.2': + optional: true + + '@esbuild/linux-arm64@0.27.2': + optional: true + + '@esbuild/linux-arm@0.27.2': + optional: true + + '@esbuild/linux-ia32@0.27.2': + optional: true + + '@esbuild/linux-loong64@0.27.2': + optional: true + + '@esbuild/linux-mips64el@0.27.2': + optional: true + + '@esbuild/linux-ppc64@0.27.2': + optional: true + + '@esbuild/linux-riscv64@0.27.2': + optional: true + + '@esbuild/linux-s390x@0.27.2': + optional: true + + '@esbuild/linux-x64@0.27.2': + optional: true + + '@esbuild/netbsd-arm64@0.27.2': + optional: true + + '@esbuild/netbsd-x64@0.27.2': + optional: true + + '@esbuild/openbsd-arm64@0.27.2': + optional: true + + '@esbuild/openbsd-x64@0.27.2': + optional: true + + '@esbuild/openharmony-arm64@0.27.2': + optional: true + + '@esbuild/sunos-x64@0.27.2': + optional: true + + '@esbuild/win32-arm64@0.27.2': + optional: true + + '@esbuild/win32-ia32@0.27.2': + optional: true + + '@esbuild/win32-x64@0.27.2': + optional: true + + '@isaacs/balanced-match@4.0.1': {} + + '@isaacs/brace-expansion@5.0.0': + dependencies: + '@isaacs/balanced-match': 4.0.1 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + + '@pnpm/config.env-replace@1.1.0': {} + + '@pnpm/network.ca-file@1.0.2': + dependencies: + graceful-fs: 4.2.10 + + '@pnpm/npm-conf@2.3.1': + dependencies: + '@pnpm/config.env-replace': 1.1.0 + '@pnpm/network.ca-file': 1.0.2 + config-chain: 1.1.13 + + '@rolldown/pluginutils@1.0.0-beta.53': {} + + '@rollup/rollup-android-arm-eabi@4.54.0': + optional: true + + '@rollup/rollup-android-arm64@4.54.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.54.0': + optional: true + + '@rollup/rollup-darwin-x64@4.54.0': + optional: true + + '@rollup/rollup-freebsd-arm64@4.54.0': + optional: true + + '@rollup/rollup-freebsd-x64@4.54.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.54.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.54.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.54.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.54.0': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.54.0': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.54.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.54.0': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.54.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.54.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.54.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.54.0': + optional: true + + '@rollup/rollup-openharmony-arm64@4.54.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.54.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.54.0': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.54.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.54.0': + optional: true + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + '@types/babel__generator': 7.27.0 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.28.0 + + '@types/babel__generator@7.27.0': + dependencies: + '@babel/types': 7.28.5 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + + '@types/babel__traverse@7.28.0': + dependencies: + '@babel/types': 7.28.5 + + '@types/estree@1.0.8': {} + + '@types/filesystem@0.0.36': + dependencies: + '@types/filewriter': 0.0.33 + + '@types/filewriter@0.0.33': {} + + '@types/har-format@1.2.16': {} + + '@types/minimatch@3.0.5': {} + + '@types/node@25.0.3': + dependencies: + undici-types: 7.16.0 + + '@types/react-dom@19.2.3(@types/react@19.2.7)': + dependencies: + '@types/react': 19.2.7 + + '@types/react@19.2.7': + dependencies: + csstype: 3.2.3 + + '@vitejs/plugin-react@5.1.2(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1))': + dependencies: + '@babel/core': 7.28.5 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.5) + '@rolldown/pluginutils': 1.0.0-beta.53 + '@types/babel__core': 7.20.5 + react-refresh: 0.18.0 + vite: 7.3.0(@types/node@25.0.3)(jiti@2.6.1) + transitivePeerDependencies: + - supports-color + + '@webext-core/fake-browser@1.3.4': + dependencies: + lodash.merge: 4.6.2 + + '@webext-core/isolated-element@1.1.3': + dependencies: + is-potential-custom-element-name: 1.0.1 + + '@webext-core/match-patterns@1.0.3': {} + + '@wxt-dev/browser@0.1.32': + dependencies: + '@types/filesystem': 0.0.36 + '@types/har-format': 1.2.16 + + '@wxt-dev/module-react@1.1.5(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1))(wxt@0.20.13(@types/node@25.0.3)(jiti@2.6.1)(rollup@4.54.0))': + dependencies: + '@vitejs/plugin-react': 5.1.2(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)) + wxt: 0.20.13(@types/node@25.0.3)(jiti@2.6.1)(rollup@4.54.0) + transitivePeerDependencies: + - supports-color + - vite + + '@wxt-dev/storage@1.2.6': + dependencies: + '@wxt-dev/browser': 0.1.32 + async-mutex: 0.5.0 + dequal: 2.0.3 + + acorn@8.15.0: {} + + adm-zip@0.5.16: {} + + ansi-align@3.0.1: + dependencies: + string-width: 4.2.3 + + ansi-escapes@7.2.0: + dependencies: + environment: 1.1.0 + + ansi-regex@5.0.1: {} + + ansi-regex@6.2.2: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.3: {} + + array-differ@4.0.0: {} + + array-union@3.0.1: {} + + async-mutex@0.5.0: + dependencies: + tslib: 2.8.1 + + async@3.2.6: {} + + atomic-sleep@1.0.0: {} + + atomically@2.1.0: + dependencies: + stubborn-fs: 2.0.0 + when-exit: 2.1.5 + + balanced-match@1.0.2: {} + + baseline-browser-mapping@2.9.11: {} + + bluebird@3.7.2: {} + + boolbase@1.0.0: {} + + boxen@8.0.1: + dependencies: + ansi-align: 3.0.1 + camelcase: 8.0.0 + chalk: 5.6.2 + cli-boxes: 3.0.0 + string-width: 7.2.0 + type-fest: 4.41.0 + widest-line: 5.0.0 + wrap-ansi: 9.0.2 + + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.28.1: + dependencies: + baseline-browser-mapping: 2.9.11 + caniuse-lite: 1.0.30001762 + electron-to-chromium: 1.5.267 + node-releases: 2.0.27 + update-browserslist-db: 1.2.3(browserslist@4.28.1) + + buffer-from@1.1.2: {} + + bundle-name@4.1.0: + dependencies: + run-applescript: 7.1.0 + + c12@3.3.3(magicast@0.3.5): + dependencies: + chokidar: 5.0.0 + confbox: 0.2.2 + defu: 6.1.4 + dotenv: 17.2.3 + exsolve: 1.0.8 + giget: 2.0.0 + jiti: 2.6.1 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 2.0.0 + pkg-types: 2.3.0 + rc9: 2.1.2 + optionalDependencies: + magicast: 0.3.5 + + cac@6.7.14: {} + + camelcase@8.0.0: {} + + caniuse-lite@1.0.30001762: {} + + chalk@5.6.2: {} + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + chokidar@5.0.0: + dependencies: + readdirp: 5.0.0 + + chrome-launcher@1.2.0: + dependencies: + '@types/node': 25.0.3 + escape-string-regexp: 4.0.0 + is-wsl: 2.2.0 + lighthouse-logger: 2.0.2 + transitivePeerDependencies: + - supports-color + + ci-info@4.3.1: {} + + citty@0.1.6: + dependencies: + consola: 3.4.2 + + cli-boxes@3.0.0: {} + + cli-cursor@5.0.0: + dependencies: + restore-cursor: 5.1.0 + + cli-spinners@2.9.2: {} + + cli-truncate@4.0.0: + dependencies: + slice-ansi: 5.0.0 + string-width: 7.2.0 + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + colorette@2.0.20: {} + + commander@2.9.0: + dependencies: + graceful-readlink: 1.0.1 + + commander@9.5.0: {} + + concat-map@0.0.1: {} + + concat-stream@1.6.2: + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 2.3.8 + typedarray: 0.0.6 + + confbox@0.1.8: {} + + confbox@0.2.2: {} + + config-chain@1.1.13: + dependencies: + ini: 1.3.8 + proto-list: 1.2.4 + + configstore@7.1.0: + dependencies: + atomically: 2.1.0 + dot-prop: 9.0.0 + graceful-fs: 4.2.11 + xdg-basedir: 5.1.0 + + consola@3.4.2: {} + + convert-source-map@2.0.0: {} + + core-util-is@1.0.3: {} + + css-select@5.2.2: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + + css-what@6.2.2: {} + + cssom@0.5.0: {} + + csstype@3.2.3: {} + + debounce@1.2.1: {} + + debug@4.3.7: + dependencies: + ms: 2.1.3 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + deep-extend@0.6.0: {} + + default-browser-id@5.0.1: {} + + default-browser@5.4.0: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.1 + + define-lazy-prop@2.0.0: {} + + define-lazy-prop@3.0.0: {} + + defu@6.1.4: {} + + dequal@2.0.3: {} + + destr@2.0.5: {} + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dot-prop@9.0.0: + dependencies: + type-fest: 4.41.0 + + dotenv-expand@12.0.3: + dependencies: + dotenv: 16.6.1 + + dotenv@16.6.1: {} + + dotenv@17.2.3: {} + + electron-to-chromium@1.5.267: {} + + emoji-regex@10.6.0: {} + + emoji-regex@8.0.0: {} + + entities@4.5.0: {} + + entities@6.0.1: {} + + environment@1.1.0: {} + + error-ex@1.3.4: + dependencies: + is-arrayish: 0.2.1 + + es-module-lexer@1.7.0: {} + + es6-error@4.1.1: {} + + esbuild@0.27.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.2 + '@esbuild/android-arm': 0.27.2 + '@esbuild/android-arm64': 0.27.2 + '@esbuild/android-x64': 0.27.2 + '@esbuild/darwin-arm64': 0.27.2 + '@esbuild/darwin-x64': 0.27.2 + '@esbuild/freebsd-arm64': 0.27.2 + '@esbuild/freebsd-x64': 0.27.2 + '@esbuild/linux-arm': 0.27.2 + '@esbuild/linux-arm64': 0.27.2 + '@esbuild/linux-ia32': 0.27.2 + '@esbuild/linux-loong64': 0.27.2 + '@esbuild/linux-mips64el': 0.27.2 + '@esbuild/linux-ppc64': 0.27.2 + '@esbuild/linux-riscv64': 0.27.2 + '@esbuild/linux-s390x': 0.27.2 + '@esbuild/linux-x64': 0.27.2 + '@esbuild/netbsd-arm64': 0.27.2 + '@esbuild/netbsd-x64': 0.27.2 + '@esbuild/openbsd-arm64': 0.27.2 + '@esbuild/openbsd-x64': 0.27.2 + '@esbuild/openharmony-arm64': 0.27.2 + '@esbuild/sunos-x64': 0.27.2 + '@esbuild/win32-arm64': 0.27.2 + '@esbuild/win32-ia32': 0.27.2 + '@esbuild/win32-x64': 0.27.2 + + escalade@3.2.0: {} + + escape-goat@4.0.0: {} + + escape-string-regexp@4.0.0: {} + + escape-string-regexp@5.0.0: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + + eventemitter3@5.0.1: {} + + exsolve@1.0.8: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-redact@3.5.0: {} + + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + filesize@11.0.13: {} + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + firefox-profile@4.7.0: + dependencies: + adm-zip: 0.5.16 + fs-extra: 11.3.3 + ini: 4.1.3 + minimist: 1.2.8 + xml2js: 0.6.2 + + form-data-encoder@4.1.0: {} + + formdata-node@6.0.3: {} + + fs-extra@11.3.3: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.0 + universalify: 2.0.1 + + fsevents@2.3.3: + optional: true + + fx-runner@1.4.0: + dependencies: + commander: 2.9.0 + shell-quote: 1.7.3 + spawn-sync: 1.0.15 + when: 3.7.7 + which: 1.2.4 + winreg: 0.0.12 + + gensync@1.0.0-beta.2: {} + + get-caller-file@2.0.5: {} + + get-east-asian-width@1.4.0: {} + + get-port-please@3.2.0: {} + + giget@2.0.0: + dependencies: + citty: 0.1.6 + consola: 3.4.2 + defu: 6.1.4 + node-fetch-native: 1.6.7 + nypm: 0.6.2 + pathe: 2.0.3 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-to-regexp@0.4.1: {} + + global-directory@4.0.1: + dependencies: + ini: 4.1.1 + + graceful-fs@4.2.10: {} + + graceful-fs@4.2.11: {} + + graceful-readlink@1.0.1: {} + + growly@1.3.0: {} + + hookable@5.5.3: {} + + html-escaper@3.0.3: {} + + htmlparser2@10.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + entities: 6.0.1 + + immediate@3.0.6: {} + + import-meta-resolve@4.2.0: {} + + inherits@2.0.4: {} + + ini@1.3.8: {} + + ini@4.1.1: {} + + ini@4.1.3: {} + + is-absolute@0.1.7: + dependencies: + is-relative: 0.1.3 + + is-arrayish@0.2.1: {} + + is-docker@2.2.1: {} + + is-docker@3.0.0: {} + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-fullwidth-code-point@4.0.0: {} + + is-fullwidth-code-point@5.1.0: + dependencies: + get-east-asian-width: 1.4.0 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-in-ci@1.0.0: {} + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + + is-installed-globally@1.0.0: + dependencies: + global-directory: 4.0.1 + is-path-inside: 4.0.0 + + is-interactive@2.0.0: {} + + is-npm@6.1.0: {} + + is-number@7.0.0: {} + + is-path-inside@4.0.0: {} + + is-plain-object@2.0.4: + dependencies: + isobject: 3.0.1 + + is-potential-custom-element-name@1.0.1: {} + + is-primitive@3.0.1: {} + + is-relative@0.1.3: {} + + is-unicode-supported@1.3.0: {} + + is-unicode-supported@2.1.0: {} + + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 + + is-wsl@3.1.0: + dependencies: + is-inside-container: 1.0.0 + + isarray@1.0.0: {} + + isexe@1.1.2: {} + + isexe@2.0.0: {} + + isobject@3.0.1: {} + + jiti@2.6.1: {} + + js-tokens@4.0.0: {} + + js-tokens@9.0.1: {} + + jsesc@3.1.0: {} + + json-parse-even-better-errors@3.0.2: {} + + json5@2.2.3: {} + + jsonfile@6.2.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + jszip@3.10.1: + dependencies: + lie: 3.3.0 + pako: 1.0.11 + readable-stream: 2.3.8 + setimmediate: 1.0.5 + + kleur@3.0.3: {} + + ky@1.14.2: {} + + latest-version@9.0.0: + dependencies: + package-json: 10.0.1 + + lie@3.3.0: + dependencies: + immediate: 3.0.6 + + lighthouse-logger@2.0.2: + dependencies: + debug: 4.4.3 + marky: 1.3.0 + transitivePeerDependencies: + - supports-color + + lines-and-columns@2.0.4: {} + + linkedom@0.18.12: + dependencies: + css-select: 5.2.2 + cssom: 0.5.0 + html-escaper: 3.0.3 + htmlparser2: 10.0.0 + uhyphen: 0.2.0 + + listr2@8.3.3: + dependencies: + cli-truncate: 4.0.0 + colorette: 2.0.20 + eventemitter3: 5.0.1 + log-update: 6.1.0 + rfdc: 1.4.1 + wrap-ansi: 9.0.2 + + local-pkg@1.1.2: + dependencies: + mlly: 1.8.0 + pkg-types: 2.3.0 + quansync: 0.2.11 + + lodash.merge@4.6.2: {} + + log-symbols@6.0.0: + dependencies: + chalk: 5.6.2 + is-unicode-supported: 1.3.0 + + log-update@6.1.0: + dependencies: + ansi-escapes: 7.2.0 + cli-cursor: 5.0.0 + slice-ansi: 7.1.2 + strip-ansi: 7.1.2 + wrap-ansi: 9.0.2 + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + magicast@0.3.5: + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + source-map-js: 1.2.1 + + make-error@1.3.6: {} + + many-keys-map@2.0.1: {} + + marky@1.3.0: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mimic-function@5.0.1: {} + + minimatch@10.1.1: + dependencies: + '@isaacs/brace-expansion': 5.0.0 + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.12 + + minimist@1.2.8: {} + + mlly@1.8.0: + dependencies: + acorn: 8.15.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.1 + + ms@2.1.3: {} + + multimatch@6.0.0: + dependencies: + '@types/minimatch': 3.0.5 + array-differ: 4.0.0 + array-union: 3.0.1 + minimatch: 3.1.2 + + nano-spawn@1.0.3: {} + + nanoid@3.3.11: {} + + node-fetch-native@1.6.7: {} + + node-forge@1.3.3: {} + + node-notifier@10.0.1: + dependencies: + growly: 1.3.0 + is-wsl: 2.2.0 + semver: 7.7.3 + shellwords: 0.1.1 + uuid: 8.3.2 + which: 2.0.2 + + node-releases@2.0.27: {} + + normalize-path@3.0.0: {} + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + nypm@0.6.2: + dependencies: + citty: 0.1.6 + consola: 3.4.2 + pathe: 2.0.3 + pkg-types: 2.3.0 + tinyexec: 1.0.2 + + obug@2.1.1: {} + + ofetch@1.5.1: + dependencies: + destr: 2.0.5 + node-fetch-native: 1.6.7 + ufo: 1.6.1 + + ohash@2.0.11: {} + + on-exit-leak-free@2.1.2: {} + + onetime@7.0.0: + dependencies: + mimic-function: 5.0.1 + + open@10.2.0: + dependencies: + default-browser: 5.4.0 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + wsl-utils: 0.1.0 + + open@8.4.2: + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + + ora@8.2.0: + dependencies: + chalk: 5.6.2 + cli-cursor: 5.0.0 + cli-spinners: 2.9.2 + is-interactive: 2.0.0 + is-unicode-supported: 2.1.0 + log-symbols: 6.0.0 + stdin-discarder: 0.2.2 + string-width: 7.2.0 + strip-ansi: 7.1.2 + + os-shim@0.1.3: {} + + package-json@10.0.1: + dependencies: + ky: 1.14.2 + registry-auth-token: 5.1.0 + registry-url: 6.0.1 + semver: 7.7.3 + + pako@1.0.11: {} + + parse-json@7.1.1: + dependencies: + '@babel/code-frame': 7.27.1 + error-ex: 1.3.4 + json-parse-even-better-errors: 3.0.2 + lines-and-columns: 2.0.4 + type-fest: 3.13.1 + + pathe@2.0.3: {} + + perfect-debounce@2.0.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.3: {} + + pino-abstract-transport@2.0.0: + dependencies: + split2: 4.2.0 + + pino-std-serializers@7.0.0: {} + + pino@9.7.0: + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.5.0 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 2.0.0 + pino-std-serializers: 7.0.0 + process-warning: 5.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.2.0 + safe-stable-stringify: 2.5.0 + sonic-boom: 4.2.0 + thread-stream: 3.1.0 + + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.8.0 + pathe: 2.0.3 + + pkg-types@2.3.0: + dependencies: + confbox: 0.2.2 + exsolve: 1.0.8 + pathe: 2.0.3 + + postcss@8.5.6: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + process-nextick-args@2.0.1: {} + + process-warning@5.0.0: {} + + promise-toolbox@0.21.0: + dependencies: + make-error: 1.3.6 + + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + + proto-list@1.2.4: {} + + publish-browser-extension@3.0.3: + dependencies: + cac: 6.7.14 + consola: 3.4.2 + dotenv: 17.2.3 + form-data-encoder: 4.1.0 + formdata-node: 6.0.3 + listr2: 8.3.3 + ofetch: 1.5.1 + zod: 4.3.4 + + pupa@3.3.0: + dependencies: + escape-goat: 4.0.0 + + quansync@0.2.11: {} + + queue-microtask@1.2.3: {} + + quick-format-unescaped@4.0.4: {} + + rc9@2.1.2: + dependencies: + defu: 6.1.4 + destr: 2.0.5 + + rc@1.2.8: + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + + react-dom@19.2.3(react@19.2.3): + dependencies: + react: 19.2.3 + scheduler: 0.27.0 + + react-refresh@0.18.0: {} + + react@19.2.3: {} + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readdirp@4.1.2: {} + + readdirp@5.0.0: {} + + real-require@0.2.0: {} + + registry-auth-token@5.1.0: + dependencies: + '@pnpm/npm-conf': 2.3.1 + + registry-url@6.0.1: + dependencies: + rc: 1.2.8 + + require-directory@2.1.1: {} + + restore-cursor@5.1.0: + dependencies: + onetime: 7.0.0 + signal-exit: 4.1.0 + + reusify@1.1.0: {} + + rfdc@1.4.1: {} + + rollup@4.54.0: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.54.0 + '@rollup/rollup-android-arm64': 4.54.0 + '@rollup/rollup-darwin-arm64': 4.54.0 + '@rollup/rollup-darwin-x64': 4.54.0 + '@rollup/rollup-freebsd-arm64': 4.54.0 + '@rollup/rollup-freebsd-x64': 4.54.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.54.0 + '@rollup/rollup-linux-arm-musleabihf': 4.54.0 + '@rollup/rollup-linux-arm64-gnu': 4.54.0 + '@rollup/rollup-linux-arm64-musl': 4.54.0 + '@rollup/rollup-linux-loong64-gnu': 4.54.0 + '@rollup/rollup-linux-ppc64-gnu': 4.54.0 + '@rollup/rollup-linux-riscv64-gnu': 4.54.0 + '@rollup/rollup-linux-riscv64-musl': 4.54.0 + '@rollup/rollup-linux-s390x-gnu': 4.54.0 + '@rollup/rollup-linux-x64-gnu': 4.54.0 + '@rollup/rollup-linux-x64-musl': 4.54.0 + '@rollup/rollup-openharmony-arm64': 4.54.0 + '@rollup/rollup-win32-arm64-msvc': 4.54.0 + '@rollup/rollup-win32-ia32-msvc': 4.54.0 + '@rollup/rollup-win32-x64-gnu': 4.54.0 + '@rollup/rollup-win32-x64-msvc': 4.54.0 + fsevents: 2.3.3 + + run-applescript@7.1.0: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-buffer@5.1.2: {} + + safe-stable-stringify@2.5.0: {} + + sax@1.4.3: {} + + scheduler@0.27.0: {} + + scule@1.3.0: {} + + semver@6.3.1: {} + + semver@7.7.3: {} + + set-value@4.1.0: + dependencies: + is-plain-object: 2.0.4 + is-primitive: 3.0.1 + + setimmediate@1.0.5: {} + + shell-quote@1.7.3: {} + + shellwords@0.1.1: {} + + signal-exit@4.1.0: {} + + sisteransi@1.0.5: {} + + slice-ansi@5.0.0: + dependencies: + ansi-styles: 6.2.3 + is-fullwidth-code-point: 4.0.0 + + slice-ansi@7.1.2: + dependencies: + ansi-styles: 6.2.3 + is-fullwidth-code-point: 5.1.0 + + sonic-boom@4.2.0: + dependencies: + atomic-sleep: 1.0.0 + + source-map-js@1.2.1: {} + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + source-map@0.7.6: {} + + spawn-sync@1.0.15: + dependencies: + concat-stream: 1.6.2 + os-shim: 0.1.3 + + split2@4.2.0: {} + + split@1.0.1: + dependencies: + through: 2.3.8 + + stdin-discarder@0.2.2: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@7.2.0: + dependencies: + emoji-regex: 10.6.0 + get-east-asian-width: 1.4.0 + strip-ansi: 7.1.2 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.2: + dependencies: + ansi-regex: 6.2.2 + + strip-bom@5.0.0: {} + + strip-json-comments@2.0.1: {} + + strip-json-comments@5.0.2: {} + + strip-literal@3.1.0: + dependencies: + js-tokens: 9.0.1 + + stubborn-fs@2.0.0: + dependencies: + stubborn-utils: 1.0.2 + + stubborn-utils@1.0.2: {} + + thread-stream@3.1.0: + dependencies: + real-require: 0.2.0 + + through@2.3.8: {} + + tinyexec@1.0.2: {} + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + tmp@0.2.5: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + tslib@2.8.1: {} + + type-fest@3.13.1: {} + + type-fest@4.41.0: {} + + typedarray@0.0.6: {} + + typescript@5.9.3: {} + + ufo@1.6.1: {} + + uhyphen@0.2.0: {} + + undici-types@7.16.0: {} + + unimport@5.6.0: + dependencies: + acorn: 8.15.0 + escape-string-regexp: 5.0.0 + estree-walker: 3.0.3 + local-pkg: 1.1.2 + magic-string: 0.30.21 + mlly: 1.8.0 + pathe: 2.0.3 + picomatch: 4.0.3 + pkg-types: 2.3.0 + scule: 1.3.0 + strip-literal: 3.1.0 + tinyglobby: 0.2.15 + unplugin: 2.3.11 + unplugin-utils: 0.3.1 + + universalify@2.0.1: {} + + unplugin-utils@0.3.1: + dependencies: + pathe: 2.0.3 + picomatch: 4.0.3 + + unplugin@2.3.11: + dependencies: + '@jridgewell/remapping': 2.3.5 + acorn: 8.15.0 + picomatch: 4.0.3 + webpack-virtual-modules: 0.6.2 + + update-browserslist-db@1.2.3(browserslist@4.28.1): + dependencies: + browserslist: 4.28.1 + escalade: 3.2.0 + picocolors: 1.1.1 + + update-notifier@7.3.1: + dependencies: + boxen: 8.0.1 + chalk: 5.6.2 + configstore: 7.1.0 + is-in-ci: 1.0.0 + is-installed-globally: 1.0.0 + is-npm: 6.1.0 + latest-version: 9.0.0 + pupa: 3.3.0 + semver: 7.7.3 + xdg-basedir: 5.1.0 + + util-deprecate@1.0.2: {} + + uuid@8.3.2: {} + + vite-node@5.2.0(@types/node@25.0.3)(jiti@2.6.1): + dependencies: + cac: 6.7.14 + es-module-lexer: 1.7.0 + obug: 2.1.1 + pathe: 2.0.3 + vite: 7.3.0(@types/node@25.0.3)(jiti@2.6.1) + transitivePeerDependencies: + - '@types/node' + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - terser + - tsx + - yaml + + vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1): + dependencies: + esbuild: 0.27.2 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.54.0 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 25.0.3 + fsevents: 2.3.3 + jiti: 2.6.1 + + watchpack@2.4.4: + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + + web-ext-run@0.2.4: + dependencies: + '@babel/runtime': 7.28.2 + '@devicefarmer/adbkit': 3.3.8 + chrome-launcher: 1.2.0 + debounce: 1.2.1 + es6-error: 4.1.1 + firefox-profile: 4.7.0 + fx-runner: 1.4.0 + multimatch: 6.0.0 + node-notifier: 10.0.1 + parse-json: 7.1.1 + pino: 9.7.0 + promise-toolbox: 0.21.0 + set-value: 4.1.0 + source-map-support: 0.5.21 + strip-bom: 5.0.0 + strip-json-comments: 5.0.2 + tmp: 0.2.5 + update-notifier: 7.3.1 + watchpack: 2.4.4 + zip-dir: 2.0.0 + transitivePeerDependencies: + - supports-color + + webpack-virtual-modules@0.6.2: {} + + when-exit@2.1.5: {} + + when@3.7.7: {} + + which@1.2.4: + dependencies: + is-absolute: 0.1.7 + isexe: 1.1.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + widest-line@5.0.0: + dependencies: + string-width: 7.2.0 + + winreg@0.0.12: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@9.0.2: + dependencies: + ansi-styles: 6.2.3 + string-width: 7.2.0 + strip-ansi: 7.1.2 + + wsl-utils@0.1.0: + dependencies: + is-wsl: 3.1.0 + + wxt@0.20.13(@types/node@25.0.3)(jiti@2.6.1)(rollup@4.54.0): + dependencies: + '@1natsu/wait-element': 4.1.2 + '@aklinker1/rollup-plugin-visualizer': 5.12.0(rollup@4.54.0) + '@webext-core/fake-browser': 1.3.4 + '@webext-core/isolated-element': 1.1.3 + '@webext-core/match-patterns': 1.0.3 + '@wxt-dev/browser': 0.1.32 + '@wxt-dev/storage': 1.2.6 + async-mutex: 0.5.0 + c12: 3.3.3(magicast@0.3.5) + cac: 6.7.14 + chokidar: 4.0.3 + ci-info: 4.3.1 + consola: 3.4.2 + defu: 6.1.4 + dotenv: 17.2.3 + dotenv-expand: 12.0.3 + esbuild: 0.27.2 + fast-glob: 3.3.3 + filesize: 11.0.13 + fs-extra: 11.3.3 + get-port-please: 3.2.0 + giget: 2.0.0 + hookable: 5.5.3 + import-meta-resolve: 4.2.0 + is-wsl: 3.1.0 + json5: 2.2.3 + jszip: 3.10.1 + linkedom: 0.18.12 + magicast: 0.3.5 + minimatch: 10.1.1 + nano-spawn: 1.0.3 + normalize-path: 3.0.0 + nypm: 0.6.2 + ohash: 2.0.11 + open: 10.2.0 + ora: 8.2.0 + perfect-debounce: 2.0.0 + picocolors: 1.1.1 + prompts: 2.4.2 + publish-browser-extension: 3.0.3 + scule: 1.3.0 + unimport: 5.6.0 + vite: 7.3.0(@types/node@25.0.3)(jiti@2.6.1) + vite-node: 5.2.0(@types/node@25.0.3)(jiti@2.6.1) + web-ext-run: 0.2.4 + transitivePeerDependencies: + - '@types/node' + - canvas + - jiti + - less + - lightningcss + - rollup + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + xdg-basedir@5.1.0: {} + + xml2js@0.6.2: + dependencies: + sax: 1.4.3 + xmlbuilder: 11.0.1 + + xmlbuilder@11.0.1: {} + + y18n@5.0.8: {} + + yallist@3.1.1: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + zip-dir@2.0.0: + dependencies: + async: 3.2.6 + jszip: 3.10.1 + + zod@4.3.4: {} diff --git a/extension/public/_locales/en/messages.json b/extension/public/_locales/en/messages.json new file mode 100644 index 0000000..331f65c --- /dev/null +++ b/extension/public/_locales/en/messages.json @@ -0,0 +1,8 @@ +{ + "downloadWithVidBee": { + "message": "Download with VidBee" + }, + "hideButton": { + "message": "Hide" + } +} diff --git a/extension/public/icon/128.png b/extension/public/icon/128.png new file mode 100644 index 0000000000000000000000000000000000000000..452adc4e20efb0a4ba4c3f02a9086f5e859d7a43 GIT binary patch literal 7022 zcmYLubyU?)^zG+fxWq+DLL{Y;E-ATmOLuqo6_At;=|(`}a%rR+q@)|96zOgO>3)9S z`>o%bwf5{iXZD%-YtCA;PNb@`EH;!B3IG7MyquK!KMwp47-;|I9uc#Ve}rlyt|Sfs zHSt*YW{`jDR~B;WN&w))@Xr?t0Js17cLBhI69D#20YE4n0A9FewW z0+|143;-2G3jB8h=pRHtWdEyWKuiG2|BZtIAi@qn{U49=KmKpX{lkAb|Bq1+p#O3I ziy^@O>kdSq{D1vlnlFe`>>pve%IUcQ02aZ200Eg+lRkLowN*=H3z}dsR{&lLM!-yY@f!(a5q^ zk7uPq5l7$M`qNWS<#X^N>~b!hbi9gz_R?!Ie)3E%4FV!Ai{^puZ&h{@UdD{f_hPoo z0UKvl)G@eWJO1TkF7`OMiT7_nBY%T-Fe~nUV8y{bJabO!=QFn{P#hV0l_=I{LXTRz z;jj}f(Kw-!5{2|&;dnwkDjKWR_*{8(!f1}u4WmVGd6IQKGf(Fq+fN;xhF%1HlWWlp zJMmSs=U9dl21v}~(5U9bz^t$%LWUE?P?n8w&Y{f`6t#0A2`bene==xZd)QZ{SC3{# zi?X87FQKX}a}CyNA;fO}2)o~@ob$Gk`n>gzJ~qnKV#vJ4X;JT8Ja%!#(Eo)LIJOvPhS;CPI3$KbE}5`F7@E)=>DM!b1*6&Gr7x9lrpv1 z{N8w1RkCYu*V)N!&3?3}!{`TnbfEQ%DqbO`DVliRdehwWCrQTpIe|nb*lU^Xwz>6E zE0t)Qeo0CfznbSIzJ>o(F1Kpwgt`|u0+mN<)O&EDx}Y)zIkl2n1QL|;PVN7h!fxpo?o_#OdBuQ-AmpCddi}pXK!7h{znyhbXM22VaZ4F?7{=Qy<-pZ zs2+q^X!+2XJ0cx*^V3anvd|Um?^i*L_kZGpEmz0T(m2_P-Yj3xBlkLuYr*cKt*&5A zIFUpqgTyy(*I_-hcT||$E8+>!T)0A~r6gLpTiXRJC)jCLBv0E;hVJI8o;=1(dLYNO zM_;Qjks%3pl{a{Lk{mCsW^JL!!Cgxq-_>d@QdeCk+u3d+PhYZe> z+l~Pf=<~3SuRWKtOZUmd>w;wr44hy00&KdX>QdG3WYOlH_baZ=8EP>-)xvb@^_^Q> zWE|}u3Y18WbAQ{&zkgqACg2sjO|@p3Xd0>r=A=_PD|Zx#thECP-xoVp29H;7_|q)@ zg7=|CMs08NA23cxf8r-x(^#I-)Q~tU&Xt&GYiTz*w2z2To@m{*PLL&__9OnPcwJ8F zkEY*enWv|-{hjW(0!au6OQG)=vq--3u6g%uXii~T|M{v1&XCVq1_3$V)Vu|zkP|I& z32J6@zpsy;2Ny44Ay5&Y9l)!&ljWb0bHw?pj$RE@0TMT%(RY&kNO*3#3C=!F7tzvf zKZ~M9GC??nkGi8mBUy7?1qSpLoF76K#jA&P=#a{5)5WHaW>P3@`IT(!;o)7-RhTGQ z+REF{dj@6_rE@C-MBsSI)s6jiWYH8}ewh*%>GCbc3sJ@>xn)O}rFE2$VY+It`%xu~ zJXI0PVlkH{9GtYRsD{azS@Jbb98=MIt0;kOfKf?LvFb(5<|twoT^rCLDW*o}z)!lM zLdwcKiE5H`2HL0(Z21xzhg0z;=D@WlGf`Lqi}u_~UCqF3f$k8D!rM-(F(hNZ@yv{f;jFh{tJT)t0OPYWmmm9Uy0#je4X^2OodgP|jx|bKZf$tM z{C9brII8F;O%$}nqF$N)0X^#jxg!_W+K^wZ`{(TrYLtXw7;6c zj~jpESo44?#0%DW9I;A{Sm>RderUXdbMG1ZoouOeq!|xWLQnRG1vj2|dlk`CQcY;V z)B=CZ!rei){tzZLlB|nRuIoj3eG5Tar7xq_B4v+Q{ry`Of*<%I#ddOB=rK4y6lrh#1!g;hz+jVkkI6?(^Ma-bB!}M-G4xDJ!9fS>4ZlE@N z5I}O8TEOxXE&6RgQR#y4g#zorY7iu`)&1X7r-X{+>zFDa=b#TMqbO)iamK~=K>1Qm z<9GBM$RjxU{0r^sTQVV}%mEr)?R#{NN%%3`hjrNDh%U$p= z^_sB96sZ}*ay{4|m zaU|Bkv3j!HGx1EUI5e-)S*+P?p&Eb|E2Bwct8yB}~NkHfp_2fiMtRTqNWas7^X0A!rHS;7!}&`=;!OHF81k-~Fb_pmhgElD4CVAg#g{?huYh5JN+bo^9M;|o*%=@V%L;o^_O%xLgF-4}#Wp46B z$1&gRG|Fbki*tK7q}uQ^JiDh_qn`SicIguvmxB! z>Lz}>r|Hnb1DEbXn2_eJzTR4ZPS%YQPtgOaQMbgXXM7$_!S?kH*y2KXQLsE6RPR!fzmDl-BsLF5`aFC2tgq8a%;Z3WbS2#MYz1X`#B$exq<4>#cei z^sIYSSxZLqZiew|=ZNSLY&!}Ipy2YESDHi|zWhoVpZpd#%zN!mO5P!v*uV1dK*}Vc z>&FlxAjHS3axR!@d(0#CF86h7vaTa0omUmZb`)1?BT2SvwK%%^n()}lpaCq7)Lhya zi?4lo`_~^F#J;NhTF+5vc*ma5+&hA_M}J#tra#A!9%iv^GFZHc02bCW4s>|&+Lnx| zDus4)+_Sz~4^i8s$j|31n=x^u)T8nG>*i;1_NO1*!mg1l3_h$BdHX@EuegQ7cgpfm z3G7+nGoX*_z5UMc!F0Mzy5#}4sD=hAhP`()r_B4lzz()3QRoZ0x>vTw?TDJPsWxm5 z)*ybn6JU2{R7)Hp=k+O{-~-BVP%ui~@nJckN}H&{eQAsO`Mkhayr0!7e-mz0*2McP z`Mc64DiKrXz2~Q}^=}$)dlS*mZxsqOF@G__ug8atTnO-5KsGo}uft3_RN4fE>njD1 zU7o`~deB&tt5w1UGYsFPNAnB!(+h(LmVY>Wig_p^4@ffGdLRO;Ku=tj&Bs6TLqeqLv#!i^XJrS_~mzSkkbcNp~`O2nq}10A6Gnbzkql#^Skd~s-L%55sB2~ zr!mJWcSqi}!Px)!V|PbHs3da`=q^`MPIEj(;~ajF*-?MxvjR1MJM z`-yqXQPn3-s5dx7@{6B4VF2#$S@fz$euI5!H~!EnIRVXJj#fqZ3fYAKwg}@wbTRG1 z7dd8e6W6dN_*$rAlQ$b9!v@*&f%Sxbi~MRk)DTroFg*|?db*>wo^3?bFoB&0arm`DCf**;7|w25veEcyyl*GG^sqX^uV$Wb{z`Q8kadO; z!8}(-)}uK0W#LhwH_Xf+k0SV~RzexlHFr|2v4uV?9SKIPDtp~k`59M~uT1p8Zc#Y$ zmnoTYe#6-~N#xi|`ee0j4Puf`qP~J!C?G?{&au>*3lF%OD03WnYt_Ame&A@ujzT4QPgnTw0)gies|lQn zrs0!Z8@_#BmiRme0;s#PUxw`u-|GYA%s0HKy_aRd*15#5C=41WgDl`zK5Ye9q$Roh zg*_8T9Hj_=BbnXj(S~Xcf3@N{r4@f!#gTMYchB){54RKD5_tcmKJzSC)`A59Wg z??kj!%#(e9)~_XGep;{X@ltt@CB}ZzOrrTRFc0Xv$|C_ zdHsepB?_#+CNB50!_Nn+mBJks6+@XCO|d{U?HL^|R1gvI)=?BP)jp%e@Z>zf%#p+0lg)#@J#RtDg-fzFXQJN!BZkFaFo z@s5=bcX=L7woQvkZsmzOwOTLAA4cJA2VK6hcKRQJ?4=mqkC4y@5_>NvR+zsG?RB0` zn~~7Nv4YRmu$e!u35*)3w|IMZ&2`VYd~33|;cw46o^OM8y^!VbDIfZfeXy4CZL1Nr z;N7119Nu^^?eAXfmF3s{Itxguv^?GD4Hg#byJpk#q70L$x*~~dCKW-|1*Usro7CMo zXR^wUV6J^b-$(jtuqUZhJDL8 zcaiY#VnH0bq;VYX%r+{2p07xLr3x$D7!EteqCA@KrWA|2&PeavW?xlE`70sfbLmra z@gppmEBpaJj<)j`Zv&dMV%HHi+u?TK7)>{7KePmu6q71ve6^%THwN!9s+@xT`BH8E z@WcjLHMDu}iT2_e%;(_M2qt*zc)HTfd8~PUflf2IiS83lBq?^TOS!lGm!lCalWf4L zXO?lTcQH&l&xKf@W*GqB1XT8{87_zioDxb)PMg_ zR9l!5q$H9$Dvnlru@QhlfsL=AR=$$(_0Q?ebd~ zor@omXANfAb=#NV!0O_0czeg%G(a>o#?6`7-A+)cw}N7`(=c;h@vIlhmj6shhsj

4o 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 D{-r62 literal 0 HcmV?d00001 diff --git a/extension/public/icon/48.png b/extension/public/icon/48.png new file mode 100644 index 0000000000000000000000000000000000000000..2e7ba2fcf127312fe79831773369954395aae5db GIT binary patch literal 2693 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 literal 0 HcmV?d00001 diff --git a/extension/public/icon/icon-success-128.png b/extension/public/icon/icon-success-128.png new file mode 100644 index 0000000000000000000000000000000000000000..fca74638e8bf74b3908d96e049f06827d285550a GIT binary patch literal 7443 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 W2VC>n%Cy1&00002R literal 0 HcmV?d00001 diff --git a/extension/public/icon/icon-success-48.png b/extension/public/icon/icon-success-48.png new file mode 100644 index 0000000000000000000000000000000000000000..6f0fd24f52a0df7ac84b830b434cd9f39afe170e GIT binary patch literal 2707 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 { log.error('Failed to initialize yt-dlp:', error) } + await startExtensionApiServer() + applyDockVisibility(settingsManager.get('hideDockIcon')) applyAutoLaunchSetting(settingsManager.get('launchAtLogin')) @@ -509,6 +512,7 @@ app.on('window-all-closed', () => { // Cleanup tray on quit app.on('will-quit', () => { destroyTray() + void stopExtensionApiServer() }) // In this file you can include the rest of your app's specific main process diff --git a/src/main/local-api.ts b/src/main/local-api.ts new file mode 100644 index 0000000..8545e1c --- /dev/null +++ b/src/main/local-api.ts @@ -0,0 +1,191 @@ +import crypto from 'node:crypto' +import http from 'node:http' +import type { AddressInfo } from 'node:net' + +import log from 'electron-log/main' + +import { downloadEngine } from './lib/download-engine' + +const PORT_RANGE_START = 27100 +const PORT_RANGE_END = 27120 +const TOKEN_TTL_MS = 60_000 + +type TokenRecord = { + expiresAt: number +} + +let server: http.Server | null = null +let serverPort: number | null = null +const tokens = new Map() + +const isLoopbackAddress = (address?: string | null): boolean => { + if (!address) return false + return address === '127.0.0.1' || address === '::1' || address === '::ffff:127.0.0.1' +} + +const writeJson = (res: http.ServerResponse, status: number, body: unknown): void => { + res.writeHead(status, { + 'Content-Type': 'application/json; charset=utf-8', + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET, OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type' + }) + res.end(JSON.stringify(body)) +} + +const writeEmpty = (res: http.ServerResponse, status: number): void => { + res.writeHead(status, { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET, OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type' + }) + res.end() +} + +const issueToken = (): string => { + const token = crypto.randomBytes(16).toString('hex') + tokens.set(token, { expiresAt: Date.now() + TOKEN_TTL_MS }) + return token +} + +const consumeToken = (token?: string | null): boolean => { + if (!token) return false + const record = tokens.get(token) + if (!record) return false + if (Date.now() > record.expiresAt) { + tokens.delete(token) + return false + } + tokens.delete(token) + return true +} + +const handleRequest = async ( + req: http.IncomingMessage, + res: http.ServerResponse +): Promise => { + try { + if (!isLoopbackAddress(req.socket.remoteAddress)) { + writeJson(res, 403, { error: 'Forbidden' }) + return + } + + if (req.method === 'OPTIONS') { + writeEmpty(res, 204) + return + } + + if (!req.url) { + writeJson(res, 400, { error: 'Missing URL' }) + return + } + + const requestUrl = new URL(req.url, 'http://127.0.0.1') + const pathname = requestUrl.pathname + + if (req.method !== 'GET') { + writeJson(res, 405, { error: 'Method not allowed' }) + return + } + + if (pathname === '/token') { + const token = issueToken() + writeJson(res, 200, { token, expiresInMs: TOKEN_TTL_MS }) + return + } + + if (pathname === '/video-info') { + const token = requestUrl.searchParams.get('token') + if (!consumeToken(token)) { + writeJson(res, 401, { error: 'Invalid token' }) + return + } + + const targetUrl = requestUrl.searchParams.get('url') + if (!targetUrl || !targetUrl.trim()) { + writeJson(res, 400, { error: 'Missing url' }) + return + } + + try { + const info = await downloadEngine.getVideoInfo(targetUrl.trim()) + writeJson(res, 200, { + title: info.title, + thumbnail: info.thumbnail, + duration: info.duration, + formats: info.formats ?? [] + }) + } catch (error) { + const message = error instanceof Error ? error.message : 'Failed to fetch video info' + const details = + error instanceof Error + ? error.stack + : typeof error === 'object' && error && 'stderr' in error + ? String((error as { stderr?: unknown }).stderr ?? '') + : undefined + writeJson(res, 500, { error: message, details }) + } + return + } + + if (pathname === '/status') { + writeJson(res, 200, { ok: true }) + return + } + + writeJson(res, 404, { error: 'Not found' }) + } catch (error) { + const message = error instanceof Error ? error.message : 'Unhandled request error' + writeJson(res, 500, { error: message }) + } +} + +const startServerOnPort = (port: number): Promise => + new Promise((resolve, reject) => { + const httpServer = http.createServer((req, res) => { + void handleRequest(req, res) + }) + + httpServer.once('error', (error) => { + httpServer.close() + reject(error) + }) + + httpServer.listen(port, '127.0.0.1', () => resolve(httpServer)) + }) + +export async function startExtensionApiServer(): Promise { + if (server && serverPort) { + return serverPort + } + + for (let port = PORT_RANGE_START; port <= PORT_RANGE_END; port += 1) { + try { + server = await startServerOnPort(port) + const address = server.address() as AddressInfo | null + serverPort = address?.port ?? port + log.info(`Extension API listening on 127.0.0.1:${serverPort}`) + return serverPort + } catch (error) { + const err = error as NodeJS.ErrnoException + if (err.code !== 'EADDRINUSE') { + log.warn('Extension API failed to start on port:', port, err) + } + } + } + + log.error(`Extension API failed to bind any port in range ${PORT_RANGE_START}-${PORT_RANGE_END}`) + return null +} + +export async function stopExtensionApiServer(): Promise { + if (!server) return + + await new Promise((resolve) => { + server?.close(() => resolve()) + }) + + server = null + serverPort = null + tokens.clear() +}