From b26d299db72a69c42e654d736b3f9f1c6b3fa350 Mon Sep 17 00:00:00 2001 From: Emre Sokullu Date: Fri, 22 May 2026 15:52:02 +0300 Subject: [PATCH 01/31] WebGPU + ONNX provider (Qwen 3 0.6B, in-browser, no server needed) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a fourth "local" provider alongside llama.cpp / Ollama / LM Studio. Unlike those, this one needs nothing installed — model weights download from HuggingFace on first use (~500MB for q4 Qwen 3 0.6B), cached in IndexedDB by @huggingface/transformers, inference runs on the user's GPU in the extension's offscreen document. Architecture: service worker └─ WebGPUProvider.chat() ──┐ ▼ chrome.runtime.sendMessage offscreen document └─ @huggingface/transformers pipeline('text-generation', 'onnx-community/Qwen3-0.6B-ONNX', { device: 'webgpu', dtype: 'q4' }) Service workers have no WebGPU; the offscreen document does. We reuse the existing offscreen doc (already hosting the local-network fetch proxy) and add new message handlers `webgpu-chat` and `webgpu-probe`. Tool use: enabled. Qwen 3's chat template renders `tools=[...]` into the system prompt and the model emits `{...}` blocks; offscreen.js parses them into OpenAI-format tool_calls so the agent's loop detector / dispatch see WebGPU exactly like any other provider. Reliability at 0.6B is mixed — the settings card will nudge users toward Ask mode in a follow-up. Streaming: v1 returns the full response (no per-token streaming yet). The 0.6B model finishes a normal turn in seconds; the round-trip-and- yield simplification let us ship the provider without first solving the background↔offscreen chunked-message router. Comment in webgpu.js's chatStream() flags the upgrade target. Default-disabled (`enabled:false`) because the first-run download is substantial and the library has to be vendored locally — see src/chrome/vendor/transformers/README.md for the one-command vendoring flow. The provider returns a clear "library not vendored" error when the file is missing, so the failure mode is obvious. Firefox: stub that fails fast with "not yet supported on Firefox". Firefox doesn't have browser.offscreen and its extension-context WebGPU exposure is its own can of worms — wiring those is its own future PR. Stub stays so the categorization parity test stays green. Tests: 4 new (130 total, all passing). webgpu provider present + local + disabled by default; no network fields (truly in-browser); _create- Provider wires the right class; chrome/firefox provider sets stay in sync. The actual chat() path can't be exercised in Node — no chrome. offscreen, no WebGPU — but the wiring + classification do. Co-Authored-By: Claude Opus 4.7 (1M context) --- .gitignore | 11 ++ src/chrome/src/offscreen/offscreen.html | 9 +- src/chrome/src/offscreen/offscreen.js | 213 +++++++++++++++++++++- src/chrome/src/providers/manager.js | 21 +++ src/chrome/src/providers/webgpu.js | 192 +++++++++++++++++++ src/chrome/src/ui/locales/en.js | 1 + src/chrome/src/ui/settings.js | 13 +- src/chrome/vendor/transformers/README.md | 69 +++++++ src/firefox/src/providers/manager.js | 19 ++ src/firefox/src/providers/webgpu.js | 37 ++++ src/firefox/src/ui/locales/en.js | 1 + src/firefox/src/ui/settings.js | 11 +- src/firefox/vendor/transformers/README.md | 10 + test/run.js | 37 ++++ 14 files changed, 635 insertions(+), 9 deletions(-) create mode 100644 src/chrome/src/providers/webgpu.js create mode 100644 src/chrome/vendor/transformers/README.md create mode 100644 src/firefox/src/providers/webgpu.js create mode 100644 src/firefox/vendor/transformers/README.md diff --git a/.gitignore b/.gitignore index 16764c309..4b554e979 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,17 @@ node_modules/ test/anonymous/.test-profile/ +# Vendored @huggingface/transformers build artifacts. See +# src/{chrome,firefox}/vendor/transformers/README.md — the build is +# dropped in locally and too big to commit. The READMEs themselves +# stay tracked. +src/chrome/vendor/transformers/*.js +src/chrome/vendor/transformers/*.wasm +src/chrome/vendor/transformers/*.mjs +src/firefox/vendor/transformers/*.js +src/firefox/vendor/transformers/*.wasm +src/firefox/vendor/transformers/*.mjs + # ---- SocialMediaDownloader test suite ---- # Cookies / session state if someone ever points the profile here smd-test-profile/ diff --git a/src/chrome/src/offscreen/offscreen.html b/src/chrome/src/offscreen/offscreen.html index b9adc49fa..369302898 100644 --- a/src/chrome/src/offscreen/offscreen.html +++ b/src/chrome/src/offscreen/offscreen.html @@ -1,2 +1,9 @@ - + + diff --git a/src/chrome/src/offscreen/offscreen.js b/src/chrome/src/offscreen/offscreen.js index 6ecfa6fe2..c94040d58 100644 --- a/src/chrome/src/offscreen/offscreen.js +++ b/src/chrome/src/offscreen/offscreen.js @@ -1,13 +1,21 @@ /** - * Offscreen document — fetch proxy for local network LLM servers. + * Offscreen document — host for tasks the MV3 service worker can't do + * itself. * - * Chrome MV3 service workers can't always reach HTTP servers on the local - * network (Private Network Access + CORS restrictions). This offscreen - * document receives fetch requests from the service worker, makes them - * from a regular page context (which has different networking rules), - * and sends the response back. + * 1. `offscreen-fetch` — fetch() proxy for local network LLM servers. + * The SW can't always reach 192.168.* / 127.* directly due to PNA + + * CORS; this page context can. See providers/fetch-with-fallback.js. + * + * 2. `webgpu-chat` / `webgpu-probe` — runs the WebGPU + ONNX local + * LLM (default Qwen 3 0.6B). The SW has no WebGPU; this document + * does. Pipeline is loaded lazily on first chat call and cached for + * the document's lifetime. Library is vendored under + * src/chrome/vendor/transformers/ — see the README there for how + * to drop the build in. */ +// ─── Local-network fetch proxy ──────────────────────────────────────────── + chrome.runtime.onMessage.addListener((msg, _sender, sendResponse) => { if (msg.type !== 'offscreen-fetch') return false; @@ -47,3 +55,196 @@ chrome.runtime.onMessage.addListener((msg, _sender, sendResponse) => { return true; // keep sendResponse channel open for async }); + +// ─── WebGPU LLM inference ───────────────────────────────────────────────── + +let _libPromise = null; // Promise resolving to the transformers module +let _libraryVersion = null; // for diagnostics +let _activeModelId = null; // which model the cached pipeline is for +let _activePipeline = null; // text-generation pipeline instance + +/** + * Lazily import the vendored @huggingface/transformers ESM build. The + * library is large (~5MB JS + ~30MB WASM blob) so we keep it out of the + * extension's normal load path — it only loads when the user actually + * picks the WebGPU provider. Missing-vendor case returns a clear error + * pointing at the vendor README. + */ +async function loadLibrary() { + if (_libPromise) return _libPromise; + _libPromise = (async () => { + let lib; + try { + // Dynamic import so a missing file fails at runtime (with a clear + // message) instead of at offscreen-doc parse time. + lib = await import('../../vendor/transformers/transformers.min.js'); + } catch (e) { + _libPromise = null; // allow retry after the user vendors the file + throw new Error( + 'transformers.js library not vendored. See ' + + 'src/chrome/vendor/transformers/README.md for how to drop the ' + + 'build in. Underlying error: ' + (e?.message || String(e)) + ); + } + _libraryVersion = lib.env?.version || lib.VERSION || 'unknown'; + if (lib.env) { + // Force HF Hub for model loads (extensions can't run a side-server + // for local model files). IndexedDB cache is on by default — that + // gives us the "big first download, instant subsequent runs" UX. + lib.env.allowLocalModels = false; + lib.env.allowRemoteModels = true; + } + return lib; + })(); + return _libPromise; +} + +async function getPipeline(modelId, dtype, device) { + if (_activePipeline && _activeModelId === modelId) return _activePipeline; + const lib = await loadLibrary(); + const { pipeline } = lib; + // Free the previous pipeline before loading a new one — two 500MB + // models pinned in GPU memory is a recipe for OOM on integrated GPUs. + if (_activePipeline && _activePipeline.dispose) { + try { await _activePipeline.dispose(); } catch {} + } + _activePipeline = await pipeline('text-generation', modelId, { + device: device || 'webgpu', + dtype: dtype || 'q4', + }); + _activeModelId = modelId; + return _activePipeline; +} + +chrome.runtime.onMessage.addListener((msg, _sender, sendResponse) => { + if (msg.type !== 'webgpu-probe') return false; + (async () => { + try { + // Just check the library imports and WebGPU exists — don't load + // model weights (that's the expensive step we defer until the + // user actually runs a chat). + await loadLibrary(); + const hasWebGPU = typeof navigator !== 'undefined' && 'gpu' in navigator; + sendResponse({ + ok: true, + libraryVersion: _libraryVersion, + device: hasWebGPU ? 'webgpu' : 'wasm', + hasWebGPU, + }); + } catch (e) { + sendResponse({ ok: false, error: e.message }); + } + })(); + return true; +}); + +chrome.runtime.onMessage.addListener((msg, _sender, sendResponse) => { + if (msg.type !== 'webgpu-chat') return false; + + (async () => { + try { + const pipe = await getPipeline(msg.model, msg.dtype, msg.device); + const messages = msg.messages || []; + const opts = msg.options || {}; + + // transformers.js text-generation pipelines accept a messages array + // for ChatML-style templating. Qwen 3 ships a chat template that + // knows about tools — passing `tools` in here makes the system + // prompt include them, and the model emits {...} + // blocks in its reply which we extract below. + const generateArgs = { + max_new_tokens: opts.maxTokens || 1024, + temperature: opts.temperature ?? 0.7, + do_sample: (opts.temperature ?? 0.7) > 0, + return_full_text: false, + }; + if (opts.tools && opts.tools.length > 0) { + // OpenAI sends {type:'function', function:{name,description,parameters}} + // Qwen's template wants just the inner function object. + generateArgs.tools = opts.tools.map(t => t.function || t); + } + + const output = await pipe(messages, generateArgs); + const text = extractGeneratedText(output); + const toolCalls = extractToolCalls(text); + + sendResponse({ + ok: true, + content: toolCalls ? '' : text, + toolCalls: toolCalls || null, + usage: null, // transformers.js doesn't surface token counts uniformly + raw: { rawText: text }, + }); + } catch (e) { + sendResponse({ ok: false, error: e.message }); + } + })(); + + return true; +}); + +/** + * Pull the generated text out of transformers.js's output. The pipeline + * returns one of a few shapes depending on options — handle the common + * ones, fall back to JSON-stringifying so we never silently drop content. + */ +function extractGeneratedText(output) { + if (!output) return ''; + if (typeof output === 'string') return output; + if (Array.isArray(output)) { + const first = output[0]; + if (!first) return ''; + if (typeof first === 'string') return first; + if (first.generated_text) { + if (typeof first.generated_text === 'string') return first.generated_text; + // ChatML mode: generated_text is the full messages array. Pick the + // last assistant message. + if (Array.isArray(first.generated_text)) { + for (let i = first.generated_text.length - 1; i >= 0; i--) { + const m = first.generated_text[i]; + if (m?.role === 'assistant' && typeof m.content === 'string') return m.content; + } + } + } + } + return JSON.stringify(output); +} + +/** + * Parse Qwen-style `{...}` blocks out of the + * model's text output and convert them to OpenAI-format tool_calls. + * Returns null if no tool calls are found. + * + * Qwen 3's chat template emits one block per tool call with `name` + + * `arguments` fields inside. The agent expects OpenAI's + * {id, type:'function', function:{name, arguments:JSON-stringified}} + * shape — we map between them here so the rest of the pipeline + * (loop detector, tool dispatch) treats WebGPU exactly like any other + * provider. + */ +function extractToolCalls(text) { + if (!text || typeof text !== 'string') return null; + if (!text.includes('')) return null; + const calls = []; + const re = /\s*([\s\S]*?)\s*<\/tool_call>/g; + let match; + let idx = 0; + while ((match = re.exec(text)) !== null) { + try { + const obj = JSON.parse(match[1]); + if (obj && obj.name) { + calls.push({ + id: `webgpu_call_${Date.now()}_${idx++}`, + type: 'function', + function: { + name: obj.name, + arguments: typeof obj.arguments === 'string' + ? obj.arguments + : JSON.stringify(obj.arguments || {}), + }, + }); + } + } catch { /* malformed tool-call block — ignore, treat as text */ } + } + return calls.length > 0 ? calls : null; +} diff --git a/src/chrome/src/providers/manager.js b/src/chrome/src/providers/manager.js index c2ef2de7b..c67a8a88d 100644 --- a/src/chrome/src/providers/manager.js +++ b/src/chrome/src/providers/manager.js @@ -1,6 +1,7 @@ import { LlamaCppProvider } from './llamacpp.js'; import { OpenAICompatibleProvider } from './openai.js'; import { AnthropicProvider, AnthropicOAuthProvider } from './anthropic.js'; +import { WebGPUProvider } from './webgpu.js'; /** * Manages LLM provider instances and persists configuration. @@ -77,6 +78,24 @@ export class ProviderManager { supportsVision: false, enabled: true, }, + // Browser-native local: WebGPU + ONNX runtime via @huggingface/transformers. + // No separate server needed — model weights download from HF Hub on + // first use (~500MB for q4 Qwen 3 0.6B), cached in IndexedDB by the + // library, inference runs in the offscreen document on the user's + // GPU. Default disabled because the first-run download is substantial + // and the library has to be vendored — see + // src/chrome/vendor/transformers/README.md. + webgpu_qwen3: { + type: 'webgpu', + category: 'local', + label: 'Qwen 3 0.6B (WebGPU, in-browser)', + model: 'onnx-community/Qwen3-0.6B-ONNX', + dtype: 'q4', + device: 'webgpu', + supportsVision: false, + useCompactPrompt: true, + enabled: false, + }, ollama: { type: 'openai', category: 'local', @@ -241,6 +260,8 @@ export class ProviderManager { return new AnthropicProvider(config); case 'anthropic_oauth': return new AnthropicOAuthProvider(config); + case 'webgpu': + return new WebGPUProvider(config); default: throw new Error(`Unknown provider type: ${config.type}`); } diff --git a/src/chrome/src/providers/webgpu.js b/src/chrome/src/providers/webgpu.js new file mode 100644 index 000000000..de16bc664 --- /dev/null +++ b/src/chrome/src/providers/webgpu.js @@ -0,0 +1,192 @@ +/** + * WebGPU Provider — runs Qwen / similar small models entirely in the + * browser via WebGPU + ONNX (@huggingface/transformers). + * + * Why this exists: the other "local" providers (llama.cpp, ollama, lmstudio) + * still require the user to install + run a separate server. This one needs + * nothing — model weights download from HuggingFace on first use, cached in + * IndexedDB by transformers.js, and inference runs on the user's GPU through + * the extension's offscreen document. + * + * Architecture: + * service worker (background) + * └─ WebGPUProvider.chat() ──┐ + * ▼ chrome.runtime.sendMessage + * offscreen document ──┐ + * └─ @huggingface/transformers │ + * pipeline('text-generation', model, { device: 'webgpu' }) + * (loaded lazily on first chat call) + * + * The offscreen document is required because service workers don't have + * WebGPU access (or DOM, or IndexedDB the way transformers.js wants it). + * Webbrain already uses an offscreen doc for the local-network fetch proxy + * — we reuse the same document and add a new message handler there. + * + * Tool use: Qwen 3 supports structured tool calls via its ChatML template, + * but at 0.6B params reliability is mixed. supportsTools = true, but the + * settings UI nudges users toward Ask mode for this provider; Act mode is + * available with a "small model, expect breakage" hint. + * + * First-run cost: ~500MB download (q4 quant of Qwen3-0.6B). Cached in + * IndexedDB by transformers.js so subsequent runs are instant. + * + * Library vendoring: the @huggingface/transformers ESM build is large (~5MB + * + a ~30MB onnxruntime-web WASM blob) — too big to commit. See + * src/chrome/vendor/transformers/README.md for how to drop the file in. + * The provider returns a clear error when the library is missing. + */ + +import { BaseLLMProvider } from './base.js'; + +export class WebGPUProvider extends BaseLLMProvider { + constructor(config = {}) { + super(config); + this.model = config.model || 'onnx-community/Qwen3-0.6B-ONNX'; + this.dtype = config.dtype || 'q4'; + // device:'webgpu' is the default; setting it explicitly here lets us + // override to 'wasm' in tests or as a fallback when WebGPU is absent. + this.device = config.device || 'webgpu'; + } + + get name() { + return 'webgpu'; + } + + get supportsTools() { + // Qwen 3 has a tool-call template. Reliability at 0.6B is best-effort — + // see the settings UI hint that nudges users toward Ask mode. + return true; + } + + get supportsVision() { + // Qwen 3 0.6B is text-only. If we add a Qwen-VL or Gemma-3n entry later, + // that provider config can opt-in via the same shape used elsewhere. + return !!this.config.supportsVision; + } + + get useCompactPrompt() { + // Default ON for this provider — 0.6B context budget is tight and the + // compact prompt is exactly the workload it was written for. + return this.config.useCompactPrompt !== false; + } + + async chat(messages, options = {}) { + const res = await this._dispatch({ + type: 'webgpu-chat', + model: this.model, + dtype: this.dtype, + device: this.device, + messages, + options: { + temperature: options.temperature, + maxTokens: options.maxTokens, + tools: options.tools || null, + toolChoice: options.toolChoice || 'auto', + }, + }); + if (!res || res.error) { + throw new Error(`webgpu: ${res?.error || 'no response from offscreen document'}`); + } + return { + content: res.content || '', + toolCalls: res.toolCalls || null, + usage: res.usage || null, + raw: res.raw || null, + }; + } + + async *chatStream(messages, options = {}) { + // v1: no true token streaming. The 0.6B model finishes a normal turn + // in a couple of seconds on most laptops; the round-trip-and-yield + // simplification lets us ship the provider without first solving the + // background↔offscreen chunked-message router. Upgrade target: when + // somebody asks for it, swap this for a streamId-based subscription + // that forwards transformers.js `streamer` callbacks back to the SW. + const result = await this.chat(messages, options); + yield { + type: result.toolCalls ? 'tool_call' : 'text', + content: result.content, + toolCalls: result.toolCalls, + }; + yield { type: 'done', usage: result.usage }; + } + + async testConnection() { + // Don't trigger a full model load just to test — that's 500MB and + // tens of seconds. Instead, just verify the offscreen document is + // reachable and the library is vendored. + try { + const res = await this._dispatch({ type: 'webgpu-probe' }); + if (!res || res.error) { + return { ok: false, error: res?.error || 'offscreen probe failed' }; + } + return { + ok: true, + model: this.model, + device: res.device || this.device, + librarVersion: res.libraryVersion || null, + }; + } catch (e) { + return { ok: false, error: e.message }; + } + } + + /** + * Send a message to the offscreen document and await its reply. + * Lazily creates the offscreen doc if it doesn't exist yet — same + * pattern as fetch-with-fallback.js. + */ + async _dispatch(msg) { + await ensureOffscreen(); + return new Promise((resolve, reject) => { + try { + chrome.runtime.sendMessage(msg, (response) => { + if (chrome.runtime.lastError) { + reject(new Error(chrome.runtime.lastError.message)); + } else { + resolve(response); + } + }); + } catch (e) { + reject(e); + } + }); + } +} + +// ─── Offscreen lifecycle ────────────────────────────────────────────────── +// +// Mirror of the helper in fetch-with-fallback.js, but kept local so the +// provider has no circular dep on the fetch layer. Both ultimately drive +// the same `src/offscreen/offscreen.html` document. + +let _offscreenReady = false; + +async function ensureOffscreen() { + if (_offscreenReady) return; + try { + const existing = await chrome.offscreen.hasDocument?.(); + if (existing) { + _offscreenReady = true; + return; + } + } catch { /* hasDocument unsupported on older Chrome — fall through */ } + try { + await chrome.offscreen.createDocument({ + url: 'src/offscreen/offscreen.html', + // WORKERS is the closest documented reason for "I want WebGPU + a + // long-lived JS runtime". LOCAL_STORAGE works too and is what the + // existing fetch path uses; we match it so we don't fight over + // recreating the doc with a different reason. + reasons: ['LOCAL_STORAGE'], + justification: 'Run local LLM inference on WebGPU', + }); + _offscreenReady = true; + } catch (e) { + if (e.message?.includes('already exists') || e.message?.includes('Only a single offscreen')) { + _offscreenReady = true; + } else { + throw e; + } + } +} diff --git a/src/chrome/src/ui/locales/en.js b/src/chrome/src/ui/locales/en.js index c3c372bdd..b7a53e9c9 100644 --- a/src/chrome/src/ui/locales/en.js +++ b/src/chrome/src/ui/locales/en.js @@ -155,6 +155,7 @@ export default { 'st.provider.field.supports_vision': 'Model supports vision (multimodal)', 'st.provider.field.compact_prompt': 'Compact prompt (recommended for small models, on by default)', 'st.provider.field.model_loaded_hint': 'leave blank to use loaded model', + 'st.provider.field.dtype': 'Quantization (e.g. q4, q8, fp16)', 'st.vision.desc': 'If set, screenshots are sent to this model for reading the page, while the active provider handles planning and tool calls. Leave blank to use the active provider for vision too. OpenAI-compatible endpoints only.', 'st.vision.save': 'Save', diff --git a/src/chrome/src/ui/settings.js b/src/chrome/src/ui/settings.js index c51ef63b1..e34d8ba01 100644 --- a/src/chrome/src/ui/settings.js +++ b/src/chrome/src/ui/settings.js @@ -6,7 +6,7 @@ import { t, getLocale, setLocale, LANGUAGES } from './i18n.js'; // Version shown in the subtitle. Kept here so it only needs one update per // release; the subtitle string itself is translated. -const EXT_VERSION = '7.3.1'; +const EXT_VERSION = '7.4.0'; const providersContainer = document.getElementById('providers'); const verboseToggle = document.getElementById('toggle-verbose'); @@ -412,6 +412,17 @@ function renderProviders() { { key: 'useCompactPrompt', labelKey: 'st.provider.field.compact_prompt', type: 'checkbox' }, ], }, + // WebGPU + ONNX in-browser provider. The model field takes a HuggingFace + // repo id (e.g. onnx-community/Qwen3-0.6B-ONNX); dtype lets the user pick + // a quantization variant if their GPU has the memory for it (q4 is the + // safe default for ~6GB VRAM laptops). + webgpu_qwen3: { + fields: [ + { key: 'model', labelKey: 'st.provider.field.model', type: 'text', placeholder: 'onnx-community/Qwen3-0.6B-ONNX' }, + { key: 'dtype', labelKey: 'st.provider.field.dtype', type: 'text', placeholder: 'q4' }, + { key: 'useCompactPrompt', labelKey: 'st.provider.field.compact_prompt', type: 'checkbox' }, + ], + }, ollama: { fields: [ { key: 'baseUrl', labelKey: 'st.provider.field.server_url', type: 'text', placeholder: 'http://localhost:11434/v1' }, diff --git a/src/chrome/vendor/transformers/README.md b/src/chrome/vendor/transformers/README.md new file mode 100644 index 000000000..32954e675 --- /dev/null +++ b/src/chrome/vendor/transformers/README.md @@ -0,0 +1,69 @@ +# Vendored @huggingface/transformers + +The WebGPU provider (`src/providers/webgpu.js`) loads the in-browser ONNX +runtime via `@huggingface/transformers`. The build is too large +(~5MB JS + a ~30MB onnxruntime-web WASM blob) to commit to the repo, so +it's vendored out-of-band. + +## How to drop the build in + +```bash +# From the repo root: +npm install @huggingface/transformers # or: pnpm / yarn + +# Copy the ESM bundle + the onnxruntime-web WASM files into both +# chrome and firefox vendor dirs. +cp node_modules/@huggingface/transformers/dist/transformers.min.js \ + src/chrome/vendor/transformers/ +cp node_modules/@huggingface/transformers/dist/transformers.min.js \ + src/firefox/vendor/transformers/ + +# onnxruntime-web ships its WASM separately. Copy the matching version: +cp node_modules/@huggingface/transformers/dist/ort-wasm-simd-threaded.* \ + src/chrome/vendor/transformers/ +cp node_modules/@huggingface/transformers/dist/ort-wasm-simd-threaded.* \ + src/firefox/vendor/transformers/ +``` + +The exact filename / path of the build inside `dist/` shifts between +library versions — check what's there. The provider tries to import +`transformers.min.js`; if you rename the build, update +`src/offscreen/offscreen.js`'s `await import('../../vendor/transformers/transformers.min.js')` +call to match. + +## Why not bundle this ourselves? + +We could, but: + +- The library is already a single-file ESM bundle out of `npm publish` — + no further bundling step buys us much. +- Keeping it out of git keeps the repo small and the diff history + readable. Build artifacts don't belong in source. +- Updating the library means updating ONE file in each vendor dir. + +## Why vendored and not loaded from a CDN? + +Manifest V3 extensions' CSP is `script-src 'self' 'wasm-unsafe-eval'`. +Remote scripts (` + From 479fe8d635e7ff26c04eac86723596f79a3441fc Mon Sep 17 00:00:00 2001 From: Emre Sokullu Date: Fri, 22 May 2026 16:10:29 +0300 Subject: [PATCH 04/31] WebGPU: download progress indicator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first time a user picks the WebGPU provider, ~500MB of Qwen 3 weights pull from HF Hub — a ~30-60s wait the existing UI doesn't hint at at all. Renders as a frozen "thinking…" spinner, which is indistinguishable from a hang. Add a progress card at the top of the messages container: ┌──────────────────────────────────────────────────┐ │ Downloading onnx-community/Qwen3-0.6B-ONNX — │ │ 142 / 487 MB │ │ █████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │ │ onnx/model_q4.onnx │ └──────────────────────────────────────────────────┘ - Aggregates loaded/total across files (model has ~8 parallel downloads — weights, tokenizer, config, etc.). - Bar fills to 100% + flips green on the 'ready' event, then auto-dismisses ~1.8s later so the user sees confirmation. - Throttled to one progress update per file per 200ms so the message channel doesn't drown in callbacks. - Fire-and-forget broadcast from offscreen → sidepanel (.catch swallows "no listener" errors when no panel is open). Firefox side has the same listener + renderer for parity, even though the Firefox WebGPU provider itself is still stubbed — once the Firefox path is wired up, the progress UI is ready. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/chrome/src/offscreen/offscreen.js | 48 ++++++++++++ src/chrome/src/ui/locales/en.js | 5 ++ src/chrome/src/ui/sidepanel.js | 106 ++++++++++++++++++++++++++ src/chrome/styles/sidepanel.css | 44 +++++++++++ src/firefox/src/ui/locales/en.js | 5 ++ src/firefox/src/ui/sidepanel.js | 91 ++++++++++++++++++++++ src/firefox/styles/sidepanel.css | 43 +++++++++++ 7 files changed, 342 insertions(+) diff --git a/src/chrome/src/offscreen/offscreen.js b/src/chrome/src/offscreen/offscreen.js index c94040d58..d8db1afd3 100644 --- a/src/chrome/src/offscreen/offscreen.js +++ b/src/chrome/src/offscreen/offscreen.js @@ -111,11 +111,59 @@ async function getPipeline(modelId, dtype, device) { _activePipeline = await pipeline('text-generation', modelId, { device: device || 'webgpu', dtype: dtype || 'q4', + // Stream download progress to the side panel. Without this the UI + // shows nothing for ~30-60s on first run while ~500MB of weights + // pull from the HF Hub, which is indistinguishable from a hang. + // The callback fires per file with one of: + // {status:'initiate', file, name} // queued + // {status:'download', file, name} // about to start + // {status:'progress', file, loaded, total, progress} // bytes streaming + // {status:'done', file, name} // file complete + // {status:'ready', model, task} // pipeline ready + progress_callback: (ev) => broadcastProgress(modelId, ev), }); _activeModelId = modelId; return _activePipeline; } +/** + * Forward a transformers.js progress event to anyone listening (side + * panel). The SW relays this to its open extension pages via + * chrome.runtime.sendMessage with action='model_download'. We use a + * "fire-and-forget, swallow rejections" pattern because no listener is + * fine — first-run UI is a bonus, not a contract. + * + * Throttling: 'progress' events fire many times per second across + * multiple files in parallel. We rate-limit to one event per file per + * 200ms so the message channel doesn't drown in updates. + */ +const _progressLastEmitted = new Map(); // key = `${modelId}|${file}`, value = ts +function broadcastProgress(modelId, ev) { + try { + const file = ev?.file || ev?.name || ''; + const status = ev?.status || ''; + // Always pass through state transitions (initiate / download / done / + // ready); rate-limit only the continuous 'progress' stream. + if (status === 'progress') { + const key = `${modelId}|${file}`; + const now = Date.now(); + const last = _progressLastEmitted.get(key) || 0; + if (now - last < 200) return; + _progressLastEmitted.set(key, now); + } + chrome.runtime.sendMessage({ + target: 'sidepanel', + action: 'model_download', + modelId, + status, + file, + loaded: ev?.loaded || 0, + total: ev?.total || 0, + progress: ev?.progress || 0, + }).catch(() => { /* no listener — fine, progress UI is best-effort */ }); + } catch { /* never let a UI update break the download */ } +} + chrome.runtime.onMessage.addListener((msg, _sender, sendResponse) => { if (msg.type !== 'webgpu-probe') return false; (async () => { diff --git a/src/chrome/src/ui/locales/en.js b/src/chrome/src/ui/locales/en.js index 76592c93f..0b2f1559e 100644 --- a/src/chrome/src/ui/locales/en.js +++ b/src/chrome/src/ui/locales/en.js @@ -62,6 +62,11 @@ export default { 'sp.clarify.input_placeholder_with_options': 'Or type a different answer…', 'sp.clarify.your_answer': 'Your answer:', + 'sp.model_download.headline': 'Downloading {model} — {mb} / {total_mb} MB', + 'sp.model_download.queued': 'Queued', + 'sp.model_download.file_done': 'File complete', + 'sp.model_download.ready': '{model} ready', + 'sp.step.details': 'details', 'sp.step.input_label': 'Input', 'sp.step.result_label': 'Result', diff --git a/src/chrome/src/ui/sidepanel.js b/src/chrome/src/ui/sidepanel.js index 228214dcb..09cbc333e 100644 --- a/src/chrome/src/ui/sidepanel.js +++ b/src/chrome/src/ui/sidepanel.js @@ -605,6 +605,18 @@ function summarizeLastTranscript() { if (sendBtn) sendBtn.click(); } +// Model-download progress (WebGPU provider's first-run weights download +// from HF Hub). Broadcast by the offscreen document via chrome.runtime +// .sendMessage with action='model_download'. Listener is separate from +// the agent_update one below because download events fire outside of any +// chat turn (the user clicks Test Connection or sends their first message; +// the model loads in the background; we want to surface progress without +// hijacking the agent's normal status pipeline). +chrome.runtime.onMessage.addListener((msg) => { + if (msg.target !== 'sidepanel' || msg.action !== 'model_download') return; + renderModelDownloadProgress(msg); +}); + chrome.runtime.onMessage.addListener((msg) => { if (msg.target !== 'sidepanel' || msg.action !== 'agent_update') return; @@ -719,6 +731,100 @@ chrome.runtime.onMessage.addListener((msg) => { } }); +/** + * Render / update the WebGPU model-download progress card. Lives at the + * top of the messages container while a download is active; auto-dismisses + * a couple of seconds after the 'ready' event so the user sees confirmation + * before it disappears. + * + * Aggregates across multiple in-flight files: the model has ~8 files (the + * .onnx tensor blob, tokenizer, config, generation_config, etc.) and they + * arrive in parallel. We sum loaded/total across files for the headline + * progress, and show the currently-downloading filename below it. + */ +const _modelDownloadState = { + cardEl: null, + files: new Map(), // file → {loaded, total, status} + dismissTimer: null, +}; + +function renderModelDownloadProgress(msg) { + const { status, file, loaded, total, modelId } = msg; + + // Track per-file progress so totals are accurate even with parallel + // downloads. 'done' / 'ready' don't have byte counts; preserve the + // last-known totals. + if (file) { + const prev = _modelDownloadState.files.get(file) || { loaded: 0, total: 0 }; + _modelDownloadState.files.set(file, { + loaded: status === 'done' ? (prev.total || prev.loaded) : (loaded || prev.loaded), + total: total || prev.total, + status, + }); + } + + // Build or find the card. + if (!_modelDownloadState.cardEl) { + const card = document.createElement('div'); + card.className = 'model-download-card'; + card.innerHTML = ` +
+
+
+ `; + if (messagesEl) messagesEl.prepend(card); + _modelDownloadState.cardEl = card; + } + const card = _modelDownloadState.cardEl; + const headline = card.querySelector('.model-download-headline'); + const fill = card.querySelector('.model-download-bar-fill'); + const detail = card.querySelector('.model-download-detail'); + + if (status === 'ready') { + headline.textContent = (typeof t === 'function' ? t('sp.model_download.ready', { model: modelId }) : `${modelId} ready`) || `${modelId} ready`; + fill.style.width = '100%'; + fill.classList.add('done'); + detail.textContent = ''; + // Linger briefly so the user sees "ready", then fade out. + if (_modelDownloadState.dismissTimer) clearTimeout(_modelDownloadState.dismissTimer); + _modelDownloadState.dismissTimer = setTimeout(() => { + if (_modelDownloadState.cardEl) { + _modelDownloadState.cardEl.remove(); + _modelDownloadState.cardEl = null; + _modelDownloadState.files.clear(); + } + }, 1800); + scrollToBottom(); + return; + } + + // Aggregate across files for the headline bar. + let totalLoaded = 0; + let totalSize = 0; + for (const f of _modelDownloadState.files.values()) { + totalLoaded += f.loaded || 0; + totalSize += f.total || 0; + } + const pct = totalSize > 0 ? Math.min(100, Math.round((totalLoaded / totalSize) * 100)) : 0; + fill.style.width = `${pct}%`; + fill.classList.remove('done'); + + const headlineText = (typeof t === 'function' + ? t('sp.model_download.headline', { model: modelId, mb: Math.round(totalLoaded / 1048576), total_mb: Math.round(totalSize / 1048576) || '?' }) + : null) || `Downloading ${modelId} — ${Math.round(totalLoaded / 1048576)} / ${Math.round(totalSize / 1048576) || '?'} MB`; + headline.textContent = headlineText; + + if (status === 'progress' || status === 'download') { + detail.textContent = file || ''; + } else if (status === 'initiate') { + detail.textContent = (typeof t === 'function' ? t('sp.model_download.queued') : 'Queued') + (file ? ` · ${file}` : ''); + } else if (status === 'done') { + detail.textContent = (typeof t === 'function' ? t('sp.model_download.file_done') : 'File complete') + (file ? ` · ${file}` : ''); + } + + scrollToBottom(); +} + /** * Render a clarify() prompt inside the current assistant message. Shows the * question, optional "reason" hint, suggested-option buttons, and a free- diff --git a/src/chrome/styles/sidepanel.css b/src/chrome/styles/sidepanel.css index 34c5fac61..f4caaff2b 100644 --- a/src/chrome/styles/sidepanel.css +++ b/src/chrome/styles/sidepanel.css @@ -1002,3 +1002,47 @@ body { cursor: pointer; } .btn-summarize-recording:hover { background: var(--accent2, #5a52d5); } + +/* WebGPU model-download progress — shown at the top of the messages + container while the local Qwen 3 weights pull from HF Hub on first + run. Auto-dismisses ~2s after the 'ready' event. */ +.model-download-card { + margin: 8px 0; + padding: 10px 12px; + border: 1px solid var(--accent); + border-radius: var(--radius, 6px); + background: var(--accent-dim, rgba(33, 150, 243, 0.08)); + display: flex; + flex-direction: column; + gap: 6px; +} +.model-download-headline { + font-size: 12px; + font-weight: 600; + color: var(--text-primary); +} +.model-download-bar { + width: 100%; + height: 6px; + background: rgba(255, 255, 255, 0.08); + border-radius: 3px; + overflow: hidden; +} +.model-download-bar-fill { + height: 100%; + width: 0%; + background: var(--accent); + transition: width 0.2s ease-out; + border-radius: 3px; +} +.model-download-bar-fill.done { + background: var(--success, #4caf50); +} +.model-download-detail { + font-size: 11px; + color: var(--text-secondary); + font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} diff --git a/src/firefox/src/ui/locales/en.js b/src/firefox/src/ui/locales/en.js index b7a53e9c9..0fce31471 100644 --- a/src/firefox/src/ui/locales/en.js +++ b/src/firefox/src/ui/locales/en.js @@ -54,6 +54,11 @@ export default { 'sp.clarify.input_placeholder_with_options': 'Or type a different answer…', 'sp.clarify.your_answer': 'Your answer:', + 'sp.model_download.headline': 'Downloading {model} — {mb} / {total_mb} MB', + 'sp.model_download.queued': 'Queued', + 'sp.model_download.file_done': 'File complete', + 'sp.model_download.ready': '{model} ready', + 'sp.step.details': 'details', 'sp.step.input_label': 'Input', 'sp.step.result_label': 'Result', diff --git a/src/firefox/src/ui/sidepanel.js b/src/firefox/src/ui/sidepanel.js index 45acd1de7..f45ad5213 100644 --- a/src/firefox/src/ui/sidepanel.js +++ b/src/firefox/src/ui/sidepanel.js @@ -287,6 +287,14 @@ async function sendMessage() { // --- Listen for Agent Updates --- +// Model-download progress (WebGPU provider — currently stubbed on +// Firefox, but the listener stays so the parity with chrome is real +// once the Firefox WebGPU path lands). +browser.runtime.onMessage.addListener((msg) => { + if (msg.target !== 'sidepanel' || msg.action !== 'model_download') return; + renderModelDownloadProgress(msg); +}); + browser.runtime.onMessage.addListener((msg) => { if (msg.target !== 'sidepanel' || msg.action !== 'agent_update') return; @@ -395,6 +403,89 @@ browser.runtime.onMessage.addListener((msg) => { } }); +/** + * Render / update the WebGPU model-download progress card. See + * chrome/sidepanel.js for the design notes. Currently inert on Firefox + * (the WebGPU provider is a stub) but the listener + rendering stay so + * the cut-over is one-line when the Firefox WebGPU path lands. + */ +const _modelDownloadState = { + cardEl: null, + files: new Map(), + dismissTimer: null, +}; + +function renderModelDownloadProgress(msg) { + const { status, file, loaded, total, modelId } = msg; + + if (file) { + const prev = _modelDownloadState.files.get(file) || { loaded: 0, total: 0 }; + _modelDownloadState.files.set(file, { + loaded: status === 'done' ? (prev.total || prev.loaded) : (loaded || prev.loaded), + total: total || prev.total, + status, + }); + } + + if (!_modelDownloadState.cardEl) { + const card = document.createElement('div'); + card.className = 'model-download-card'; + card.innerHTML = ` +
+
+
+ `; + if (messagesEl) messagesEl.prepend(card); + _modelDownloadState.cardEl = card; + } + const card = _modelDownloadState.cardEl; + const headline = card.querySelector('.model-download-headline'); + const fill = card.querySelector('.model-download-bar-fill'); + const detail = card.querySelector('.model-download-detail'); + + if (status === 'ready') { + headline.textContent = (typeof t === 'function' ? t('sp.model_download.ready', { model: modelId }) : `${modelId} ready`) || `${modelId} ready`; + fill.style.width = '100%'; + fill.classList.add('done'); + detail.textContent = ''; + if (_modelDownloadState.dismissTimer) clearTimeout(_modelDownloadState.dismissTimer); + _modelDownloadState.dismissTimer = setTimeout(() => { + if (_modelDownloadState.cardEl) { + _modelDownloadState.cardEl.remove(); + _modelDownloadState.cardEl = null; + _modelDownloadState.files.clear(); + } + }, 1800); + scrollToBottom(); + return; + } + + let totalLoaded = 0; + let totalSize = 0; + for (const f of _modelDownloadState.files.values()) { + totalLoaded += f.loaded || 0; + totalSize += f.total || 0; + } + const pct = totalSize > 0 ? Math.min(100, Math.round((totalLoaded / totalSize) * 100)) : 0; + fill.style.width = `${pct}%`; + fill.classList.remove('done'); + + const headlineText = (typeof t === 'function' + ? t('sp.model_download.headline', { model: modelId, mb: Math.round(totalLoaded / 1048576), total_mb: Math.round(totalSize / 1048576) || '?' }) + : null) || `Downloading ${modelId} — ${Math.round(totalLoaded / 1048576)} / ${Math.round(totalSize / 1048576) || '?'} MB`; + headline.textContent = headlineText; + + if (status === 'progress' || status === 'download') { + detail.textContent = file || ''; + } else if (status === 'initiate') { + detail.textContent = (typeof t === 'function' ? t('sp.model_download.queued') : 'Queued') + (file ? ` · ${file}` : ''); + } else if (status === 'done') { + detail.textContent = (typeof t === 'function' ? t('sp.model_download.file_done') : 'File complete') + (file ? ` · ${file}` : ''); + } + + scrollToBottom(); +} + /** * Render a clarify() prompt inside the current assistant message. Shows * the question, optional "reason" hint, suggested-option buttons, and a diff --git a/src/firefox/styles/sidepanel.css b/src/firefox/styles/sidepanel.css index 48b27ba82..3211316d4 100644 --- a/src/firefox/styles/sidepanel.css +++ b/src/firefox/styles/sidepanel.css @@ -925,3 +925,46 @@ body { border-top: 1px dashed var(--border); } + +/* WebGPU model-download progress — currently inert on Firefox (provider + is stubbed), kept for parity with chrome so the layout doesn't drift. */ +.model-download-card { + margin: 8px 0; + padding: 10px 12px; + border: 1px solid var(--accent); + border-radius: var(--radius, 6px); + background: var(--accent-dim, rgba(33, 150, 243, 0.08)); + display: flex; + flex-direction: column; + gap: 6px; +} +.model-download-headline { + font-size: 12px; + font-weight: 600; + color: var(--text-primary); +} +.model-download-bar { + width: 100%; + height: 6px; + background: rgba(255, 255, 255, 0.08); + border-radius: 3px; + overflow: hidden; +} +.model-download-bar-fill { + height: 100%; + width: 0%; + background: var(--accent); + transition: width 0.2s ease-out; + border-radius: 3px; +} +.model-download-bar-fill.done { + background: var(--success, #4caf50); +} +.model-download-detail { + font-size: 11px; + color: var(--text-secondary); + font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} From 3ab4a972a783fc569fedb369ab5768c49246b575 Mon Sep 17 00:00:00 2001 From: Emre Sokullu Date: Fri, 22 May 2026 16:13:46 +0300 Subject: [PATCH 05/31] Vendor @huggingface/transformers 4.2.0 (WebGPU + ONNX runtime) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commits the three files the WebGPU provider needs: src/chrome/vendor/transformers/ ├─ transformers.web.min.js (422 KB — browser ESM bundle) ├─ ort-wasm-simd-threaded.jsep.mjs ( 46 KB — WASM loader shim) └─ ort-wasm-simd-threaded.jsep.wasm ( 25 MB — WebGPU ONNX runtime) Yes, the .wasm is 25MB. It's the cost of shipping a real local LLM runtime — there's no smaller variant that does WebGPU. The trade-off: the extension grows from ~2MB to ~28MB on disk, in exchange for a provider that works straight from `git clone` with zero per-developer setup. Previous behaviour was "vendor the library yourself per the README" which is realistic for a 1-person team and friction for any larger group. Implementation details: - We vendor the .web.min.js variant (not the dual ESM/CJS transformers.min.js or the Node builds). Smaller, browser-only, matches our actual import path. - env.backends.onnx.wasm.wasmPaths is pinned to the vendor dir's chrome-extension:// URL. Without this the loader resolves the WASM path relative to transformers.web.min.js's URL — which happens to work today because they're siblings, but only by accident. Setting it explicitly makes the wiring obvious and survives future re-vendoring at different paths. Wrapped in try/catch so library shape changes between versions fall back to default resolution. - The CPU-fallback WASM variants (.wasm / .asyncify.wasm / .jspi.wasm) are intentionally NOT vendored — system without WebGPU gets a clear "WebGPU not available" error instead. Saves ~40MB of WASM we don't use. Add them later if CPU fallback becomes a real ask. - Firefox vendor dir stays empty (gitignored) — the Firefox WebGPU provider is still a stub; no point shipping 25MB of WASM it doesn't reach. Comment in .gitignore flags this for whoever wires the Firefox path next. - package.json now lists @huggingface/transformers as a regular dep (not devDep) — semantically wrong for an ESM file we commit, but useful: `npm install` keeps the version pinned for whoever needs to update the vendored files later. The README documents the update flow. The README in the vendor dir reflects the new "it's checked in" reality and explains the update procedure for next time. Co-Authored-By: Claude Opus 4.7 (1M context) --- .gitignore | 12 +- package-lock.json | 979 ++++++++++++++++++ package.json | 5 +- src/chrome/src/offscreen/offscreen.js | 21 +- src/chrome/vendor/transformers/README.md | 101 +- .../ort-wasm-simd-threaded.jsep.mjs | 106 ++ .../ort-wasm-simd-threaded.jsep.wasm | Bin 0 -> 26101073 bytes .../transformers/transformers.web.min.js | 36 + 8 files changed, 1201 insertions(+), 59 deletions(-) create mode 100644 src/chrome/vendor/transformers/ort-wasm-simd-threaded.jsep.mjs create mode 100644 src/chrome/vendor/transformers/ort-wasm-simd-threaded.jsep.wasm create mode 100644 src/chrome/vendor/transformers/transformers.web.min.js diff --git a/.gitignore b/.gitignore index 4b554e979..b7b36c9e1 100644 --- a/.gitignore +++ b/.gitignore @@ -3,13 +3,11 @@ node_modules/ test/anonymous/.test-profile/ -# Vendored @huggingface/transformers build artifacts. See -# src/{chrome,firefox}/vendor/transformers/README.md — the build is -# dropped in locally and too big to commit. The READMEs themselves -# stay tracked. -src/chrome/vendor/transformers/*.js -src/chrome/vendor/transformers/*.wasm -src/chrome/vendor/transformers/*.mjs +# Vendored @huggingface/transformers — Chrome's build is committed +# (see src/chrome/vendor/transformers/README.md for versioning notes). +# Firefox's stays gitignored because the Firefox WebGPU provider is +# still a stub; once it's wired, copy the chrome vendor over and +# remove the firefox exclusion below. src/firefox/vendor/transformers/*.js src/firefox/vendor/transformers/*.wasm src/firefox/vendor/transformers/*.mjs diff --git a/package-lock.json b/package-lock.json index c6c854117..2abdd55a3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,10 +8,695 @@ "name": "webbrain", "version": "7.4.0", "license": "MIT", + "dependencies": { + "@huggingface/transformers": "^4.2.0" + }, "devDependencies": { "playwright": "^1.48.0" } }, + "node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@huggingface/jinja": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/@huggingface/jinja/-/jinja-0.5.9.tgz", + "integrity": "sha512-uWTG+l3VJRsl7EXxYizuL3P+cCPoc3cRqbWWRcQN0FhejRfbdq0RNhCmbY/YDtnTcz9icdLYuLDjsnz4d8JMuw==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@huggingface/tokenizers": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@huggingface/tokenizers/-/tokenizers-0.1.3.tgz", + "integrity": "sha512-8rF/RRT10u+kn7YuUbUg0OF30K8rjTc78aHpxT+qJ1uWSqxT1MHi8+9ltwYfkFYJzT/oS+qw3JVfHtNMGAdqyA==", + "license": "Apache-2.0" + }, + "node_modules/@huggingface/transformers": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@huggingface/transformers/-/transformers-4.2.0.tgz", + "integrity": "sha512-8BRCoBMH0XsWaEIamuR0LrJGAfftgHAfb2Vrffy0VKlSAE/MnUJ5/h/zTfEP3fDIft+nk7TqB8xXEyABGitBjQ==", + "license": "Apache-2.0", + "dependencies": { + "@huggingface/jinja": "^0.5.6", + "@huggingface/tokenizers": "^0.1.3", + "onnxruntime-node": "1.24.3", + "onnxruntime-web": "1.26.0-dev.20260416-b7804b056c", + "sharp": "^0.34.5" + } + }, + "node_modules/@img/colour": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", + "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "cpu": [ + "riscv64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "cpu": [ + "ppc64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "cpu": [ + "riscv64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.7.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz", + "integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.1.tgz", + "integrity": "sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.1.tgz", + "integrity": "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.2.tgz", + "integrity": "sha512-pa0vFRuws4wkvaXKK1uXZMAwAX4/t8ANaJo45iw/oQHNQ9q5xUzwgFmVJGXiga2BeN+zpX7Vf9vmsiIa2J+MUw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.1.tgz", + "integrity": "sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==", + "license": "BSD-3-Clause" + }, + "node_modules/@types/node": { + "version": "25.9.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.1.tgz", + "integrity": "sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==", + "license": "MIT", + "dependencies": { + "undici-types": ">=7.24.0 <7.24.7" + } + }, + "node_modules/adm-zip": { + "version": "0.5.17", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.17.tgz", + "integrity": "sha512-+Ut8d9LLqwEvHHJl1+PIHqoyDxFgVN847JTVM3Izi3xHDWPE4UtzzXysMZQs64DMcrJfBeS/uoEP4AD3HQHnQQ==", + "license": "MIT", + "engines": { + "node": ">=12.0" + } + }, + "node_modules/boolean": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", + "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "license": "MIT" + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "license": "MIT" + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flatbuffers": { + "version": "25.9.23", + "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-25.9.23.tgz", + "integrity": "sha512-MI1qs7Lo4Syw0EOzUl0xjs2lsoeqFku44KpngfIduHBYvzm8h2+7K8YMQh1JtVVVrUvhLpNwqVi4DERegUJhPQ==", + "license": "Apache-2.0" + }, "node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", @@ -27,6 +712,151 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/global-agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", + "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", + "license": "BSD-3-Clause", + "dependencies": { + "boolean": "^3.0.1", + "es6-error": "^4.1.1", + "matcher": "^3.0.0", + "roarr": "^2.15.3", + "semver": "^7.3.2", + "serialize-error": "^7.0.1" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/guid-typescript": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/guid-typescript/-/guid-typescript-1.0.9.tgz", + "integrity": "sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ==", + "license": "ISC" + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "license": "ISC" + }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/matcher": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/onnxruntime-common": { + "version": "1.24.3", + "resolved": "https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.24.3.tgz", + "integrity": "sha512-GeuPZO6U/LBJXvwdaqHbuUmoXiEdeCjWi/EG7Y1HNnDwJYuk6WUbNXpF6luSUY8yASul3cmUlLGrCCL1ZgVXqA==", + "license": "MIT" + }, + "node_modules/onnxruntime-node": { + "version": "1.24.3", + "resolved": "https://registry.npmjs.org/onnxruntime-node/-/onnxruntime-node-1.24.3.tgz", + "integrity": "sha512-JH7+czbc8ALA819vlTgcV+Q214/+VjGeBHDjX81+ZCD0PCVCIFGFNtT0V4sXG/1JXypKPgScQcB3ij/hk3YnTg==", + "hasInstallScript": true, + "license": "MIT", + "os": [ + "win32", + "darwin", + "linux" + ], + "dependencies": { + "adm-zip": "^0.5.16", + "global-agent": "^3.0.0", + "onnxruntime-common": "1.24.3" + } + }, + "node_modules/onnxruntime-web": { + "version": "1.26.0-dev.20260416-b7804b056c", + "resolved": "https://registry.npmjs.org/onnxruntime-web/-/onnxruntime-web-1.26.0-dev.20260416-b7804b056c.tgz", + "integrity": "sha512-MD6Ss4GSpQBo6zqoJzyT9LRbKYs7x/JVN23FT24EcEvlqF4VuzPOeH6X38orZPKHQDbprn7K+SBpu0/mj2CQiw==", + "license": "MIT", + "dependencies": { + "flatbuffers": "^25.1.24", + "guid-typescript": "^1.0.9", + "long": "^5.2.3", + "onnxruntime-common": "1.24.0-dev.20251116-b39e144322", + "platform": "^1.3.6", + "protobufjs": "^7.2.4" + } + }, + "node_modules/onnxruntime-web/node_modules/onnxruntime-common": { + "version": "1.24.0-dev.20251116-b39e144322", + "resolved": "https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.24.0-dev.20251116-b39e144322.tgz", + "integrity": "sha512-BOoomdHYmNRL5r4iQ4bMvsl2t0/hzVQ3OM3PHD0gxeXu1PmggqBv3puZicEUVOA3AtHHYmqZtjMj9FOfGrATTw==", + "license": "MIT" + }, + "node_modules/platform": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", + "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==", + "license": "MIT" + }, "node_modules/playwright": { "version": "1.59.1", "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.59.1.tgz", @@ -58,6 +888,155 @@ "engines": { "node": ">=18" } + }, + "node_modules/protobufjs": { + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.1.tgz", + "integrity": "sha512-4K0myLaWL5EteuSAro91EGFgcfVgxb64Jx+7oDAY6GOkXD4M69yuSEljNcInGVCA5sOPxmZ/EqDLj2x0Q0+Ygg==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.5", + "@protobufjs/eventemitter": "^1.1.1", + "@protobufjs/fetch": "^1.1.1", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.2", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.1", + "@types/node": ">=13.7.0", + "long": "^5.3.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/roarr": { + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", + "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", + "license": "BSD-3-Clause", + "dependencies": { + "boolean": "^3.0.1", + "detect-node": "^2.0.4", + "globalthis": "^1.0.1", + "json-stringify-safe": "^5.0.1", + "semver-compare": "^1.0.0", + "sprintf-js": "^1.1.2" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/semver": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", + "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "license": "MIT" + }, + "node_modules/serialize-error": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.13.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/sharp": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.2", + "semver": "^7.7.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "license": "BSD-3-Clause" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD", + "optional": true + }, + "node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/undici-types": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", + "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==", + "license": "MIT" } } } diff --git a/package.json b/package.json index 9c2089ae8..bcd5cdd1a 100644 --- a/package.json +++ b/package.json @@ -20,5 +20,8 @@ "type": "git", "url": "https://github.com/esokullu/webbrain.git" }, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@huggingface/transformers": "^4.2.0" + } } diff --git a/src/chrome/src/offscreen/offscreen.js b/src/chrome/src/offscreen/offscreen.js index d8db1afd3..267d99ff2 100644 --- a/src/chrome/src/offscreen/offscreen.js +++ b/src/chrome/src/offscreen/offscreen.js @@ -75,11 +75,12 @@ async function loadLibrary() { _libPromise = (async () => { let lib; try { - // Dynamic import so a missing file fails at runtime (with a clear - // message) instead of at offscreen-doc parse time. - lib = await import('../../vendor/transformers/transformers.min.js'); + // Dynamic import so a vendor-mishap fails at runtime (with a clear + // message) instead of at offscreen-doc parse time. The .web build + // is the browser ESM variant; transformers.node.* is for Node. + lib = await import('../../vendor/transformers/transformers.web.min.js'); } catch (e) { - _libPromise = null; // allow retry after the user vendors the file + _libPromise = null; // allow retry after the user re-vendors throw new Error( 'transformers.js library not vendored. See ' + 'src/chrome/vendor/transformers/README.md for how to drop the ' + @@ -93,6 +94,18 @@ async function loadLibrary() { // gives us the "big first download, instant subsequent runs" UX. lib.env.allowLocalModels = false; lib.env.allowRemoteModels = true; + // Pin the WASM file URL to OUR vendor dir. Without this, the + // onnxruntime-web loader resolves the wasm path relative to + // transformers.web.min.js's URL — which DOES work for us today + // (both files are siblings in vendor/transformers/) but only by + // happy accident. Setting it explicitly makes the wiring obvious + // and survives future re-vendoring at different paths. + try { + if (lib.env.backends?.onnx?.wasm) { + const base = chrome.runtime.getURL('vendor/transformers/'); + lib.env.backends.onnx.wasm.wasmPaths = base; + } + } catch { /* if the shape moves between library versions, fall back to defaults */ } } return lib; })(); diff --git a/src/chrome/vendor/transformers/README.md b/src/chrome/vendor/transformers/README.md index 32954e675..5f10e4825 100644 --- a/src/chrome/vendor/transformers/README.md +++ b/src/chrome/vendor/transformers/README.md @@ -1,45 +1,44 @@ # Vendored @huggingface/transformers The WebGPU provider (`src/providers/webgpu.js`) loads the in-browser ONNX -runtime via `@huggingface/transformers`. The build is too large -(~5MB JS + a ~30MB onnxruntime-web WASM blob) to commit to the repo, so -it's vendored out-of-band. +runtime via `@huggingface/transformers`. The relevant build files are +committed in this directory so the extension works straight from a +fresh `git clone` — no per-developer vendoring step. -## How to drop the build in +## What's here -```bash -# From the repo root: -npm install @huggingface/transformers # or: pnpm / yarn +| File | Source | Purpose | +| --- | --- | --- | +| `transformers.web.min.js` | `node_modules/@huggingface/transformers/dist/` | Browser ESM bundle of the library | +| `ort-wasm-simd-threaded.jsep.mjs` | `node_modules/@huggingface/transformers/dist/` | JS loader for the WebGPU WASM blob | +| `ort-wasm-simd-threaded.jsep.wasm` | `node_modules/onnxruntime-web/dist/` | The actual WebGPU-enabled ONNX runtime (~25MB) | -# Copy the ESM bundle + the onnxruntime-web WASM files into both -# chrome and firefox vendor dirs. -cp node_modules/@huggingface/transformers/dist/transformers.min.js \ - src/chrome/vendor/transformers/ -cp node_modules/@huggingface/transformers/dist/transformers.min.js \ - src/firefox/vendor/transformers/ +The `.web.min.js` build is the browser ESM variant — not +`transformers.min.js` (dual ESM/CJS), not `transformers.node.*`. The +import path in `src/offscreen/offscreen.js` is hard-coded to +`transformers.web.min.js`; if you change which build is vendored, update +that import. -# onnxruntime-web ships its WASM separately. Copy the matching version: -cp node_modules/@huggingface/transformers/dist/ort-wasm-simd-threaded.* \ - src/chrome/vendor/transformers/ -cp node_modules/@huggingface/transformers/dist/ort-wasm-simd-threaded.* \ - src/firefox/vendor/transformers/ -``` +## Current vendored version -The exact filename / path of the build inside `dist/` shifts between -library versions — check what's there. The provider tries to import -`transformers.min.js`; if you rename the build, update -`src/offscreen/offscreen.js`'s `await import('../../vendor/transformers/transformers.min.js')` -call to match. +| webbrain | @huggingface/transformers | onnxruntime-web | +| --- | --- | --- | +| 7.4.0+ | 4.2.0 | (matched, transitive dep of transformers) | -## Why not bundle this ourselves? +## Updating -We could, but: +```bash +npm install @huggingface/transformers@latest +cp node_modules/@huggingface/transformers/dist/transformers.web.min.js \ + src/chrome/vendor/transformers/ +cp node_modules/@huggingface/transformers/dist/ort-wasm-simd-threaded.jsep.mjs \ + src/chrome/vendor/transformers/ +cp node_modules/onnxruntime-web/dist/ort-wasm-simd-threaded.jsep.wasm \ + src/chrome/vendor/transformers/ +``` -- The library is already a single-file ESM bundle out of `npm publish` — - no further bundling step buys us much. -- Keeping it out of git keeps the repo small and the diff history - readable. Build artifacts don't belong in source. -- Updating the library means updating ONE file in each vendor dir. +Then bump the version row in the table above, commit, and re-run the +extension to verify Qwen 3 still loads. ## Why vendored and not loaded from a CDN? @@ -51,19 +50,27 @@ only path. ## Runtime configuration -`offscreen.js` configures the library to fetch model weights from the -HuggingFace CDN (`allowRemoteModels = true`) and to cache them in -IndexedDB (the library's default). First-run for Qwen 3 0.6B q4 is -roughly 500MB; subsequent runs are instant. - -If you need to pin the onnxruntime WASM location (e.g. because the -library's auto-detection picks the wrong path), set -`env.backends.onnx.wasm.wasmPaths` in `offscreen.js` to a -chrome-extension:// URL pointing at the vendor dir. Document any such -override here when you make it. - -## Versions tested - -| webbrain | @huggingface/transformers | notes | -| --- | --- | --- | -| 7.4.0 | (TBD, fill in when first vendored) | First release with WebGPU provider | +`offscreen.js` configures the library to: + +- Fetch model weights from the HuggingFace CDN (`allowRemoteModels = true`). +- Cache them in IndexedDB (the library's default — first-run downloads + big, subsequent runs are instant). +- Pin `env.backends.onnx.wasm.wasmPaths` to this directory's + `chrome-extension://` URL so the runtime finds the `.wasm` file + reliably regardless of how the library is bundled. + +If a future library version changes the `env.backends.onnx.wasm` shape, +the `wasmPaths` setter is wrapped in a try/catch — failure falls back +to the library's own resolution heuristics. + +## Files NOT vendored (and why) + +- `transformers.js` / `transformers.min.js` (dual builds, ~1.3MB each) — + redundant with the `.web.min.js` we use; the dual variants embed Node- + only code paths we never reach. +- `transformers.node.*` — Node runtime, unused. +- `ort-wasm-simd-threaded.asyncify.wasm` / `.jspi.wasm` / `.wasm` — CPU + fallback variants. Adding them would let the provider fall back to + WASM-CPU when WebGPU is absent, but for now we surface a clear + "WebGPU not available" error instead. Add these later if we want + CPU fallback for systems without WebGPU. diff --git a/src/chrome/vendor/transformers/ort-wasm-simd-threaded.jsep.mjs b/src/chrome/vendor/transformers/ort-wasm-simd-threaded.jsep.mjs new file mode 100644 index 000000000..bff014969 --- /dev/null +++ b/src/chrome/vendor/transformers/ort-wasm-simd-threaded.jsep.mjs @@ -0,0 +1,106 @@ +async function ortWasmThreaded(moduleArg={}){var moduleRtn;var f=moduleArg,aa=!!globalThis.window,ba=!!globalThis.WorkerGlobalScope,h=globalThis.process?.versions?.node&&"renderer"!=globalThis.process?.type,m=ba&&self.name?.startsWith("em-pthread");if(h){const {createRequire:a}=await import("module");var require=a(import.meta.url),ca=require("worker_threads");global.Worker=ca.Worker;m=(ba=!ca.Xd)&&"em-pthread"==ca.workerData}f.mountExternalData=(a,b)=>{a.startsWith("./")&&(a=a.substring(2));(f.Xc||(f.Xc=new Map)).set(a,b)}; +f.unmountExternalData=()=>{delete f.Xc};var SharedArrayBuffer=globalThis.SharedArrayBuffer??(new WebAssembly.Memory({initial:0,maximum:0,shared:!0})).buffer.constructor;const da=a=>async(...b)=>{try{if(f.Yc)throw Error("Session already started");const d=f.Yc={Kd:b[0],errors:[]},c=await a(...b);if(f.Yc!==d)throw Error("Session mismatch");f.dd?.flush();const e=d.errors;if(0k);if(0{if("webgpu"===a){[f.dd,f.Ad,f.Ed,f.ed,f.Dd,f.$b,f.Fd,f.Hd,f.Bd,f.Cd,f.Gd]=b;const d=f.dd;f.jsepRegisterBuffer=(c,e,g,k)=>d.registerBuffer(c,e,g,k);f.jsepGetBuffer=c=>d.getBuffer(c);f.jsepCreateDownloader=(c,e,g)=>d.createDownloader(c,e,g);f.jsepOnCreateSession=c=>{d.onCreateSession(c)};f.jsepOnReleaseSession=c=>{d.onReleaseSession(c)};f.jsepOnRunStart=c=>d.onRunStart(c);f.Id=(c,e)=>{d.upload(c,e)}}else if("webnn"===a){const d=b[0];[f.Wd,f.sd,f.webnnEnsureTensor,f.td,f.webnnDownloadTensor, +f.Rd,f.webnnEnableTraceEvent]=b.slice(1);f.webnnReleaseTensorId=f.sd;f.webnnUploadTensor=f.td;f.webnnRegisterMLContext=f.Rd;f.webnnOnRunStart=c=>d.onRunStart(c);f.webnnOnRunEnd=d.onRunEnd.bind(d);f.webnnOnReleaseSession=c=>{d.onReleaseSession(c)};f.webnnCreateMLTensorDownloader=(c,e)=>d.createMLTensorDownloader(c,e);f.webnnRegisterMLTensor=(c,e,g,k)=>d.registerMLTensor(c,e,g,k);f.webnnCreateMLContext=c=>d.createMLContext(c);f.webnnRegisterMLConstant=(c,e,g,k,l,n)=>d.registerMLConstant(c,e,g,k,l,f.Xc, +n);f.webnnRegisterGraphInput=d.registerGraphInput.bind(d);f.webnnIsGraphInput=d.isGraphInput.bind(d);f.webnnRegisterGraphOutput=d.registerGraphOutput.bind(d);f.webnnIsGraphOutput=d.isGraphOutput.bind(d);f.webnnCreateTemporaryTensor=d.createTemporaryTensor.bind(d);f.webnnIsGraphInputOutputTypeSupported=d.isGraphInputOutputTypeSupported.bind(d)}}; +let fa=()=>{const a=b=>(...d)=>{const c=q;d=b(...d);return q!=c?ea():d};(b=>{for(const d of b)f[d]=a(f[d])})(["_OrtAppendExecutionProvider","_OrtCreateSession","_OrtRun","_OrtRunWithBinding","_OrtBindInput"]);"undefined"!==typeof da&&(f._OrtRun=da(f._OrtRun),f._OrtRunWithBinding=da(f._OrtRunWithBinding));fa=void 0};f.asyncInit=()=>{fa?.()};var ha="./this.program",ia=(a,b)=>{throw b;},ja=import.meta.url,ka="",la,ma; +if(h){var fs=require("fs");ja.startsWith("file:")&&(ka=require("path").dirname(require("url").fileURLToPath(ja))+"/");ma=a=>{a=na(a)?new URL(a):a;return fs.readFileSync(a)};la=async a=>{a=na(a)?new URL(a):a;return fs.readFileSync(a,void 0)};1{process.exitCode=a;throw b;}}else if(aa||ba){try{ka=(new URL(".",ja)).href}catch{}h||(ba&&(ma=a=>{var b=new XMLHttpRequest;b.open("GET",a,!1);b.responseType="arraybuffer"; +b.send(null);return new Uint8Array(b.response)}),la=async a=>{if(na(a))return new Promise((d,c)=>{var e=new XMLHttpRequest;e.open("GET",a,!0);e.responseType="arraybuffer";e.onload=()=>{200==e.status||0==e.status&&e.response?d(e.response):c(e.status)};e.onerror=c;e.send(null)});var b=await fetch(a,{credentials:"same-origin"});if(b.ok)return b.arrayBuffer();throw Error(b.status+" : "+b.url);})}var oa=console.log.bind(console),pa=console.error.bind(console); +if(h){var qa=require("util"),ra=a=>"object"==typeof a?qa.inspect(a):a;oa=(...a)=>fs.writeSync(1,a.map(ra).join(" ")+"\n");pa=(...a)=>fs.writeSync(2,a.map(ra).join(" ")+"\n")}var sa=oa,r=pa,ta,ua,t=!1,va,na=a=>a.startsWith("file://");function v(){x.buffer!=A.buffer&&wa()}var xa,ya; +if(h&&m){var za=ca.parentPort;za.on("message",a=>global.onmessage?.({data:a}));Object.assign(globalThis,{self:global,postMessage:a=>za.postMessage(a)});process.on("uncaughtException",a=>{postMessage({Sc:"uncaughtException",error:a});process.exit(1)})}var Aa; +if(m){var Ba=!1;self.onunhandledrejection=b=>{throw b.reason||b;};function a(b){try{var d=b.data,c=d.Sc;if("load"===c){let e=[];self.onmessage=g=>e.push(g);Aa=()=>{postMessage({Sc:"loaded"});for(let g of e)a(g);self.onmessage=a};for(const g of d.xd)if(!f[g]||f[g].proxy)f[g]=(...k)=>{postMessage({Sc:"callHandler",wd:g,args:k})},"print"==g&&(sa=f[g]),"printErr"==g&&(r=f[g]);x=d.Od;wa();ua=d.Pd;Ca();Da()}else if("run"===c){Ea(d.Rc);Fa(d.Rc,0,0,1,0,0);Ga();Ha(d.Rc);Ba||(Ia(),Ba=!0);try{Ja(d.Md,d.bd)}catch(e){if("unwind"!= +e)throw e;}}else"setimmediate"!==d.target&&("checkMailbox"===c?Ba&&Ka():c&&(r(`worker: received unknown command ${c}`),r(d)))}catch(e){throw La(),e;}}self.onmessage=a}var A,B,Ma,Na,C,D,Oa,E,F,Pa,Qa=!1;function wa(){var a=x.buffer;f.HEAP8=A=new Int8Array(a);Ma=new Int16Array(a);f.HEAPU8=B=new Uint8Array(a);Na=new Uint16Array(a);f.HEAP32=C=new Int32Array(a);f.HEAPU32=D=new Uint32Array(a);Oa=new Float32Array(a);E=new Float64Array(a);F=new BigInt64Array(a);Pa=new BigUint64Array(a)} +function Ra(){Qa=!0;m?Aa():G.sb()}function H(a){a="Aborted("+a+")";r(a);t=!0;a=new WebAssembly.RuntimeError(a+". Build with -sASSERTIONS for more info.");ya?.(a);throw a;}var Sa;async function Ta(a){if(!ta)try{var b=await la(a);return new Uint8Array(b)}catch{}if(a==Sa&&ta)a=new Uint8Array(ta);else if(ma)a=ma(a);else throw"both async and sync fetching of the wasm failed";return a} +async function Ua(a,b){try{var d=await Ta(a);return await WebAssembly.instantiate(d,b)}catch(c){r(`failed to asynchronously prepare wasm: ${c}`),H(c)}}async function Va(a){var b=Sa;if(!ta&&!na(b)&&!h)try{var d=fetch(b,{credentials:"same-origin"});return await WebAssembly.instantiateStreaming(d,a)}catch(c){r(`wasm streaming compile failed: ${c}`),r("falling back to ArrayBuffer instantiation")}return Ua(b,a)} +function Wa(){Xa={la:Ya,gb:Za,g:$a,J:ab,f:bb,p:cb,h:db,ga:eb,b:fb,S:gb,Ha:hb,n:ib,_:jb,Xa:mb,Da:nb,Fa:ob,Ya:pb,Va:qb,Oa:rb,Ua:sb,ja:tb,Ea:ub,Ba:vb,Wa:wb,Ca:xb,bb:yb,da:zb,wa:Ab,ua:Bb,ca:Cb,O:Db,H:Eb,va:Fb,Z:Gb,xa:Hb,Ra:Ib,za:Jb,Ia:Kb,sa:Lb,ea:Mb,Qa:Ha,_a:Nb,Q:Ob,r:Pb,c:Qb,hb:Rb,y:Sb,M:Tb,D:Ub,l:Vb,s:Wb,ib:Xb,I:Yb,R:Zb,j:$b,u:ac,q:bc,k:cc,La:dc,Ma:ec,Na:fc,Ja:gc,Ka:hc,ta:ic,db:jc,ab:kc,v:lc,$:mc,fa:nc,$a:oc,V:pc,Za:qc,Aa:rc,F:sc,T:tc,ka:uc,ya:vc,fb:wc,eb:xc,Sa:yc,Ta:zc,Ga:Ac,U:Bc,ia:Cc,Pa:Dc,ha:Ec, +kb:Fc,ma:Gc,lb:Hc,na:Ic,G:Jc,e:Kc,t:Lc,w:Mc,B:Nc,mb:Oc,K:Pc,x:Qc,oa:Rc,X:Sc,aa:Tc,nb:Uc,ob:Vc,qa:Wc,pa:Xc,pb:Yc,N:Zc,Y:$c,d:ad,A:bd,m:cd,jb:dd,o:ed,z:fd,C:gd,E:hd,L:jd,qb:kd,P:ld,ba:md,W:nd,rb:od,ra:pd,i:qd,a:x,cb:rd};return{a:Xa}} +async function Ca(){function a(c,e){var g=G=c.exports;c={};for(let [k,l]of Object.entries(g))"function"==typeof l?(g=sd(l),c[k]=g):c[k]=l;G=c;G=td();ud.push(G._b);c=G;vd=c.tb;Ia=c.ub;f._OrtInit=c.vb;f._OrtGetLastError=c.wb;f._OrtCreateSessionOptions=c.xb;f._OrtAppendExecutionProvider=c.yb;f._OrtAddFreeDimensionOverride=c.zb;f._OrtAddSessionConfigEntry=c.Ab;f._OrtReleaseSessionOptions=c.Bb;f._OrtCreateSession=c.Cb;f._OrtReleaseSession=c.Db;f._OrtGetInputOutputCount=c.Eb;f._OrtGetInputOutputMetadata= +c.Fb;f._OrtFree=c.Gb;f._OrtCreateTensor=c.Hb;f._OrtGetTensorData=c.Ib;f._OrtReleaseTensor=c.Jb;f._OrtCreateRunOptions=c.Kb;f._OrtAddRunConfigEntry=c.Lb;f._OrtReleaseRunOptions=c.Mb;f._OrtCreateBinding=c.Nb;f._OrtBindInput=c.Ob;f._OrtBindOutput=c.Pb;f._OrtClearBoundOutputs=c.Qb;f._OrtReleaseBinding=c.Rb;f._OrtRunWithBinding=c.Sb;f._OrtRun=c.Tb;f._OrtEndProfiling=c.Ub;f._JsepOutput=c.Vb;f._JsepGetNodeName=c.Wb;wd=c.Xb;I=f._free=c.Yb;xd=f._malloc=c.Zb;Fa=c.ac;La=c.bc;yd=c.cc;zd=c.dc;Ad=c.ec;Bd=c.fc; +Cd=c.gc;J=c.hc;Dd=c.ic;Ed=c.jc;K=c.kc;Fd=c.lc;L=c.mc;Gd=c.nc;Hd=c.oc;Id=c.pc;Jd=c.qc;dynCall_vii=c.rc;Kd=c.sc;dynCall_v=c.tc;Ld=c.uc;Md=c.vc;dynCall_iii=c.wc;Nd=c.xc;Od=c.yc;Pd=c.zc;Qd=c.Ac;dynCall_vi=c.Bc;Rd=c.Cc;Sd=c.Dc;Td=c.Ec;Ud=c.Fc;Vd=c.Gc;Wd=c.Hc;Xd=c.Ic;Yd=c.Jc;Zd=c.Kc;$d=c.Lc;ae=c.Mc;be=c.Nc;ce=c.Pc;de=c.Qc;ee=c.$c;fe=c.ad;ge=c.fd;he=c.jd;ie=c.kd;je=c.ld;ke=c.md;le=c.nd;me=c.od;ne=c.pd;oe=c.qd;pe=c.vd;qe=c.Sd;re=c.Td;se=c.Ud;te=c.Vd;ua=e;return G}var b=Wa();if(f.instantiateWasm)return new Promise(c=> +{f.instantiateWasm(b,(e,g)=>{c(a(e,g))})});if(m){var d=new WebAssembly.Instance(ua,Wa());return a(d,ua)}Sa??=f.locateFile?f.locateFile?f.locateFile("ort-wasm-simd-threaded.jsep.wasm",ka):ka+"ort-wasm-simd-threaded.jsep.wasm":(new URL("ort-wasm-simd-threaded.jsep.wasm",import.meta.url)).href;return function(c){return a(c.instance,c.module)}(await Va(b))}class ue{name="ExitStatus";constructor(a){this.message=`Program terminated with exit(${a})`;this.status=a}} +var ve=a=>{a.terminate();a.onmessage=()=>{}},we=[],xe=0,ye=null,Ce=a=>{0==M.length&&(ze(),Ae(M[0]));var b=M.pop();if(!b)return 6;Be.push(b);N[a.Rc]=b;b.Rc=a.Rc;var d={Sc:"run",Md:a.Ld,bd:a.bd,Rc:a.Rc};h&&b.unref();b.postMessage(d,a.rd);return 0},O=0,P=(a,b,...d)=>{var c=16*d.length,e=L(),g=Fd(c),k=g>>>3,l;for(l of d)"bigint"==typeof l?((v(),F)[k++>>>0]=1n,(v(),F)[k++>>>0]=l):((v(),F)[k++>>>0]=0n,(v(),E)[k++>>>0]=l);a=yd(a,0,c,g,b);K(e);return a}; +function rd(a){if(m)return P(0,1,a);va=a;if(!(0{va=a;if(m)throw De(a),"unwind";rd(a)},M=[],Be=[],ud=[],N={};function Ee(){for(var a=f.numThreads-1;a--;)ze();we.push(async()=>{var b=Fe();xe++;await b;xe--;0==xe&&ye&&(b=ye,ye=null,b())})}var Ge=a=>{var b=a.Rc;delete N[b];M.push(a);Be.splice(Be.indexOf(a),1);a.Rc=0;zd(b)};function Ga(){ud.forEach(a=>a())} +var Ae=a=>new Promise(b=>{a.onmessage=g=>{var k=g.data;g=k.Sc;if(k.Zc&&k.Zc!=wd()){var l=N[k.Zc];l?l.postMessage(k,k.rd):r(`Internal error! Worker sent a message "${g}" to target pthread ${k.Zc}, but that thread no longer exists!`)}else if("checkMailbox"===g)Ka();else if("spawnThread"===g)Ce(k);else if("cleanupThread"===g)He(()=>{Ge(N[k.Nd])});else if("loaded"===g)a.loaded=!0,h&&!a.Rc&&a.unref(),b(a);else if("setimmediate"===k.target)a.postMessage(k);else if("uncaughtException"===g)a.onerror(k.error); +else if("callHandler"===g)f[k.wd](...k.args);else g&&r(`worker sent an unknown command ${g}`)};a.onerror=g=>{r(`${"worker sent an error!"} ${g.filename}:${g.lineno}: ${g.message}`);throw g;};h&&(a.on("message",g=>a.onmessage({data:g})),a.on("error",g=>a.onerror(g)));var d=[],c=[],e;for(e of c)f.propertyIsEnumerable(e)&&d.push(e);a.postMessage({Sc:"load",xd:d,Od:x,Pd:ua})});async function Fe(){if(!m)return Promise.all(M.map(Ae))} +function ze(){var a=new Worker(new URL(import.meta.url),{type:"module",workerData:"em-pthread",name:"em-pthread"});M.push(a)}function Ea(a){var b=(v(),D)[a+52>>>2>>>0];a=(v(),D)[a+56>>>2>>>0];Ed(b,b-a);K(b)}var Ja=(a,b)=>{O=0;a=Kd(a,b);0>>=0;var b=new Ke(a);0==(v(),A)[b.Tc+12>>>0]&&(Le(b,!0),Je--);Me(b,!1);Ie.push(b);return Jd(a)}var Q=0,ab=()=>{J(0,0);var a=Ie.pop();Gd(a.cd);Q=0}; +function Le(a,b){b=b?1:0;(v(),A)[a.Tc+12>>>0]=b}function Me(a,b){b=b?1:0;(v(),A)[a.Tc+13>>>0]=b}class Ke{constructor(a){this.cd=a;this.Tc=a-24}}var Ne=a=>{var b=Q;if(!b)return Dd(0),0;var d=new Ke(b);(v(),D)[d.Tc+16>>>2>>>0]=b;var c=(v(),D)[d.Tc+4>>>2>>>0];if(!c)return Dd(0),b;for(var e of a){if(0===e||e===c)break;if(Id(e,c,d.Tc+16))return Dd(e),b}Dd(c);return b};function bb(){return Ne([])}function cb(a){return Ne([a>>>0])}function db(a,b,d,c){return Ne([a>>>0,b>>>0,d>>>0,c>>>0])} +var eb=()=>{var a=Ie.pop();a||H("no exception to throw");var b=a.cd;0==(v(),A)[a.Tc+13>>>0]&&(Ie.push(a),Me(a,!0),Le(a,!1),Je++);Hd(b);Q=b;throw Q;};function fb(a,b,d){a>>>=0;var c=new Ke(a);b>>>=0;d>>>=0;(v(),D)[c.Tc+16>>>2>>>0]=0;(v(),D)[c.Tc+4>>>2>>>0]=b;(v(),D)[c.Tc+8>>>2>>>0]=d;Hd(a);Q=a;Je++;throw Q;}var gb=()=>Je;function Oe(a,b,d,c){return m?P(2,1,a,b,d,c):hb(a,b,d,c)} +function hb(a,b,d,c){a>>>=0;b>>>=0;d>>>=0;c>>>=0;if(!globalThis.SharedArrayBuffer)return 6;var e=[];if(m&&0===e.length)return Oe(a,b,d,c);a={Ld:d,Rc:a,bd:c,rd:e};return m?(a.Sc="spawnThread",postMessage(a,e),0):Ce(a)}function ib(a){Q||=a>>>0;throw Q;} +var Pe=globalThis.TextDecoder&&new TextDecoder,Qe=(a,b,d,c)=>{d=b+d;if(c)return d;for(;a[b]&&!(b>=d);)++b;return b},Re=(a,b=0,d,c)=>{b>>>=0;d=Qe(a,b,d,c);if(16e?c+=String.fromCharCode(e):(e-=65536,c+=String.fromCharCode(55296| +e>>10,56320|e&1023))}}else c+=String.fromCharCode(e)}return c},R=(a,b,d)=>(a>>>=0)?Re((v(),B),a,b,d):"";function jb(a,b,d){return m?P(3,1,a,b,d):0}function mb(a,b){if(m)return P(4,1,a,b)}function nb(a,b){if(m)return P(5,1,a,b)}function ob(a,b,d){if(m)return P(6,1,a,b,d)}function pb(a,b,d){return m?P(7,1,a,b,d):0}function qb(a,b){if(m)return P(8,1,a,b)}function rb(a,b,d){if(m)return P(9,1,a,b,d)}function sb(a,b,d,c){if(m)return P(10,1,a,b,d,c)}function tb(a,b,d,c){if(m)return P(11,1,a,b,d,c)} +function ub(a,b,d,c){if(m)return P(12,1,a,b,d,c)}function vb(a){if(m)return P(13,1,a)}function wb(a,b){if(m)return P(14,1,a,b)}function xb(a,b,d){if(m)return P(15,1,a,b,d)}var yb=()=>H(""),S=a=>{a>>>=0;for(var b="";;){var d=(v(),B)[a++>>>0];if(!d)return b;b+=String.fromCharCode(d)}},Se={},Te={},Ue={},Ve=class extends Error{constructor(a){super(a);this.name="BindingError"}}; +function We(a,b,d={}){var c=b.name;if(!a)throw new Ve(`type "${c}" must have a positive integer typeid pointer`);if(Te.hasOwnProperty(a)){if(d.yd)return;throw new Ve(`Cannot register type '${c}' twice`);}Te[a]=b;delete Ue[a];Se.hasOwnProperty(a)&&(b=Se[a],delete Se[a],b.forEach(e=>e()))}function T(a,b,d={}){return We(a,b,d)} +var Xe=(a,b,d)=>{switch(b){case 1:return d?c=>(v(),A)[c>>>0]:c=>(v(),B)[c>>>0];case 2:return d?c=>(v(),Ma)[c>>>1>>>0]:c=>(v(),Na)[c>>>1>>>0];case 4:return d?c=>(v(),C)[c>>>2>>>0]:c=>(v(),D)[c>>>2>>>0];case 8:return d?c=>(v(),F)[c>>>3>>>0]:c=>(v(),Pa)[c>>>3>>>0];default:throw new TypeError(`invalid integer width (${b}): ${a}`);}}; +function zb(a,b,d,c,e){a>>>=0;d>>>=0;b=S(b>>>0);c=0n===c;let g=k=>k;if(c){const k=8*d;g=l=>BigInt.asUintN(k,l);e=g(e)}T(a,{name:b,Oc:g,Vc:(k,l)=>{"number"==typeof l&&(l=BigInt(l));return l},Uc:Xe(b,d,!c),Wc:null})}function Ab(a,b,d,c){a>>>=0;b=S(b>>>0);T(a,{name:b,Oc:function(e){return!!e},Vc:function(e,g){return g?d:c},Uc:function(e){return this.Oc((v(),B)[e>>>0])},Wc:null})}var Ye=[],U=[0,1,,1,null,1,!0,1,!1,1];function Qb(a){a>>>=0;9{if(!a)throw new Ve(`Cannot use deleted val. handle = ${a}`);return U[a]},X=a=>{switch(a){case void 0:return 2;case null:return 4;case !0:return 6;case !1:return 8;default:const b=Ye.pop()||U.length;U[b]=a;U[b+1]=1;return b}};function Ze(a){return this.Oc((v(),D)[a>>>2>>>0])}var $e={name:"emscripten::val",Oc:a=>{var b=V(a);Qb(a);return b},Vc:(a,b)=>X(b),Uc:Ze,Wc:null};function Bb(a){return T(a>>>0,$e)} +var af=(a,b)=>{switch(b){case 4:return function(d){return this.Oc((v(),Oa)[d>>>2>>>0])};case 8:return function(d){return this.Oc((v(),E)[d>>>3>>>0])};default:throw new TypeError(`invalid float width (${b}): ${a}`);}};function Cb(a,b,d){a>>>=0;d>>>=0;b=S(b>>>0);T(a,{name:b,Oc:c=>c,Vc:(c,e)=>e,Uc:af(b,d),Wc:null})}function Db(a,b,d,c,e){a>>>=0;d>>>=0;b=S(b>>>0);let g=l=>l;if(0===c){var k=32-8*d;g=l=>l<>>k;e=g(e)}T(a,{name:b,Oc:g,Vc:(l,n)=>n,Uc:Xe(b,d,0!==c),Wc:null})} +function Eb(a,b,d){function c(g){var k=(v(),D)[g>>>2>>>0];g=(v(),D)[g+4>>>2>>>0];return new e((v(),A).buffer,g,k)}a>>>=0;var e=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array,BigInt64Array,BigUint64Array][b];d=S(d>>>0);T(a,{name:d,Oc:c,Uc:c},{yd:!0})} +var Y=(a,b,d)=>{var c=(v(),B);b>>>=0;if(0=k){if(b>=d)break;c[b++>>>0]=k}else if(2047>=k){if(b+1>=d)break;c[b++>>>0]=192|k>>6;c[b++>>>0]=128|k&63}else if(65535>=k){if(b+2>=d)break;c[b++>>>0]=224|k>>12;c[b++>>>0]=128|k>>6&63;c[b++>>>0]=128|k&63}else{if(b+3>=d)break;c[b++>>>0]=240|k>>18;c[b++>>>0]=128|k>>12&63;c[b++>>>0]=128|k>>6&63;c[b++>>>0]=128|k&63;g++}}c[b>>>0]=0;a=b-e}else a=0;return a},bf=a=>{for(var b=0,d=0;d=c?b++:2047>=c?b+=2:55296<=c&&57343>=c?(b+=4,++d):b+=3}return b}; +function Fb(a,b){a>>>=0;b=S(b>>>0);T(a,{name:b,Oc(d){var c=(v(),D)[d>>>2>>>0];c=R(d+4,c,!0);I(d);return c},Vc(d,c){c instanceof ArrayBuffer&&(c=new Uint8Array(c));var e="string"==typeof c;if(!(e||ArrayBuffer.isView(c)&&1==c.BYTES_PER_ELEMENT))throw new Ve("Cannot pass non-string to std::string");var g=e?bf(c):c.length;var k=xd(4+g+1),l=k+4;(v(),D)[k>>>2>>>0]=g;e?Y(c,l,g+1):(v(),B).set(c,l>>>0);null!==d&&d.push(I,k);return k},Uc:Ze,Wc(d){I(d)}})} +var cf=globalThis.TextDecoder?new TextDecoder("utf-16le"):void 0,df=(a,b,d)=>{a>>>=1;b=Qe((v(),Na),a,b/2,d);if(16>>0];d+=String.fromCharCode(c)}return d},ef=(a,b,d)=>{d??=2147483647;if(2>d)return 0;d-=2;var c=b;d=d<2*a.length?d/2:a.length;for(var e=0;e>>1>>>0]=g;b+=2}(v(),Ma)[b>>>1>>>0]=0;return b-c},ff=a=>2*a.length,gf=(a,b,d)=>{var c="";a>>>=2;for(var e=0;!(e>=b/4);e++){var g= +(v(),D)[a+e>>>0];if(!g&&!d)break;c+=String.fromCodePoint(g)}return c},hf=(a,b,d)=>{b>>>=0;d??=2147483647;if(4>d)return 0;var c=b;d=c+d-4;for(var e=0;e>>2>>>0]=g;b+=4;if(b+4>d)break}(v(),C)[b>>>2>>>0]=0;return b-c},jf=a=>{for(var b=0,d=0;d>>=0;b>>>=0;d>>>=0;d=S(d);if(2===b){var c=df;var e=ef;var g=ff}else c=gf,e=hf,g=jf;T(a,{name:d,Oc:k=>{var l=(v(),D)[k>>>2>>>0];l=c(k+4,l*b,!0);I(k);return l},Vc:(k,l)=>{if("string"!=typeof l)throw new Ve(`Cannot pass non-string to C++ string type ${d}`);var n=g(l),p=xd(4+n+b);(v(),D)[p>>>2>>>0]=n/b;e(l,p+4,n+b);null!==k&&k.push(I,p);return p},Uc:Ze,Wc(k){I(k)}})}function Hb(a,b){a>>>=0;b=S(b>>>0);T(a,{zd:!0,name:b,Oc:()=>{},Vc:()=>{}})} +function Ib(a){Fa(a>>>0,!ba,1,!aa,131072,!1);Ga()}var He=a=>{if(!t)try{if(a(),!(0Number((navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)||[])[2]);function Ha(a){a>>>=0;kf||(Atomics.waitAsync((v(),C),a>>>2,a).value.then(Ka),a+=128,Atomics.store((v(),C),a>>>2,1))}var Ka=()=>He(()=>{var a=wd();a&&(Ha(a),Cd())}); +function Jb(a,b){a>>>=0;a==b>>>0?setTimeout(Ka):m?postMessage({Zc:a,Sc:"checkMailbox"}):(a=N[a])&&a.postMessage({Sc:"checkMailbox"})}var lf=[];function Kb(a,b,d,c,e){b>>>=0;e>>>=0;lf.length=0;d=e>>>3;for(c=e+c>>>3;d>>0]?g=(v(),F)[d++>>>0]:g=(v(),E)[d++>>>0];lf.push(g)}return(b?mf[b]:nf[a])(...lf)}var Lb=()=>{O=0};function Mb(a){a>>>=0;m?postMessage({Sc:"cleanupThread",Nd:a}):Ge(N[a])}function Nb(a){h&&N[a>>>0].ref()}var of=a=>{try{a()}catch(b){H(b)}}; +function sd(a){var b=(...d)=>{pf.push(a);try{return a(...d)}finally{t||(pf.pop(),q&&1===Z&&0===pf.length&&(Z=0,O+=1,of(re),"undefined"!=typeof Fibers&&Fibers.Zd()))}};qf.set(a,b);return b}var Z=0,q=null,rf=0,pf=[],sf=new Map,tf=new Map,qf=new Map,uf=0,vf=null,wf=[];function ea(){return new Promise((a,b)=>{vf={resolve:a,reject:b}})} +function xf(){var a=xd(65548),b=a+12;(v(),D)[a>>>2>>>0]=b;(v(),D)[a+4>>>2>>>0]=b+65536;b=pf[0];if(!sf.has(b)){var d=uf++;sf.set(b,d);tf.set(d,b)}b=sf.get(b);(v(),C)[a+8>>>2>>>0]=b;return a}function yf(){var a=(v(),C)[q+8>>>2>>>0];a=tf.get(a);a=qf.get(a);--O;return a()} +function zf(a){if(!t){if(0===Z){var b=!1,d=!1;a((c=0)=>{if(!t&&(rf=c,b=!0,d)){Z=2;of(()=>se(q));"undefined"!=typeof MainLoop&&MainLoop.ud&&MainLoop.resume();c=!1;try{var e=yf()}catch(l){e=l,c=!0}var g=!1;if(!q){var k=vf;k&&(vf=null,(c?k.reject:k.resolve)(e),g=!0)}if(c&&!g)throw e;}});d=!0;b||(Z=1,q=xf(),"undefined"!=typeof MainLoop&&MainLoop.ud&&MainLoop.pause(),of(()=>qe(q)))}else 2===Z?(Z=0,of(te),I(q),q=null,wf.forEach(He)):H(`invalid state: ${Z}`);return rf}}var Af=a=>zf(b=>{a().then(b)}); +function Ob(a){a>>>=0;return Af(async()=>{var b=await V(a);return X(b)})}var Bf=[],Cf=a=>{var b=Bf.length;Bf.push(a);return b},Df=(a,b)=>{for(var d=Array(a),c=0;c>>2>>>0],k=Te[g];if(void 0===k)throw a=`parameter ${c}`,g=vd(g),b=S(g),I(g),new Ve(`${a} has unknown type ${b}`);d[e]=k}return d},Ef=(a,b,d)=>{var c=[];a=a(c,d);c.length&&((v(),D)[b>>>2>>>0]=X(c));return a},Ff={},Gf=a=>{var b=Ff[a];return void 0===b?S(a):b}; +function Pb(a,b,d){var [c,...e]=Df(a,b>>>0);b=c.Vc.bind(c);var g=e.map(n=>n.Uc.bind(n));a--;var k={toValue:V};a=g.map((n,p)=>{var u=`argFromPtr${p}`;k[u]=n;return`${u}(args${p?"+"+8*p:""})`});switch(d){case 0:var l="toValue(handle)";break;case 2:l="new (toValue(handle))";break;case 3:l="";break;case 1:k.getStringOrSymbol=Gf,l="toValue(handle)[getStringOrSymbol(methodName)]"}l+=`(${a})`;c.zd||(k.toReturnWire=b,k.emval_returnValue=Ef,l=`return emval_returnValue(toReturnWire, destructorsRef, ${l})`); +l=`return function (handle, methodName, destructorsRef, args) {\n ${l}\n }`;d=(new Function(Object.keys(k),l))(...Object.values(k));l=`methodCaller<(${e.map(n=>n.name)}) => ${c.name}>`;return Cf(Object.defineProperty(d,"name",{value:l}))}function Rb(a,b){b>>>=0;a=V(a>>>0);b=V(b);return a==b}function Sb(a){a>>>=0;if(!a)return X(globalThis);a=Gf(a);return X(globalThis[a])}function Tb(a){a=Gf(a>>>0);return X(f[a])}function Ub(a,b){b>>>=0;a=V(a>>>0);b=V(b);return X(a[b])} +function Vb(a){a>>>=0;9>>0](b>>>0,d>>>0,c>>>0,e>>>0)}function Xb(a,b,d,c,e){return Wb(a>>>0,b>>>0,d>>>0,c>>>0,e>>>0)}function Yb(){return X([])}function Zb(a){a=V(a>>>0);for(var b=Array(a.length),d=0;d>>0))}function ac(){return X({})}function bc(a){a>>>=0;for(var b=V(a);b.length;){var d=b.pop();b.pop()(d)}Qb(a)}function cc(a,b,d){b>>>=0;d>>>=0;a=V(a>>>0);b=V(b);d=V(d);a[b]=d} +function dc(a,b){a=-9007199254740992>a||9007199254740992>>=0;a=new Date(1E3*a);(v(),C)[b>>>2>>>0]=a.getUTCSeconds();(v(),C)[b+4>>>2>>>0]=a.getUTCMinutes();(v(),C)[b+8>>>2>>>0]=a.getUTCHours();(v(),C)[b+12>>>2>>>0]=a.getUTCDate();(v(),C)[b+16>>>2>>>0]=a.getUTCMonth();(v(),C)[b+20>>>2>>>0]=a.getUTCFullYear()-1900;(v(),C)[b+24>>>2>>>0]=a.getUTCDay();a=(a.getTime()-Date.UTC(a.getUTCFullYear(),0,1,0,0,0,0))/864E5|0;(v(),C)[b+28>>>2>>>0]=a} +var Hf=a=>0===a%4&&(0!==a%100||0===a%400),If=[0,31,60,91,121,152,182,213,244,274,305,335],Jf=[0,31,59,90,120,151,181,212,243,273,304,334]; +function ec(a,b){a=-9007199254740992>a||9007199254740992>>=0;a=new Date(1E3*a);(v(),C)[b>>>2>>>0]=a.getSeconds();(v(),C)[b+4>>>2>>>0]=a.getMinutes();(v(),C)[b+8>>>2>>>0]=a.getHours();(v(),C)[b+12>>>2>>>0]=a.getDate();(v(),C)[b+16>>>2>>>0]=a.getMonth();(v(),C)[b+20>>>2>>>0]=a.getFullYear()-1900;(v(),C)[b+24>>>2>>>0]=a.getDay();var d=(Hf(a.getFullYear())?If:Jf)[a.getMonth()]+a.getDate()-1|0;(v(),C)[b+28>>>2>>>0]=d;(v(),C)[b+36>>>2>>>0]=-(60*a.getTimezoneOffset());d=(new Date(a.getFullYear(), +6,1)).getTimezoneOffset();var c=(new Date(a.getFullYear(),0,1)).getTimezoneOffset();a=(d!=c&&a.getTimezoneOffset()==Math.min(c,d))|0;(v(),C)[b+32>>>2>>>0]=a} +function fc(a){a>>>=0;var b=new Date((v(),C)[a+20>>>2>>>0]+1900,(v(),C)[a+16>>>2>>>0],(v(),C)[a+12>>>2>>>0],(v(),C)[a+8>>>2>>>0],(v(),C)[a+4>>>2>>>0],(v(),C)[a>>>2>>>0],0),d=(v(),C)[a+32>>>2>>>0],c=b.getTimezoneOffset(),e=(new Date(b.getFullYear(),6,1)).getTimezoneOffset(),g=(new Date(b.getFullYear(),0,1)).getTimezoneOffset(),k=Math.min(g,e);0>d?(v(),C)[a+32>>>2>>>0]=Number(e!=g&&k==c):0>>2>>>0]=b.getDay();d=(Hf(b.getFullYear())? +If:Jf)[b.getMonth()]+b.getDate()-1|0;(v(),C)[a+28>>>2>>>0]=d;(v(),C)[a>>>2>>>0]=b.getSeconds();(v(),C)[a+4>>>2>>>0]=b.getMinutes();(v(),C)[a+8>>>2>>>0]=b.getHours();(v(),C)[a+12>>>2>>>0]=b.getDate();(v(),C)[a+16>>>2>>>0]=b.getMonth();(v(),C)[a+20>>>2>>>0]=b.getYear();a=b.getTime();return BigInt(isNaN(a)?-1:a/1E3)}function gc(a,b,d,c,e,g,k){return m?P(16,1,a,b,d,c,e,g,k):-52}function hc(a,b,d,c,e,g){if(m)return P(17,1,a,b,d,c,e,g)}var Kf={},sc=()=>performance.timeOrigin+performance.now(); +function ic(a,b){if(m)return P(18,1,a,b);Kf[a]&&(clearTimeout(Kf[a].id),delete Kf[a]);if(!b)return 0;var d=setTimeout(()=>{delete Kf[a];He(()=>Bd(a,performance.timeOrigin+performance.now()))},b);Kf[a]={id:d,Yd:b};return 0} +function jc(a,b,d,c){a>>>=0;b>>>=0;d>>>=0;c>>>=0;var e=(new Date).getFullYear(),g=(new Date(e,0,1)).getTimezoneOffset();e=(new Date(e,6,1)).getTimezoneOffset();var k=Math.max(g,e);(v(),D)[a>>>2>>>0]=60*k;(v(),C)[b>>>2>>>0]=Number(g!=e);b=l=>{var n=Math.abs(l);return`UTC${0<=l?"-":"+"}${String(Math.floor(n/60)).padStart(2,"0")}${String(n%60).padStart(2,"0")}`};a=b(g);b=b(e);eDate.now(),Lf=1; +function kc(a,b,d){d>>>=0;if(!(0<=a&&3>=a))return 28;if(0===a)a=Date.now();else if(Lf)a=performance.timeOrigin+performance.now();else return 52;a=Math.round(1E6*a);(v(),F)[d>>>3>>>0]=BigInt(a);return 0}var Mf=[],Nf=(a,b)=>{Mf.length=0;for(var d;d=(v(),B)[a++>>>0];){var c=105!=d;c&=112!=d;b+=c&&b%8?4:0;Mf.push(112==d?(v(),D)[b>>>2>>>0]:106==d?(v(),F)[b>>>3>>>0]:105==d?(v(),C)[b>>>2>>>0]:(v(),E)[b>>>3>>>0]);b+=c?8:4}return Mf};function lc(a,b,d){a>>>=0;b=Nf(b>>>0,d>>>0);return mf[a](...b)} +function mc(a,b,d){a>>>=0;b=Nf(b>>>0,d>>>0);return mf[a](...b)}var nc=()=>{};function pc(a,b){return r(R(a>>>0,b>>>0))}var qc=()=>{O+=1;throw"unwind";};function rc(){return 4294901760}var tc=()=>h?require("os").cpus().length:navigator.hardwareConcurrency,Of={},Pf=a=>{var b;return(b=/\bwasm-function\[\d+\]:(0x[0-9a-f]+)/.exec(a))?+b[1]:(b=/:(\d+):\d+(?:\)|$)/.exec(a))?2147483648|+b[1]:0},Qf=a=>{for(var b of a)(a=Pf(b))&&(Of[a]=b)}; +function wc(){var a=Error().stack.toString().split("\n");"Error"==a[0]&&a.shift();Qf(a);Of.gd=Pf(a[3]);Of.Jd=a;return Of.gd}function uc(a){a=Of[a>>>0];if(!a)return 0;var b;if(b=/^\s+at .*\.wasm\.(.*) \(.*\)$/.exec(a))a=b[1];else if(b=/^\s+at (.*) \(.*\)$/.exec(a))a=b[1];else if(b=/^(.+?)@/.exec(a))a=b[1];else return 0;I(uc.hd??0);b=bf(a)+1;var d=xd(b);d&&Y(a,d,b);uc.hd=d;return uc.hd} +function vc(a){a>>>=0;var b=(v(),B).length;if(a<=b||4294901760=d;d*=2){var c=b*(1+.2/d);c=Math.min(c,a+100663296);a:{c=(Math.min(4294901760,65536*Math.ceil(Math.max(a,c)/65536))-x.buffer.byteLength+65535)/65536|0;try{x.grow(c);wa();var e=1;break a}catch(g){}e=void 0}if(e)return!0}return!1} +function xc(a,b,d){a>>>=0;b>>>=0;if(Of.gd==a)var c=Of.Jd;else c=Error().stack.toString().split("\n"),"Error"==c[0]&&c.shift(),Qf(c);for(var e=3;c[e]&&Pf(c[e])!=a;)++e;for(a=0;a>>2>>>0]=Pf(c[a+e]);return a} +var Rf={},Tf=()=>{if(!Sf){var a={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:(globalThis.navigator?.language??"C").replace("-","_")+".UTF-8",_:ha||"./this.program"},b;for(b in Rf)void 0===Rf[b]?delete a[b]:a[b]=Rf[b];var d=[];for(b in a)d.push(`${b}=${a[b]}`);Sf=d}return Sf},Sf;function yc(a,b){if(m)return P(19,1,a,b);a>>>=0;b>>>=0;var d=0,c=0,e;for(e of Tf()){var g=b+d;(v(),D)[a+c>>>2>>>0]=g;d+=Y(e,g,Infinity)+1;c+=4}return 0} +function zc(a,b){if(m)return P(20,1,a,b);a>>>=0;b>>>=0;var d=Tf();(v(),D)[a>>>2>>>0]=d.length;a=0;for(var c of d)a+=bf(c)+1;(v(),D)[b>>>2>>>0]=a;return 0}function Bc(a){return m?P(21,1,a):52}function Cc(a,b,d,c){return m?P(22,1,a,b,d,c):52}function Dc(a,b,d,c){return m?P(23,1,a,b,d,c):70}var Uf=[null,[],[]]; +function Ec(a,b,d,c){if(m)return P(24,1,a,b,d,c);b>>>=0;d>>>=0;c>>>=0;for(var e=0,g=0;g>>2>>>0],l=(v(),D)[b+4>>>2>>>0];b+=8;for(var n=0;n>>0],w=Uf[p];0===u||10===u?((1===p?sa:r)(Re(w)),w.length=0):w.push(u)}e+=l}(v(),D)[c>>>2>>>0]=e;return 0}function qd(a){return a>>>0}m||Ee();m||(x=new WebAssembly.Memory({initial:256,maximum:65536,shared:!0}),wa());f.wasmBinary&&(ta=f.wasmBinary);f.stackSave=()=>L();f.stackRestore=a=>K(a);f.stackAlloc=a=>Fd(a); +f.setValue=function(a,b,d="i8"){d.endsWith("*")&&(d="*");switch(d){case "i1":(v(),A)[a>>>0]=b;break;case "i8":(v(),A)[a>>>0]=b;break;case "i16":(v(),Ma)[a>>>1>>>0]=b;break;case "i32":(v(),C)[a>>>2>>>0]=b;break;case "i64":(v(),F)[a>>>3>>>0]=BigInt(b);break;case "float":(v(),Oa)[a>>>2>>>0]=b;break;case "double":(v(),E)[a>>>3>>>0]=b;break;case "*":(v(),D)[a>>>2>>>0]=b;break;default:H(`invalid type for setValue: ${d}`)}}; +f.getValue=function(a,b="i8"){b.endsWith("*")&&(b="*");switch(b){case "i1":return(v(),A)[a>>>0];case "i8":return(v(),A)[a>>>0];case "i16":return(v(),Ma)[a>>>1>>>0];case "i32":return(v(),C)[a>>>2>>>0];case "i64":return(v(),F)[a>>>3>>>0];case "float":return(v(),Oa)[a>>>2>>>0];case "double":return(v(),E)[a>>>3>>>0];case "*":return(v(),D)[a>>>2>>>0];default:H(`invalid type for getValue: ${b}`)}};f.UTF8ToString=R;f.stringToUTF8=Y;f.lengthBytesUTF8=bf; +var nf=[rd,De,Oe,jb,mb,nb,ob,pb,qb,rb,sb,tb,ub,vb,wb,xb,gc,hc,ic,yc,zc,Bc,Cc,Dc,Ec],mf={967452:(a,b,d,c,e)=>{if("undefined"==typeof f||!f.Xc)return 1;a=R(Number(a>>>0));a.startsWith("./")&&(a=a.substring(2));a=f.Xc.get(a);if(!a)return 2;b=Number(b>>>0);d=Number(d>>>0);c=Number(c>>>0);if(b+d>a.byteLength)return 3;try{const g=a.subarray(b,b+d);switch(e){case 0:(v(),B).set(g,c>>>0);break;case 1:f.Qd?f.Qd(c,g):f.Id(c,g);break;default:return 4}return 0}catch{return 4}},968276:(a,b,d)=>{f.td(a,(v(),B).subarray(b>>> +0,b+d>>>0))},968340:()=>f.Wd(),968382:a=>{f.sd(a)},968419:()=>{f.Bd()},968450:()=>{f.Cd()},968479:()=>{f.Gd()},968504:a=>f.Ad(a),968537:a=>f.Ed(a),968569:(a,b,d)=>{f.ed(Number(a),Number(b),Number(d),!0)},968632:(a,b,d)=>{f.ed(Number(a),Number(b),Number(d))},968689:()=>"undefined"!==typeof wasmOffsetConverter,968746:a=>{f.$b("Abs",a,void 0)},968797:a=>{f.$b("Neg",a,void 0)},968848:a=>{f.$b("Floor",a,void 0)},968901:a=>{f.$b("Ceil",a,void 0)},968953:a=>{f.$b("Reciprocal",a,void 0)},969011:a=>{f.$b("Sqrt", +a,void 0)},969063:a=>{f.$b("Exp",a,void 0)},969114:a=>{f.$b("Erf",a,void 0)},969165:a=>{f.$b("Sigmoid",a,void 0)},969220:(a,b,d)=>{f.$b("HardSigmoid",a,{alpha:b,beta:d})},969299:a=>{f.$b("Log",a,void 0)},969350:a=>{f.$b("Sin",a,void 0)},969401:a=>{f.$b("Cos",a,void 0)},969452:a=>{f.$b("Tan",a,void 0)},969503:a=>{f.$b("Asin",a,void 0)},969555:a=>{f.$b("Acos",a,void 0)},969607:a=>{f.$b("Atan",a,void 0)},969659:a=>{f.$b("Sinh",a,void 0)},969711:a=>{f.$b("Cosh",a,void 0)},969763:a=>{f.$b("Asinh",a,void 0)}, +969816:a=>{f.$b("Acosh",a,void 0)},969869:a=>{f.$b("Atanh",a,void 0)},969922:a=>{f.$b("Tanh",a,void 0)},969974:a=>{f.$b("Not",a,void 0)},970025:(a,b,d)=>{f.$b("Clip",a,{min:b,max:d})},970094:a=>{f.$b("Clip",a,void 0)},970146:(a,b)=>{f.$b("Elu",a,{alpha:b})},970204:a=>{f.$b("Gelu",a,void 0)},970256:a=>{f.$b("Relu",a,void 0)},970308:(a,b)=>{f.$b("LeakyRelu",a,{alpha:b})},970372:(a,b)=>{f.$b("ThresholdedRelu",a,{alpha:b})},970442:(a,b)=>{f.$b("Cast",a,{to:b})},970500:a=>{f.$b("Add",a,void 0)},970551:a=> +{f.$b("Sub",a,void 0)},970602:a=>{f.$b("Mul",a,void 0)},970653:a=>{f.$b("Div",a,void 0)},970704:a=>{f.$b("Pow",a,void 0)},970755:a=>{f.$b("Equal",a,void 0)},970808:a=>{f.$b("Greater",a,void 0)},970863:a=>{f.$b("GreaterOrEqual",a,void 0)},970925:a=>{f.$b("Less",a,void 0)},970977:a=>{f.$b("LessOrEqual",a,void 0)},971036:(a,b,d,c,e)=>{f.$b("ReduceMean",a,{keepDims:!!b,noopWithEmptyAxes:!!d,axes:c?Array.from((v(),C).subarray(Number(c)>>>0,Number(e)>>>0)):[]})},971211:(a,b,d,c,e)=>{f.$b("ReduceMax",a, +{keepDims:!!b,noopWithEmptyAxes:!!d,axes:c?Array.from((v(),C).subarray(Number(c)>>>0,Number(e)>>>0)):[]})},971385:(a,b,d,c,e)=>{f.$b("ReduceMin",a,{keepDims:!!b,noopWithEmptyAxes:!!d,axes:c?Array.from((v(),C).subarray(Number(c)>>>0,Number(e)>>>0)):[]})},971559:(a,b,d,c,e)=>{f.$b("ReduceProd",a,{keepDims:!!b,noopWithEmptyAxes:!!d,axes:c?Array.from((v(),C).subarray(Number(c)>>>0,Number(e)>>>0)):[]})},971734:(a,b,d,c,e)=>{f.$b("ReduceSum",a,{keepDims:!!b,noopWithEmptyAxes:!!d,axes:c?Array.from((v(), +C).subarray(Number(c)>>>0,Number(e)>>>0)):[]})},971908:(a,b,d,c,e)=>{f.$b("ReduceL1",a,{keepDims:!!b,noopWithEmptyAxes:!!d,axes:c?Array.from((v(),C).subarray(Number(c)>>>0,Number(e)>>>0)):[]})},972081:(a,b,d,c,e)=>{f.$b("ReduceL2",a,{keepDims:!!b,noopWithEmptyAxes:!!d,axes:c?Array.from((v(),C).subarray(Number(c)>>>0,Number(e)>>>0)):[]})},972254:(a,b,d,c,e)=>{f.$b("ReduceLogSum",a,{keepDims:!!b,noopWithEmptyAxes:!!d,axes:c?Array.from((v(),C).subarray(Number(c)>>>0,Number(e)>>>0)):[]})},972431:(a,b, +d,c,e)=>{f.$b("ReduceSumSquare",a,{keepDims:!!b,noopWithEmptyAxes:!!d,axes:c?Array.from((v(),C).subarray(Number(c)>>>0,Number(e)>>>0)):[]})},972611:(a,b,d,c,e)=>{f.$b("ReduceLogSumExp",a,{keepDims:!!b,noopWithEmptyAxes:!!d,axes:c?Array.from((v(),C).subarray(Number(c)>>>0,Number(e)>>>0)):[]})},972791:a=>{f.$b("Where",a,void 0)},972844:(a,b,d)=>{f.$b("Transpose",a,{perm:b?Array.from((v(),C).subarray(Number(b)>>>0,Number(d)>>>0)):[]})},972968:(a,b,d,c)=>{f.$b("DepthToSpace",a,{blocksize:b,mode:R(d), +format:c?"NHWC":"NCHW"})},973101:(a,b,d,c)=>{f.$b("DepthToSpace",a,{blocksize:b,mode:R(d),format:c?"NHWC":"NCHW"})},973234:(a,b,d,c,e,g,k,l,n,p,u,w,y,z,W)=>{f.$b("ConvTranspose",a,{format:n?"NHWC":"NCHW",autoPad:b,dilations:[d],group:c,kernelShape:[e],pads:[g,k],strides:[l],wIsConst:()=>!!(v(),A)[p>>>0],outputPadding:u?Array.from((v(),C).subarray(Number(u)>>>0,Number(w)>>>0)):[],outputShape:y?Array.from((v(),C).subarray(Number(y)>>>0,Number(z)>>>0)):[],activation:R(W)})},973667:(a,b,d,c,e,g,k,l,n, +p,u,w,y,z)=>{f.$b("ConvTranspose",a,{format:l?"NHWC":"NCHW",autoPad:b,dilations:Array.from((v(),C).subarray(Number(d)>>>0,(Number(d)>>>0)+2>>>0)),group:c,kernelShape:Array.from((v(),C).subarray(Number(e)>>>0,(Number(e)>>>0)+2>>>0)),pads:Array.from((v(),C).subarray(Number(g)>>>0,(Number(g)>>>0)+4>>>0)),strides:Array.from((v(),C).subarray(Number(k)>>>0,(Number(k)>>>0)+2>>>0)),wIsConst:()=>!!(v(),A)[n>>>0],outputPadding:p?Array.from((v(),C).subarray(Number(p)>>>0,Number(u)>>>0)):[],outputShape:w?Array.from((v(), +C).subarray(Number(w)>>>0,Number(y)>>>0)):[],activation:R(z)})},974328:(a,b,d,c,e,g,k,l,n,p,u,w,y,z,W)=>{f.$b("ConvTranspose",a,{format:n?"NHWC":"NCHW",autoPad:b,dilations:[d],group:c,kernelShape:[e],pads:[g,k],strides:[l],wIsConst:()=>!!(v(),A)[p>>>0],outputPadding:u?Array.from((v(),C).subarray(Number(u)>>>0,Number(w)>>>0)):[],outputShape:y?Array.from((v(),C).subarray(Number(y)>>>0,Number(z)>>>0)):[],activation:R(W)})},974761:(a,b,d,c,e,g,k,l,n,p,u,w,y,z)=>{f.$b("ConvTranspose",a,{format:l?"NHWC": +"NCHW",autoPad:b,dilations:Array.from((v(),C).subarray(Number(d)>>>0,(Number(d)>>>0)+2>>>0)),group:c,kernelShape:Array.from((v(),C).subarray(Number(e)>>>0,(Number(e)>>>0)+2>>>0)),pads:Array.from((v(),C).subarray(Number(g)>>>0,(Number(g)>>>0)+4>>>0)),strides:Array.from((v(),C).subarray(Number(k)>>>0,(Number(k)>>>0)+2>>>0)),wIsConst:()=>!!(v(),A)[n>>>0],outputPadding:p?Array.from((v(),C).subarray(Number(p)>>>0,Number(u)>>>0)):[],outputShape:w?Array.from((v(),C).subarray(Number(w)>>>0,Number(y)>>>0)): +[],activation:R(z)})},975422:(a,b)=>{f.$b("GlobalAveragePool",a,{format:b?"NHWC":"NCHW"})},975513:(a,b,d,c,e,g,k,l,n,p,u,w,y,z)=>{f.$b("AveragePool",a,{format:z?"NHWC":"NCHW",auto_pad:b,ceil_mode:d,count_include_pad:c,storage_order:e,dilations:g?Array.from((v(),C).subarray(Number(g)>>>0,Number(k)>>>0)):[],kernel_shape:l?Array.from((v(),C).subarray(Number(l)>>>0,Number(n)>>>0)):[],pads:p?Array.from((v(),C).subarray(Number(p)>>>0,Number(u)>>>0)):[],strides:w?Array.from((v(),C).subarray(Number(w)>>> +0,Number(y)>>>0)):[]})},975992:(a,b)=>{f.$b("GlobalAveragePool",a,{format:b?"NHWC":"NCHW"})},976083:(a,b,d,c,e,g,k,l,n,p,u,w,y,z)=>{f.$b("AveragePool",a,{format:z?"NHWC":"NCHW",auto_pad:b,ceil_mode:d,count_include_pad:c,storage_order:e,dilations:g?Array.from((v(),C).subarray(Number(g)>>>0,Number(k)>>>0)):[],kernel_shape:l?Array.from((v(),C).subarray(Number(l)>>>0,Number(n)>>>0)):[],pads:p?Array.from((v(),C).subarray(Number(p)>>>0,Number(u)>>>0)):[],strides:w?Array.from((v(),C).subarray(Number(w)>>> +0,Number(y)>>>0)):[]})},976562:(a,b)=>{f.$b("GlobalMaxPool",a,{format:b?"NHWC":"NCHW"})},976649:(a,b,d,c,e,g,k,l,n,p,u,w,y,z)=>{f.$b("MaxPool",a,{format:z?"NHWC":"NCHW",auto_pad:b,ceil_mode:d,count_include_pad:c,storage_order:e,dilations:g?Array.from((v(),C).subarray(Number(g)>>>0,Number(k)>>>0)):[],kernel_shape:l?Array.from((v(),C).subarray(Number(l)>>>0,Number(n)>>>0)):[],pads:p?Array.from((v(),C).subarray(Number(p)>>>0,Number(u)>>>0)):[],strides:w?Array.from((v(),C).subarray(Number(w)>>>0,Number(y)>>> +0)):[]})},977124:(a,b)=>{f.$b("GlobalMaxPool",a,{format:b?"NHWC":"NCHW"})},977211:(a,b,d,c,e,g,k,l,n,p,u,w,y,z)=>{f.$b("MaxPool",a,{format:z?"NHWC":"NCHW",auto_pad:b,ceil_mode:d,count_include_pad:c,storage_order:e,dilations:g?Array.from((v(),C).subarray(Number(g)>>>0,Number(k)>>>0)):[],kernel_shape:l?Array.from((v(),C).subarray(Number(l)>>>0,Number(n)>>>0)):[],pads:p?Array.from((v(),C).subarray(Number(p)>>>0,Number(u)>>>0)):[],strides:w?Array.from((v(),C).subarray(Number(w)>>>0,Number(y)>>>0)):[]})}, +977686:(a,b,d,c,e)=>{f.$b("Gemm",a,{alpha:b,beta:d,transA:c,transB:e})},977790:a=>{f.$b("MatMul",a,void 0)},977844:(a,b,d,c)=>{f.$b("ArgMax",a,{keepDims:!!b,selectLastIndex:!!d,axis:c})},977952:(a,b,d,c)=>{f.$b("ArgMin",a,{keepDims:!!b,selectLastIndex:!!d,axis:c})},978060:(a,b)=>{f.$b("Softmax",a,{axis:b})},978123:(a,b)=>{f.$b("Concat",a,{axis:b})},978183:(a,b,d,c,e)=>{f.$b("Split",a,{axis:b,numOutputs:d,splitSizes:c?Array.from((v(),C).subarray(Number(c)>>>0,Number(e)>>>0)):[]})},978339:a=>{f.$b("Expand", +a,void 0)},978393:(a,b)=>{f.$b("Gather",a,{axis:Number(b)})},978464:(a,b)=>{f.$b("GatherElements",a,{axis:Number(b)})},978543:(a,b)=>{f.$b("GatherND",a,{batch_dims:Number(b)})},978622:(a,b,d,c,e,g,k,l,n,p,u)=>{f.$b("Resize",a,{antialias:b,axes:d?Array.from((v(),C).subarray(Number(d)>>>0,Number(c)>>>0)):[],coordinateTransformMode:R(e),cubicCoeffA:g,excludeOutside:k,extrapolationValue:l,keepAspectRatioPolicy:R(n),mode:R(p),nearestMode:R(u)})},978984:(a,b,d,c,e,g,k)=>{f.$b("Slice",a,{starts:b?Array.from((v(), +C).subarray(Number(b)>>>0,Number(d)>>>0)):[],ends:c?Array.from((v(),C).subarray(Number(c)>>>0,Number(e)>>>0)):[],axes:g?Array.from((v(),C).subarray(Number(g)>>>0,Number(k)>>>0)):[]})},979248:a=>{f.$b("Tile",a,void 0)},979300:(a,b,d)=>{f.$b("InstanceNormalization",a,{epsilon:b,format:d?"NHWC":"NCHW"})},979414:(a,b,d)=>{f.$b("InstanceNormalization",a,{epsilon:b,format:d?"NHWC":"NCHW"})},979528:a=>{f.$b("Range",a,void 0)},979581:(a,b)=>{f.$b("Einsum",a,{equation:R(b)})},979662:(a,b,d,c,e)=>{f.$b("Pad", +a,{mode:b,value:d,pads:c?Array.from((v(),C).subarray(Number(c)>>>0,Number(e)>>>0)):[]})},979805:(a,b,d,c,e,g)=>{f.$b("BatchNormalization",a,{epsilon:b,momentum:d,spatial:!!e,trainingMode:!!c,format:g?"NHWC":"NCHW"})},979974:(a,b,d,c,e,g)=>{f.$b("BatchNormalization",a,{epsilon:b,momentum:d,spatial:!!e,trainingMode:!!c,format:g?"NHWC":"NCHW"})},980143:(a,b,d)=>{f.$b("CumSum",a,{exclusive:Number(b),reverse:Number(d)})},980240:(a,b,d)=>{f.$b("DequantizeLinear",a,{axis:b,blockSize:d})},980330:(a,b,d,c, +e)=>{f.$b("GridSample",a,{align_corners:b,mode:R(d),padding_mode:R(c),format:e?"NHWC":"NCHW"})},980500:(a,b,d,c,e)=>{f.$b("GridSample",a,{align_corners:b,mode:R(d),padding_mode:R(c),format:e?"NHWC":"NCHW"})},980670:(a,b)=>{f.$b("ScatterND",a,{reduction:R(b)})},980755:(a,b,d,c,e,g,k,l,n)=>{f.$b("Attention",a,{numHeads:b,isUnidirectional:d,maskFilterValue:c,scale:e,doRotary:g,qkvHiddenSizes:k?Array.from((v(),C).subarray(Number(l)>>>0,Number(l)+k>>>0)):[],pastPresentShareBuffer:!!n})},981027:a=>{f.$b("BiasAdd", +a,void 0)},981082:a=>{f.$b("BiasSplitGelu",a,void 0)},981143:a=>{f.$b("FastGelu",a,void 0)},981199:(a,b,d,c,e,g,k,l,n,p,u,w,y,z,W,kb)=>{f.$b("Conv",a,{format:w?"NHWC":"NCHW",auto_pad:b,dilations:d?Array.from((v(),C).subarray(Number(d)>>>0,Number(c)>>>0)):[],group:e,kernel_shape:g?Array.from((v(),C).subarray(Number(g)>>>0,Number(k)>>>0)):[],pads:l?Array.from((v(),C).subarray(Number(l)>>>0,Number(n)>>>0)):[],strides:p?Array.from((v(),C).subarray(Number(p)>>>0,Number(u)>>>0)):[],w_is_const:()=>!!(v(), +A)[Number(y)>>>0],activation:R(z),activation_params:W?Array.from((v(),Oa).subarray(Number(W)>>>0,Number(kb)>>>0)):[]})},981783:a=>{f.$b("Gelu",a,void 0)},981835:(a,b,d,c,e,g,k,l,n)=>{f.$b("GroupQueryAttention",a,{numHeads:b,kvNumHeads:d,scale:c,softcap:e,doRotary:g,rotaryInterleaved:k,smoothSoftmax:l,localWindowSize:n})},982052:(a,b,d,c)=>{f.$b("LayerNormalization",a,{axis:b,epsilon:d,simplified:!!c})},982163:(a,b,d,c)=>{f.$b("LayerNormalization",a,{axis:b,epsilon:d,simplified:!!c})},982274:(a,b, +d,c,e,g)=>{f.$b("MatMulNBits",a,{k:b,n:d,accuracyLevel:c,bits:e,blockSize:g})},982401:(a,b,d,c,e,g)=>{f.$b("MultiHeadAttention",a,{numHeads:b,isUnidirectional:d,maskFilterValue:c,scale:e,doRotary:g})},982560:(a,b)=>{f.$b("QuickGelu",a,{alpha:b})},982624:(a,b,d,c,e)=>{f.$b("RotaryEmbedding",a,{interleaved:!!b,numHeads:d,rotaryEmbeddingDim:c,scale:e})},982763:(a,b,d)=>{f.$b("SkipLayerNormalization",a,{epsilon:b,simplified:!!d})},982865:(a,b,d)=>{f.$b("SkipLayerNormalization",a,{epsilon:b,simplified:!!d})}, +982967:(a,b,d,c)=>{f.$b("GatherBlockQuantized",a,{gatherAxis:b,quantizeAxis:d,blockSize:c})},983088:a=>{f.Fd(a)},983122:(a,b)=>f.Hd(Number(a),Number(b),f.Yc.Kd,f.Yc.errors)};function Za(a,b,d){return Af(async()=>{await f.Dd(Number(a),Number(b),Number(d))})}function Ya(){return"undefined"!==typeof wasmOffsetConverter} +var vd,Ia,wd,I,xd,Fa,La,yd,zd,Ad,Bd,Cd,J,Dd,Ed,K,Fd,L,Gd,Hd,Id,Jd,dynCall_vii,Kd,dynCall_v,Ld,Md,dynCall_iii,Nd,Od,Pd,Qd,dynCall_vi,Rd,Sd,Td,Ud,Vd,Wd,Xd,Yd,Zd,$d,ae,be,ce,de,ee,fe,ge,he,ie,je,ke,le,me,ne,oe,pe,qe,re,se,te,Xa;function Mc(a,b,d,c){var e=L();try{return Qd(a,b,d,c)}catch(g){K(e);if(g!==g+0)throw g;J(1,0)}}function Lc(a,b,d){var c=L();try{return dynCall_iii(a,b,d)}catch(e){K(c);if(e!==e+0)throw e;J(1,0)}} +function ad(a){var b=L();try{dynCall_v(a)}catch(d){K(b);if(d!==d+0)throw d;J(1,0)}}function Kc(a,b){var d=L();try{return Kd(a,b)}catch(c){K(d);if(c!==c+0)throw c;J(1,0)}}function cd(a,b,d){var c=L();try{dynCall_vii(a,b,d)}catch(e){K(c);if(e!==e+0)throw e;J(1,0)}}function bd(a,b){var d=L();try{dynCall_vi(a,b)}catch(c){K(d);if(c!==c+0)throw c;J(1,0)}}function Qc(a,b,d,c,e,g,k){var l=L();try{return Od(a,b,d,c,e,g,k)}catch(n){K(l);if(n!==n+0)throw n;J(1,0)}} +function gd(a,b,d,c,e,g){var k=L();try{Ld(a,b,d,c,e,g)}catch(l){K(k);if(l!==l+0)throw l;J(1,0)}}function ed(a,b,d,c){var e=L();try{Pd(a,b,d,c)}catch(g){K(e);if(g!==g+0)throw g;J(1,0)}}function fd(a,b,d,c,e){var g=L();try{Md(a,b,d,c,e)}catch(k){K(g);if(k!==k+0)throw k;J(1,0)}}function hd(a,b,d,c,e,g,k){var l=L();try{Sd(a,b,d,c,e,g,k)}catch(n){K(l);if(n!==n+0)throw n;J(1,0)}}function pd(a,b,d,c,e,g,k){var l=L();try{Td(a,b,d,c,e,g,k)}catch(n){K(l);if(n!==n+0)throw n;J(1,0)}} +function od(a,b,d,c,e,g,k,l){var n=L();try{Xd(a,b,d,c,e,g,k,l)}catch(p){K(n);if(p!==p+0)throw p;J(1,0)}}function Nc(a,b,d,c,e){var g=L();try{return Rd(a,b,d,c,e)}catch(k){K(g);if(k!==k+0)throw k;J(1,0)}}function jd(a,b,d,c,e,g,k,l){var n=L();try{Yd(a,b,d,c,e,g,k,l)}catch(p){K(n);if(p!==p+0)throw p;J(1,0)}}function md(a,b,d,c,e,g,k,l,n,p,u,w){var y=L();try{Ud(a,b,d,c,e,g,k,l,n,p,u,w)}catch(z){K(y);if(z!==z+0)throw z;J(1,0)}} +function Pc(a,b,d,c,e,g){var k=L();try{return Vd(a,b,d,c,e,g)}catch(l){K(k);if(l!==l+0)throw l;J(1,0)}}function Zc(a,b,d){var c=L();try{return Zd(a,b,d)}catch(e){K(c);if(e!==e+0)throw e;J(1,0);return 0n}}function kd(a,b,d,c,e,g,k,l,n){var p=L();try{Nd(a,b,d,c,e,g,k,l,n)}catch(u){K(p);if(u!==u+0)throw u;J(1,0)}}function Jc(a){var b=L();try{return $d(a)}catch(d){K(b);if(d!==d+0)throw d;J(1,0)}}function Wc(a,b,d){var c=L();try{return ae(a,b,d)}catch(e){K(c);if(e!==e+0)throw e;J(1,0)}} +function Yc(a,b){var d=L();try{return pe(a,b)}catch(c){K(d);if(c!==c+0)throw c;J(1,0);return 0n}}function Xc(a){var b=L();try{return be(a)}catch(d){K(b);if(d!==d+0)throw d;J(1,0);return 0n}}function Vc(a,b,d,c){var e=L();try{return he(a,b,d,c)}catch(g){K(e);if(g!==g+0)throw g;J(1,0)}}function Uc(a,b,d,c,e){var g=L();try{return ie(a,b,d,c,e)}catch(k){K(g);if(k!==k+0)throw k;J(1,0)}}function Tc(a,b,d,c,e,g){var k=L();try{return je(a,b,d,c,e,g)}catch(l){K(k);if(l!==l+0)throw l;J(1,0)}} +function Oc(a,b,d,c,e,g){var k=L();try{return ke(a,b,d,c,e,g)}catch(l){K(k);if(l!==l+0)throw l;J(1,0)}}function Rc(a,b,d,c,e,g,k,l){var n=L();try{return Wd(a,b,d,c,e,g,k,l)}catch(p){K(n);if(p!==p+0)throw p;J(1,0)}}function $c(a,b,d,c,e){var g=L();try{return le(a,b,d,c,e)}catch(k){K(g);if(k!==k+0)throw k;J(1,0);return 0n}}function Ic(a,b,d,c){var e=L();try{return me(a,b,d,c)}catch(g){K(e);if(g!==g+0)throw g;J(1,0)}} +function Gc(a,b,d,c){var e=L();try{return ne(a,b,d,c)}catch(g){K(e);if(g!==g+0)throw g;J(1,0)}}function Sc(a,b,d,c,e,g,k,l,n,p,u,w){var y=L();try{return oe(a,b,d,c,e,g,k,l,n,p,u,w)}catch(z){K(y);if(z!==z+0)throw z;J(1,0)}}function ld(a,b,d,c,e,g,k,l,n,p,u){var w=L();try{fe(a,b,d,c,e,g,k,l,n,p,u)}catch(y){K(w);if(y!==y+0)throw y;J(1,0)}}function nd(a,b,d,c,e,g,k,l,n,p,u,w,y,z,W,kb){var Vf=L();try{ge(a,b,d,c,e,g,k,l,n,p,u,w,y,z,W,kb)}catch(lb){K(Vf);if(lb!==lb+0)throw lb;J(1,0)}} +function Hc(a,b,d){var c=L();try{return ce(a,b,d)}catch(e){K(c);if(e!==e+0)throw e;J(1,0)}}function Fc(a,b,d){var c=L();try{return de(a,b,d)}catch(e){K(c);if(e!==e+0)throw e;J(1,0)}}function dd(a,b,d,c){var e=L();try{ee(a,b,d,c)}catch(g){K(e);if(g!==g+0)throw g;J(1,0)}}function td(){var a=G;a=Object.assign({},a);var b=c=>e=>c(e)>>>0,d=c=>()=>c()>>>0;a.tb=b(a.tb);a.Xb=d(a.Xb);a.Zb=b(a.Zb);a.lc=b(a.lc);a.mc=d(a.mc);a.qc=b(a.qc);return a} +function Da(){if(0{xa=a;ya=b}); +;return moduleRtn}export default ortWasmThreaded;var isPthread=globalThis.self?.name?.startsWith("em-pthread");var isNode=globalThis.process?.versions?.node&&globalThis.process?.type!="renderer";if(isNode)isPthread=(await import("worker_threads")).workerData==="em-pthread";isPthread&&ortWasmThreaded(); diff --git a/src/chrome/vendor/transformers/ort-wasm-simd-threaded.jsep.wasm b/src/chrome/vendor/transformers/ort-wasm-simd-threaded.jsep.wasm new file mode 100644 index 0000000000000000000000000000000000000000..68576a4c2f4ef74c10137603d1c266202d2ed25a GIT binary patch literal 26101073 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