diff --git a/frontend/package.json b/frontend/package.json index 403025d..c2594fd 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -9,6 +9,7 @@ }, "dependencies": { "kaplay": "^3001.0.19", + "kokoro-js": "^1.2.1", "nostr-tools": "^2.23.3", "vue": "^3.5.13", "vue-router": "^4.5.1" diff --git a/frontend/src/game/sounds.ts b/frontend/src/game/sounds.ts index 4921185..d661242 100644 --- a/frontend/src/game/sounds.ts +++ b/frontend/src/game/sounds.ts @@ -1,4 +1,7 @@ -// Procedural 8-bit sound system + announcer voice using Web Audio + Speech Synthesis +// Procedural 8-bit sound system + announcer voice using Web Audio + Kokoro TTS +// Falls back to Speech Synthesis if Kokoro model hasn't loaded yet +import { initKokoro, isKokoroReady, kokoroSpeak, kokoroSpeakAsync, kokoroStop, setAudioContext } from './tts' + let ctx: AudioContext | null = null let musicGain: GainNode | null = null let sfxGain: GainNode | null = null @@ -307,12 +310,18 @@ let _speechQueueDepth = 0 const VOICE_VOLUME_SCALE = 0.7 function speak(text: string, profileName: string, cancelPrevious: boolean = false, _echo: boolean = false) { - if (typeof speechSynthesis === 'undefined') return if (masterMuted) return + // Try Kokoro TTS first — high quality, no browser bugs + if (isKokoroReady() && sfxGain) { + const profile = voiceProfiles[profileName] || voiceProfiles.announcer + if (cancelPrevious) kokoroStop() + kokoroSpeak(text, profileName, sfxGain, profile.volume * VOICE_VOLUME_SCALE) + return + } + // Fallback: Web Speech API + if (typeof speechSynthesis === 'undefined') return if (!voicesLoaded) loadVoices() - // Chrome bug: speechSynthesis can get stuck. Nudge it. if (speechSynthesis.paused) speechSynthesis.resume() - // Flush if queue is getting deep — max 2 queued to prevent buildup if (cancelPrevious || (speechSynthesis.pending && speechSynthesis.speaking)) { if (_speechQueueDepth > 2) { speechSynthesis.cancel() @@ -329,7 +338,6 @@ function speak(text: string, profileName: string, cancelPrevious: boolean = fals utter.onend = () => { _speechQueueDepth = Math.max(0, _speechQueueDepth - 1) } utter.onerror = (ev) => { _speechQueueDepth = Math.max(0, _speechQueueDepth - 1) - // Retry once on non-cancel errors (interrupted = browser killed it, not us) if (ev.error !== 'canceled' && ev.error !== 'interrupted') { setTimeout(() => { if (!masterMuted && typeof speechSynthesis !== 'undefined') { @@ -352,11 +360,19 @@ const _isIOS = typeof navigator !== 'undefined' && /iPad|iPhone|iPod/.test(navig const _isDesktopChrome = typeof navigator !== 'undefined' && /Chrome/.test(navigator.userAgent) && !/Mobile/.test(navigator.userAgent) /** Core async speak — resolves when speech finishes or bails fast if speech won't work */ -function _speakAsyncCore(text: string, profileName: string, rateOverride?: number, cancelPrevious?: boolean): Promise { +async function _speakAsyncCore(text: string, profileName: string, rateOverride?: number, cancelPrevious?: boolean): Promise { + if (masterMuted) return + // Try Kokoro TTS first + if (isKokoroReady() && sfxGain) { + if (cancelPrevious) kokoroStop() + const profile = voiceProfiles[profileName] || voiceProfiles.announcer + const handled = await kokoroSpeakAsync(text, profileName, sfxGain, profile.volume * VOICE_VOLUME_SCALE) + if (handled) return + } + // Fallback: Web Speech API return new Promise((resolve) => { - if (typeof speechSynthesis === 'undefined' || masterMuted) { resolve(); return } + if (typeof speechSynthesis === 'undefined') { resolve(); return } if (!voicesLoaded) loadVoices() - // No voices available = speech won't work, bail immediately if (!voicesLoaded) { resolve(); return } if (speechSynthesis.paused) speechSynthesis.resume() if (cancelPrevious) { speechSynthesis.cancel(); _speechQueueDepth = 0 } @@ -377,14 +393,10 @@ function _speakAsyncCore(text: string, profileName: string, rateOverride?: numbe _speechQueueDepth = Math.max(0, _speechQueueDepth - 1) resolve() } - // Hard safety cap — never block longer than 8s const safetyTimeout = setTimeout(cleanup, 8_000) - // Fast bail: if speech hasn't started within 500ms, it's not going to work (mobile/no gesture) const startupCheck = setTimeout(() => { if (!speechSynthesis.speaking && !speechSynthesis.pending) cleanup() }, 500) - // Desktop Chrome keepalive: periodic pause/resume prevents Chrome's 15s silent cutoff - // Do NOT do this on iOS — it permanently kills speech on Safari let keepalive: ReturnType | null = null if (_isDesktopChrome) { keepalive = setInterval(() => { @@ -412,6 +424,7 @@ function speakAsync(text: string, profileName: string, cancelPrevious: boolean = export function stopAllAudio() { stopMusic() + kokoroStop() if (typeof speechSynthesis !== 'undefined') speechSynthesis.cancel() _speechQueueDepth = 0 // Disconnect gain nodes to instantly kill all in-flight oscillators/buffers, @@ -435,6 +448,11 @@ export function stopAllAudio() { // Public voice functions export function announce(text: string, pitch?: number, rate?: number) { if (masterMuted) return + // Kokoro ignores pitch/rate overrides — just use the announcer profile + if (isKokoroReady()) { + speak(text, 'announcer') + return + } if (pitch !== undefined || rate !== undefined) { if (typeof speechSynthesis === 'undefined') return if (!voicesLoaded) loadVoices() @@ -2846,6 +2864,7 @@ export function setMasterMute(muted: boolean) { if (muted) { if (musicGain) musicGain.gain.value = 0 if (sfxGain) sfxGain.gain.value = 0 + kokoroStop() if (typeof speechSynthesis !== 'undefined') speechSynthesis.cancel() } else { if (musicGain) musicGain.gain.value = MUSIC_VOL @@ -2863,7 +2882,10 @@ export async function ensureAudioContext() { if (c.state === 'suspended') { try { await c.resume() } catch {} } - // Prime speech synthesis on user gesture — mobile browsers require + // Share AudioContext with kokoro and start loading the model + setAudioContext(c) + initKokoro() + // Prime speech synthesis as fallback — mobile browsers require // a speak() call inside a user gesture to unlock speechSynthesis if (typeof speechSynthesis !== 'undefined') { if (!voicesLoaded) loadVoices() diff --git a/frontend/src/game/tts.ts b/frontend/src/game/tts.ts new file mode 100644 index 0000000..651fd06 --- /dev/null +++ b/frontend/src/game/tts.ts @@ -0,0 +1,303 @@ +// Kokoro TTS engine — high-quality client-side text-to-speech +// Lazy-loads the 86MB q8 model on first use, caches in browser storage. +// Falls through to speechSynthesis if model isn't ready yet. + +import type { KokoroTTS as KokoroTTSType } from 'kokoro-js' + +type KokoroVoice = 'af_heart' | 'af_alloy' | 'af_aoede' | 'af_bella' | 'af_jessica' | 'af_kore' | + 'af_nicole' | 'af_nova' | 'af_river' | 'af_sarah' | 'af_sky' | + 'am_adam' | 'am_echo' | 'am_eric' | 'am_fenrir' | 'am_liam' | 'am_michael' | 'am_onyx' | 'am_puck' | 'am_santa' | + 'bf_emma' | 'bf_isabella' | 'bf_alice' | 'bf_lily' | + 'bm_daniel' | 'bm_fable' | 'bm_george' | 'bm_lewis' + +interface VoiceMapping { + voice: KokoroVoice + speed: number +} + +// Map each voice profile to a kokoro voice + speed modifier. +// With 28 distinct voices, each profile gets a genuinely different voice. +const VOICE_MAP: Record = { + // --- Authoritative / announcer --- + announcer: { voice: 'am_fenrir', speed: 0.95 }, + deep: { voice: 'am_onyx', speed: 0.85 }, + smooth: { voice: 'am_liam', speed: 0.95 }, + question_reader:{ voice: 'af_kore', speed: 1.05 }, + news: { voice: 'am_michael', speed: 1.0 }, + + // --- High energy --- + hype: { voice: 'af_heart', speed: 1.3 }, + screamer: { voice: 'af_sarah', speed: 1.5 }, + sportscaster: { voice: 'am_michael', speed: 1.4 }, + auctioneer: { voice: 'am_puck', speed: 1.8 }, + hyper: { voice: 'af_nova', speed: 1.8 }, + punk: { voice: 'am_puck', speed: 1.2 }, + drill: { voice: 'am_onyx', speed: 1.15 }, + karen: { voice: 'af_jessica', speed: 1.4 }, + terrified: { voice: 'af_sky', speed: 1.6 }, + power_up: { voice: 'af_river', speed: 1.3 }, + wrestler_v: { voice: 'am_fenrir', speed: 1.0 }, + + // --- Deep / menacing --- + boomer: { voice: 'bm_george', speed: 0.7 }, + movie: { voice: 'am_echo', speed: 0.8 }, + demon_v: { voice: 'bm_lewis', speed: 0.7 }, + final_boss: { voice: 'am_echo', speed: 0.55 }, + boss_taunt: { voice: 'am_onyx', speed: 0.9 }, + game_over: { voice: 'am_fenrir', speed: 0.8 }, + giant: { voice: 'bm_george', speed: 0.5 }, + mainframe: { voice: 'am_adam', speed: 0.6 }, + + // --- Calm / wise --- + preacher: { voice: 'bm_daniel', speed: 0.75 }, + wizard_v: { voice: 'am_echo', speed: 0.85 }, + sensei: { voice: 'bm_fable', speed: 0.7 }, + professor: { voice: 'bm_daniel', speed: 0.8 }, + ancient: { voice: 'am_eric', speed: 0.45 }, + opera: { voice: 'bf_emma', speed: 0.65 }, + + // --- Cute / high --- + chipmunk: { voice: 'af_nicole', speed: 1.7 }, + baby: { voice: 'bf_lily', speed: 1.1 }, + fairy: { voice: 'af_bella', speed: 1.2 }, + angel: { voice: 'af_bella', speed: 0.9 }, + tutorial: { voice: 'af_nicole', speed: 1.1 }, + valley: { voice: 'af_heart', speed: 1.2 }, + + // --- Robots / computers --- + robot: { voice: 'am_adam', speed: 0.9 }, + ai_core: { voice: 'af_alloy', speed: 1.0 }, + mech: { voice: 'am_adam', speed: 0.8 }, + android_v: { voice: 'af_alloy', speed: 1.05 }, + siri: { voice: 'af_aoede', speed: 1.0 }, + hal: { voice: 'am_echo', speed: 0.7 }, + dial_up: { voice: 'af_sky', speed: 1.4 }, + glitch: { voice: 'af_sarah', speed: 1.7 }, + glitchbot: { voice: 'am_puck', speed: 1.8 }, + + // --- Accents --- + posh: { voice: 'bf_emma', speed: 0.85 }, + aussie: { voice: 'bm_george', speed: 1.05 }, + scottish: { voice: 'bm_lewis', speed: 1.1 }, + french: { voice: 'bf_isabella', speed: 0.9 }, + texan: { voice: 'am_eric', speed: 0.8 }, + + // --- Character voices --- + whisper: { voice: 'af_bella', speed: 0.7 }, + surfer: { voice: 'am_liam', speed: 1.0 }, + pirate_v: { voice: 'am_eric', speed: 0.95 }, + cowboy_v: { voice: 'am_eric', speed: 0.85 }, + ninja_v: { voice: 'bm_fable', speed: 1.05 }, + alien_v: { voice: 'bf_alice', speed: 0.8 }, + echo_v: { voice: 'am_echo', speed: 0.8 }, + + // --- Old people --- + grandpa: { voice: 'am_eric', speed: 0.6 }, + grandma: { voice: 'bf_lily', speed: 0.55 }, + crotchety: { voice: 'bm_daniel', speed: 1.0 }, + + // --- Misc characters --- + drunk: { voice: 'am_liam', speed: 0.6 }, + sleepy: { voice: 'bm_fable', speed: 0.4 }, + stoner: { voice: 'am_liam', speed: 0.5 }, + npc: { voice: 'af_river', speed: 0.95 }, + conspiracy: { voice: 'bm_fable', speed: 1.2 }, +} + +// Default fallback +const DEFAULT_VOICE: VoiceMapping = { voice: 'am_fenrir', speed: 1.0 } + +let ttsInstance: KokoroTTSType | null = null +let ttsLoading = false +let ttsLoadFailed = false +let _audioCtx: AudioContext | null = null + +// Audio cache: key = "voice:speed:text" → AudioBuffer +const audioCache = new Map() +const MAX_CACHE = 200 + +// Currently playing sources (for stop) +const activeSources: Set = new Set() + +function getAudioCtx(): AudioContext { + if (!_audioCtx) _audioCtx = new AudioContext() + if (_audioCtx.state === 'suspended') _audioCtx.resume().catch(() => {}) + return _audioCtx +} + +/** Set the shared AudioContext (called from sounds.ts so we share one context) */ +export function setAudioContext(ctx: AudioContext) { + _audioCtx = ctx +} + +/** Is the kokoro model loaded and ready? */ +export function isKokoroReady(): boolean { + return ttsInstance !== null +} + +/** Is the kokoro model currently loading? */ +export function isKokoroLoading(): boolean { + return ttsLoading +} + +/** Start loading the kokoro model. Call early (e.g. on first user gesture). */ +export async function initKokoro(onProgress?: (pct: number) => void): Promise { + if (ttsInstance || ttsLoading || ttsLoadFailed) return + ttsLoading = true + try { + const { KokoroTTS } = await import('kokoro-js') + ttsInstance = await KokoroTTS.from_pretrained('onnx-community/Kokoro-82M-ONNX', { + dtype: 'q8', + device: null, // auto-detect (WebGPU → WASM fallback) + progress_callback: onProgress ? (p: any) => { + if (p.progress !== undefined) onProgress(p.progress) + } : undefined, + }) + ttsLoading = false + // Pre-cache common fight phrases in the background + _precacheCommon() + } catch (e) { + console.warn('[kokoro] Failed to load TTS model:', e) + ttsLoading = false + ttsLoadFailed = true + } +} + +// Common phrases to pre-generate so they play instantly +const PRECACHE_PHRASES: Array<{ text: string; profile: string }> = [ + { text: 'K. O.!', profile: 'announcer' }, + { text: 'Devastating!', profile: 'deep' }, + { text: 'Flawless victory!', profile: 'deep' }, + { text: 'Finish it!', profile: 'announcer' }, + { text: 'Fatality!', profile: 'deep' }, + { text: 'Round one!', profile: 'announcer' }, + { text: 'Round two!', profile: 'announcer' }, + { text: 'Round three!', profile: 'announcer' }, + { text: 'Fight!', profile: 'announcer' }, +] + +async function _precacheCommon() { + if (!ttsInstance) return + for (const { text, profile } of PRECACHE_PHRASES) { + try { + await _generateAndCache(text, profile) + } catch { /* swallow — non-critical */ } + } +} + +function _cacheKey(text: string, profile: string): string { + const m = VOICE_MAP[profile] || DEFAULT_VOICE + return `${m.voice}:${m.speed}:${text}` +} + +async function _generateAndCache(text: string, profile: string): Promise { + if (!ttsInstance) return null + const key = _cacheKey(text, profile) + const cached = audioCache.get(key) + if (cached) return cached + + const mapping = VOICE_MAP[profile] || DEFAULT_VOICE + const raw = await ttsInstance.generate(text, { + voice: mapping.voice, + speed: mapping.speed, + }) + + // Convert Float32Array → AudioBuffer + const ctx = getAudioCtx() + const buf = ctx.createBuffer(1, raw.audio.length, raw.sampling_rate) + buf.getChannelData(0).set(raw.audio) + + // Evict oldest if cache is full + if (audioCache.size >= MAX_CACHE) { + const oldest = audioCache.keys().next().value + if (oldest) audioCache.delete(oldest) + } + audioCache.set(key, buf) + return buf +} + +/** + * Play audio through the given destination node with volume control. + * Returns a promise that resolves when playback finishes. + */ +function _playBuffer(buf: AudioBuffer, dest: AudioNode, volume: number): Promise { + return new Promise((resolve) => { + const ctx = getAudioCtx() + const src = ctx.createBufferSource() + src.buffer = buf + const gain = ctx.createGain() + gain.gain.value = volume + src.connect(gain) + gain.connect(dest) + activeSources.add(src) + src.onended = () => { + activeSources.delete(src) + resolve() + } + src.start() + }) +} + +/** + * Generate and play TTS. Returns a promise that resolves when done. + * Returns null if kokoro isn't ready (caller should fall back). + */ +export async function kokoroSpeakAsync( + text: string, + profileName: string, + dest: AudioNode, + volume: number = 0.7, +): Promise { + if (!ttsInstance) return false + try { + const buf = await _generateAndCache(text, profileName) + if (!buf) return false + await _playBuffer(buf, dest, volume) + return true + } catch (e) { + console.warn('[kokoro] Speech generation failed:', e) + return false + } +} + +/** + * Fire-and-forget version. Returns true if kokoro handled it, false to fall back. + */ +export function kokoroSpeak( + text: string, + profileName: string, + dest: AudioNode, + volume: number = 0.7, +): boolean { + if (!ttsInstance) return false + // Check cache for instant playback + const key = _cacheKey(text, profileName) + const cached = audioCache.get(key) + if (cached) { + _playBuffer(cached, dest, volume) + return true + } + // Generate async — will play when ready + _generateAndCache(text, profileName).then(buf => { + if (buf) _playBuffer(buf, dest, volume) + }).catch(() => {}) + return true +} + +/** Stop all currently playing kokoro audio */ +export function kokoroStop() { + for (const src of activeSources) { + try { src.stop() } catch {} + } + activeSources.clear() +} + +/** Clear the audio cache */ +export function kokoroClearCache() { + audioCache.clear() +} + +/** Get the kokoro voice mapping for a profile name */ +export function getKokoroVoice(profileName: string): VoiceMapping { + return VOICE_MAP[profileName] || DEFAULT_VOICE +} diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 53004ab..0145c58 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -28,6 +28,7 @@ export default defineConfig({ }, workbox: { globPatterns: ['**/*.{js,css,html,svg,png,woff,woff2}'], + maximumFileSizeToCacheInBytes: 5 * 1024 * 1024, // 5MB — kokoro TTS chunk is ~2.2MB cleanupOutdatedCaches: true, skipWaiting: true, clientsClaim: true, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 483f5ea..8039c16 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,9 @@ importers: kaplay: specifier: ^3001.0.19 version: 3001.0.19 + kokoro-js: + specifier: ^1.2.1 + version: 1.2.1 nostr-tools: specifier: ^2.23.3 version: 2.23.3(typescript@5.9.3) @@ -611,6 +614,9 @@ packages: '@drizzle-team/brocli@0.10.2': resolution: {integrity: sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==} + '@emnapi/runtime@1.8.1': + resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} + '@esbuild-kit/core-utils@3.3.2': resolution: {integrity: sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==} deprecated: 'Merged into tsx: https://tsx.is' @@ -1051,10 +1057,174 @@ packages: peerDependencies: hono: ^4 + '@huggingface/jinja@0.5.5': + resolution: {integrity: sha512-xRlzazC+QZwr6z4ixEqYHo9fgwhTZ3xNSdljlKfUFGZSdlvt166DljRELFUfFytlYOYvo3vTisA/AFOuOAzFQQ==} + engines: {node: '>=18'} + + '@huggingface/transformers@3.8.1': + resolution: {integrity: sha512-tsTk4zVjImqdqjS8/AOZg2yNLd1z9S5v+7oUPpXaasDRwEDhB+xnglK1k5cad26lL5/ZIaeREgWWy0bs9y9pPA==} + + '@img/colour@1.1.0': + resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} + engines: {node: '>=18'} + + '@img/sharp-darwin-arm64@0.34.5': + resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.34.5': + resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.2.4': + resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.2.4': + resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.2.4': + resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-arm@1.2.4': + resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-ppc64@1.2.4': + resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-riscv64@1.2.4': + resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-s390x@1.2.4': + resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-x64@1.2.4': + resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-linux-arm64@0.34.5': + resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-arm@0.34.5': + resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-ppc64@0.34.5': + resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-riscv64@0.34.5': + resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-s390x@0.34.5': + resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-x64@0.34.5': + resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-linuxmusl-arm64@0.34.5': + resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-linuxmusl-x64@0.34.5': + resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-wasm32@0.34.5': + resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.34.5': + resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.34.5': + resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.34.5': + resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + '@isaacs/cliui@9.0.0': resolution: {integrity: sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==} engines: {node: '>=18'} + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -1089,6 +1259,36 @@ packages: '@petamoriken/float16@3.9.3': resolution: {integrity: sha512-8awtpHXCx/bNpFt4mt2xdkgtgVvKqty8VbjHI/WWWQuEw+KLzFot3f4+LkQY9YmOtq7A5GdOnqoIC8Pdygjk2g==} + '@protobufjs/aspromise@1.1.2': + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + + '@protobufjs/base64@1.1.2': + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + + '@protobufjs/codegen@2.0.4': + resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} + + '@protobufjs/eventemitter@1.1.0': + resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} + + '@protobufjs/fetch@1.1.0': + resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} + + '@protobufjs/float@1.0.2': + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + + '@protobufjs/inquire@1.1.0': + resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} + + '@protobufjs/path@1.1.2': + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + + '@protobufjs/pool@1.1.0': + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + + '@protobufjs/utf8@1.1.0': + resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} + '@rollup/plugin-babel@5.3.1': resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==} engines: {node: '>= 10.0.0'} @@ -1579,6 +1779,10 @@ packages: bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + boolean@3.2.0: + resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + brace-expansion@2.0.2: resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} @@ -1635,6 +1839,10 @@ packages: chownr@1.1.4: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} @@ -1727,6 +1935,9 @@ packages: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} + detect-node@2.1.0: + resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} + dotenv@17.3.1: resolution: {integrity: sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==} engines: {node: '>=12'} @@ -1881,6 +2092,9 @@ packages: resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} engines: {node: '>= 0.4'} + es6-error@4.1.1: + resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} + esbuild-register@3.6.0: resolution: {integrity: sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==} peerDependencies: @@ -1905,6 +2119,10 @@ packages: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + estree-walker@1.0.1: resolution: {integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==} @@ -1950,6 +2168,9 @@ packages: filelist@1.0.6: resolution: {integrity: sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==} + flatbuffers@25.9.23: + resolution: {integrity: sha512-MI1qs7Lo4Syw0EOzUl0xjs2lsoeqFku44KpngfIduHBYvzm8h2+7K8YMQh1JtVVVrUvhLpNwqVi4DERegUJhPQ==} + for-each@0.3.5: resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} engines: {node: '>= 0.4'} @@ -2024,6 +2245,10 @@ packages: deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true + global-agent@3.0.0: + resolution: {integrity: sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==} + engines: {node: '>=10.0'} + globalthis@1.0.4: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} @@ -2035,6 +2260,9 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + guid-typescript@1.0.9: + resolution: {integrity: sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ==} + has-bigints@1.1.0: resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} engines: {node: '>= 0.4'} @@ -2233,6 +2461,9 @@ packages: json-schema@0.4.0: resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} @@ -2249,6 +2480,9 @@ packages: resolution: {integrity: sha512-T8GdXGXvgv/vbYVA1lcHzuDNVhp3juOJJE8OZs0vR5MdGNElBvANEeTSnqAAhJpSXtNxpeNy29pqkok3RnXKtg==} engines: {node: '>=20.0.0'} + kokoro-js@1.2.1: + resolution: {integrity: sha512-oq0HZJWis3t8lERkMJh84WLU86dpYD0EuBPtqYnLlQzyFP1OkyBRDcweAqCfhNOpltyN9j/azp1H6uuC47gShw==} + leven@3.1.0: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} engines: {node: '>=6'} @@ -2336,6 +2570,9 @@ packages: lodash@4.17.23: resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==} + long@5.3.2: + resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} + loupe@3.2.1: resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} @@ -2352,6 +2589,10 @@ packages: magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + matcher@3.0.0: + resolution: {integrity: sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==} + engines: {node: '>=10'} + math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} @@ -2379,6 +2620,10 @@ packages: resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} + minizlib@3.1.0: + resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} + engines: {node: '>= 18'} + mkdirp-classic@0.5.3: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} @@ -2434,6 +2679,19 @@ packages: once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + onnxruntime-common@1.21.0: + resolution: {integrity: sha512-Q632iLLrtCAVOTO65dh2+mNbQir/QNTVBG3h/QdZBpns7mZ0RYbLRBgGABPbpU9351AgYy7SJf1WaeVwMrBFPQ==} + + onnxruntime-common@1.22.0-dev.20250409-89f8206ba4: + resolution: {integrity: sha512-vDJMkfCfb0b1A836rgHj+ORuZf4B4+cc2bASQtpeoJLueuFc5DuYwjIZUBrSvx/fO5IrLjLz+oTrB3pcGlhovQ==} + + onnxruntime-node@1.21.0: + resolution: {integrity: sha512-NeaCX6WW2L8cRCSqy3bInlo5ojjQqu2fD3D+9W5qb5irwxhEyWKXeH2vZ8W9r6VxaMPUan+4/7NDwZMtouZxEw==} + os: [win32, darwin, linux] + + onnxruntime-web@1.22.0-dev.20250409-89f8206ba4: + resolution: {integrity: sha512-0uS76OPgH0hWCPrFKlL8kYVV7ckM7t/36HfbgoFw6Nd0CZVVbQC4PkrR8mBX8LtNUFZO25IQBqV2Hx2ho3FlbQ==} + own-keys@1.0.1: resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} engines: {node: '>= 0.4'} @@ -2462,6 +2720,9 @@ packages: resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} engines: {node: '>= 14.16'} + phonemizer@1.2.1: + resolution: {integrity: sha512-v0KJ4mi2T4Q7eJQ0W15Xd4G9k4kICSXE8bpDeJ8jisL4RyJhNWsweKTOi88QXFc4r4LZlz5jVL5lCHhkpdT71A==} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -2473,6 +2734,9 @@ packages: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} + platform@1.3.6: + resolution: {integrity: sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==} + possible-typed-array-names@1.1.0: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} @@ -2495,6 +2759,10 @@ packages: resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==} engines: {node: ^14.13.1 || >=16.0.0} + protobufjs@7.5.4: + resolution: {integrity: sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==} + engines: {node: '>=12.0.0'} + pump@3.0.4: resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} @@ -2555,6 +2823,10 @@ packages: engines: {node: '>= 0.4'} hasBin: true + roarr@2.15.4: + resolution: {integrity: sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==} + engines: {node: '>=8.0'} + rollup@2.80.0: resolution: {integrity: sha512-cIFJOD1DESzpjOBl763Kp1AH7UE/0fcdHe6rZXUdQ9c50uvgigvW97u3IcSeBwOkgqL/PXPBktBCh0KEu5L8XQ==} engines: {node: '>=10.0.0'} @@ -2583,6 +2855,9 @@ packages: resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} engines: {node: '>= 0.4'} + semver-compare@1.0.0: + resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==} + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -2592,6 +2867,10 @@ packages: engines: {node: '>=10'} hasBin: true + serialize-error@7.0.1: + resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==} + engines: {node: '>=10'} + serialize-javascript@6.0.2: resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} @@ -2607,6 +2886,10 @@ packages: resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} engines: {node: '>= 0.4'} + sharp@0.34.5: + resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -2672,6 +2955,9 @@ packages: resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} deprecated: Please use @jridgewell/sourcemap-codec instead + sprintf-js@1.1.3: + resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} @@ -2750,6 +3036,10 @@ packages: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} engines: {node: '>=6'} + tar@7.5.10: + resolution: {integrity: sha512-8mOPs1//5q/rlkNSPcCegA6hiHJYDmSLEI8aMH/CdSQJNWztHC9WHNam5zdQlfpTwB9Xp7IBEsHfV5LKMJGVAw==} + engines: {node: '>=18'} + temp-dir@2.0.0: resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==} engines: {node: '>=8'} @@ -2803,6 +3093,10 @@ packages: tunnel-agent@0.6.0: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + type-fest@0.13.1: + resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} + engines: {node: '>=10'} + type-fest@0.16.0: resolution: {integrity: sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==} engines: {node: '>=10'} @@ -3079,6 +3373,10 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} @@ -3759,6 +4057,11 @@ snapshots: '@drizzle-team/brocli@0.10.2': {} + '@emnapi/runtime@1.8.1': + dependencies: + tslib: 2.8.1 + optional: true + '@esbuild-kit/core-utils@3.3.2': dependencies: esbuild: 0.18.20 @@ -3986,8 +4289,117 @@ snapshots: dependencies: hono: 4.12.5 + '@huggingface/jinja@0.5.5': {} + + '@huggingface/transformers@3.8.1': + dependencies: + '@huggingface/jinja': 0.5.5 + onnxruntime-node: 1.21.0 + onnxruntime-web: 1.22.0-dev.20250409-89f8206ba4 + sharp: 0.34.5 + + '@img/colour@1.1.0': {} + + '@img/sharp-darwin-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.2.4 + optional: true + + '@img/sharp-darwin-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.2.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.2.4': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-riscv64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-s390x@1.2.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + optional: true + + '@img/sharp-linux-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.2.4 + optional: true + + '@img/sharp-linux-arm@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.2.4 + optional: true + + '@img/sharp-linux-ppc64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-ppc64': 1.2.4 + optional: true + + '@img/sharp-linux-riscv64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-riscv64': 1.2.4 + optional: true + + '@img/sharp-linux-s390x@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.2.4 + optional: true + + '@img/sharp-linux-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + optional: true + + '@img/sharp-wasm32@0.34.5': + dependencies: + '@emnapi/runtime': 1.8.1 + optional: true + + '@img/sharp-win32-arm64@0.34.5': + optional: true + + '@img/sharp-win32-ia32@0.34.5': + optional: true + + '@img/sharp-win32-x64@0.34.5': + optional: true + '@isaacs/cliui@9.0.0': {} + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.3 + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -4022,6 +4434,29 @@ snapshots: '@petamoriken/float16@3.9.3': {} + '@protobufjs/aspromise@1.1.2': {} + + '@protobufjs/base64@1.1.2': {} + + '@protobufjs/codegen@2.0.4': {} + + '@protobufjs/eventemitter@1.1.0': {} + + '@protobufjs/fetch@1.1.0': + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/inquire': 1.1.0 + + '@protobufjs/float@1.0.2': {} + + '@protobufjs/inquire@1.1.0': {} + + '@protobufjs/path@1.1.2': {} + + '@protobufjs/pool@1.1.0': {} + + '@protobufjs/utf8@1.1.0': {} + '@rollup/plugin-babel@5.3.1(@babel/core@7.29.0)(rollup@2.80.0)': dependencies: '@babel/core': 7.29.0 @@ -4480,6 +4915,8 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 + boolean@3.2.0: {} + brace-expansion@2.0.2: dependencies: balanced-match: 1.0.2 @@ -4543,6 +4980,8 @@ snapshots: chownr@1.1.4: {} + chownr@3.0.0: {} + cliui@8.0.1: dependencies: string-width: 4.2.3 @@ -4632,6 +5071,8 @@ snapshots: detect-libc@2.1.2: {} + detect-node@2.1.0: {} + dotenv@17.3.1: {} drizzle-kit@0.30.6: @@ -4757,6 +5198,8 @@ snapshots: is-date-object: 1.1.0 is-symbol: 1.1.1 + es6-error@4.1.1: {} + esbuild-register@3.6.0(esbuild@0.19.12): dependencies: debug: 4.4.3 @@ -4846,6 +5289,8 @@ snapshots: escalade@3.2.0: {} + escape-string-regexp@4.0.0: {} + estree-walker@1.0.1: {} estree-walker@2.0.2: {} @@ -4876,6 +5321,8 @@ snapshots: dependencies: minimatch: 5.1.9 + flatbuffers@25.9.23: {} + for-each@0.3.5: dependencies: is-callable: 1.2.7 @@ -4968,6 +5415,15 @@ snapshots: package-json-from-dist: 1.0.1 path-scurry: 2.0.2 + global-agent@3.0.0: + dependencies: + boolean: 3.2.0 + es6-error: 4.1.1 + matcher: 3.0.0 + roarr: 2.15.4 + semver: 7.7.4 + serialize-error: 7.0.1 + globalthis@1.0.4: dependencies: define-properties: 1.2.1 @@ -4977,6 +5433,8 @@ snapshots: graceful-fs@4.2.11: {} + guid-typescript@1.0.9: {} + has-bigints@1.1.0: {} has-flag@4.0.0: {} @@ -5155,6 +5613,8 @@ snapshots: json-schema@0.4.0: {} + json-stringify-safe@5.0.1: {} + json5@2.2.3: {} jsonfile@6.2.0: @@ -5167,6 +5627,11 @@ snapshots: kaplay@3001.0.19: {} + kokoro-js@1.2.1: + dependencies: + '@huggingface/transformers': 3.8.1 + phonemizer: 1.2.1 + leven@3.1.0: {} lightningcss-android-arm64@1.31.1: @@ -5224,6 +5689,8 @@ snapshots: lodash@4.17.23: {} + long@5.3.2: {} + loupe@3.2.1: {} lru-cache@11.2.6: {} @@ -5240,6 +5707,10 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + matcher@3.0.0: + dependencies: + escape-string-regexp: 4.0.0 + math-intrinsics@1.1.0: {} mimic-response@3.1.0: {} @@ -5260,6 +5731,10 @@ snapshots: minipass@7.1.3: {} + minizlib@3.1.0: + dependencies: + minipass: 7.1.3 + mkdirp-classic@0.5.3: {} ms@2.1.3: {} @@ -5309,6 +5784,25 @@ snapshots: dependencies: wrappy: 1.0.2 + onnxruntime-common@1.21.0: {} + + onnxruntime-common@1.22.0-dev.20250409-89f8206ba4: {} + + onnxruntime-node@1.21.0: + dependencies: + global-agent: 3.0.0 + onnxruntime-common: 1.21.0 + tar: 7.5.10 + + onnxruntime-web@1.22.0-dev.20250409-89f8206ba4: + dependencies: + flatbuffers: 25.9.23 + guid-typescript: 1.0.9 + long: 5.3.2 + onnxruntime-common: 1.22.0-dev.20250409-89f8206ba4 + platform: 1.3.6 + protobufjs: 7.5.4 + own-keys@1.0.1: dependencies: get-intrinsic: 1.3.0 @@ -5332,12 +5826,16 @@ snapshots: pathval@2.0.1: {} + phonemizer@1.2.1: {} + picocolors@1.1.1: {} picomatch@2.3.1: {} picomatch@4.0.3: {} + platform@1.3.6: {} + possible-typed-array-names@1.1.0: {} postcss@8.5.8: @@ -5365,6 +5863,21 @@ snapshots: pretty-bytes@6.1.1: {} + protobufjs@7.5.4: + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.4 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.0 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.0 + '@types/node': 22.19.15 + long: 5.3.2 + pump@3.0.4: dependencies: end-of-stream: 1.4.5 @@ -5442,6 +5955,15 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + roarr@2.15.4: + dependencies: + boolean: 3.2.0 + detect-node: 2.1.0 + globalthis: 1.0.4 + json-stringify-safe: 5.0.1 + semver-compare: 1.0.0 + sprintf-js: 1.1.3 + rollup@2.80.0: optionalDependencies: fsevents: 2.3.3 @@ -5502,10 +6024,16 @@ snapshots: es-errors: 1.3.0 is-regex: 1.2.1 + semver-compare@1.0.0: {} + semver@6.3.1: {} semver@7.7.4: {} + serialize-error@7.0.1: + dependencies: + type-fest: 0.13.1 + serialize-javascript@6.0.2: dependencies: randombytes: 2.1.0 @@ -5532,6 +6060,37 @@ snapshots: es-errors: 1.3.0 es-object-atoms: 1.1.1 + sharp@0.34.5: + dependencies: + '@img/colour': 1.1.0 + detect-libc: 2.1.2 + semver: 7.7.4 + 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 + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -5597,6 +6156,8 @@ snapshots: sourcemap-codec@1.4.8: {} + sprintf-js@1.1.3: {} + stackback@0.0.2: {} std-env@3.10.0: {} @@ -5702,6 +6263,14 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 + tar@7.5.10: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.3 + minizlib: 3.1.0 + yallist: 5.0.0 + temp-dir@2.0.0: {} tempy@0.6.0: @@ -5752,6 +6321,8 @@ snapshots: dependencies: safe-buffer: 5.2.1 + type-fest@0.13.1: {} + type-fest@0.16.0: {} typed-array-buffer@1.0.3: @@ -6124,6 +6695,8 @@ snapshots: yallist@3.1.1: {} + yallist@5.0.0: {} + yargs-parser@21.1.1: {} yargs@17.7.2: