@degreesign/chat 1.7.2 → 1.7.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # @degreesign/chat
2
2
 
3
- Headless on-device AI chat for browsers, workers and Node: one model in memory,
4
- one streamed reply, no UI. A wllama CPU engine and a LiteRT-LM WebGPU engine
5
- handle text and image turns, downloads resume after a reload, and every export
6
- is typed.
3
+ Plug-and-play on-device AI chat for browsers, workers and Node: one model in
4
+ memory, unlimited offline replies in any UI. The package picks the engine,
5
+ manages the download, fits the prompt and reuses the cache; a wllama CPU engine
6
+ and a LiteRT-LM WebGPU engine run it all locally, and every export is typed.
7
7
 
8
8
  [![npm version](https://img.shields.io/npm/v/@degreesign/chat.svg)](https://www.npmjs.com/package/@degreesign/chat)
9
9
  [![license](https://img.shields.io/badge/license-MIT-blue.svg)](#licensing)
@@ -12,8 +12,19 @@ is typed.
12
12
  [![architecture](https://img.shields.io/badge/architecture-view-blue.svg)](https://degreesign.github.io/ds_chat/architecture.html)
13
13
  [![comparison](https://img.shields.io/badge/comparison-web--llm-blue.svg)](https://degreesign.github.io/ds_chat/vs_web_llm.html)
14
14
 
15
+ ## Demo
16
+
17
+ [Open the showcase](https://degreesign.github.io/ds_chat/) for a live chat demo
18
+ in the browser, or browse the [architecture
19
+ map](https://degreesign.github.io/ds_chat/architecture.html). The demo downloads
20
+ a model once, about 1.5 GB on the CPU engine or 2.0 GB on WebGPU, and then
21
+ answers on the device.
22
+
23
+ **[Open the live showcase →](https://degreesign.github.io/ds_chat/)**
24
+
15
25
  ## Table of contents
16
26
 
27
+ - [Demo](#demo)
17
28
  - [Why](#why)
18
29
  - [Install](#install)
19
30
  - [Quick start](#quick-start)
@@ -39,8 +50,10 @@ is typed.
39
50
  with the network off.
40
51
  - On device: weights download once, then every reply is generated locally,
41
52
  with no API key and no per-reply cost.
42
- - Headless and stateless: results arrive through callbacks, no UI is rendered
43
- and no history is kept; the host passes the whole message list.
53
+ - Plug and play: the package picks the engine, fits the prompt, resumes the
54
+ download and reuses the cache, with no setup.
55
+ - Headless and stateless: results arrive through callbacks, so any UI can
56
+ render them, and no history is kept; the host passes the whole message list.
44
57
  - Two engines behind one runtime: CPU through wllama, WebGPU through LiteRT-LM.
45
58
  - Typed and portable: declarations for every export, and importing it works in
46
59
  browsers, workers, React and Node.
@@ -136,7 +149,7 @@ already loaded skips the download and the load. One model stays resident, and
136
149
 
137
150
  The budget defaults are 250 reply tokens, 128 CPU thinking tokens, 1200 GPU
138
151
  reasoning tokens (320 on the CPU), 2 images, 1 audio clip, 1000 characters per
139
- message, 10000 prompt characters, 32 CPU threads and a 0.5 GPU busy share. The
152
+ message, 10000 prompt characters, 32 CPU threads and a full GPU busy share. The
140
153
  CPU engine ignores `gpuShare`; the GPU engine applies it after prefill.
141
154
 
142
155
  `CancelChat` is `() => void`:
@@ -366,6 +379,9 @@ user: {next turn}
366
379
  and empty messages are skipped.
367
380
  - `maxContentLength` clips each message and `promptCharBudget` bounds the whole
368
381
  prompt; image and audio payloads do not count against it.
382
+ - Every prompt is fitted to the model context window: oldest non-system turns
383
+ are dropped until the prompt and a 64-token reply fit, and the reply budget
384
+ is capped to the remaining window with 128 tokens reserved for the template.
369
385
  - System messages are folded into one leading system turn.
370
386
  - Images and audio come from the newest turns first, capped by `maxImages`
371
387
  (default 2) and `maxAudio` (default 1). Older parts are dropped, text stays.
@@ -405,10 +421,11 @@ google-chrome --enable-features=Vulkan --use-angle=vulkan
405
421
  `--enable-features=Vulkan,WebGPU` and `--use-angle=vulkan`.
406
422
 
407
423
  The GPU engine keeps the model and KV cache in GPU memory and rests after every
408
- token readback, so the card stays near 50% of wall time. `limits.gpuShare`
409
- overrides that for one reply, from 0.05 to 1; `1` disables the rest, and prefill
410
- runs unpaced. A busy card can lose the device (`VK_ERROR_DEVICE_LOST`); close
411
- other GPU tabs or use the CPU model.
424
+ token readback only when `limits.gpuShare` asks for it. The default is `1`, no
425
+ rest, so the card sits at the full decode rate; lower it, from 0.05 to 1, to
426
+ leave the card time between tokens, and prefill always runs unpaced. A busy card
427
+ can lose the device (`VK_ERROR_DEVICE_LOST`); close other GPU tabs or use the
428
+ CPU model.
412
429
 
413
430
  ## Engines and assets
414
431
 
@@ -1,2 +1,2 @@
1
1
  /*! For license information please see chat.min.mjs.LICENSE.txt */
2
- var e={167(e){e.exports=(()=>{var e={28:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.migrateSecure=t.showError=t.config=t.configureStorageSync=t.configureStorage=void 0;const n=r(896),o=r(205),a={storageKey:"appData",dbName:"appDB",storeName:"appStorage",encryptionKey:void 0,hideErrors:!1,localStoragePrefix:"ds:"},i=({storageKey:e,dbName:t,storeName:r,encryptionKey:n,hideErrors:o,localStoragePrefix:i})=>{try{e&&(a.storageKey=e),t&&(a.dbName=t),r&&(a.storeName=r),n&&(a.encryptionKeyStr=n),null!=o&&(a.hideErrors=o),i&&(a.localStoragePrefix=i)}catch(e){s()&&console.log("configureStorageSync failed",e)}},s=()=>!a.hideErrors;t.config=a,t.configureStorage=async({storageKey:e,dbName:t,storeName:r,encryptionKey:n,hideErrors:c,localStoragePrefix:l})=>{try{i({storageKey:e,dbName:t,storeName:r,hideErrors:c,localStoragePrefix:l}),n&&(a.encryptionKey=await(0,o.cryptoKey)(n),a.encryptionKeyStr=n)}catch(e){s()&&console.log("configureStorage failed",e)}},t.configureStorageSync=i,t.showError=s,t.migrateSecure=async({storedKeys:e,newEncryptionKey:t,newDbName:r,newStoreName:i})=>{s()&&console.log("Data migration started...");const c=a.encryptionKey,l=a.dbName,u=a.storeName;a.encryptionKey=await(0,o.cryptoKey)(t)??a.encryptionKey,a.encryptionKeyStr=t??a.encryptionKeyStr,a.dbName=r??a.dbName,a.storeName=i??a.storeName;for(let t=0;t<e.length;t++){const r=e[t];try{const e=await(0,n.readDB)({key:r,dbName:l,storeName:u}),t=e?c?await(0,o.decryptData)(e,c):JSON.parse(e):void 0,i=t?a.encryptionKey?await(0,o.encryptData)(t,a.encryptionKey):JSON.stringify(t):void 0;i&&await(0,n.saveDB)({key:r,data:i,dbName:a.dbName,storeName:a.storeName})}catch(e){s()&&console.log("migrateSecure failed",r,e)}}s()&&console.log("Data migration finished!")}},185:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.base64ToBytes=t.bytesToBase64=void 0,t.bytesToBase64=e=>{let t="",r=0;for(;r<e.length;r+=32768)t+=String.fromCharCode(...e.subarray(r,r+32768));return btoa(t)},t.base64ToBytes=e=>{const t=atob(e),r=new Uint8Array(t.length);for(let e=0;e<t.length;e++)r[e]=t.charCodeAt(e);return r}},205:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.decrypt=t.encrypt=t.decryptData=t.encryptData=t.cryptoKey=void 0;const n=r(28),o=r(185),a=async(e,t)=>{try{const r=crypto.getRandomValues(new Uint8Array(12)),n=(new TextEncoder).encode(JSON.stringify(e)),a=await crypto.subtle.encrypt({name:"AES-GCM",iv:r},t,n),i=new Uint8Array(a),s=new Uint8Array(r.length+i.length);return s.set(r),s.set(i,r.length),(0,o.bytesToBase64)(s)}catch(t){(0,n.showError)()&&console.log("encryptData failed",t);try{return JSON.stringify(e)}catch(e){}}},i=async(e,t)=>{try{const r=(0,o.base64ToBytes)(e),n=r.slice(0,12),a=r.slice(12),i=await crypto.subtle.decrypt({name:"AES-GCM",iv:n},t,a);return JSON.parse((new TextDecoder).decode(i))}catch(e){(0,n.showError)()&&console.log("decryptData failed",e)}};t.cryptoKey=async e=>{try{if(!e)return;const t=await crypto.subtle.importKey("raw",(new TextEncoder).encode(e),"PBKDF2",!1,["deriveKey"]);return await crypto.subtle.deriveKey({name:"PBKDF2",salt:(new TextEncoder).encode("salt"),iterations:1e5,hash:"SHA-256"},t,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"])}catch(e){(0,n.showError)()&&console.log("processKey failed",e)}},t.encryptData=a,t.decryptData=i,t.encrypt=async e=>{try{return n.config?.encryptionKey?await a(e,n.config.encryptionKey):JSON.stringify(e)}catch(t){(0,n.showError)()&&console.log("encrypt failed",t);try{return JSON.stringify(e)}catch(e){}}},t.decrypt=async e=>{try{return n.config?.encryptionKey?await i(e,n.config.encryptionKey):JSON.parse(e)}catch(e){(0,n.showError)()&&console.log("decrypt failed",e)}}},247:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.readSecureSync=t.saveSecureSync=t.readSecure=t.saveSecure=void 0;const n=r(28),o=r(896),a=r(205),i=r(622);t.saveSecure=async({key:e,data:t})=>{try{return await(0,o.saveDB)({key:e,data:t?await(0,a.encrypt)(t):void 0,dbName:n.config.dbName,storeName:n.config.storeName})}catch(e){(0,n.showError)()&&console.log("saveSecure failed",e)}return!1},t.readSecure=async e=>{try{const t=await(0,o.readDB)({key:e,dbName:n.config.dbName,storeName:n.config.storeName});return t?await(0,a.decrypt)(t):void 0}catch(e){(0,n.showError)()&&console.log("readSecure failed",e)}},t.saveSecureSync=({key:e,data:t})=>{try{return void 0===t?localStorage.removeItem(e):localStorage.setItem(e,(0,i.encryptSync)(t)??""),!0}catch(e){(0,n.showError)()&&console.log("saveSecureSync failed",e)}return!1},t.readSecureSync=e=>{try{const t=localStorage.getItem(e);return t?(0,i.decryptSync)(t):void 0}catch(e){(0,n.showError)()&&console.log("readSecureSync failed",e)}}},421:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.readData=t.saveData=void 0;const n=r(28);t.saveData=({key:e,data:t})=>{try{void 0===t?localStorage.removeItem(e):localStorage.setItem(e,JSON.stringify(t))}catch(e){(0,n.showError)()&&console.log("saveData failed",e)}},t.readData=e=>{try{const t=localStorage.getItem(e);return t?JSON.parse(t):void 0}catch(e){(0,n.showError)()&&console.log("readData failed",e)}}},622:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.decryptSync=t.encryptSync=t.decryptDataSync=t.encryptDataSync=void 0;const n=r(28),o=r(185),a=(e,t,r)=>{try{const n=new Uint8Array(e.length);for(let o=0;o<e.length;o++)n[o]=e[o]^255&t.charCodeAt(o%t.length)^r[o%r.length];return n}catch(e){(0,n.showError)()&&console.log("xorCipher failed",e)}},i=(e,t)=>{try{const r=crypto.getRandomValues(new Uint8Array(8)),i=(new TextEncoder).encode(JSON.stringify(e)),s=a(i,t,r),c=new Uint8Array(r.length+i.length);return c.set(r),s&&c.set(s,r.length),`${n.config.localStoragePrefix}${(0,o.bytesToBase64)(c)}`}catch(t){(0,n.showError)()&&console.log("encryptDataSync failed",t);try{return JSON.stringify(e)}catch(e){}}},s=(e,t)=>{try{const r=(0,o.base64ToBytes)(e.startsWith(n.config.localStoragePrefix)?e.slice(n.config.localStoragePrefix.length):e),i=r.slice(0,8),s=a(r.slice(8),t,i);return s?JSON.parse((new TextDecoder).decode(s)):void 0}catch(e){(0,n.showError)()&&console.log("decryptDataSync failed",e)}};t.encryptDataSync=i,t.decryptDataSync=s,t.encryptSync=e=>{try{return n.config?.encryptionKeyStr?i(e,n.config.encryptionKeyStr):JSON.stringify(e)}catch(t){(0,n.showError)()&&console.log("encryptSync failed",t);try{return JSON.stringify(e)}catch(e){}}},t.decryptSync=e=>{try{return n.config?.encryptionKeyStr?s(e,n.config.encryptionKeyStr):JSON.parse(e)}catch(e){(0,n.showError)()&&console.log("decryptSync failed",e)}}},896:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.readDB=t.saveDB=t.openDB=void 0;const n=r(28),o=({dbName:e,storeName:t,version:r=1}={})=>new Promise((o,a)=>{e=e||n.config.dbName;const i=indexedDB.open(e,r);i.onupgradeneeded=()=>{t=t||n.config.storeName;const e=i.result;e.objectStoreNames.contains(t)||e.createObjectStore(t,{keyPath:"id"})},i.onsuccess=()=>o(i.result),i.onerror=()=>{(0,n.showError)()&&console.log("openDB failed",i.error),a(i.error)}});t.openDB=o,t.saveDB=async({key:e,data:t,dbName:r,storeName:a})=>{try{const i=await o({dbName:r,storeName:a});return new Promise(r=>{const o=i.transaction([a],"readwrite").objectStore(a),s=t?o.put({id:e,data:t}):o.delete(e);s.onsuccess=()=>r(!0),s.onerror=()=>{(0,n.showError)()&&console.log("saveDB error",s.error),r(!1)},i.close()})}catch(e){(0,n.showError)()&&console.log("saveSecure failed",e)}return!1},t.readDB=async({key:e,dbName:t,storeName:r})=>{try{const a=await o({dbName:t,storeName:r});return new Promise(t=>{const o=a.transaction([r],"readonly").objectStore(r).get(e);o.onsuccess=()=>t(o?.result?.data),o.onerror=()=>{(0,n.showError)()&&console.log("readDB error",o.error),t(void 0)},a.close()})}catch(e){(0,n.showError)()&&console.log("readDB failed",e)}}},915:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.readLarge=t.saveLarge=void 0;const n=r(28),o=r(896);t.saveLarge=async({key:e,data:t})=>{try{return await(0,o.saveDB)({key:e,data:t?JSON.stringify(t):void 0,dbName:n.config.dbName,storeName:n.config.storeName})}catch(e){(0,n.showError)()&&console.log("saveLarge failed",e)}return!1},t.readLarge=async e=>{try{const t=await(0,o.readDB)({key:e,dbName:n.config.dbName,storeName:n.config.storeName});return t?JSON.parse(t):void 0}catch(e){(0,n.showError)()&&console.log("readLarge failed",e)}}}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var a=t[n]={exports:{}};return e[n](a,a.exports,r),a.exports}var n={};return(()=>{var e=n;Object.defineProperty(e,"__esModule",{value:!0}),e.cryptoKey=e.decryptDataSync=e.encryptDataSync=e.decryptData=e.encryptData=e.saveSecureSync=e.readSecureSync=e.saveSecure=e.readSecure=e.saveLarge=e.readLarge=e.saveData=e.readData=e.migrateSecure=e.config=e.configureStorageSync=e.configureStorage=void 0;const t=r(28);Object.defineProperty(e,"configureStorage",{enumerable:!0,get:function(){return t.configureStorage}}),Object.defineProperty(e,"configureStorageSync",{enumerable:!0,get:function(){return t.configureStorageSync}}),Object.defineProperty(e,"config",{enumerable:!0,get:function(){return t.config}}),Object.defineProperty(e,"migrateSecure",{enumerable:!0,get:function(){return t.migrateSecure}});const o=r(421);Object.defineProperty(e,"readData",{enumerable:!0,get:function(){return o.readData}}),Object.defineProperty(e,"saveData",{enumerable:!0,get:function(){return o.saveData}});const a=r(915);Object.defineProperty(e,"readLarge",{enumerable:!0,get:function(){return a.readLarge}}),Object.defineProperty(e,"saveLarge",{enumerable:!0,get:function(){return a.saveLarge}});const i=r(247);Object.defineProperty(e,"readSecure",{enumerable:!0,get:function(){return i.readSecure}}),Object.defineProperty(e,"saveSecure",{enumerable:!0,get:function(){return i.saveSecure}}),Object.defineProperty(e,"readSecureSync",{enumerable:!0,get:function(){return i.readSecureSync}}),Object.defineProperty(e,"saveSecureSync",{enumerable:!0,get:function(){return i.saveSecureSync}});const s=r(205);Object.defineProperty(e,"cryptoKey",{enumerable:!0,get:function(){return s.cryptoKey}}),Object.defineProperty(e,"decryptData",{enumerable:!0,get:function(){return s.decryptData}}),Object.defineProperty(e,"encryptData",{enumerable:!0,get:function(){return s.encryptData}});const c=r(622);Object.defineProperty(e,"encryptDataSync",{enumerable:!0,get:function(){return c.encryptDataSync}}),Object.defineProperty(e,"decryptDataSync",{enumerable:!0,get:function(){return c.decryptDataSync}})})(),n})()},155(e){e.exports=(()=>{var e={125:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.addZ=t.tN=t.monNm=t.tmUTC=t.tmAP=t.moYrDt=t.shortDt=t.fullLong=t.fullDate=t.fullDt=t.invDt=t.dayRes=t.timeStandard=t.dateStandard=t.seoDt=t.thisYear=t.oneMon=t.oneMin=t.oneHr=t.oneDay=t.oneSec=void 0;const r=()=>Date.now(),n=["January","February","March","April","May","June","July","August","September","October","November","December"],o=["JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"],a=["st","nd","rd","th"],i=e=>0==+e?"00":+e<10&&+e>=1?`0${e}`:`${e}`,s=e=>{const t=new Date(e);return`${t.getUTCFullYear()}-${i(t.getUTCMonth()+1)}-${i(t.getUTCDate())}`},c=e=>i(e.getUTCHours())+`:${i(e.getUTCMinutes())}`+`:${i(e.getUTCSeconds())}`;t.tN=r,t.monNm=n,t.dayRes=90,t.oneSec=1e3,t.oneMin=6e4,t.oneHr=36e5,t.oneDay=864e5,t.oneMon=27e8,t.addZ=i,t.tmUTC=e=>{const t=new Date(e);return i(t.getUTCHours())+`:${i(t.getUTCMinutes())} UTC`},t.tmAP=e=>{const t=new Date(e),r=t.getHours();return i(r>12?r-12:r)+`:${i(t.getMinutes())}`+(r>=12?"pm":"am")},t.shortDt=e=>{const t=new Date(e);return`${t.getDate()} ${o[t.getMonth()]}`},t.moYrDt=e=>{const t=new Date(e);return`${o[t.getMonth()]} ${t.getFullYear()}`},t.fullDt=e=>{const t=new Date(e);return`${t.getDate()} ${o[t.getMonth()]} ${t.getFullYear()}`},t.fullDate=e=>{const t=new Date(e);return`${t.getDate()} ${n[t.getMonth()]} ${t.getFullYear()}`},t.fullLong=e=>`${(e=>{const t=new Date(e),r=t.getDate();return r+a[r<5?r-1:r>4&&r<21?3:r>20&&r<25?r-21:r>24&&r<31?3:0]+` of ${n[t.getMonth()]}`})(e)} ${new Date(e).getFullYear()}`,t.thisYear=e=>(e?new Date(e):new Date)?.getUTCFullYear(),t.dateStandard=s,t.timeStandard=c,t.seoDt=e=>{!e&&(e=r());const t=new Date(e);return`${s(t)}T${c(t)}Z`},t.invDt=e=>{const t=new Date(e);return`${t.getUTCFullYear()}`.split("20")[1]+i(t.getUTCMonth()+1)+i(t.getUTCDate())+`${e}`.slice(10)}},240:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.idRandLong=t.idRandShort=t.idShuffle=void 0;const r=["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","@",".","_","0","1","2","3","4","5","6","7","8","9"],n=({data:e,password:t})=>{try{const n=(e,t)=>r.includes(e.toLowerCase())?r[(r.indexOf(e.toLowerCase())+Math.pow(t,3))%r.length]:e;return[...e].map(e=>n(e,Number(t))).join("")}catch{return""}},o=async({data:e,password:t})=>{if(!e||!t)return"";try{crypto.subtle;const r=new TextEncoder,n=r.encode(e),o=r.encode(t),a=await crypto.subtle.digest("SHA-256",o),i=new Uint8Array(a),s=i.slice(0,32),c=i.slice(0,12),l=await crypto.subtle.importKey("raw",s,{name:"AES-GCM"},!1,["encrypt"]),u=await crypto.subtle.encrypt({name:"AES-GCM",iv:c},l,n);return btoa(String.fromCharCode(...new Uint8Array(u))).replace(/\+/g,"a").replace(/\//g,"b").replace(/=/g,"c").toLowerCase()}catch{return""}};t.idShuffle=async({data:e,password:t})=>4==t?.length?n({data:e,password:t}):await o({data:e,password:t}),t.idRandShort=(e=10)=>{try{return crypto.randomUUID()?.replaceAll("-","")?.slice(0,e)}catch(e){return console.log("idRandShort failed",e),""}},t.idRandLong=(e=10)=>{try{const t="abcdefghijklmnopqrstuvwxyz",r=new Uint8Array(e);return crypto.getRandomValues(r),Array.from(r).map(e=>t[e%26]).join("")}catch(e){return console.log("idRandLong failed",e),""}}},246:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.cacheCheck=t.delayCode=void 0;const n=r(125);t.delayCode=async(e=0)=>await new Promise(t=>setTimeout(t,e)),t.cacheCheck=({analysisCacheLimit:e,lastUpdated:t,forceRefresh:r})=>{const o=Date.now();if(t&&(!r&&t>o-e||r&&t>o-n.oneDay))return!0}},792:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.isEven=t.pNum=t.sharpeRatio=t.priceVariations=t.nTxtAr=t.zNum=t.addCom=t.adjNum=t.rNum=void 0;const r=[1,.1,.01,.001,1e-4,1e-5,1e-6,1e-7,1e-8,1e-9,1e-10,1e-11,1e-12,1e-13,1e-14,1e-15,1e-16,1e-17,1e-18,1e-19],n=(e,t=6)=>{const n=+e,o=n?Math.abs(n):0,a=o>1&&t?t-`${Math.round(o)}`.length:0;return n?(n<0?-1:1)*(Number.isInteger(o)||o<1e-16?o:o>1e5?Math.round(o):o>1?Number(o.toFixed(a<0?0:a)):((e,t)=>{let n=0;for(const o of r){if(o<e)return Number(e.toFixed(t+n-1));n++}return e})(o,t)):e},o=(e,t)=>{const r=(n(e,t)+"").split(".");return r[0]=r[0].replace(/\B(?=(\d{3})+(?!\d))/g,","),r.join(".")},a=(e,t=3)=>{const r=Number(e);if(!e||!r)return e+"";const a=Math.abs(r);return(r<0?"-":"")+(a>1e9?o(a/1e9,t)+"b":a>1e6?o(a/1e6,t)+"m":a<1e-6&&a>1e-16?(1+n(a,t)+"").replace(/1./g,"0."):o(a,t))};t.nTxtAr=["zero","one","two","three","four","five","six","seven","eight","nine","ten"],t.rNum=n,t.addCom=o,t.adjNum=a,t.zNum=e=>{const t=Number(e);let r=t?Math.abs(t):0,n=1e10;for(;n>1;)r>n&&(r=Math.round(r/(n/10))*(n/10)),n/=10;return t?(t<0?"-":"")+a(r,2):e},t.pNum=e=>+e||0==+e?Math.round(1e6*+e)/1e6:null,t.priceVariations=e=>{try{let t=0;const r=[...e].sort((e,t)=>e[0]-t[0]),n=e.reduce((e,[,t])=>e+t,0),o=r.find(([,e])=>(t+=e,t>=n/2))[0];return e.filter(([e])=>Math.abs(e-o)/o<.05).map(([e])=>e)}catch{return[]}},t.sharpeRatio=({assetPrices:e,minExpectedReturn:t=.05})=>{if(!e?.length||e?.length<2)return 0;const r=e.slice(1).map((t,r)=>(t-e[r])/e[r]),n=r.reduce((e,t)=>e+t,0)/r.length,o=Math.sqrt(r.reduce((e,t)=>e+Math.pow(t-n,2),0)/r.length);return(n-t)/o},t.isEven=e=>e%2==0},794:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.restoreObj=t.restoreObjStr=t.storeObj=t.storeObjStr=t.objNestValueCount=t.objLen=t.objSortSimple=t.objSort=void 0;const n=r(125),o=e=>{try{return Object.keys(e||{})?.length||0}catch(e){return console.log(e),0}},a=e=>{try{return e?.replace(/"/g,"'")}catch(e){return console.log((0,n.tN)(),"storeObjStr failed",e),""}},i=e=>{try{return e?.toString()?.replace(/'/g,'"')}catch(e){console.log((0,n.tN)(),"restoreObjStr failed",e)}};t.objLen=o,t.objNestValueCount=e=>{let t=0;if(o(e))for(const r in e)t+=o(e[r])?1:0;return t},t.objSort=(e={},t,r=-1)=>Object.fromEntries(Object.entries(e).sort(([,e],[,n])=>null===e[t]||void 0===e[t]?1:null===n[t]||void 0===n[t]?-1:e[t]>n[t]?1*r:-1*r)),t.objSortSimple=(e={},t=-1)=>Object.fromEntries(Object.entries(e).sort(([,e],[,r])=>null==e?1:null==r?-1:e>r?1*t:-1*t)),t.storeObjStr=a,t.storeObj=e=>{try{return a(JSON.stringify(e))}catch(e){return console.log((0,n.tN)(),"storeObj failed",e),""}},t.restoreObjStr=i,t.restoreObj=e=>{try{if(!e)return;const t=i(e);return t?JSON.parse(t):void 0}catch(e){console.log((0,n.tN)(),"restoreObj failed",e)}}},830:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.phaseDifference=t.compareArrays=t.squeezeArray=t.forecastNextTotal=t.forecastNext=t.getMax=t.getMean=t.getSum=t.maxVl=t.minVl=t.sumArr=void 0;const r=e=>{try{return e?.length?e.reduce((e,t)=>e+t):0}catch(e){return console.log("sumArr failed",e),0}},n=e=>{try{return e?.length?e.reduce((e,t)=>e+t,0):0}catch(e){return console.log("getSum failed",e),0}},o=e=>{try{return e?.length?n(e)/e.length:0}catch(e){return console.log("getMean failed",e),0}},a=e=>{try{return e?.length?Math.max(...e):0}catch(e){return console.log("getMax failed",e),0}},i=e=>{try{if(!e?.length)return 0;const t=[...e].sort((e,t)=>e-t),r=Math.floor(t.length/2);return t.length%2?t[r]:(t[r-1]+t[r])/2}catch(e){return console.log("median failed",e),0}},s=({currentPeriod:e,steps:t=1})=>{try{const r=(Array.isArray(e)?e:[]).filter(Number.isFinite);if(!r.length||t<=0)return[];if(r.length<2){const e=Math.max(0,o(r));return Array.from({length:t},()=>e)}const n=r.length,{slope:s,intercept:c}=(e=>{try{const t=e.length,r=[];for(let n=0;n<t-1;n++)for(let o=n+1;o<t;o++)r.push((e[o]-e[n])/(o-n));const n=i(r);return{slope:n,intercept:i(e.map((e,t)=>e-n*t))}}catch(e){return console.log("theilSen failed",e),{slope:0,intercept:0}}})(r),l=c+s*(n-1),u=a(r),d=u>0?3*u:1/0;return Array.from({length:t},(e,t)=>{const r=t+1,o=l+s*n*Math.log1p(r/n);return Math.max(0,Math.min(o,d))})}catch(e){return console.log("forecastNext failed",e),[]}};t.sumArr=r,t.maxVl=(e,t)=>{let r=0;for(let n=0;n<e.length;n++){const o=e[n];o[t]>r&&(r=o[t])}return r},t.minVl=(e,t)=>{let r=0;for(let n=0;n<e.length;n++){const o=e[n];o[t]<r&&(r=o[t])}return r},t.getSum=n,t.getMean=o,t.getMax=a,t.forecastNext=s,t.forecastNextTotal=e=>{try{const t=s({currentPeriod:e,steps:e?.length});return n(t)}catch(e){return console.log("forecastNextTotal failed",e),0}},t.squeezeArray=({arr:e,targetLength:t})=>{try{if(!e||0===e.length||t<=0)throw new Error("Invalid input");const n=Math.ceil(e.length/t);return Array.from({length:t},(t,o)=>{const a=o*n,i=Math.min(a+n,e.length),s=e.slice(a,i);return r(s)}).slice(0,t)}catch(e){return console.log("squeezeArray failed",e),[]}},t.compareArrays=({arrays:e})=>{try{const t=[...e],n=Math.min(...t.map(e=>e.length));for(let e=0;e<t.length;e++)t.splice(n);const o=t.map(e=>r(e)),a=[],i=Math.min(...o),s=o.indexOf(i),c=i/Math.max(...o);for(let e=0;e<t.length;e++){const r=t[e];if(a[e]=[],e==s)a[e]=r;else for(let t=0;t<r.length;t++)a[e].push(c*r[t])}return a}catch(t){return console.log("compareArrays failed",t),e}},t.phaseDifference=({array1:e,array2:t})=>{try{let r=e.length,n=e.reduce((e,t)=>e+t)/r,o=t.reduce((e,t)=>e+t)/r,a=e.map(e=>e-n),i=t.map(e=>e-o),s=Math.floor(r/2),c=-1/0,l=0;for(let e=-s;e<=s;e++){let t=0,n=0,o=0,s=0;for(let c=0;c<r;c++){let l=c+e;l>=0&&l<r&&(t+=a[c]*i[l],n+=a[c]*a[c],o+=i[l]*i[l],s++)}if(n>0&&o>0&&s>=.8*r){let r=t/Math.sqrt(n*o);r>c&&(c=r,l=e)}}return l}catch(e){return console.log("phaseDifference failed",e),0}}}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var a=t[n]={exports:{}};return e[n](a,a.exports,r),a.exports}var n={};return(()=>{var e=n;Object.defineProperty(e,"__esModule",{value:!0}),e.idShuffle=e.isEven=e.pNum=e.nTxtAr=e.zNum=e.addCom=e.adjNum=e.rNum=e.sharpeRatio=e.priceVariations=e.timeStandard=e.dateStandard=e.addZ=e.tN=e.monNm=e.tmUTC=e.tmAP=e.moYrDt=e.shortDt=e.fullLong=e.fullDate=e.fullDt=e.invDt=e.dayRes=e.thisYear=e.seoDt=e.oneMon=e.oneMin=e.oneHr=e.oneDay=e.oneSec=e.restoreObj=e.restoreObjStr=e.storeObj=e.storeObjStr=e.objSortSimple=e.objSort=e.objNestValueCount=e.objLen=e.phaseDifference=e.compareArrays=e.squeezeArray=e.forecastNextTotal=e.forecastNext=e.getMax=e.getMean=e.getSum=e.maxVl=e.minVl=e.sumArr=void 0,e.cacheCheck=e.delayCode=e.idRandLong=e.idRandShort=void 0;const t=r(246);Object.defineProperty(e,"cacheCheck",{enumerable:!0,get:function(){return t.cacheCheck}}),Object.defineProperty(e,"delayCode",{enumerable:!0,get:function(){return t.delayCode}});const o=r(830);Object.defineProperty(e,"sumArr",{enumerable:!0,get:function(){return o.sumArr}}),Object.defineProperty(e,"minVl",{enumerable:!0,get:function(){return o.minVl}}),Object.defineProperty(e,"maxVl",{enumerable:!0,get:function(){return o.maxVl}}),Object.defineProperty(e,"getMax",{enumerable:!0,get:function(){return o.getMax}}),Object.defineProperty(e,"getMean",{enumerable:!0,get:function(){return o.getMean}}),Object.defineProperty(e,"getSum",{enumerable:!0,get:function(){return o.getSum}}),Object.defineProperty(e,"forecastNext",{enumerable:!0,get:function(){return o.forecastNext}}),Object.defineProperty(e,"forecastNextTotal",{enumerable:!0,get:function(){return o.forecastNextTotal}}),Object.defineProperty(e,"squeezeArray",{enumerable:!0,get:function(){return o.squeezeArray}}),Object.defineProperty(e,"compareArrays",{enumerable:!0,get:function(){return o.compareArrays}}),Object.defineProperty(e,"phaseDifference",{enumerable:!0,get:function(){return o.phaseDifference}});const a=r(240);Object.defineProperty(e,"idRandLong",{enumerable:!0,get:function(){return a.idRandLong}}),Object.defineProperty(e,"idRandShort",{enumerable:!0,get:function(){return a.idRandShort}}),Object.defineProperty(e,"idShuffle",{enumerable:!0,get:function(){return a.idShuffle}});const i=r(792);Object.defineProperty(e,"addCom",{enumerable:!0,get:function(){return i.addCom}}),Object.defineProperty(e,"adjNum",{enumerable:!0,get:function(){return i.adjNum}}),Object.defineProperty(e,"priceVariations",{enumerable:!0,get:function(){return i.priceVariations}}),Object.defineProperty(e,"nTxtAr",{enumerable:!0,get:function(){return i.nTxtAr}}),Object.defineProperty(e,"rNum",{enumerable:!0,get:function(){return i.rNum}}),Object.defineProperty(e,"zNum",{enumerable:!0,get:function(){return i.zNum}}),Object.defineProperty(e,"sharpeRatio",{enumerable:!0,get:function(){return i.sharpeRatio}}),Object.defineProperty(e,"pNum",{enumerable:!0,get:function(){return i.pNum}}),Object.defineProperty(e,"isEven",{enumerable:!0,get:function(){return i.isEven}});const s=r(125);Object.defineProperty(e,"oneSec",{enumerable:!0,get:function(){return s.oneSec}}),Object.defineProperty(e,"oneDay",{enumerable:!0,get:function(){return s.oneDay}}),Object.defineProperty(e,"oneHr",{enumerable:!0,get:function(){return s.oneHr}}),Object.defineProperty(e,"oneMin",{enumerable:!0,get:function(){return s.oneMin}}),Object.defineProperty(e,"oneMon",{enumerable:!0,get:function(){return s.oneMon}}),Object.defineProperty(e,"seoDt",{enumerable:!0,get:function(){return s.seoDt}}),Object.defineProperty(e,"dayRes",{enumerable:!0,get:function(){return s.dayRes}}),Object.defineProperty(e,"invDt",{enumerable:!0,get:function(){return s.invDt}}),Object.defineProperty(e,"fullDt",{enumerable:!0,get:function(){return s.fullDt}}),Object.defineProperty(e,"fullDate",{enumerable:!0,get:function(){return s.fullDate}}),Object.defineProperty(e,"fullLong",{enumerable:!0,get:function(){return s.fullLong}}),Object.defineProperty(e,"shortDt",{enumerable:!0,get:function(){return s.shortDt}}),Object.defineProperty(e,"moYrDt",{enumerable:!0,get:function(){return s.moYrDt}}),Object.defineProperty(e,"tmAP",{enumerable:!0,get:function(){return s.tmAP}}),Object.defineProperty(e,"tmUTC",{enumerable:!0,get:function(){return s.tmUTC}}),Object.defineProperty(e,"monNm",{enumerable:!0,get:function(){return s.monNm}}),Object.defineProperty(e,"tN",{enumerable:!0,get:function(){return s.tN}}),Object.defineProperty(e,"addZ",{enumerable:!0,get:function(){return s.addZ}}),Object.defineProperty(e,"timeStandard",{enumerable:!0,get:function(){return s.timeStandard}}),Object.defineProperty(e,"dateStandard",{enumerable:!0,get:function(){return s.dateStandard}}),Object.defineProperty(e,"thisYear",{enumerable:!0,get:function(){return s.thisYear}});const c=r(794);Object.defineProperty(e,"objSort",{enumerable:!0,get:function(){return c.objSort}}),Object.defineProperty(e,"objLen",{enumerable:!0,get:function(){return c.objLen}}),Object.defineProperty(e,"objNestValueCount",{enumerable:!0,get:function(){return c.objNestValueCount}}),Object.defineProperty(e,"restoreObj",{enumerable:!0,get:function(){return c.restoreObj}}),Object.defineProperty(e,"restoreObjStr",{enumerable:!0,get:function(){return c.restoreObjStr}}),Object.defineProperty(e,"storeObj",{enumerable:!0,get:function(){return c.storeObj}}),Object.defineProperty(e,"storeObjStr",{enumerable:!0,get:function(){return c.storeObjStr}}),Object.defineProperty(e,"objSortSimple",{enumerable:!0,get:function(){return c.objSortSimple}})})(),n})()}};const t={};function r(n){const o=t[n];if(void 0!==o)return o.exports;const a=t[n]={exports:{}};return e[n].call(a.exports,a,a.exports,r),a.exports}var n,o,a,i,s,c,l,u,d,g,m,p;let f;r.m=e,r.d=(e,t)=>{for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.f={},r.e=e=>{const t=[];return r.f.j(e,t),Promise.all(t)},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{const e={520:()=>import("./engine-litert.min.mjs"),924:()=>import("./engine-wllama.min.mjs")},t={792:0},n=e=>{let{__webpack_esm_ids__:n,__webpack_esm_modules__:o,__webpack_esm_runtime__:a}=e;var i,s,c=0;for(i in o)r.o(o,i)&&(r.m[i]=o[i]);for(a&&a(r);c<n.length;c++)s=n[c],r.o(t,s)&&t[s]&&t[s][0](),t[s]=0};r.f.j=(o,a)=>{let i=r.o(t,o)?t[o]:void 0;if(0!==i)if(i)a.push(i[1]);else{let r=e[o]().then(n,e=>{throw 0!==t[o]&&(t[o]=void 0),e});r=Promise.race([r,new Promise(e=>i=t[o]=[e])]),a.push(i[1]=r)}}})(),function(e){e.system="system",e.user="user",e.assistant="assistant"}(n||(n={})),function(e){e[e.online=0]="online",e[e.away=1]="away",e[e.offline=2]="offline"}(o||(o={})),function(e){e[e.idle=0]="idle",e[e.downloading=1]="downloading",e[e.ready=2]="ready",e[e.error=3]="error",e[e.unsupported=4]="unsupported"}(a||(a={})),function(e){e.cpu="cpu",e.gpu="gpu",e.none="none"}(i||(i={})),function(e){e.download="download",e.load="load"}(s||(s={})),function(e){e.analyze="analyze",e.describe="describe",e.translate="translate",e.tags="tags",e.translateTags="translateTags"}(c||(c={})),function(e){e.translate="translate",e.tags="tags",e.translateTags="translateTags"}(l||(l={})),function(e){e.model="model",e.limits="limits",e.logging="logging",e.onStatus="onStatus"}(u||(u={})),function(e){e.quota="QuotaExceededError",e.notAllowed="NotAllowedError",e.notSupported="NotSupportedError",e.invalidState="InvalidStateError",e.typeMismatch="TypeMismatchError",e.security="SecurityError"}(d||(d={})),function(e){e.qwen3_vl_2b="qwen3-vl-2b",e.qwen3_vl_2b_instruct="qwen3-vl-2b-instruct",e.qwen3_vl_2b_instruct_q3="qwen3-vl-2b-instruct-q3",e.gemma4_e2b_limited="gemma4-e2b-limited"}(g||(g={})),function(e){e.websearch="websearch",e.calculate="calculate",e.currency="currency"}(m||(m={})),function(e){e.wikipedia="wikipedia",e.duckduckgo="duckduckgo"}(p||(p={}));const y=[{id:g.qwen3_vl_2b,reasoning:!0,cpu:{repo:"Qwen/Qwen3-VL-2B-Thinking-GGUF",file:"Qwen3VL-2B-Thinking-Q4_K_M.gguf",mmproj:{file:"mmproj-Qwen3VL-2B-Thinking-Q8_0.gguf"}}},{id:g.qwen3_vl_2b_instruct,reasoning:!1,cpu:{repo:"unsloth/Qwen3-VL-2B-Instruct-GGUF",file:"Qwen3-VL-2B-Instruct-Q4_K_M.gguf",mmproj:{repo:"Qwen/Qwen3-VL-2B-Instruct-GGUF",file:"mmproj-Qwen3VL-2B-Instruct-Q8_0.gguf"}}},{id:g.qwen3_vl_2b_instruct_q3,reasoning:!1,cpu:{repo:"unsloth/Qwen3-VL-2B-Instruct-GGUF",file:"Qwen3-VL-2B-Instruct-Q3_K_M.gguf",mmproj:{repo:"Qwen/Qwen3-VL-2B-Instruct-GGUF",file:"mmproj-Qwen3VL-2B-Instruct-Q8_0.gguf"}}},{id:g.gemma4_e2b_limited,reasoning:!0,litert:{repo:"litert-community/gemma-4-E2B-it-litert-lm",file:"gemma-4-E2B-it-gpu.litertlm",vision:!1,audio:!1}}],h=e=>{const t=e??("undefined"==typeof navigator?void 0:navigator);if(!t)return!1;if("boolean"==typeof t.userAgentData?.mobile)return t.userAgentData.mobile;const r=t.userAgent||"";return/Android|iPhone|iPad|iPod|Mobile/i.test(r)||/Macintosh/.test(r)&&t.maxTouchPoints>1},w=e=>e?y.find(t=>t.id==e):void 0,b=async()=>{const e="undefined"==typeof navigator?void 0:navigator.gpu;if(!e)return!1;let t;try{return!!await Promise.race([e.requestAdapter({powerPreference:"high-performance"}),new Promise(e=>{t=setTimeout(()=>e(void 0),1500)})])}catch{return!1}finally{t&&clearTimeout(t)}},v=async e=>w(e??await(async()=>(f||(f=(async()=>await b()?g.gemma4_e2b_limited:g.qwen3_vl_2b)()),await f))()),S=e=>!!e.cpu?.mmproj||!0===e.litert?.vision,x=e=>!!e.cpu?.mmproj?.audio||!0===e.litert?.audio;var M=r(155);const j=new URL("./../assets/wllama/wllama.wasm",import.meta.url).href,P=new URL("./../assets/wllama/compat/wllama.wasm",import.meta.url).href,k=new URL("./../assets/wllama/compat/wllama.js",import.meta.url).href,D=new URL("./../assets/litert/litertlm_wasm_internal.js",import.meta.url).href,N=(new URL("./../assets/litert/litertlm_wasm_internal.wasm",import.meta.url).href,{width:384,height:384}),_=async e=>{if(!e.startsWith("data:"))return await(await fetch(e)).arrayBuffer();const t=e.indexOf(","),r=t>=0?e.slice(0,t):"";if(t<0)throw new Error("Invalid image data");if(!r.includes(";base64"))return await(await fetch(e)).arrayBuffer();const n=atob(e.slice(t+1)),o=new Uint8Array(n.length);for(let e=0;e<n.length;e++)o[e]=n.charCodeAt(e);return o.buffer},T=async(e,t,r=128)=>{if(!e||"function"!=typeof fetch||"function"!=typeof createImageBitmap)return e;try{const n=await fetch(e),o=await createImageBitmap(await n.blob()),a=t??((e,t,r=128)=>{let n=32,o=32,a=1/0,i=1/0;const s=e/Math.max(1,t);for(let e=1;e<=r;e++){const t=Math.ceil(r/e),c=Math.floor((r+8)/e);for(let r=t;r<=c;r++){const t=r*e,c=Math.abs(r/e-s);(c<a-1e-9||Math.abs(c-a)<=1e-9&&t<i)&&(n=32*r,o=32*e,a=c,i=t)}}return{width:n,height:o}})(o.width,o.height,r),i=o.width/Math.max(1,o.height),s=a.width/a.height,c=Math.min(o.width,i>s?o.height*s:o.width),l=Math.min(o.height,i>s?o.height:o.width/s),u=(o.width-c)/2,d=(o.height-l)/2,g=((e,t)=>{if("undefined"!=typeof OffscreenCanvas)return new OffscreenCanvas(e,t);if("undefined"==typeof document)return;const r=document.createElement("canvas");return r.width=e,r.height=t,r})(a.width,a.height),m=g?g.getContext("2d"):null;if(!g||!m||o.width<1||o.height<1)return o.close(),e;if(m.drawImage(o,u,d,c,l,0,0,a.width,a.height),o.close(),(e=>"undefined"!=typeof OffscreenCanvas&&e instanceof OffscreenCanvas)(g)){const t=await g.convertToBlob({type:"image/jpeg",quality:.85});return await(e=>new Promise(t=>{if("undefined"==typeof FileReader)return void t("");const r=new FileReader;r.onerror=()=>t(""),r.onload=()=>t(`${r.result}`),r.readAsDataURL(e)}))(t)||e}return g.toDataURL("image/jpeg",.85)}catch{return e}},O={maxReplyTokens:250,maxThinkingTokens:128,maxReasoningTokens:320,maxImages:2,imageTokens:128,maxAudio:1,maxContentLength:1e3,promptCharBudget:1e4,maxThreads:32,gpuShare:.5},E=(e,t)=>{let r=0;for(const n of e)if("string"!=typeof n.content)for(const e of n.content)r+="text"==e.type?e.text.length/4:t;else r+=n.content.length/4;return Math.round(r)},L=(e,t,r)=>"number"==typeof e&&Number.isFinite(e)&&e>=r?Math.floor(e):t,C=(e={},t=!1)=>{const r=O;return{maxReplyTokens:L(e.maxReplyTokens,r.maxReplyTokens,1),maxThinkingTokens:L(e.maxThinkingTokens,r.maxThinkingTokens,1),maxReasoningTokens:L(e.maxReasoningTokens,t?1200:r.maxReasoningTokens,1),maxImages:L(e.maxImages,r.maxImages,0),imageTokens:L(e.imageTokens,r.imageTokens,1),maxAudio:L(e.maxAudio,r.maxAudio,0),maxContentLength:L(e.maxContentLength,r.maxContentLength,1),promptCharBudget:L(e.promptCharBudget,r.promptCharBudget,1),maxThreads:L(e.maxThreads,r.maxThreads,1),gpuShare:"number"==typeof e.gpuShare&&Number.isFinite(e.gpuShare)&&e.gpuShare>0?Math.min(1,Math.max(.05,e.gpuShare)):r.gpuShare}},A=(e,t,r=.7)=>({stream:!0,temperature:r,max_tokens:t?e.maxReasoningTokens:e.maxReplyTokens}),R=(e,t)=>`https://huggingface.co/${e}/resolve/main/${t}`,$=e=>Number(e.headers.get("content-length"))||0,U=(e,t)=>e.some(e=>Array.isArray(e.content)&&e.content.some(e=>e.type==t)),q=e=>U(e,"image"),B=e=>U(e,"audio"),z=["<|channel>thought\n","<|channel>thought"],I=["<channel|>"],K=(e,t,r)=>t.length||r.length?[...e?[{type:"text",text:e}]:[],...t.map(e=>({type:"image",url:e})),...r.map(e=>({type:"audio",url:e}))]:e,F=e=>"string"==typeof e?e?[{type:"text",text:e}]:[]:e,W=(e,t)=>{if("string"==typeof e&&"string"==typeof t)return`${e}\n${t}`;const r=[];for(const n of[...F(e),{type:"text",text:"\n"},...F(t)]){const e=r[r.length-1];"text"==n.type&&"text"==e?.type?e.text+=n.text:r.push(n)}return r},V=h()?3e6:3e5,G=Math.max(V,84e4);class J extends Error{}const Y=async(e,t,r)=>{let n;try{return await Promise.race([e,new Promise((e,o)=>{n=setTimeout(()=>o(new J(r)),t)})])}finally{n&&clearTimeout(n)}},H=e=>{try{Promise.resolve(e.next?.()).catch(()=>{}).finally(()=>{try{Promise.resolve(e.return?.()).catch(()=>{})}catch{}})}catch{}},Q=async({model:e,logging:t,onReason:r,onText:n,onSpeed:o,onPromptSpeed:a,promptTokens:i,start:s,stopped:c,firstTimeoutMs:l=V,idleTimeoutMs:u=3e4,onStall:d})=>{let g,m="",p="",f="",y=!1,h=!1,w=!1,b=0,v=0,S=0,x=0,j=0,P=0,k=0;const D=e=>{!Number.isFinite(e)||e<=0||(b=(0,M.rNum)(e),a?.(b))},N=()=>{if(y||w||!i)return;const e=performance.now()-j;e>0&&D(1e3*i/e)},_=()=>{null!=g&&(clearInterval(g),g=void 0)},T=e=>{if(!e)return;const t=performance.now(),r=e.n_prompt_tokens_processed??e.processed;if("number"!=typeof r||r<=0)return;w=!0,_();let n=0;n="number"==typeof e.time_ms&&e.time_ms>0?1e3*r/e.time_ms:v?1e3*(r-S)/Math.max(1,t-v):1e3*r/Math.max(1,t-j),t-x<500||(x=t,v=t,S=r,D(n))};a&&i&&(g=setInterval(N,500));const O=((e,t)=>{let r="",n=!1;const o=(e,t)=>{let r=-1,n="";for(const o of t){const t=e.indexOf(o);t>=0&&(r<0||t<r)&&(r=t,n=o)}return{at:r,tag:n}},a=(e,t)=>{let r="";for(const n of t)for(let t=Math.min(e.length,n.length-1);t>r.length;t--)if(e.endsWith(n.slice(0,t))){r=e.slice(e.length-t);break}return r};return{feed:i=>{let s=r+i;for(r="";s;){if(n){const{at:t,tag:i}=o(s,I);if(t>=0){t&&e(s.slice(0,t)),s=s.slice(t+i.length),n=!1;continue}const c=a(s,I);e(s.slice(0,s.length-c.length)),r=c;break}{const{at:e,tag:i}=o(s,z);if(e>=0){e&&t(s.slice(0,e)),s=s.slice(e+i.length),s.startsWith("\n")&&(s=s.slice(1)),n=!0;continue}const c=a(s,z);t(s.slice(0,s.length-c.length)),r=c;break}}},flush:()=>{r&&(n?e(r):t(r),r="")}}})(e=>{p+=e,r(e)},e=>{m+=e,n(e)});try{j=performance.now();const e=s();Promise.resolve(e).catch(()=>{});const n=(await Y(e,l,"Model did not start"))[Symbol.asyncIterator]();for(;;){if(c()){H(n);break}let e;try{const t=n.next();Promise.resolve(t).catch(()=>{}),e=await Y(t,y?u:l,y?"Model stopped responding":"Model did not reply")}catch(e){if(e instanceof J&&(m||p)){d?.(),H(n),t&&console.log("Local chat stalled",e);break}throw e}if(e.done)break;const a=e.value,i=a?.choices?.[0],s=i?.delta,g="string"==typeof s?.reasoning_content?s.reasoning_content:"string"==typeof s?.reasoning?s.reasoning:"",w=!!g||!!s?.content||!!i?.finish_reason,v=a?.timings?.prompt_per_second;if(w){if(y||(T(a?.prompt_progress),b||N(),y=!0,_()),!h&&"number"==typeof v&&Number.isFinite(v)&&v>0&&(h=!0,D(v)),i?.finish_reason&&(f=i.finish_reason),g&&(p+=g,r(g)),s?.content&&O.feed(s.content),g||s?.content){const e=performance.now();P||(k=e),P+=1,P>1&&e>k&&o?.((0,M.rNum)(1e3*P/(e-k)))}}else T(a?.prompt_progress),!h&&"number"==typeof v&&Number.isFinite(v)&&v>0&&(h=!0,D(v),_())}O.flush()}catch(e){if(t&&console.log("Local chat failed",e),e instanceof J&&!c())throw e}finally{_()}const E=c()?void 0:m||void 0;return t&&(console.log("Local chat reply",e.id,E?"****":""),console.log("Local chat finish",e.id,f||"none",m.length,p.length)),E},Z=async({model:e,params:t,start:r,stopped:o,onStall:a})=>{const i=await(async(e,t,r=128)=>{const n=[];for(const o of e){if("string"==typeof o.content){n.push(o);continue}const e=[];for(const n of o.content)e.push("image"==n.type?{type:"image",url:await T(n.url,t,r)}:n);n.push({role:"user",content:e})}return n})(((e,t=O)=>{let r=0,o=t.maxImages,a=t.maxAudio;const i=t.maxContentLength,s=e.filter(e=>"string"==typeof e.content&&!!e.content.trim()||!(e.role!=n.user||!e.images?.length&&!e.audio?.length)),c=[],l=[];for(let e=s.length-1;e>=0;e--){const u=s[e],d=("string"==typeof u.content?u.content:"").slice(0,i),g=u.role==n.user?(u.images||[]).filter(e=>"string"==typeof e&&!!e).slice(0,Math.max(0,o)):[],m=u.role==n.user?(u.audio||[]).filter(e=>"string"==typeof e&&!!e).slice(0,Math.max(0,a)):[];if(d||g.length||m.length){if(d&&r+d.length>t.promptCharBudget)break;r+=d.length,o-=g.length,a-=m.length,u.role==n.system?c.unshift(d):u.role==n.assistant?l.unshift({role:"assistant",content:d}):l.unshift({role:"user",content:K(d,g,m)})}}for(;l.length&&"user"!=l[0].role;)l.shift();const u=[];for(const e of l){const t=u[u.length-1];"assistant"==t?.role&&"assistant"==e.role?t.content=`${t.content}\n${e.content}`:"user"==t?.role&&"user"==e.role?t.content=W(t.content,e.content):"assistant"==e.role?u.push({role:"assistant",content:e.content}):u.push({role:"user",content:e.content})}const d=c.join("\n\n"),g=[];return d&&g.push({role:"system",content:d}),g.push(...u),g})(t.messages,t.limits),e.litert?N:void 0,t.limits.imageTokens);return t.logging&&((e,t)=>{console.log("Local chat call",e.id,t.map(({role:e,content:t})=>({role:e,content:"****",...Array.isArray(t)?{images:t.filter(e=>"image"==e.type).length,audio:t.filter(e=>"audio"==e.type).length}:{}})))})(e,i),await Q({model:e,logging:t.logging,onReason:t.onReason,onText:t.onText,onSpeed:t.onSpeed,onPromptSpeed:t.onPromptSpeed,promptTokens:E(i,t.limits.imageTokens),start:()=>r(i),stopped:o,onStall:a,firstTimeoutMs:q(i)?G:V})};let X=!1;const ee=33554432,te=new Set([d.quota,d.notAllowed,d.notSupported,d.invalidState,d.typeMismatch,d.security]),re=new Map,ne=new Set,oe=e=>{let t=0;const r=(e.split("/").pop()||"model").replace(/[^\w.-]+/g,"_");for(let r=0;r<e.length;r++)t=31*t+e.charCodeAt(r)>>>0;return`${t.toString(16)}-${r}`},ae=e=>{const t=/^part-(\d+)$/.exec(e);return t?Number(t[1]):-1},ie=async()=>{if(!X)if("undefined"!=typeof navigator&&navigator.storage?.getDirectory)try{return await navigator.storage.getDirectory()}catch{return}else X=!0},se=async()=>{try{if("undefined"==typeof navigator||!navigator.storage?.estimate)return;const e=await navigator.storage.estimate();return"number"==typeof e.quota&&e.quota>0?e.quota-(e.usage||0):void 0}catch{return}},ce=async(e,t)=>{try{return await e.getDirectoryHandle(t)}catch{return}},le=async e=>{if(e)try{const t=await e.getFile(),r=JSON.parse(await t.text());return{total:Number(r.total)||0,etag:`${r.etag||""}`,complete:!0===r.complete}}catch{return}},ue=async(e,t)=>{try{const r=await e.getFileHandle("meta.json",{create:!0}),n=await r.createWritable();await n.write(JSON.stringify(t)),await n.close()}catch{}},de=async function*(e){for await(const t of e)yield t},ge=async e=>{try{for await(const[t,r]of de(e))"file"==r.kind&&ae(t)>=0&&await e.removeEntry(t).catch(()=>{})}catch{}},me=async(e,t)=>{try{const r=await(await e.getFileHandle(t)).getFile(),n=await le(await e.getFileHandle(`${t}.json`).catch(()=>{}));if(!n)return;return{file:r,size:r.size,total:n.total,etag:n.etag,complete:n.total?r.size>=n.total:!0===n.complete}}catch{return}},pe=async(e,t)=>{const r=await ce(e,t);if(r){const e=await(async e=>await le(await e.getFileHandle("meta.json").catch(()=>{})))(r),t=await(async e=>{const t=[];try{for await(const[r,n]of de(e)){const e=ae(r);if("file"!=n.kind||e<0)continue;const o=await n.getFile();t.push({part:{start:e,size:o.size},file:o})}}catch{return}const r=(e=>{let t=0;const r=[];for(const n of[...e].sort((e,t)=>e.start-t.start))if(n.size){if(n.start!=t)break;r.push(n),t+=n.size}return r})(t.map(e=>e.part)),n=new Set(r.map(e=>e.start)),o=t.filter(e=>n.has(e.part.start)).sort((e,t)=>e.part.start-t.part.start).map(e=>e.file);if(o.length)return{file:1==o.length?o[0]:new Blob(o),size:r.reduce((e,t)=>e+t.size,0)}})(r),n=e?.total||0,o=t?.size??0,a=t?.file??new Blob;return{file:n&&o>n?a.slice(0,n):a,size:o,total:n,etag:e?.etag||"",complete:n?o>=n:!0===e?.complete}}return await me(e,t)},fe=(e,t)=>{const r=e.headers.get("content-range"),n=/bytes (\d+)-/.exec(r||""),o=/\/(\d+)\s*$/.exec(r||""),a=e.headers.get("etag")||"";if(206==e.status){const e=n?Number(n[1]):t.size,r=o?Number(o[1]):t.total;if(e!=t.size)return;if(t.total&&r&&t.total!=r)return;if(t.etag&&a&&t.etag!=a)return;return{start:e,total:r||t.total,etag:a||t.etag}}if(!t.etag||!a||t.etag==a)return{start:0,total:$(e)||t.total,etag:a||t.etag}},ye=async({dir:e,start:t,skip:r,total:n,body:o,onProgress:a,onChunk:i})=>{let c,l,u=t,d=0,g=r;const m=async()=>{const t=await e.getFileHandle((e=>`part-${e}`)(u),{create:!0});l=await t.createWritable(),d=0},p=async()=>{const e=l;l=void 0,e&&await e.close()};try{const e=o.getReader();for(c=e;;){const{done:r,value:o}=await e.read();if(r)break;i();let c=0;for(g&&(c=Math.min(g,o.byteLength),g-=c);c<o.byteLength;){l||await m();const e=Math.min(ee-d,o.byteLength-c);await l.write({type:"write",position:d,data:o.slice(c,c+e)}),c+=e,d+=e,u+=e,d==ee&&await p()}u>t&&a(n?u/n:0,s.download)}await p()}catch(e){throw await p().catch(()=>{}),await(c?.cancel().catch(()=>{})),e}return u},he=e=>e?.name==d.quota,we=e=>{const t=async()=>{const t=await ie();if(t)try{return await t.getDirectoryHandle(e,{create:!0})}catch{return}};return{stored:async e=>{const r=await t();return r?await pe(r,oe(e)):void 0},download:async({url:r,signal:n,onProgress:o})=>{if(ne.has(r))throw new DOMException("Storage is full",d.quota);const a=`${e}|${r}`,i=re.get(a);if(i)return await i;const c=await t();if(!c)return;const l=(async(e,t,r,n)=>{const o=oe(t),a=await me(e,o);if(a?.complete)return a;let i=await ce(e,o);i||(await e.removeEntry(o).catch(()=>{}),await e.removeEntry(`${o}.json`).catch(()=>{}),i=await e.getDirectoryHandle(o,{create:!0}));let c=0,l=0,u=!1;for(;;){if(r?.aborted)throw new Error("Cancelled");const a=await pe(e,o);if(a?.complete)return a;const g=a?.size??0,m=a?.total||0,p=a?.etag||"";if(g>c)c=g,l=0;else if(++l>4)throw new Error("Model download failed");g&&m&&n(g/m,s.download);const f=m?Math.min(g+ee,m)-1:g+ee-1,y=new AbortController,h=()=>y.abort(),w={size:g,total:m,etag:p};let b,v=setTimeout(h,3e4);r?.addEventListener("abort",h,{once:!0});try{if(b=await fetch(t,{signal:y.signal,headers:{Range:`bytes=${g}-${f}`}}),416==b.status){if(await(b.body?.cancel().catch(()=>{})),m&&g>=m){await ue(i,{total:m,etag:p,complete:!0});continue}await ge(i),await ue(i,{total:0,etag:"",complete:!1});continue}if(!b.ok||!b.body)throw await(b.body?.cancel().catch(()=>{})),new Error("Model download failed");const r=fe(b,w);if(!r){await b.body.cancel().catch(()=>{}),await ge(i),await ue(i,{total:0,etag:"",complete:!1});continue}await ue(i,{total:r.total,etag:r.etag,complete:!1});const a=0==r.start?g:0,s=r.start+a;if(!u&&r.total>s){u=!0;const e=await se();if(null!=e&&e<r.total-s)throw await b.body.cancel().catch(()=>{}),new DOMException("Storage is full",d.quota)}const c=await ye({dir:i,start:s,skip:a,total:r.total,body:b.body,onProgress:n,onChunk:()=>{clearTimeout(v),v=setTimeout(h,3e4)}});if(!r.total){await ue(i,{total:c,etag:r.etag,complete:!0});const t=await pe(e,o);if(t)return t}}catch(e){if(r?.aborted)throw new Error("Cancelled");if(e instanceof DOMException&&te.has(e.name))throw e;await new Promise(e=>setTimeout(e,250+500*l))}finally{clearTimeout(v),r?.removeEventListener("abort",h)}}})(c,r,n,o).catch(e=>{throw he(e)&&ne.add(r),e}).finally(()=>{re.delete(a)});return re.set(a,l),await l},remove:async e=>{ne.delete(e);const r=await t();r&&await(async(e,t)=>{await e.removeEntry(t,{recursive:!0}).catch(()=>{}),await e.removeEntry(`${t}.json`).catch(()=>{})})(r,oe(e))},purge:async()=>{ne.clear();const t=await ie();t&&await t.removeEntry(e,{recursive:!0}).catch(()=>{})}}},be=(e,...t)=>{!0===e&&console.log(...t)};let ve=!1,Se=0;const xe="litertlm-models",Me=.5,je=we("litert-store"),Pe={num_output_candidates:1,wait_for_weight_uploads:!0,num_decode_steps_per_sync:1,sequence_batch_size:0,supported_lora_ranks:[],max_top_k:40,enable_decode_logits:!1,enable_external_embeddings:!1,use_submodel:!1,use_autosized_ringbuffers:!0};let ke=Me,De=!1,Ne=0;const _e=new WeakSet,Te=(...e)=>{ve&&console.log(...e)},Oe=(...e)=>{ve&&console.error(...e)},Ee=e=>e.replace(/<\|channel>thought\n?[\s\S]*?<channel\|>/g,"").replace(/<\|channel>thought[\s\S]*$/,"").trim(),Le=async()=>{const e=performance.now(),t=e-Ne;if(Ne=e,!De)return;const r=Math.round(((e,t=.5)=>Math.min(500,Math.max(0,e*(1/t-1))))(t,ke));r<1||(await new Promise(e=>setTimeout(e,r)),Ne=performance.now())},Ce=(e=.5)=>{ke=e>0?e:Me,De=!0,Ne=performance.now()},Ae=async()=>{try{if("undefined"==typeof caches)return;return await caches.open(xe)}catch{return}},Re=new Map,$e=(e,t,r)=>{let n=0;return e.pipeThrough(new TransformStream({transform:(e,o)=>{n+=e.byteLength,r(t?n/t:0,s.download),o.enqueue(e)}}))},Ue=async(e,t=!0)=>{const r=[];for(const n of e){if("string"==typeof n.content){r.push({role:n.role,content:n.content});continue}const e=[];for(const r of n.content)"text"!=r.type?t?e.push({type:r.type,data:await _(r.url)}):e.push({type:"text",text:`[${r.type}]`}):e.push({type:"text",text:r.text});r.push({role:n.role,content:e})}return r},qe=(e,t)=>{if(e.role!=t.role)return!1;if("string"==typeof e.content||"string"==typeof t.content)return"string"==typeof e.content&&"string"==typeof t.content&&Ee(e.content)==Ee(t.content);if(e.content.length!=t.content.length)return!1;for(let r=0;r<e.content.length;r++){const n=e.content[r],o=t.content[r];if(n.type!=o.type)return!1;if("text"==n.type&&"text"==o.type){if(Ee(n.text)!=Ee(o.text))return!1}else{if("text"==n.type||"text"==o.type)return!1;if(!!n.url!=!!o.url)return!1}}return!0},Be=async function*({engine:e,mod:t,params:r,messages:n,session:o}){const a=n[n.length-1],i=A(r.limits,r.reasoning,r.temperature);if("user"!=a?.role)throw new Error("No user turn");const s=n.slice(0,-1),c=(await Ue([a]))[0];if(!c)throw new Error("Empty prompt");let l;const u=o.reasoning==r.reasoning&&o.maxTokens==i.max_tokens,d=!!o.conversation&&((e,t)=>{const r="system"==e[0]?.role?e[0]:void 0,n="system"==t[0]?.role?t[0]:void 0;if(!r!=!n)return!1;if(r&&n&&!qe(r,n))return!1;const o=r?e.slice(1):e,a=n?t.slice(1):t;if(!a.length||a.length>o.length)return!1;const i=o.length-a.length;for(let e=0;e<a.length;e++)if(!qe(o[i+e],a[e]))return!1;return!0})(o.sent,s);if(u&&d&&o.conversation)be(ve,"LiteRT conversation reused",o.sent.length),l=o.conversation;else{const n=await Ue(s,!1);o.conversation=void 0,o.sent=[];const a=performance.now();l=await e.createConversation({sessionConfig:{maxOutputTokens:i.max_tokens,samplerParams:{type:t.SamplerType.TOP_K,temperature:i.temperature,k:40,p:.95}},preface:{...n.length?{messages:n}:{},extra_context:{enable_thinking:r.reasoning}},prefillPrefaceOnInit:n.length>0}),be(ve,"LiteRT conversation created",n.length,Math.round(performance.now()-a),"flags",u,"history",d),o.conversation=l,o.reasoning=r.reasoning,o.maxTokens=i.max_tokens,o.sent=[...s]}o.sent.push(a);let g,m=!1,p=!0,f="";const y=()=>{g&&g.cancel().catch(()=>{});try{Promise.resolve(l.cancel()).catch(()=>{})}catch{}};r.signal?.addEventListener("abort",y,{once:!0});try{if(r.signal?.aborted)return;const e=l.sendMessageStreaming(c).getReader();for(g=e;;){const t=performance.now(),{done:n,value:o}=await e.read().catch(e=>{if(r.signal?.aborted)return{done:!0,value:void 0};throw e}),a=performance.now()-t;if(n)break;const i=p;p=!1,i&&(be(ve,"LiteRT first chunk",Math.round(a)),Ce(r.limits.gpuShare));let s="string"==typeof o.content?o.content:"";const c={};if(Array.isArray(o.content))for(const e of o.content)"text"==e.type&&(s+=e.text);s&&(c.content=s,f+=s);const l=o.channels?.thought;l&&(c.reasoning=l),(c.content||c.reasoning)&&(yield{choices:[{delta:c}]})}m=!0}finally{De=!1,r.signal?.removeEventListener("abort",y),m&&f?o.sent.push({role:"assistant",content:f}):(o.conversation=void 0,o.sent=[])}},ze={backend:i.gpu,startLLM:async({model:e,limits:t,onProgress:n,signal:o,logging:a})=>{ve=!0===a;const c=e.litert;if(!c)throw new Error("Model has no LiteRT artifact");const l=h()?16384:32768,u=await r.e(520).then(()=>r(507)),d=globalThis,g=d.Module;d.Module={print:Te,printErr:Oe};try{await u.getOrLoadGlobalLiteRtLm(D)}finally{d.Module=g}if(o?.aborted)throw new Error("Cancelled");const m=u.getGlobalLiteRtLm(),p=m.liteRtLmWasm;if(await m.setupDefaultWebGpuDevice(),o?.aborted)throw new Error("Cancelled");const f=p.preinitializedWebGPUDevice;if(!f)throw new Error("No WebGPU device");if(!_e.has(f)){const e=(({device:e,pace:t})=>new Proxy(e,{get:(e,r)=>{if("createBuffer"==r)return(...n)=>{const o=Reflect.get(e,r,e).apply(e,n),a=o.mapAsync;try{o.mapAsync=async(...e)=>{await a.apply(o,e),await t()}}catch{}return o};const n=Reflect.get(e,r,e);return"function"==typeof n?n.bind(e):n}}))({device:f,pace:Le});_e.add(f),_e.add(e),p.preinitializedWebGPUDevice=e}let y,w=!1;const b=R(c.repo,c.file),v=await Ae(),S=v?await v.match(b):void 0;if(S?.body)y=S.body;else{const e=await je.stored(b);e?.complete&&(y=e.file.stream())}if(!y){const e=await je.download({url:b,signal:o,onProgress:n}).catch(e=>{if(o?.aborted)throw new Error("Cancelled");a&&console.log("Local model store failed",e),w=he(e)});e&&(y=e.file.stream())}if(!y&&v&&!w)try{await(async(e,t,r,n)=>{const o=Re.get(e);if(o)return await o;const a=(async()=>{const o=await fetch(e,{signal:r});if(!o.ok||!o.body)throw new Error("Model download failed");const a=$(o),i=$e(o.body,a,n);await t.put(e,new Response(i,{headers:{"content-type":"application/octet-stream",...a?{"content-length":`${a}`}:{}}}))})().finally(()=>{Re.delete(e)});return Re.set(e,a),await a})(b,v,o,n);const e=await v.match(b);e?.body&&(y=e.body)}catch(e){if(o?.aborted)throw new Error("Cancelled");a&&console.log("Local model cache failed",e)}if(y||(y=await(async(e,t,r)=>{const n=await fetch(e,{signal:t});if(!n.ok||!n.body)throw new Error("Model download failed");return $e(n.body,$(n),r)})(b,o,n)),o?.aborted)throw new Error("Cancelled");n(1,s.load);const x=await u.Engine.create((({model:e,limits:t,contextSize:r,source:n,mod:o})=>{const a=e.litert;return{model:n,mainExecutorSettings:{maxNumTokens:r,...a?.vision?{maxNumImages:Math.max(1,t.maxImages)}:{},backendConfig:Pe},...a?.vision?{visionBackend:o.Backend.GPU,maxVisionTokensPerImage:70,minVisionTokensPerImage:70}:{},...a?.audio?{audioBackend:o.Backend.CPU}:{}}})({model:e,limits:t,contextSize:l,source:y,mod:u}));Se+=1;const j=()=>{Se=Math.max(0,Se-1),Se||(e=>{try{const t=e.getGlobalLiteRtLm().liteRtLmWasm,r=t.preinitializedWebGPUDevice;t.preinitializedWebGPUDevice=void 0,t.WebGPU&&(t.WebGPU.preinitializedDeviceId=void 0),r?.destroy?.()}catch{}try{e.unloadLiteRtLm()}catch{}})(u)};try{const e=performance.now(),t=await x.createConversation();await t.delete(),be(ve,"LiteRT conversation warm-up",Math.round(performance.now()-e))}catch(e){be(ve,"LiteRT conversation warm-up failed",e)}if(o?.aborted)throw await x.delete(),j(),new Error("Cancelled");const P={sent:[],reasoning:!1,maxTokens:0};return{model:e,backend:i.gpu,contextSize:l,chat:t=>(async({engine:e,model:t,mod:r,params:n,session:o})=>{ve=!0===n.logging;const a=()=>{try{o.conversation?.cancel()}catch{}o.conversation=void 0,o.sent=[]};try{const i=await Z({model:t,params:n,stopped:()=>!!n.signal?.aborted,onStall:a,start:async a=>{if(n.signal?.aborted)throw new Error("Cancelled");if(q(a)&&!t.litert?.vision)throw new Error("Model does not accept images");if(B(a)&&!t.litert?.audio)throw new Error("Model does not accept audio");return Be({engine:e,mod:r,params:n,messages:a,session:o})}}),s=o.conversation;if(s&&n.onPromptSpeed&&!n.signal?.aborted){const e=await s.getBenchmarkInfo().catch(()=>{}),t=e?.lastPrefillTokensPerSecond;"number"==typeof t&&Number.isFinite(t)&&t>0&&n.onPromptSpeed((0,M.rNum)(t))}return i}catch(e){throw a(),e}})({engine:x,model:e,mod:u,params:t,session:P}),unload:async()=>{const e=P.conversation;P.conversation=void 0,P.sent=[];try{await(e?.delete())}catch{}await x.delete(),j()}}},cached:async e=>{const t=e.litert;if(!t)return!1;const r=R(t.repo,t.file),[n,o]=await Promise.all([Ae(),je.stored(r)]);if(o?.complete)return!0;try{return!(!n||!await n.match(r))}catch{return!1}},purge:async()=>{try{await je.purge(),"undefined"!=typeof caches&&await caches.delete(xe)}catch{}}};let Ie,Ke,Fe="",We=!1;const Ve=we("wllama-store"),Ge=[g.qwen3_vl_2b_instruct,g.qwen3_vl_2b_instruct_q3],Je=e=>e.cpu?.mmproj&&Ge.includes(e.id)?{image_min_tokens:16,image_max_tokens:128}:{},Ye=e=>`${e.wasm}|${e.compatWasm}|${e.compatWorker}`,He=e=>{const t={wasm:j,compatWasm:P,compatWorker:k};return{wasm:e?.wasm||t.wasm,compatWasm:e?.compatWasm||t.compatWasm,compatWorker:e?.compatWorker||t.compatWorker}},Qe=e=>{const t=e=>(...t)=>{We&&("string"==typeof t[0]&&t[0].includes("ggml_webgpu: Failed to get an adapter")||e(...t))};return{...e,log:t(e.log),warn:t(e.warn),error:t(e.error)}},Ze=async()=>{if(Ie)return Ie;const e=await r.e(924).then(()=>r(577)),t=Ke||He(),n=new e.Wllama({default:t.wasm},{logger:Qe(e.LoggerWithoutDebug)});return Ke||(Ke=t,Fe=Ye(t)),n.setCompat({wasm:t.compatWasm,worker:t.compatWorker}),Ie=n,n},Xe=async()=>{const e=Ie;Ie=void 0;try{await(e?.exit())}catch{}},et=(e,t)=>e.name.includes(t)||!!e.metadata?.originalURL?.includes(t),tt=e=>{const t=e.cpu;return t?[{name:t.file,url:R(t.repo,t.file)},...t.mmproj?[{name:t.mmproj.file,url:R(t.mmproj.repo??t.repo,t.mmproj.file)}]:[]]:[]},rt=async e=>{const t=tt(e);if(!t.length)return!1;for(const e of t){const t=await Ve.stored(e.url);if(!t?.complete)return!1}return!0},nt=async(e,t,r,n)=>{const o=await fetch(e,{signal:n,headers:{Range:`bytes=${t}-${r-1}`}});if(206!=o.status)throw await(o.body?.cancel().catch(()=>{})),new Error("Model range failed");return await o.arrayBuffer()},ot=async(e,t)=>{const r=await fetch(e,{method:"HEAD",signal:t});await(r.body?.cancel().catch(()=>{}));const n=Number(r.headers.get("content-length"))||0;if(!r.ok||!n)throw new Error("Model size unknown");return n},at=({url:e,stored:t,storedSize:r,total:n,signal:o})=>{const a=Math.max(0,Math.min(r,n));return{size:n,slice:(r,i)=>({arrayBuffer:async()=>{const s=Math.max(0,Math.min(r??0,n)),c=Math.max(s,Math.min(i??n,n));if(c<=s)return new ArrayBuffer(0);if(t&&c<=a)return await t.slice(s,c).arrayBuffer();if(!t||s>=a)return await nt(e,s,c,o);const l=await t.slice(s,a).arrayBuffer(),u=await nt(e,a,c,o),d=new Uint8Array(l.byteLength+u.byteLength);return d.set(new Uint8Array(l)),d.set(new Uint8Array(u),l.byteLength),d.buffer}})}},it=async({model:e,signal:t,onProgress:r})=>{const n=tt(e),o=[];for(let e=0;e<n.length;e++){if(t?.aborted)throw new Error("Cancelled");const a=await Ve.download({url:n[e].url,signal:t,onProgress:(t,o)=>r((e+t)/n.length,o)});if(!a)return;o.push(a.file)}return o.length?o:void 0},st=async e=>{const t=[];for(const r of e){if("string"==typeof r.content){"system"==r.role?t.push({role:"system",content:r.content}):"assistant"==r.role?t.push({role:"assistant",content:r.content}):t.push({role:"user",content:r.content});continue}const e=[];for(const t of r.content)"text"==t.type?e.push({type:"text",text:t.text}):e.push({type:t.type,data:await _(t.url)});t.push({role:"user",content:e})}return t},ct={backend:i.cpu,startLLM:async({model:e,limits:t,onProgress:r,signal:n,logging:o,assets:a})=>{We=!0===o;const c=h()?4096:8192,l=e.cpu;if(!l)throw new Error("Model has no CPU artifact");const u=He(a),d=Ye(u);Ie&&d!=Fe&&await Xe(),Ke=u,Fe=d;const g="undefined"!=typeof navigator?navigator.hardwareConcurrency:0,m=Math.min((e=>{const t=e||4;return Math.max(1,t-Math.max(1,Math.floor(t/5)))})(g),t.maxThreads),p=await Ze(),f=await rt(e),y=l.mmproj?.file;if(n?.aborted)throw await Xe(),new Error("Cancelled");if(!f&&y){const e=await p.cacheManager.list(),t=e.some(e=>et(e,l.file)),r=e.some(e=>et(e,y));t&&!r&&await p.cacheManager.deleteMany(e=>et(e,l.file))}const w={n_ctx:c,n_threads:m,n_parallel:1,warmup:!0,...e.reasoning?{reasoning_budget_tokens:t.maxThinkingTokens}:{reasoning_budget_tokens:0},n_gpu_layers:0,jinja:!0,ctx_shift:!0,n_keep:Math.max(64,Math.round(c/16)),...Je(e)};try{let t=f?await it({model:e,signal:n,onProgress:r}):void 0;t||(t=await(async(e,t)=>{const r=tt(t);if(!r.length)return;const n=(await e.modelManager.getModels().catch(()=>[])).find(e=>e.url==r[0].url);return n?await n.open().catch(()=>{}):void 0})(p,e)),t||(t=await it({model:e,signal:n,onProgress:r}).catch(e=>{if(n?.aborted)throw new Error("Cancelled");o&&console.log("Local model store failed",e)})),t||(t=await(async(e,t)=>{const r=[];for(const n of tt(e)){if(t?.aborted)throw new Error("Cancelled");const e=await Ve.stored(n.url),o=e?.total||await ot(n.url,t);if(!o)throw new Error("Model size unknown");r.push(at({url:n.url,stored:e?.file,storedSize:Math.min(e?.size||0,o),total:o,signal:t}))}return r})(e,n)),r(1,s.load),await p.loadModel(t,w)}catch(e){throw await Xe(),e}if(n?.aborted)throw await Xe(),new Error("Cancelled");const b=p.getLoadedContextInfo();if(!b.n_ctx)throw await Xe(),new Error("Failed to create model context");return be(o,"CPU engine ready",e.id,"cores","undefined"!=typeof navigator?navigator.hardwareConcurrency:0,"isolated","undefined"!=typeof crossOriginIsolated&&crossOriginIsolated,"requested",m,"multithread",p.isMultithread(),"active",p.getNumThreads(),"context",b.n_ctx,"batch",b.n_batch,"ubatch",b.n_ubatch),{model:e,backend:i.cpu,contextSize:c,chat:t=>(async(e,t,r)=>{if(We=!0===r.logging,e.isModelLoaded())return await Z({model:t,params:r,stopped:()=>!!r.signal?.aborted,start:async n=>{if(q(n)&&!e.supportInputModality("image"))throw new Error("Model does not accept images");if(B(n)&&!e.supportInputModality("audio"))throw new Error("Model does not accept audio");return await e.createChatCompletion({messages:await st(n),...A(r.limits,r.reasoning,r.temperature),timings_per_token:!0,return_progress:!0,...r.repeatPenalty?{penalty_repeat:r.repeatPenalty}:{},abortSignal:r.signal,...t.reasoning||Ge.includes(t.id)?{chat_template_kwargs:{enable_thinking:r.reasoning}}:{}})}})})(p,e,t),unload:async()=>{if(Ie==p)await Xe();else try{await p.exit()}catch{}}}},cached:async e=>{try{return!!e.cpu&&(!!await rt(e)||await(async(e,t)=>{const r=tt(t),n=await e.modelManager.getModels().catch(()=>[]);return!!r.length&&n.some(e=>e.url==r[0].url)})(await Ze(),e))}catch{return!1}},purge:async()=>{try{await Ve.purge()}catch{}try{const e=await Ze();await e.cacheManager.clear()}catch{}}},lt=((e={})=>{let t,r,n,o=a.idle;const c=e.engines?.cpu||ct,l=e.engines?.litert||ze,u=new Map,d=new Map,g=new Map,m=new Map,p=new Map,f=new Map,y=new Map,h=new Map,w=new Map,b=t=>{if(e.backend!=i.none)return e.backend==i.cpu?t.cpu?c:void 0:e.backend==i.gpu?t.litert?l:void 0:t.litert&&"undefined"!=typeof navigator&&navigator.gpu&&"undefined"!=typeof WebAssembly?l:!t.cpu||"undefined"==typeof window&&"undefined"==typeof self&&"undefined"==typeof Worker||"undefined"==typeof WebAssembly?void 0:c},v=e=>e?u.get(e):t?u.get(t.id):void 0,S=e=>{o=e},x=async e=>{const r=u.get(e);r&&(u.delete(e),t?.id==e&&(t=[...u.values()].pop()?.model),u.size||d.size||S(a.idle),await r.unload())},M=async()=>{for(const e of[...u.keys()])await x(e)},j=(e,t,r)=>{const n={percent:Math.max(0,Math.min(1,t)),phase:r||s.download};p.set(e,n);for(const t of m.get(e)??[])t.report(n.percent,n.phase)},P=e=>{y.set(e,(y.get(e)??0)+1),f.get(e)?.abort(),f.delete(e);const t=d.get(e);t&&g.set(e,t),d.delete(e),m.delete(e),p.delete(e),h.set(e,a.idle),o!=a.downloading||d.size||u.size||S(a.idle)},k=(e,t,r)=>{const n=d.get(e);return n?new Promise(o=>{let a=!1;const i={report:t,settle:e=>{a||(a=!0,r?.removeEventListener("abort",s),o(e))}},s=()=>{((e,t)=>{const r=m.get(e);r&&m.set(e,r.filter(e=>e!=t)),queueMicrotask(()=>{!m.get(e)?.length&&d.has(e)&&P(e)})})(e,i),i.settle(!1)},c=m.get(e);c?c.push(i):m.set(e,[i]),r?.aborted?s():r?.addEventListener("abort",s,{once:!0}),n.attempt.then(i.settle,()=>i.settle(!1))}):Promise.resolve(!1)},D=async e=>{if(e)await x(e);else{for(const e of[...d.keys()])P(e);p.clear(),h.clear(),w.clear(),r=void 0,S(a.idle),await M()}};return{load:async({model:e,limits:n,assets:o,logging:i,signal:c,onProgress:l})=>{if(c?.aborted)return!1;if(u.has(e.id))return t=e,!0;if(d.has(e.id)){const t=p.get(e.id);return t&&l(t.percent,t.phase),await k(e.id,l,c)}const v=b(e);if(!v){const t="Model is not supported on this device";return r=t,w.set(e.id,t),h.set(e.id,a.unsupported),S(a.unsupported),!1}const x=[...d.values(),...g.values()];for(const e of x)P(e.model.id);const D=(y.get(e.id)??0)+1;let N;y.set(e.id,D);const _=(async()=>{if(await Promise.all(x.map(e=>e.attempt.catch(()=>!1))),D!=y.get(e.id))return!1;if(await(async()=>{try{if("undefined"==typeof navigator)return;await(navigator.storage?.persist?.())}catch{}})(),D!=y.get(e.id))return!1;if(await M(),D!=y.get(e.id))return!1;const c=await v.cached(e);if(D!=y.get(e.id))return!1;r=void 0,w.delete(e.id),h.set(e.id,a.downloading),S(a.downloading),j(e.id,0,s.download),c&&j(e.id,1,s.load);const l=new AbortController;f.set(e.id,l);try{const c=await v.startLLM({model:e,limits:n,logging:i,signal:l.signal,assets:o,onProgress:(t,r)=>{D==y.get(e.id)&&j(e.id,t,r)}});return D!=y.get(e.id)||l.signal.aborted?(await c.unload(),!1):(u.set(e.id,c),t=e,r=void 0,w.delete(e.id),h.set(e.id,a.ready),S(a.ready),j(e.id,1,s.load),!0)}catch(t){if(D!=y.get(e.id))return!1;const n=`${t?.message||`${t}`}`;return r=n,w.set(e.id,n),h.set(e.id,a.error),S(a.error),i&&console.log("Local model failed",t),!1}finally{f.get(e.id)==l&&f.delete(e.id)}})(),T=_.finally(()=>{g.get(e.id)==N&&g.delete(e.id),d.get(e.id)==N&&(d.delete(e.id),m.delete(e.id),p.delete(e.id))});return N={model:e,attempt:T},d.set(e.id,N),m.set(e.id,[]),await k(e.id,l,c)},chat:async e=>{if(!v(e.model))return;for(;n;)await n.catch(()=>{});const r=v(e.model);if(!r)return;t?.id!=r.model.id&&(t=r.model);const o=r.chat(e);n=o;try{return await o}finally{n==o&&(n=void 0)}},unload:D,clear:async()=>{const e=[...d.values(),...g.values()].map(e=>e.attempt);await D(),await Promise.all(e.map(e=>e.catch(()=>{}))),await Promise.all([c.purge(),l.purge()])},ready:e=>!!v(e),loading:e=>e?d.has(e):d.size>0,status:e=>v(e)?a.ready:e?d.has(e)?h.get(e)??a.downloading:w.has(e)?h.get(e)??a.error:a.idle:o,backend:e=>v(e)?.backend??i.none,error:e=>e?w.get(e):r,model:()=>t}})(),ut=(e,t,r)=>{const n=e.status(t),i=w(t);return{...t?{model:t}:{},availability:n==a.ready?o.online:n==a.error||n==a.unsupported?o.offline:o.away,status:n,backend:e.backend(t),supportsImages:!!i&&S(i),supportsAudio:!!i&&x(i),ready:e.ready(t),loading:e.loading(t),requesting:r.requesting,phase:r.phase,percent:r.percent,...r.error?{error:r.error}:{}}},dt=(e=>{let t,r=0;const o=t=>t.input.onStatus?.(ut(e,t.model??t.input.model,t));return i=>{t?.controller.abort();const c=e.ready(i.model),l={token:++r,input:i,controller:new AbortController,percent:c?100:0,phase:c?s.load:s.download,requesting:!1,cancelled:!1};return t=l,o(l),(async t=>{const{input:a}=t,i=!0===a.logging,c=await v(a.model);if(t.model=c?.id,t.token!=r)return;const l=a.messages.some(e=>e.role!=n.system&&"string"==typeof e.content&&!!e.content.trim()),u=a.messages.some(e=>e.role==n.user&&!!e.images?.some(e=>"string"==typeof e&&!!e)),d=a.messages.some(e=>e.role==n.user&&!!e.audio?.some(e=>"string"==typeof e&&!!e)),g=l||u||d;if(!c)return t.error="Unknown model",void o(t);if(!g)return t.error="No prompt",void o(t);const m=S(c),p=x(c);if(!(l||u&&m||d&&p))return d&&!p?t.error="Model does not accept audio":u&&!m&&(t.error="Model does not accept images"),void o(t);const f=C(a.limits,!!c.litert),y=await e.load({model:c,limits:f,logging:i,signal:t.controller.signal,onProgress:(e,n)=>{t.token==r&&(t.percent=Math.round(100*e),t.phase=n,o(t))}}).catch(e=>(t.token==r&&(t.error=`${e?.message||`${e}`}`),!1));if(t.token!=r)return;if(t.cancelled)return void o(t);if(!y)return t.error||(t.error=e.error(c.id)||"Model not ready"),void o(t);const h=u&&!m||d&&!p?a.messages.map(({images:e,audio:t,...r})=>({...r,...e&&m?{images:e}:{},...t&&p?{audio:t}:{}})):a.messages;t.requesting=!0,t.error=void 0,t.percent=100,t.phase=s.load,o(t);let w,b="",M="";try{w=await e.chat({model:c.id,messages:h,limits:f,reasoning:!0===a.reasoning,logging:i,onReason:e=>{t.token!=r||t.cancelled||(b+=e,a.onThinking?.(b))},onText:e=>{t.token!=r||t.cancelled||(M+=e,a.onResponse?.(M))},onSpeed:e=>{t.token!=r||t.cancelled||a.onSpeed?.(e)},onPromptSpeed:e=>{t.token!=r||t.cancelled||a.onPromptSpeed?.(e)},signal:t.controller.signal})}catch(n){if(t.token!=r)return;return t.requesting=!1,t.error=`${n?.message||`${n}`}`,t.cancelled||await e.unload(c.id).catch(()=>{}),void o(t)}t.token==r&&(t.requesting=!1,w||t.cancelled||(t.error="No reply",await e.unload(c.id).catch(()=>{})),o(t))})(l),()=>(t=>{t.token==r&&(t.cancelled=!0,t.controller.abort(),t.model&&e.status(t.model)==a.ready?e.unload(t.model).then(()=>o(t)):queueMicrotask(()=>o(t)))})(l)}})(lt),gt=(pt=lt,async(e={})=>{const t=await v(e.model),r=r=>e.onStatus?.(ut(pt,t?.id,r));if(!t)return r({requesting:!1,phase:s.download,percent:0,error:"Unknown model"}),!1;let n,o=0,a=s.download;const i=pt.ready(t.id);return await pt.load({model:t,limits:C(e.limits,!!t.litert),logging:!0===e.logging,onProgress:(e,t)=>{o=Math.round(100*e),a=t,r({requesting:!1,phase:a,percent:o})}}).catch(e=>(n=`${e?.message||`${e}`}`,!1))?(i&&r({requesting:!1,phase:s.load,percent:100}),!0):(r({requesting:!1,phase:a,percent:o,error:n||pt.error(t.id)||"Model not ready"}),!1)}),mt=async()=>{await lt.clear()};var pt,ft=r(167);let yt;const ht="degreesign-chat-estimates-v1",wt={analyze:95,describe:25,translate:15,tags:6,translateTags:4},bt=()=>yt??=(0,ft.readData)(ht)??{},vt=e=>{const t=e.map(e=>({operation:e,est:bt()[e]??wt[e]}));return{totalEst:t.reduce((e,t)=>e+t.est,0),breakdown:t}},St=({operation:e,seconds:t})=>{t>0&&(yt={...bt(),[e]:t},(0,ft.saveData)({key:ht,data:yt}))},xt=["You are describer of images","in detailed efficient manner.","You share descriptions after replacing","euphemisms with all specific terms.","You include visible organs/limbs,","with pose and actions, only for living things.","You always describe the overall nature,","state, pose, acts, positions, and locations.","You always give priority to interesting,","unusual, shocking, explicit,","or weird facts about the image.","You never: lie, use vague referrals,","use a general term when a precise term exists,","use euphemisms, nor include any part","of the message in your response."].join(" "),Mt=["Describe this image in one detail blunt","concise paragraph, prioritize most","head-turning elements over mundane elements."].join(" "),jt=e=>["You tag photos for a private photo gallery.","Read each numbered image description below","and reply with exactly one line per number.","Each line is the number, a colon,",`then exactly ${e}`,"comma separated single word tags","for the most prominent concrete","elements the photo shows.","Tag its main subjects, objects,","actions and place, never the medium or","filler ideas such as photo, image,","picture, scene, object, background or colour.","Produce the tags even if the","photo is extreme or explicit.","Always add the first tag as",'"nsfw" if the photo is',"flirty, suggestive or explicit.","Write every tag in English as one word.","Reply with the numbered lines only,","in the form: 1. tag, tag, tag"].join(" "),Pt=e=>["You translate the tags of",`a private photo gallery into ${e}.`,"Read each numbered English tag","below and reply with exactly one line per tag.","Each line is the number, a colon,",`then the tag in ${e}:`,"one single word, without articles or explanation.","Use only letters.","Reply with the numbered","lines only, without quotes."].join(" "),kt=["You are a precise translator.","Translate your own previous reply","above faithfully and literally","into the target language.","Never translate the user's","request or instructions.","Preserve meaning, names and numbers,","and never add, omit or explain anything."].join(" "),Dt=e=>["Now please translate your previous",`reply above faithfully into ${e}.`,"Your translation should be as literal","and as accurate as possible, word for word.","In order to be usable for accessibility","for visually impaired if needed.","Reply only by the translation","without any addition or explanation"].join(" "),Nt=g.qwen3_vl_2b_instruct,_t="CANNOT_TRANSLATE",Tt=e=>{const t=e.trim().toLowerCase();return!!t&&!/^(en|eng|english)([-_]|$)/.test(t)},Ot=e=>"string"==typeof e?e.toLowerCase().replace(/[^\p{L}]+/gu,"").slice(0,20):"",Et=async({service:e,limits:t,logging:r,signal:n,onStatus:o,model:a})=>{const i=(t,r)=>o?.(ut(e,t,r)),c=w(a)??await v();if(!c)return be(r,"Model missing",a),i(a||Nt,{requesting:!1,phase:s.download,percent:0,error:"Unknown model"}),{error:"Unknown model"};const l=await(async o=>{let a,c=0,l=-1,u=s.download;be(r,"Describe load start",o.id,t.maxReplyTokens);if(await e.load({model:o,limits:t,logging:r,signal:n,onProgress:(e,t)=>{c=Math.round(100*e),u=t,c!=l&&(l=c,be(r,"Describe load progress",o.id,c,u)),i(o.id,{requesting:!1,phase:u,percent:c})}}).catch(e=>(a=`${e?.message||`${e}`}`,!1)))return be(r,"Describe load ready",o.id),void i(o.id,{requesting:!1,phase:s.load,percent:100});const d=a||e.error(o.id)||"Model not ready";return be(r,"Describe load failed",o.id,d),i(o.id,{requesting:!1,phase:u,percent:c,error:d}),d})(c);return l?{error:l}:n?.aborted?{aborted:!0}:(i(c.id,{requesting:!0,phase:s.load,percent:100}),{report:i,generate:async({model:o,messages:a,stage:c,repeatPenalty:l,temperature:u,limits:d,onSpeed:g,onText:m})=>{let p="";const f=Date.now();if(be(r,"Describe generate start",c,o,a.length),!n?.aborted)try{const i=await e.chat({model:o,messages:a,limits:d?{...t,...d}:t,reasoning:!1,...l?{repeatPenalty:l}:{},...void 0===u?{}:{temperature:u},logging:r,signal:n,onReason:e=>{be(r,"Describe reason",c,o,e)},onText:e=>{p+=e,be(r,"Describe text",c,o,e),m?.(p)},onSpeed:e=>{be(r,"Describe speed",c,o,e),g?.(e)}});return be(r,"Describe generate reply",c,o,Date.now()-f,i?.length??0,i),i}catch(e){if(be(r,"Describe generate failed",c,o,e),n?.aborted)return;throw i(o,{requesting:!1,phase:s.load,percent:100,error:`${e?.message||`${e}`}`}),e}},model:c})},Lt=e=>async t=>{const r=!0===t.logging,o=C({maxReplyTokens:128,imageTokens:192,...t.limits});t.onEstimate?.(vt([c.analyze,c.describe])),be(r,"Describe image start",t.image.length);const a=await Et({service:e,limits:o,logging:r,signal:t.signal,onStatus:t.onStatus,model:Nt});if("error"in a)throw new Error(a.error);if("aborted"in a)return"";let i,l="";const{report:u,generate:d,model:g}=a,m=Date.now();try{l=(await d({model:g.id,messages:[{role:n.system,content:t.systemRulesOverride||xt},{role:n.user,content:Mt,images:[t.image]}],stage:"describe",repeatPenalty:1,temperature:.1,onSpeed:t.onSpeed,onText:e=>{i??=Date.now(),t.onText?.(e)}})||"").trim()}catch(e){if(t.signal?.aborted)return"";throw e}const p=Date.now();return be(r,"Describe image done",p-m,l),u(g.id,{requesting:!1,phase:s.load,percent:100}),l?(St({operation:c.analyze,seconds:((i??p)-m)/1e3}),St({operation:c.describe,seconds:(p-(i??m))/1e3}),l):(be(r,"Describe image empty"),u(g.id,{requesting:!1,phase:s.load,percent:100,error:"No description"}),"")},Ct=e=>async t=>{const r=t.tags.map(e=>({...e})),o=t.targetLanguage.trim(),a=t.targetCode.trim()||"en",i=!0===t.logging;if(!r.length||"en"==a||!Tt(o))return r;t.onEstimate?.(vt([c.translateTags]));const u=C({maxReplyTokens:256,...t.limits}),d=await Et({service:e,limits:u,logging:i,signal:t.signal,onStatus:t.onStatus,model:t.model});if("error"in d||"aborted"in d)return r;const{report:g,generate:m,model:p}=d,f=Date.now(),y=r.map((e,t)=>`${t+1}. ${e.en}`).join("\n");try{((e,t,r)=>{if("en"!=r)for(const n of e.matchAll(/^\s*(\d+)\s*[:.\-]\s*(.+)$/gm)){const e=t[Number(n[1])-1],o=Ot(n[2]);e&&o&&o!=e.en&&(e[r]=o)}})((await m({model:p.id,messages:[{role:n.system,content:Pt(o)},{role:n.user,content:y}],stage:l.translateTags,limits:{maxReplyTokens:256},onText:t.onText})||"").trim(),r,a),St({operation:c.translateTags,seconds:(Date.now()-f)/1e3})}catch(e){be(i,"Enhance tag translate failed",e)}return g(p.id,{requesting:!1,phase:s.load,percent:100}),r},At=e=>async t=>{const r=t.descriptionEN.trim(),o=t.targetLanguage.trim(),a=t.targetCode.trim()||"en",i=!1!==t.withTags,u=!1!==t.withDescription,d=!0===t.logging,g=Ct(e),m=!!r&&u&&"en"!=a&&Tt(o),p=i&&"en"!=a&&Tt(o),f=[...m?[c.translate]:[],...i?[c.tags]:[],...p?[c.translateTags]:[]],y={description:r,translated:!1,tags:[],nsfw:void 0};if(be(d,"Enhance start",r.length,o,a),!r||!f.length)return y;t.onEstimate?.(vt(f));const h=C({maxReplyTokens:256,...t.limits}),w=await Et({service:e,limits:h,logging:d,signal:t.signal,onStatus:t.onStatus,model:t.model});if("error"in w||"aborted"in w)return y;const{report:b,generate:v,model:S}=w;if(m){t.onStage?.(l.translate);const e=Date.now();try{const a=(await v({model:S.id,messages:[{role:n.system,content:kt},{role:n.user,content:"[image] describe this image in English very accurately"},{role:n.assistant,content:r},{role:n.user,content:Dt(o)}],stage:l.translate,limits:{maxReplyTokens:256},onSpeed:t.onSpeed,onText:e=>t.onText?.(e,l.translate)})||"").trim(),i=a.replace(/[^a-z]/gi,"").toUpperCase().includes(_t.replace(/[^a-z]/gi,""));a&&!i&&(y.description=a,y.translated=!0),St({operation:c.translate,seconds:(Date.now()-e)/1e3})}catch(e){be(d,"Enhance translate failed",e)}}if(i){t.onStage?.(l.tags);const e=Date.now();try{const o=(e=>{const t=[],r=e=>{const r=(e=>"string"==typeof e?e.toLowerCase().replace(/[^a-z]+/g,"").slice(0,20):"")(e);r.length<2||t.some(e=>e.en==r)||t.push({en:r})};for(const t of e.matchAll(/^\s*\d+\s*[:.\-]\s*(.+)$/gm))for(const e of(t[1]||"").split(/[,;\n]+/))for(const t of e.split(/\s+/))r(t);if(!t.length)for(const t of e.split(/[,;\n]+/))for(const e of t.split(/\s+/))r(e);return t})((await v({model:S.id,messages:[{role:n.system,content:jt(3)},{role:n.user,content:r}],stage:l.tags,limits:{maxReplyTokens:128},onSpeed:t.onSpeed,onText:e=>t.onText?.(e,l.tags)})||"").trim());y.nsfw=o.some(e=>"nsfw"==e.en),y.tags=o.filter(e=>"nsfw"!=e.en).slice(0,3),St({operation:c.tags,seconds:(Date.now()-e)/1e3}),be(d,"Enhance tags",y.tags)}catch(e){be(d,"Enhance tags failed",e)}}return p&&y.tags.length&&(t.onStage?.(l.translateTags),y.tags=await g({tags:y.tags,targetLanguage:o,targetCode:a,model:S.id,signal:t.signal,limits:t.limits,logging:d,onStatus:t.onStatus,onText:e=>t.onText?.(e,l.translateTags)})),b(S.id,{requesting:!1,phase:s.load,percent:100}),y},Rt=Lt(lt),$t=At(lt),Ut=Ct(lt),qt=e=>{const t=e.trim().toLowerCase();return!!t&&!/^(en|eng|english)([-_]|$)/.test(t)},Bt=(e=>{const t=Lt(e),r=At(e);return async e=>{let n;const o=[],a=e.targetLanguage.trim()||"en",i=async()=>n??=await b();for(let n=0;n<e.images.length&&!e.signal?.aborted;n++){e.currentIndex?.(n);let s="";const c=Date.now(),u=e.images[n];try{s=await t({image:u,systemRulesOverride:e.additionalRules,signal:e.signal,limits:e.limits,logging:e.logging,onStatus:e.onStatus,onSpeed:t=>e.onSpeed?.(n,t),onText:t=>e.onText?.(n,t,"describe")})}catch{}const d=Math.max(0,Date.now()-c);if(!s){o.push({descriptionEN:"",description:"",durationMs:d}),e.currentIndex?.(n,"",void 0,d);continue}e.currentIndex?.(n,s,void 0,d);let m=s;if(qt(e.targetLanguage)&&await i())try{const t=await r({descriptionEN:s,targetLanguage:e.targetLanguage,targetCode:a,withTags:!1,withDescription:!0,model:g.gemma4_e2b_limited,signal:e.signal,limits:e.limits,logging:e.logging,onStatus:e.onStatus,onSpeed:t=>e.onSpeed?.(n,t),onText:(t,r)=>{r==l.translate&&e.onText?.(n,t,"translate")}});t.translated&&(m=t.description)}catch{}if(o.push({descriptionEN:s,description:m,durationMs:d}),e.currentIndex?.(n,s,m,d),e.signal?.aborted)break}return o}})(lt),zt=(e=>{const t=At(e);return async e=>{const r=[...e.descriptions],n=e.targetLanguage.trim(),o=n||"en";if(!r.length||!qt(n))return r;if(!await b())return r;for(let a=0;a<r.length&&!e.signal?.aborted;a++){const i=r[a]||"";if(!i){e.currentIndex?.(a,i,i);continue}let s=i;try{const r=await t({descriptionEN:i,targetLanguage:n,targetCode:o,withTags:!1,withDescription:!0,model:g.gemma4_e2b_limited,signal:e.signal,limits:e.limits,logging:e.logging,onStatus:e.onStatus,onSpeed:t=>e.onSpeed?.(a,t),onText:(t,r)=>{r==l.translate&&e.onText?.(a,t,"translate")}});r.translated&&(s=r.description)}catch{}r[a]=s,e.currentIndex?.(a,i,s)}return r}})(lt),It=/^[0-9+\-*/%^().]+$/,Kt=e=>{let t=0;const r=e=>!!e&&e>="0"&&e<="9",n=e=>{throw new Error(e)},o=()=>{let o;for("("==e[t]?(t++,o=s(),")"!=e[t]&&n("Unbalanced parentheses"),t++):o=(()=>{const o=t;for(;r(e[t]);)t++;let a="";const i=e.slice(o,t);if("."==e[t]){t++;const n=t;for(;r(e[t]);)t++;a=e.slice(n,t)}return i||a?Number(`${i||"0"}.${a||"0"}`):n("Expected a number")})();"%"==e[t];)t++,o/=100;return o},a=()=>"+"==e[t]?(t++,a()):"-"==e[t]?(t++,-a()):(()=>{const r=o();return"^"!=e[t]?r:(t++,r**a())})(),i=()=>{let r=a();for(;"*"==e[t]||"/"==e[t];){const o=e[t];t++;const i=a();"*"==o?r*=i:(i||n("Division by zero"),r/=i)}return r},s=()=>{let r=i();for(;"+"==e[t]||"-"==e[t];){const n=e[t];t++;const o=i();r="+"==n?r+o:r-o}return r},c=s();return t<e.length&&n("Unexpected character"),Number.isFinite(c)||n("Result is not a finite number"),c},Ft={name:"calculate",description:"Evaluate an arithmetic expression. Supports + - * / % ^ and parentheses; % divides by 100.",parameters:{type:"object",properties:{expression:{type:"string",description:"Arithmetic expression, for example 2*(3+4)"}},required:["expression"]},execute:e=>{const t=e.expression;if("string"!=typeof t)throw new Error("Missing expression");return(e=>{if(e.trim().length>200)throw new Error("Expression is too long");const t=(e=>e.replace(/×/g,"*").replace(/÷/g,"/").replace(/−/g,"-").replace(/,/g,"").replace(/\s+/g,""))(e);if(!t)throw new Error("Expression is empty");if(!It.test(t))throw new Error("Unsupported character");const r=Kt(t);return{expression:t,result:Math.abs(r)>=1e5?(0,M.pNum)(r)??r:(0,M.rNum)(r,12)}})(t)}};let Wt,Vt={},Gt=0,Jt=!1,Yt=!1;const Ht="degreesign-chat-prices-v1",Qt="EUR",Zt=5*M.oneMin,Xt=30*M.oneSec,er=e=>{const t={};for(const[r,n]of Object.entries(e??{}))"number"==typeof n&&Number.isFinite(n)&&(t[r.trim().toUpperCase()]=n);return t},tr=(e,t)=>e&&e.sourceAt>t.sourceAt?e:t,rr=async({fiat:e,crypto:t})=>{try{const r=await fetch("https://srv.coinexams.com/data.json");if(!r.ok)throw new Error(`Price feed failed with ${r.status}`);const n=await r.json(),o=Date.now(),a=e?((e,t)=>{const r=er(e.rates?.current),n=er(e.rates?.yesterday);if(Object.keys(r).length)return{fetchedAt:t,sourceAt:Number(e.rates?.date)||t,rates:r,yesterday:n}})(n,o):void 0,i=t?((e,t)=>{const r=e.coins??{},n={},o={};for(const[e,t]of Object.entries(r)){const r=e.trim().toUpperCase(),a=t?.pr,i=t?.yst;"number"==typeof a&&Number.isFinite(a)&&(n[r]=a),"number"==typeof i&&Number.isFinite(i)&&(o[r]=i)}if(Object.keys(n).length)return{fetchedAt:t,sourceAt:Number(e.date)||t,prices:n,yesterday:o}})(n,o):void 0;if(e&&!a)throw new Error("Price feed is unavailable");if(t&&!i)throw new Error("Price feed is unavailable");a&&(Vt.fiat=tr(Vt.fiat,a)),i&&(Vt.crypto=tr(Vt.crypto,i)),Gt=0,Jt=!1,(()=>{try{if("undefined"==typeof localStorage)return;localStorage.setItem(Ht,JSON.stringify(Vt))}catch{}})()}catch(e){throw Gt=Date.now(),Jt=!0,e}},nr=e=>!!Vt.crypto&&(e in Vt.crypto.prices||e in Vt.crypto.yesterday),or=e=>!!Vt.fiat&&(e in Vt.fiat.rates||e in Vt.fiat.yesterday),ar=async e=>{const t=(e=>{const t={fiat:!1,crypto:!1};for(const r of e){if(r==Qt)continue;const e=nr(r)||or(r);!nr(r)&&e||(t.crypto=!0),nr(r)||(t.fiat=!0)}return t})(e),r=Date.now(),n=t.fiat&&r-(Vt.fiat?.fetchedAt??0)>=M.oneHr,o=t.crypto&&r-(Vt.crypto?.fetchedAt??0)>=Zt;(n||o)&&("undefined"!=typeof navigator&&!1===navigator.onLine||Gt&&r-Gt<Xt||(Wt||(Wt=rr({fiat:n,crypto:o}).catch(()=>{}).finally(()=>{Wt=void 0})),await Wt))},ir=e=>{if(e==Qt)return 1;const t=Vt.crypto?.yesterday[e],r=Vt.fiat?.yesterday[e];return t||(r?1/r:void 0)},sr=(e,t)=>{if("string"!=typeof e||!e.trim())throw new Error(`Missing ${t}`);return e.trim().toUpperCase()},cr=e=>Math.abs(e)>=1e5?(0,M.pNum)(e)??e:(0,M.rNum)(e,8),lr=async e=>{(()=>{if(!Yt){Yt=!0;try{if("undefined"==typeof localStorage)return;const e=localStorage.getItem(Ht);if(!e)return;const t=JSON.parse(e);Vt={...t.fiat?{fiat:t.fiat}:{},...t.crypto?{crypto:t.crypto}:{}}}catch{}}})();const t=sr(e.from,"from"),r=void 0===e.to||null===e.to?Qt:sr(e.to,"to"),n=(e=>{if(null==e)return 1;if("number"!=typeof e||!Number.isFinite(e))throw new Error("Invalid amount");return e})(e.amount);await ar([t,r]);const o=e=>{const t=(e=>{if(e==Qt)return 1;const t=Vt.crypto?.prices[e],r=Vt.fiat?.rates[e];return t||(r?1/r:void 0)})(e);if(void 0!==t)return t;if(!Vt.fiat&&!Vt.crypto)throw new Error("Prices unavailable offline");if(nr(e)||or(e))throw new Error(`Unavailable quote for ${e}`);throw new Error(`Unknown symbol ${e}`)},a=o(t),i=o(r),s=ir(t),c=ir(r),l=a/i,u=s&&c?s/c:void 0,d=void 0===u?void 0:l-u,g=void 0===u?void 0:100*(l/u-1),m=(e=>{const t=[];for(const r of e)r!=Qt&&(nr(r)?Vt.crypto&&t.push(Vt.crypto.sourceAt):or(r)&&Vt.fiat&&t.push(Vt.fiat.sourceAt));return t})([t,r]),p=m.length?Math.min(...m):Date.now();return{from:t,to:r,amount:n,rate:cr(l),...void 0===u?{}:{previousRate:cr(u),change:cr(d??0),changePercent:(0,M.rNum)(g??0,4)},result:cr(n*l),updatedAt:new Date(p).toISOString(),stale:Jt&&!(!Vt.fiat&&!Vt.crypto)}},ur={name:"currency",description:"Get the EUR price of a fiat currency, crypto coin or metal, or convert an amount. Returns the 24-hour change.",parameters:{type:"object",properties:{from:{type:"string",description:"Currency, coin or metal to convert from"},to:{type:"string",description:"Currency, coin or metal to convert to, EUR by default"},amount:{type:"number",description:"Amount to convert, 1 by default"}},required:["from"]},execute:e=>lr(e)},dr={amp:"&",apos:"'",gt:">",lt:"<",nbsp:" ",quot:'"',hellip:"...",mdash:"-",ndash:"-",ldquo:'"',lsquo:"'",rdquo:'"',rsquo:"'"},gr=(e,t,r,n)=>"number"==typeof e&&Number.isFinite(e)?Math.min(r,Math.max(t,e)):n,mr=(e,t)=>e.replace(/<[^>]*>/g," ").replace(/&(#x?[0-9a-f]+|[a-z]+);/gi,(e,t)=>{const r=(e=>{if(e.startsWith("#")){const t="x"==e[1]||"X"==e[1],r=parseInt(t?e.slice(2):e.slice(1),t?16:10);return r>0&&r<=1114111?String.fromCodePoint(r):e}return dr[e.toLowerCase()]??e})(t);return r==t?e:r}).replace(/\s+/g," ").trim().slice(0,Math.max(0,t)).trim(),pr=/^[a-z]{2,3}(-[a-z]{2,4})?$/i,fr=async(e,t)=>{const r=new AbortController,n=setTimeout(()=>r.abort(),t);try{const t=await fetch(e,{signal:r.signal});if(!t.ok)throw new Error(`Search failed with ${t.status}`);return await t.json()}catch(e){if(r.signal.aborted)throw new Error(`Search timed out after ${t} ms`);throw e}finally{clearTimeout(n)}},yr=(e={})=>{const t=((e={})=>{const t=e.language?.trim()??"";return{provider:e.provider==p.duckduckgo?p.duckduckgo:p.wikipedia,language:pr.test(t)?t:"en",limit:Math.round(gr(e.limit,1,20,3)),snippetLength:Math.round(gr(e.snippetLength,1,4e3,400)),timeout:gr(e.timeout,1e3,3e4,8e3)}})(e);return{name:"websearch",description:t.provider==p.duckduckgo?"Search DuckDuckGo for an instant answer and related topics.":"Search Wikipedia and return a few matching articles.",parameters:{type:"object",properties:{query:{type:"string",description:"What to search for"}},required:["query"]},execute:async e=>{const r="string"==typeof e.query?e.query.trim():"";if(!r)throw new Error("Missing query");const n=t.provider==p.duckduckgo?await(async(e,t)=>{const r=`https://api.duckduckgo.com/?format=json&no_html=1&skip_disambig=1&q=${encodeURIComponent(t)}`,n=await fr(r,e.timeout),o=[],a=new Set,i=(t,r,n)=>{t&&n&&!a.has(t)&&(a.add(t),o.push({title:mr(r||n,200),url:t,snippet:mr(n,e.snippetLength)}))},s=e=>{for(const t of e)t.Topics?s(t.Topics):i(t.FirstURL,t.Text,t.Text)};i(n.AbstractURL,n.Heading||n.AbstractText,n.AbstractText);for(const e of n.Results??[])i(e.FirstURL,e.Text,e.Text);return s(n.RelatedTopics??[]),o.slice(0,e.limit)})(t,r):await(async(e,t)=>{const r=`https://${e.language}.wikipedia.org`,n=`${r}/w/rest.php/v1/search/page?q=${encodeURIComponent(t)}&limit=${e.limit}`,o=await fr(n,e.timeout),a=[];for(const t of o.pages??[]){const n=t.key;n&&a.push({title:mr(t.title??n,200),url:`${r}/wiki/${encodeURIComponent(n)}`,snippet:mr(`${t.description??""} ${t.excerpt??""}`,e.snippetLength)})}return a})(t,r);return n}}},hr=(e,t)=>{const r=[];for(const n of e)n==m.websearch?r.push(yr(t)):n==m.calculate?r.push(Ft):n==m.currency&&r.push(ur);return r},wr=128;export{m as BuiltinTool,g as ChatModelId,u as ChatPreloadField,o as ChatStatus,l as DescriptionEnhancedStage,c as EstimateOperation,i as LlmBackend,s as LlmPhase,n as LlmRole,a as LlmStatus,p as WebSearchProvider,hr as builtinTools,Ft as calculateTool,mt as clearModelCache,dt as createChat,ur as currencyTool,Rt as describeImage,Bt as describeImages,Nt as describeModelId,zt as describeTranslated,$t as descriptionEnhanced,b as gpuAdapter,wr as imageReplyTokens,gt as preloadModel,Ut as translateTags,yr as webSearchTool};
2
+ var e={167(e){e.exports=(()=>{var e={28:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.migrateSecure=t.showError=t.config=t.configureStorageSync=t.configureStorage=void 0;const n=r(896),o=r(205),a={storageKey:"appData",dbName:"appDB",storeName:"appStorage",encryptionKey:void 0,hideErrors:!1,localStoragePrefix:"ds:"},i=({storageKey:e,dbName:t,storeName:r,encryptionKey:n,hideErrors:o,localStoragePrefix:i})=>{try{e&&(a.storageKey=e),t&&(a.dbName=t),r&&(a.storeName=r),n&&(a.encryptionKeyStr=n),null!=o&&(a.hideErrors=o),i&&(a.localStoragePrefix=i)}catch(e){s()&&console.log("configureStorageSync failed",e)}},s=()=>!a.hideErrors;t.config=a,t.configureStorage=async({storageKey:e,dbName:t,storeName:r,encryptionKey:n,hideErrors:c,localStoragePrefix:l})=>{try{i({storageKey:e,dbName:t,storeName:r,hideErrors:c,localStoragePrefix:l}),n&&(a.encryptionKey=await(0,o.cryptoKey)(n),a.encryptionKeyStr=n)}catch(e){s()&&console.log("configureStorage failed",e)}},t.configureStorageSync=i,t.showError=s,t.migrateSecure=async({storedKeys:e,newEncryptionKey:t,newDbName:r,newStoreName:i})=>{s()&&console.log("Data migration started...");const c=a.encryptionKey,l=a.dbName,u=a.storeName;a.encryptionKey=await(0,o.cryptoKey)(t)??a.encryptionKey,a.encryptionKeyStr=t??a.encryptionKeyStr,a.dbName=r??a.dbName,a.storeName=i??a.storeName;for(let t=0;t<e.length;t++){const r=e[t];try{const e=await(0,n.readDB)({key:r,dbName:l,storeName:u}),t=e?c?await(0,o.decryptData)(e,c):JSON.parse(e):void 0,i=t?a.encryptionKey?await(0,o.encryptData)(t,a.encryptionKey):JSON.stringify(t):void 0;i&&await(0,n.saveDB)({key:r,data:i,dbName:a.dbName,storeName:a.storeName})}catch(e){s()&&console.log("migrateSecure failed",r,e)}}s()&&console.log("Data migration finished!")}},185:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.base64ToBytes=t.bytesToBase64=void 0,t.bytesToBase64=e=>{let t="",r=0;for(;r<e.length;r+=32768)t+=String.fromCharCode(...e.subarray(r,r+32768));return btoa(t)},t.base64ToBytes=e=>{const t=atob(e),r=new Uint8Array(t.length);for(let e=0;e<t.length;e++)r[e]=t.charCodeAt(e);return r}},205:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.decrypt=t.encrypt=t.decryptData=t.encryptData=t.cryptoKey=void 0;const n=r(28),o=r(185),a=async(e,t)=>{try{const r=crypto.getRandomValues(new Uint8Array(12)),n=(new TextEncoder).encode(JSON.stringify(e)),a=await crypto.subtle.encrypt({name:"AES-GCM",iv:r},t,n),i=new Uint8Array(a),s=new Uint8Array(r.length+i.length);return s.set(r),s.set(i,r.length),(0,o.bytesToBase64)(s)}catch(t){(0,n.showError)()&&console.log("encryptData failed",t);try{return JSON.stringify(e)}catch(e){}}},i=async(e,t)=>{try{const r=(0,o.base64ToBytes)(e),n=r.slice(0,12),a=r.slice(12),i=await crypto.subtle.decrypt({name:"AES-GCM",iv:n},t,a);return JSON.parse((new TextDecoder).decode(i))}catch(e){(0,n.showError)()&&console.log("decryptData failed",e)}};t.cryptoKey=async e=>{try{if(!e)return;const t=await crypto.subtle.importKey("raw",(new TextEncoder).encode(e),"PBKDF2",!1,["deriveKey"]);return await crypto.subtle.deriveKey({name:"PBKDF2",salt:(new TextEncoder).encode("salt"),iterations:1e5,hash:"SHA-256"},t,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"])}catch(e){(0,n.showError)()&&console.log("processKey failed",e)}},t.encryptData=a,t.decryptData=i,t.encrypt=async e=>{try{return n.config?.encryptionKey?await a(e,n.config.encryptionKey):JSON.stringify(e)}catch(t){(0,n.showError)()&&console.log("encrypt failed",t);try{return JSON.stringify(e)}catch(e){}}},t.decrypt=async e=>{try{return n.config?.encryptionKey?await i(e,n.config.encryptionKey):JSON.parse(e)}catch(e){(0,n.showError)()&&console.log("decrypt failed",e)}}},247:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.readSecureSync=t.saveSecureSync=t.readSecure=t.saveSecure=void 0;const n=r(28),o=r(896),a=r(205),i=r(622);t.saveSecure=async({key:e,data:t})=>{try{return await(0,o.saveDB)({key:e,data:t?await(0,a.encrypt)(t):void 0,dbName:n.config.dbName,storeName:n.config.storeName})}catch(e){(0,n.showError)()&&console.log("saveSecure failed",e)}return!1},t.readSecure=async e=>{try{const t=await(0,o.readDB)({key:e,dbName:n.config.dbName,storeName:n.config.storeName});return t?await(0,a.decrypt)(t):void 0}catch(e){(0,n.showError)()&&console.log("readSecure failed",e)}},t.saveSecureSync=({key:e,data:t})=>{try{return void 0===t?localStorage.removeItem(e):localStorage.setItem(e,(0,i.encryptSync)(t)??""),!0}catch(e){(0,n.showError)()&&console.log("saveSecureSync failed",e)}return!1},t.readSecureSync=e=>{try{const t=localStorage.getItem(e);return t?(0,i.decryptSync)(t):void 0}catch(e){(0,n.showError)()&&console.log("readSecureSync failed",e)}}},421:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.readData=t.saveData=void 0;const n=r(28);t.saveData=({key:e,data:t})=>{try{void 0===t?localStorage.removeItem(e):localStorage.setItem(e,JSON.stringify(t))}catch(e){(0,n.showError)()&&console.log("saveData failed",e)}},t.readData=e=>{try{const t=localStorage.getItem(e);return t?JSON.parse(t):void 0}catch(e){(0,n.showError)()&&console.log("readData failed",e)}}},622:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.decryptSync=t.encryptSync=t.decryptDataSync=t.encryptDataSync=void 0;const n=r(28),o=r(185),a=(e,t,r)=>{try{const n=new Uint8Array(e.length);for(let o=0;o<e.length;o++)n[o]=e[o]^255&t.charCodeAt(o%t.length)^r[o%r.length];return n}catch(e){(0,n.showError)()&&console.log("xorCipher failed",e)}},i=(e,t)=>{try{const r=crypto.getRandomValues(new Uint8Array(8)),i=(new TextEncoder).encode(JSON.stringify(e)),s=a(i,t,r),c=new Uint8Array(r.length+i.length);return c.set(r),s&&c.set(s,r.length),`${n.config.localStoragePrefix}${(0,o.bytesToBase64)(c)}`}catch(t){(0,n.showError)()&&console.log("encryptDataSync failed",t);try{return JSON.stringify(e)}catch(e){}}},s=(e,t)=>{try{const r=(0,o.base64ToBytes)(e.startsWith(n.config.localStoragePrefix)?e.slice(n.config.localStoragePrefix.length):e),i=r.slice(0,8),s=a(r.slice(8),t,i);return s?JSON.parse((new TextDecoder).decode(s)):void 0}catch(e){(0,n.showError)()&&console.log("decryptDataSync failed",e)}};t.encryptDataSync=i,t.decryptDataSync=s,t.encryptSync=e=>{try{return n.config?.encryptionKeyStr?i(e,n.config.encryptionKeyStr):JSON.stringify(e)}catch(t){(0,n.showError)()&&console.log("encryptSync failed",t);try{return JSON.stringify(e)}catch(e){}}},t.decryptSync=e=>{try{return n.config?.encryptionKeyStr?s(e,n.config.encryptionKeyStr):JSON.parse(e)}catch(e){(0,n.showError)()&&console.log("decryptSync failed",e)}}},896:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.readDB=t.saveDB=t.openDB=void 0;const n=r(28),o=({dbName:e,storeName:t,version:r=1}={})=>new Promise((o,a)=>{e=e||n.config.dbName;const i=indexedDB.open(e,r);i.onupgradeneeded=()=>{t=t||n.config.storeName;const e=i.result;e.objectStoreNames.contains(t)||e.createObjectStore(t,{keyPath:"id"})},i.onsuccess=()=>o(i.result),i.onerror=()=>{(0,n.showError)()&&console.log("openDB failed",i.error),a(i.error)}});t.openDB=o,t.saveDB=async({key:e,data:t,dbName:r,storeName:a})=>{try{const i=await o({dbName:r,storeName:a});return new Promise(r=>{const o=i.transaction([a],"readwrite").objectStore(a),s=t?o.put({id:e,data:t}):o.delete(e);s.onsuccess=()=>r(!0),s.onerror=()=>{(0,n.showError)()&&console.log("saveDB error",s.error),r(!1)},i.close()})}catch(e){(0,n.showError)()&&console.log("saveSecure failed",e)}return!1},t.readDB=async({key:e,dbName:t,storeName:r})=>{try{const a=await o({dbName:t,storeName:r});return new Promise(t=>{const o=a.transaction([r],"readonly").objectStore(r).get(e);o.onsuccess=()=>t(o?.result?.data),o.onerror=()=>{(0,n.showError)()&&console.log("readDB error",o.error),t(void 0)},a.close()})}catch(e){(0,n.showError)()&&console.log("readDB failed",e)}}},915:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.readLarge=t.saveLarge=void 0;const n=r(28),o=r(896);t.saveLarge=async({key:e,data:t})=>{try{return await(0,o.saveDB)({key:e,data:t?JSON.stringify(t):void 0,dbName:n.config.dbName,storeName:n.config.storeName})}catch(e){(0,n.showError)()&&console.log("saveLarge failed",e)}return!1},t.readLarge=async e=>{try{const t=await(0,o.readDB)({key:e,dbName:n.config.dbName,storeName:n.config.storeName});return t?JSON.parse(t):void 0}catch(e){(0,n.showError)()&&console.log("readLarge failed",e)}}}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var a=t[n]={exports:{}};return e[n](a,a.exports,r),a.exports}var n={};return(()=>{var e=n;Object.defineProperty(e,"__esModule",{value:!0}),e.cryptoKey=e.decryptDataSync=e.encryptDataSync=e.decryptData=e.encryptData=e.saveSecureSync=e.readSecureSync=e.saveSecure=e.readSecure=e.saveLarge=e.readLarge=e.saveData=e.readData=e.migrateSecure=e.config=e.configureStorageSync=e.configureStorage=void 0;const t=r(28);Object.defineProperty(e,"configureStorage",{enumerable:!0,get:function(){return t.configureStorage}}),Object.defineProperty(e,"configureStorageSync",{enumerable:!0,get:function(){return t.configureStorageSync}}),Object.defineProperty(e,"config",{enumerable:!0,get:function(){return t.config}}),Object.defineProperty(e,"migrateSecure",{enumerable:!0,get:function(){return t.migrateSecure}});const o=r(421);Object.defineProperty(e,"readData",{enumerable:!0,get:function(){return o.readData}}),Object.defineProperty(e,"saveData",{enumerable:!0,get:function(){return o.saveData}});const a=r(915);Object.defineProperty(e,"readLarge",{enumerable:!0,get:function(){return a.readLarge}}),Object.defineProperty(e,"saveLarge",{enumerable:!0,get:function(){return a.saveLarge}});const i=r(247);Object.defineProperty(e,"readSecure",{enumerable:!0,get:function(){return i.readSecure}}),Object.defineProperty(e,"saveSecure",{enumerable:!0,get:function(){return i.saveSecure}}),Object.defineProperty(e,"readSecureSync",{enumerable:!0,get:function(){return i.readSecureSync}}),Object.defineProperty(e,"saveSecureSync",{enumerable:!0,get:function(){return i.saveSecureSync}});const s=r(205);Object.defineProperty(e,"cryptoKey",{enumerable:!0,get:function(){return s.cryptoKey}}),Object.defineProperty(e,"decryptData",{enumerable:!0,get:function(){return s.decryptData}}),Object.defineProperty(e,"encryptData",{enumerable:!0,get:function(){return s.encryptData}});const c=r(622);Object.defineProperty(e,"encryptDataSync",{enumerable:!0,get:function(){return c.encryptDataSync}}),Object.defineProperty(e,"decryptDataSync",{enumerable:!0,get:function(){return c.decryptDataSync}})})(),n})()},155(e){e.exports=(()=>{var e={125:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.addZ=t.tN=t.monNm=t.tmUTC=t.tmAP=t.moYrDt=t.shortDt=t.fullLong=t.fullDate=t.fullDt=t.invDt=t.dayRes=t.timeStandard=t.dateStandard=t.seoDt=t.thisYear=t.oneMon=t.oneMin=t.oneHr=t.oneDay=t.oneSec=void 0;const r=()=>Date.now(),n=["January","February","March","April","May","June","July","August","September","October","November","December"],o=["JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"],a=["st","nd","rd","th"],i=e=>0==+e?"00":+e<10&&+e>=1?`0${e}`:`${e}`,s=e=>{const t=new Date(e);return`${t.getUTCFullYear()}-${i(t.getUTCMonth()+1)}-${i(t.getUTCDate())}`},c=e=>i(e.getUTCHours())+`:${i(e.getUTCMinutes())}`+`:${i(e.getUTCSeconds())}`;t.tN=r,t.monNm=n,t.dayRes=90,t.oneSec=1e3,t.oneMin=6e4,t.oneHr=36e5,t.oneDay=864e5,t.oneMon=27e8,t.addZ=i,t.tmUTC=e=>{const t=new Date(e);return i(t.getUTCHours())+`:${i(t.getUTCMinutes())} UTC`},t.tmAP=e=>{const t=new Date(e),r=t.getHours();return i(r>12?r-12:r)+`:${i(t.getMinutes())}`+(r>=12?"pm":"am")},t.shortDt=e=>{const t=new Date(e);return`${t.getDate()} ${o[t.getMonth()]}`},t.moYrDt=e=>{const t=new Date(e);return`${o[t.getMonth()]} ${t.getFullYear()}`},t.fullDt=e=>{const t=new Date(e);return`${t.getDate()} ${o[t.getMonth()]} ${t.getFullYear()}`},t.fullDate=e=>{const t=new Date(e);return`${t.getDate()} ${n[t.getMonth()]} ${t.getFullYear()}`},t.fullLong=e=>`${(e=>{const t=new Date(e),r=t.getDate();return r+a[r<5?r-1:r>4&&r<21?3:r>20&&r<25?r-21:r>24&&r<31?3:0]+` of ${n[t.getMonth()]}`})(e)} ${new Date(e).getFullYear()}`,t.thisYear=e=>(e?new Date(e):new Date)?.getUTCFullYear(),t.dateStandard=s,t.timeStandard=c,t.seoDt=e=>{!e&&(e=r());const t=new Date(e);return`${s(t)}T${c(t)}Z`},t.invDt=e=>{const t=new Date(e);return`${t.getUTCFullYear()}`.split("20")[1]+i(t.getUTCMonth()+1)+i(t.getUTCDate())+`${e}`.slice(10)}},240:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.idRandLong=t.idRandShort=t.idShuffle=void 0;const r=["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","@",".","_","0","1","2","3","4","5","6","7","8","9"],n=({data:e,password:t})=>{try{const n=(e,t)=>r.includes(e.toLowerCase())?r[(r.indexOf(e.toLowerCase())+Math.pow(t,3))%r.length]:e;return[...e].map(e=>n(e,Number(t))).join("")}catch{return""}},o=async({data:e,password:t})=>{if(!e||!t)return"";try{crypto.subtle;const r=new TextEncoder,n=r.encode(e),o=r.encode(t),a=await crypto.subtle.digest("SHA-256",o),i=new Uint8Array(a),s=i.slice(0,32),c=i.slice(0,12),l=await crypto.subtle.importKey("raw",s,{name:"AES-GCM"},!1,["encrypt"]),u=await crypto.subtle.encrypt({name:"AES-GCM",iv:c},l,n);return btoa(String.fromCharCode(...new Uint8Array(u))).replace(/\+/g,"a").replace(/\//g,"b").replace(/=/g,"c").toLowerCase()}catch{return""}};t.idShuffle=async({data:e,password:t})=>4==t?.length?n({data:e,password:t}):await o({data:e,password:t}),t.idRandShort=(e=10)=>{try{return crypto.randomUUID()?.replaceAll("-","")?.slice(0,e)}catch(e){return console.log("idRandShort failed",e),""}},t.idRandLong=(e=10)=>{try{const t="abcdefghijklmnopqrstuvwxyz",r=new Uint8Array(e);return crypto.getRandomValues(r),Array.from(r).map(e=>t[e%26]).join("")}catch(e){return console.log("idRandLong failed",e),""}}},246:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.cacheCheck=t.delayCode=void 0;const n=r(125);t.delayCode=async(e=0)=>await new Promise(t=>setTimeout(t,e)),t.cacheCheck=({analysisCacheLimit:e,lastUpdated:t,forceRefresh:r})=>{const o=Date.now();if(t&&(!r&&t>o-e||r&&t>o-n.oneDay))return!0}},792:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.isEven=t.pNum=t.sharpeRatio=t.priceVariations=t.nTxtAr=t.zNum=t.addCom=t.adjNum=t.rNum=void 0;const r=[1,.1,.01,.001,1e-4,1e-5,1e-6,1e-7,1e-8,1e-9,1e-10,1e-11,1e-12,1e-13,1e-14,1e-15,1e-16,1e-17,1e-18,1e-19],n=(e,t=6)=>{const n=+e,o=n?Math.abs(n):0,a=o>1&&t?t-`${Math.round(o)}`.length:0;return n?(n<0?-1:1)*(Number.isInteger(o)||o<1e-16?o:o>1e5?Math.round(o):o>1?Number(o.toFixed(a<0?0:a)):((e,t)=>{let n=0;for(const o of r){if(o<e)return Number(e.toFixed(t+n-1));n++}return e})(o,t)):e},o=(e,t)=>{const r=(n(e,t)+"").split(".");return r[0]=r[0].replace(/\B(?=(\d{3})+(?!\d))/g,","),r.join(".")},a=(e,t=3)=>{const r=Number(e);if(!e||!r)return e+"";const a=Math.abs(r);return(r<0?"-":"")+(a>1e9?o(a/1e9,t)+"b":a>1e6?o(a/1e6,t)+"m":a<1e-6&&a>1e-16?(1+n(a,t)+"").replace(/1./g,"0."):o(a,t))};t.nTxtAr=["zero","one","two","three","four","five","six","seven","eight","nine","ten"],t.rNum=n,t.addCom=o,t.adjNum=a,t.zNum=e=>{const t=Number(e);let r=t?Math.abs(t):0,n=1e10;for(;n>1;)r>n&&(r=Math.round(r/(n/10))*(n/10)),n/=10;return t?(t<0?"-":"")+a(r,2):e},t.pNum=e=>+e||0==+e?Math.round(1e6*+e)/1e6:null,t.priceVariations=e=>{try{let t=0;const r=[...e].sort((e,t)=>e[0]-t[0]),n=e.reduce((e,[,t])=>e+t,0),o=r.find(([,e])=>(t+=e,t>=n/2))[0];return e.filter(([e])=>Math.abs(e-o)/o<.05).map(([e])=>e)}catch{return[]}},t.sharpeRatio=({assetPrices:e,minExpectedReturn:t=.05})=>{if(!e?.length||e?.length<2)return 0;const r=e.slice(1).map((t,r)=>(t-e[r])/e[r]),n=r.reduce((e,t)=>e+t,0)/r.length,o=Math.sqrt(r.reduce((e,t)=>e+Math.pow(t-n,2),0)/r.length);return(n-t)/o},t.isEven=e=>e%2==0},794:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.restoreObj=t.restoreObjStr=t.storeObj=t.storeObjStr=t.objNestValueCount=t.objLen=t.objSortSimple=t.objSort=void 0;const n=r(125),o=e=>{try{return Object.keys(e||{})?.length||0}catch(e){return console.log(e),0}},a=e=>{try{return e?.replace(/"/g,"'")}catch(e){return console.log((0,n.tN)(),"storeObjStr failed",e),""}},i=e=>{try{return e?.toString()?.replace(/'/g,'"')}catch(e){console.log((0,n.tN)(),"restoreObjStr failed",e)}};t.objLen=o,t.objNestValueCount=e=>{let t=0;if(o(e))for(const r in e)t+=o(e[r])?1:0;return t},t.objSort=(e={},t,r=-1)=>Object.fromEntries(Object.entries(e).sort(([,e],[,n])=>null===e[t]||void 0===e[t]?1:null===n[t]||void 0===n[t]?-1:e[t]>n[t]?1*r:-1*r)),t.objSortSimple=(e={},t=-1)=>Object.fromEntries(Object.entries(e).sort(([,e],[,r])=>null==e?1:null==r?-1:e>r?1*t:-1*t)),t.storeObjStr=a,t.storeObj=e=>{try{return a(JSON.stringify(e))}catch(e){return console.log((0,n.tN)(),"storeObj failed",e),""}},t.restoreObjStr=i,t.restoreObj=e=>{try{if(!e)return;const t=i(e);return t?JSON.parse(t):void 0}catch(e){console.log((0,n.tN)(),"restoreObj failed",e)}}},830:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.phaseDifference=t.compareArrays=t.squeezeArray=t.forecastNextTotal=t.forecastNext=t.getMax=t.getMean=t.getSum=t.maxVl=t.minVl=t.sumArr=void 0;const r=e=>{try{return e?.length?e.reduce((e,t)=>e+t):0}catch(e){return console.log("sumArr failed",e),0}},n=e=>{try{return e?.length?e.reduce((e,t)=>e+t,0):0}catch(e){return console.log("getSum failed",e),0}},o=e=>{try{return e?.length?n(e)/e.length:0}catch(e){return console.log("getMean failed",e),0}},a=e=>{try{return e?.length?Math.max(...e):0}catch(e){return console.log("getMax failed",e),0}},i=e=>{try{if(!e?.length)return 0;const t=[...e].sort((e,t)=>e-t),r=Math.floor(t.length/2);return t.length%2?t[r]:(t[r-1]+t[r])/2}catch(e){return console.log("median failed",e),0}},s=({currentPeriod:e,steps:t=1})=>{try{const r=(Array.isArray(e)?e:[]).filter(Number.isFinite);if(!r.length||t<=0)return[];if(r.length<2){const e=Math.max(0,o(r));return Array.from({length:t},()=>e)}const n=r.length,{slope:s,intercept:c}=(e=>{try{const t=e.length,r=[];for(let n=0;n<t-1;n++)for(let o=n+1;o<t;o++)r.push((e[o]-e[n])/(o-n));const n=i(r);return{slope:n,intercept:i(e.map((e,t)=>e-n*t))}}catch(e){return console.log("theilSen failed",e),{slope:0,intercept:0}}})(r),l=c+s*(n-1),u=a(r),d=u>0?3*u:1/0;return Array.from({length:t},(e,t)=>{const r=t+1,o=l+s*n*Math.log1p(r/n);return Math.max(0,Math.min(o,d))})}catch(e){return console.log("forecastNext failed",e),[]}};t.sumArr=r,t.maxVl=(e,t)=>{let r=0;for(let n=0;n<e.length;n++){const o=e[n];o[t]>r&&(r=o[t])}return r},t.minVl=(e,t)=>{let r=0;for(let n=0;n<e.length;n++){const o=e[n];o[t]<r&&(r=o[t])}return r},t.getSum=n,t.getMean=o,t.getMax=a,t.forecastNext=s,t.forecastNextTotal=e=>{try{const t=s({currentPeriod:e,steps:e?.length});return n(t)}catch(e){return console.log("forecastNextTotal failed",e),0}},t.squeezeArray=({arr:e,targetLength:t})=>{try{if(!e||0===e.length||t<=0)throw new Error("Invalid input");const n=Math.ceil(e.length/t);return Array.from({length:t},(t,o)=>{const a=o*n,i=Math.min(a+n,e.length),s=e.slice(a,i);return r(s)}).slice(0,t)}catch(e){return console.log("squeezeArray failed",e),[]}},t.compareArrays=({arrays:e})=>{try{const t=[...e],n=Math.min(...t.map(e=>e.length));for(let e=0;e<t.length;e++)t.splice(n);const o=t.map(e=>r(e)),a=[],i=Math.min(...o),s=o.indexOf(i),c=i/Math.max(...o);for(let e=0;e<t.length;e++){const r=t[e];if(a[e]=[],e==s)a[e]=r;else for(let t=0;t<r.length;t++)a[e].push(c*r[t])}return a}catch(t){return console.log("compareArrays failed",t),e}},t.phaseDifference=({array1:e,array2:t})=>{try{let r=e.length,n=e.reduce((e,t)=>e+t)/r,o=t.reduce((e,t)=>e+t)/r,a=e.map(e=>e-n),i=t.map(e=>e-o),s=Math.floor(r/2),c=-1/0,l=0;for(let e=-s;e<=s;e++){let t=0,n=0,o=0,s=0;for(let c=0;c<r;c++){let l=c+e;l>=0&&l<r&&(t+=a[c]*i[l],n+=a[c]*a[c],o+=i[l]*i[l],s++)}if(n>0&&o>0&&s>=.8*r){let r=t/Math.sqrt(n*o);r>c&&(c=r,l=e)}}return l}catch(e){return console.log("phaseDifference failed",e),0}}}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var a=t[n]={exports:{}};return e[n](a,a.exports,r),a.exports}var n={};return(()=>{var e=n;Object.defineProperty(e,"__esModule",{value:!0}),e.idShuffle=e.isEven=e.pNum=e.nTxtAr=e.zNum=e.addCom=e.adjNum=e.rNum=e.sharpeRatio=e.priceVariations=e.timeStandard=e.dateStandard=e.addZ=e.tN=e.monNm=e.tmUTC=e.tmAP=e.moYrDt=e.shortDt=e.fullLong=e.fullDate=e.fullDt=e.invDt=e.dayRes=e.thisYear=e.seoDt=e.oneMon=e.oneMin=e.oneHr=e.oneDay=e.oneSec=e.restoreObj=e.restoreObjStr=e.storeObj=e.storeObjStr=e.objSortSimple=e.objSort=e.objNestValueCount=e.objLen=e.phaseDifference=e.compareArrays=e.squeezeArray=e.forecastNextTotal=e.forecastNext=e.getMax=e.getMean=e.getSum=e.maxVl=e.minVl=e.sumArr=void 0,e.cacheCheck=e.delayCode=e.idRandLong=e.idRandShort=void 0;const t=r(246);Object.defineProperty(e,"cacheCheck",{enumerable:!0,get:function(){return t.cacheCheck}}),Object.defineProperty(e,"delayCode",{enumerable:!0,get:function(){return t.delayCode}});const o=r(830);Object.defineProperty(e,"sumArr",{enumerable:!0,get:function(){return o.sumArr}}),Object.defineProperty(e,"minVl",{enumerable:!0,get:function(){return o.minVl}}),Object.defineProperty(e,"maxVl",{enumerable:!0,get:function(){return o.maxVl}}),Object.defineProperty(e,"getMax",{enumerable:!0,get:function(){return o.getMax}}),Object.defineProperty(e,"getMean",{enumerable:!0,get:function(){return o.getMean}}),Object.defineProperty(e,"getSum",{enumerable:!0,get:function(){return o.getSum}}),Object.defineProperty(e,"forecastNext",{enumerable:!0,get:function(){return o.forecastNext}}),Object.defineProperty(e,"forecastNextTotal",{enumerable:!0,get:function(){return o.forecastNextTotal}}),Object.defineProperty(e,"squeezeArray",{enumerable:!0,get:function(){return o.squeezeArray}}),Object.defineProperty(e,"compareArrays",{enumerable:!0,get:function(){return o.compareArrays}}),Object.defineProperty(e,"phaseDifference",{enumerable:!0,get:function(){return o.phaseDifference}});const a=r(240);Object.defineProperty(e,"idRandLong",{enumerable:!0,get:function(){return a.idRandLong}}),Object.defineProperty(e,"idRandShort",{enumerable:!0,get:function(){return a.idRandShort}}),Object.defineProperty(e,"idShuffle",{enumerable:!0,get:function(){return a.idShuffle}});const i=r(792);Object.defineProperty(e,"addCom",{enumerable:!0,get:function(){return i.addCom}}),Object.defineProperty(e,"adjNum",{enumerable:!0,get:function(){return i.adjNum}}),Object.defineProperty(e,"priceVariations",{enumerable:!0,get:function(){return i.priceVariations}}),Object.defineProperty(e,"nTxtAr",{enumerable:!0,get:function(){return i.nTxtAr}}),Object.defineProperty(e,"rNum",{enumerable:!0,get:function(){return i.rNum}}),Object.defineProperty(e,"zNum",{enumerable:!0,get:function(){return i.zNum}}),Object.defineProperty(e,"sharpeRatio",{enumerable:!0,get:function(){return i.sharpeRatio}}),Object.defineProperty(e,"pNum",{enumerable:!0,get:function(){return i.pNum}}),Object.defineProperty(e,"isEven",{enumerable:!0,get:function(){return i.isEven}});const s=r(125);Object.defineProperty(e,"oneSec",{enumerable:!0,get:function(){return s.oneSec}}),Object.defineProperty(e,"oneDay",{enumerable:!0,get:function(){return s.oneDay}}),Object.defineProperty(e,"oneHr",{enumerable:!0,get:function(){return s.oneHr}}),Object.defineProperty(e,"oneMin",{enumerable:!0,get:function(){return s.oneMin}}),Object.defineProperty(e,"oneMon",{enumerable:!0,get:function(){return s.oneMon}}),Object.defineProperty(e,"seoDt",{enumerable:!0,get:function(){return s.seoDt}}),Object.defineProperty(e,"dayRes",{enumerable:!0,get:function(){return s.dayRes}}),Object.defineProperty(e,"invDt",{enumerable:!0,get:function(){return s.invDt}}),Object.defineProperty(e,"fullDt",{enumerable:!0,get:function(){return s.fullDt}}),Object.defineProperty(e,"fullDate",{enumerable:!0,get:function(){return s.fullDate}}),Object.defineProperty(e,"fullLong",{enumerable:!0,get:function(){return s.fullLong}}),Object.defineProperty(e,"shortDt",{enumerable:!0,get:function(){return s.shortDt}}),Object.defineProperty(e,"moYrDt",{enumerable:!0,get:function(){return s.moYrDt}}),Object.defineProperty(e,"tmAP",{enumerable:!0,get:function(){return s.tmAP}}),Object.defineProperty(e,"tmUTC",{enumerable:!0,get:function(){return s.tmUTC}}),Object.defineProperty(e,"monNm",{enumerable:!0,get:function(){return s.monNm}}),Object.defineProperty(e,"tN",{enumerable:!0,get:function(){return s.tN}}),Object.defineProperty(e,"addZ",{enumerable:!0,get:function(){return s.addZ}}),Object.defineProperty(e,"timeStandard",{enumerable:!0,get:function(){return s.timeStandard}}),Object.defineProperty(e,"dateStandard",{enumerable:!0,get:function(){return s.dateStandard}}),Object.defineProperty(e,"thisYear",{enumerable:!0,get:function(){return s.thisYear}});const c=r(794);Object.defineProperty(e,"objSort",{enumerable:!0,get:function(){return c.objSort}}),Object.defineProperty(e,"objLen",{enumerable:!0,get:function(){return c.objLen}}),Object.defineProperty(e,"objNestValueCount",{enumerable:!0,get:function(){return c.objNestValueCount}}),Object.defineProperty(e,"restoreObj",{enumerable:!0,get:function(){return c.restoreObj}}),Object.defineProperty(e,"restoreObjStr",{enumerable:!0,get:function(){return c.restoreObjStr}}),Object.defineProperty(e,"storeObj",{enumerable:!0,get:function(){return c.storeObj}}),Object.defineProperty(e,"storeObjStr",{enumerable:!0,get:function(){return c.storeObjStr}}),Object.defineProperty(e,"objSortSimple",{enumerable:!0,get:function(){return c.objSortSimple}})})(),n})()}};const t={};function r(n){const o=t[n];if(void 0!==o)return o.exports;const a=t[n]={exports:{}};return e[n].call(a.exports,a,a.exports,r),a.exports}var n,o,a,i,s,c,l,u,d,g,m,p;let f;r.m=e,r.d=(e,t)=>{for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.f={},r.e=e=>{const t=[];return r.f.j(e,t),Promise.all(t)},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{const e={520:()=>import("./engine-litert.min.mjs"),924:()=>import("./engine-wllama.min.mjs")},t={792:0},n=e=>{let{__webpack_esm_ids__:n,__webpack_esm_modules__:o,__webpack_esm_runtime__:a}=e;var i,s,c=0;for(i in o)r.o(o,i)&&(r.m[i]=o[i]);for(a&&a(r);c<n.length;c++)s=n[c],r.o(t,s)&&t[s]&&t[s][0](),t[s]=0};r.f.j=(o,a)=>{let i=r.o(t,o)?t[o]:void 0;if(0!==i)if(i)a.push(i[1]);else{let r=e[o]().then(n,e=>{throw 0!==t[o]&&(t[o]=void 0),e});r=Promise.race([r,new Promise(e=>i=t[o]=[e])]),a.push(i[1]=r)}}})(),function(e){e.system="system",e.user="user",e.assistant="assistant"}(n||(n={})),function(e){e[e.online=0]="online",e[e.away=1]="away",e[e.offline=2]="offline"}(o||(o={})),function(e){e[e.idle=0]="idle",e[e.downloading=1]="downloading",e[e.ready=2]="ready",e[e.error=3]="error",e[e.unsupported=4]="unsupported"}(a||(a={})),function(e){e.cpu="cpu",e.gpu="gpu",e.none="none"}(i||(i={})),function(e){e.download="download",e.load="load"}(s||(s={})),function(e){e.analyze="analyze",e.describe="describe",e.translate="translate",e.tags="tags",e.translateTags="translateTags"}(c||(c={})),function(e){e.translate="translate",e.tags="tags",e.translateTags="translateTags"}(l||(l={})),function(e){e.model="model",e.limits="limits",e.logging="logging",e.onStatus="onStatus"}(u||(u={})),function(e){e.quota="QuotaExceededError",e.notAllowed="NotAllowedError",e.notSupported="NotSupportedError",e.invalidState="InvalidStateError",e.typeMismatch="TypeMismatchError",e.security="SecurityError"}(d||(d={})),function(e){e.qwen3_vl_2b="qwen3-vl-2b",e.qwen3_vl_2b_instruct="qwen3-vl-2b-instruct",e.qwen3_vl_2b_instruct_q3="qwen3-vl-2b-instruct-q3",e.gemma4_e2b_limited="gemma4-e2b-limited"}(g||(g={})),function(e){e.websearch="websearch",e.calculate="calculate",e.currency="currency"}(m||(m={})),function(e){e.wikipedia="wikipedia",e.duckduckgo="duckduckgo"}(p||(p={}));const y=[{id:g.qwen3_vl_2b,reasoning:!0,cpu:{repo:"Qwen/Qwen3-VL-2B-Thinking-GGUF",file:"Qwen3VL-2B-Thinking-Q4_K_M.gguf",mmproj:{file:"mmproj-Qwen3VL-2B-Thinking-Q8_0.gguf"}}},{id:g.qwen3_vl_2b_instruct,reasoning:!1,cpu:{repo:"unsloth/Qwen3-VL-2B-Instruct-GGUF",file:"Qwen3-VL-2B-Instruct-Q4_K_M.gguf",mmproj:{repo:"Qwen/Qwen3-VL-2B-Instruct-GGUF",file:"mmproj-Qwen3VL-2B-Instruct-Q8_0.gguf"}}},{id:g.qwen3_vl_2b_instruct_q3,reasoning:!1,cpu:{repo:"unsloth/Qwen3-VL-2B-Instruct-GGUF",file:"Qwen3-VL-2B-Instruct-Q3_K_M.gguf",mmproj:{repo:"Qwen/Qwen3-VL-2B-Instruct-GGUF",file:"mmproj-Qwen3VL-2B-Instruct-Q8_0.gguf"}}},{id:g.gemma4_e2b_limited,reasoning:!0,litert:{repo:"litert-community/gemma-4-E2B-it-litert-lm",file:"gemma-4-E2B-it-gpu.litertlm",vision:!1,audio:!1}}],h=e=>{const t=e??("undefined"==typeof navigator?void 0:navigator);if(!t)return!1;if("boolean"==typeof t.userAgentData?.mobile)return t.userAgentData.mobile;const r=t.userAgent||"";return/Android|iPhone|iPad|iPod|Mobile/i.test(r)||/Macintosh/.test(r)&&t.maxTouchPoints>1},w=e=>e.litert?h()?16384:32768:h()?4096:8192,b=e=>e?y.find(t=>t.id==e):void 0,v=async()=>{const e="undefined"==typeof navigator?void 0:navigator.gpu;if(!e)return!1;let t;try{return!!await Promise.race([e.requestAdapter({powerPreference:"high-performance"}),new Promise(e=>{t=setTimeout(()=>e(void 0),1500)})])}catch{return!1}finally{t&&clearTimeout(t)}},S=async e=>b(e??await(async()=>(f||(f=(async()=>await v()?g.gemma4_e2b_limited:g.qwen3_vl_2b)()),await f))()),x=e=>!!e.cpu?.mmproj||!0===e.litert?.vision,M=e=>!!e.cpu?.mmproj?.audio||!0===e.litert?.audio;var j=r(155);const k=new URL("./../assets/wllama/wllama.wasm",import.meta.url).href,P=new URL("./../assets/wllama/compat/wllama.wasm",import.meta.url).href,D=new URL("./../assets/wllama/compat/wllama.js",import.meta.url).href,T=new URL("./../assets/litert/litertlm_wasm_internal.js",import.meta.url).href,N=(new URL("./../assets/litert/litertlm_wasm_internal.wasm",import.meta.url).href,{width:384,height:384}),_=async e=>{if(!e.startsWith("data:"))return await(await fetch(e)).arrayBuffer();const t=e.indexOf(","),r=t>=0?e.slice(0,t):"";if(t<0)throw new Error("Invalid image data");if(!r.includes(";base64"))return await(await fetch(e)).arrayBuffer();const n=atob(e.slice(t+1)),o=new Uint8Array(n.length);for(let e=0;e<n.length;e++)o[e]=n.charCodeAt(e);return o.buffer},O=async(e,t,r=128)=>{if(!e||"function"!=typeof fetch||"function"!=typeof createImageBitmap)return e;try{const n=await fetch(e),o=await createImageBitmap(await n.blob()),a=t??((e,t,r=128)=>{let n=32,o=32,a=1/0,i=1/0;const s=e/Math.max(1,t);for(let e=1;e<=r;e++){const t=Math.ceil(r/e),c=Math.floor((r+8)/e);for(let r=t;r<=c;r++){const t=r*e,c=Math.abs(r/e-s);(c<a-1e-9||Math.abs(c-a)<=1e-9&&t<i)&&(n=32*r,o=32*e,a=c,i=t)}}return{width:n,height:o}})(o.width,o.height,r),i=o.width/Math.max(1,o.height),s=a.width/a.height,c=Math.min(o.width,i>s?o.height*s:o.width),l=Math.min(o.height,i>s?o.height:o.width/s),u=(o.width-c)/2,d=(o.height-l)/2,g=((e,t)=>{if("undefined"!=typeof OffscreenCanvas)return new OffscreenCanvas(e,t);if("undefined"==typeof document)return;const r=document.createElement("canvas");return r.width=e,r.height=t,r})(a.width,a.height),m=g?g.getContext("2d"):null;if(!g||!m||o.width<1||o.height<1)return o.close(),e;if(m.drawImage(o,u,d,c,l,0,0,a.width,a.height),o.close(),(e=>"undefined"!=typeof OffscreenCanvas&&e instanceof OffscreenCanvas)(g)){const t=await g.convertToBlob({type:"image/jpeg",quality:.85});return await(e=>new Promise(t=>{if("undefined"==typeof FileReader)return void t("");const r=new FileReader;r.onerror=()=>t(""),r.onload=()=>t(`${r.result}`),r.readAsDataURL(e)}))(t)||e}return g.toDataURL("image/jpeg",.85)}catch{return e}},E={maxReplyTokens:250,maxThinkingTokens:128,maxReasoningTokens:320,maxImages:2,imageTokens:128,maxAudio:1,maxContentLength:1e3,promptCharBudget:1e4,maxThreads:32,gpuShare:1},L=(e,t)=>{let r=0;for(const n of e)if("string"!=typeof n.content)for(const e of n.content)r+="text"==e.type?e.text.length/4:t;else r+=n.content.length/4;return Math.round(r)},C=({model:e,limits:t,messages:r,reasoning:n})=>{const o=w(e),a=((e,t,r)=>{const n=[...e];for(;L(n,r)>t&&!(n.filter(e=>"user"==e.role).length<2);){const e="system"==n[0]?.role?1:2;n.splice(e,"assistant"==n[e+1]?.role?2:1)}return n})(r,o-64-128,t.imageTokens),i=o-L(a,t.imageTokens)-128;return{messages:a,maxTokens:Math.max(64,Math.min(n?t.maxReasoningTokens:t.maxReplyTokens,i))}},A=(e,t,r)=>"number"==typeof e&&Number.isFinite(e)&&e>=r?Math.floor(e):t,R=(e={},t=!1)=>{const r=E;return{maxReplyTokens:A(e.maxReplyTokens,r.maxReplyTokens,1),maxThinkingTokens:A(e.maxThinkingTokens,r.maxThinkingTokens,1),maxReasoningTokens:A(e.maxReasoningTokens,t?1200:r.maxReasoningTokens,1),maxImages:A(e.maxImages,r.maxImages,0),imageTokens:A(e.imageTokens,r.imageTokens,1),maxAudio:A(e.maxAudio,r.maxAudio,0),maxContentLength:A(e.maxContentLength,r.maxContentLength,1),promptCharBudget:A(e.promptCharBudget,r.promptCharBudget,1),maxThreads:A(e.maxThreads,r.maxThreads,1),gpuShare:"number"==typeof e.gpuShare&&Number.isFinite(e.gpuShare)&&e.gpuShare>0?Math.min(1,Math.max(.05,e.gpuShare)):r.gpuShare}},$=(e,t,r=.7,n)=>({stream:!0,temperature:r,max_tokens:n??(t?e.maxReasoningTokens:e.maxReplyTokens)}),U=(e,t)=>`https://huggingface.co/${e}/resolve/main/${t}`,q=e=>Number(e.headers.get("content-length"))||0,B=(e,t)=>e.some(e=>Array.isArray(e.content)&&e.content.some(e=>e.type==t)),z=e=>B(e,"image"),I=e=>B(e,"audio"),K=["<|channel>thought\n","<|channel>thought"],F=["<channel|>"],W=(e,t,r)=>t.length||r.length?[...e?[{type:"text",text:e}]:[],...t.map(e=>({type:"image",url:e})),...r.map(e=>({type:"audio",url:e}))]:e,V=e=>"string"==typeof e?e?[{type:"text",text:e}]:[]:e,G=(e,t)=>{if("string"==typeof e&&"string"==typeof t)return`${e}\n${t}`;const r=[];for(const n of[...V(e),{type:"text",text:"\n"},...V(t)]){const e=r[r.length-1];"text"==n.type&&"text"==e?.type?e.text+=n.text:r.push(n)}return r},J=h()?3e6:3e5,Y=Math.max(J,84e4);class H extends Error{}const Q=async(e,t,r)=>{let n;try{return await Promise.race([e,new Promise((e,o)=>{n=setTimeout(()=>o(new H(r)),t)})])}finally{n&&clearTimeout(n)}},Z=e=>{try{Promise.resolve(e.next?.()).catch(()=>{}).finally(()=>{try{Promise.resolve(e.return?.()).catch(()=>{})}catch{}})}catch{}},X=async({model:e,logging:t,onReason:r,onText:n,onSpeed:o,onPromptSpeed:a,promptTokens:i,start:s,stopped:c,firstTimeoutMs:l=J,idleTimeoutMs:u=3e4,onStall:d})=>{let g,m="",p="",f="",y=!1,h=!1,w=!1,b=0,v=0,S=0,x=0,M=0,k=0,P=0;const D=e=>{!Number.isFinite(e)||e<=0||(b=(0,j.rNum)(e),a?.(b))},T=()=>{if(y||w||!i)return;const e=performance.now()-M;e>0&&D(1e3*i/e)},N=()=>{null!=g&&(clearInterval(g),g=void 0)},_=e=>{if(!e)return;const t=performance.now(),r=e.n_prompt_tokens_processed??e.processed;if("number"!=typeof r||r<=0)return;w=!0,N();let n=0;n="number"==typeof e.time_ms&&e.time_ms>0?1e3*r/e.time_ms:v?1e3*(r-S)/Math.max(1,t-v):1e3*r/Math.max(1,t-M),t-x<500||(x=t,v=t,S=r,D(n))};a&&i&&(g=setInterval(T,500));const O=((e,t)=>{let r="",n=!1;const o=(e,t)=>{let r=-1,n="";for(const o of t){const t=e.indexOf(o);t>=0&&(r<0||t<r)&&(r=t,n=o)}return{at:r,tag:n}},a=(e,t)=>{let r="";for(const n of t)for(let t=Math.min(e.length,n.length-1);t>r.length;t--)if(e.endsWith(n.slice(0,t))){r=e.slice(e.length-t);break}return r};return{feed:i=>{let s=r+i;for(r="";s;){if(n){const{at:t,tag:i}=o(s,F);if(t>=0){t&&e(s.slice(0,t)),s=s.slice(t+i.length),n=!1;continue}const c=a(s,F);e(s.slice(0,s.length-c.length)),r=c;break}{const{at:e,tag:i}=o(s,K);if(e>=0){e&&t(s.slice(0,e)),s=s.slice(e+i.length),s.startsWith("\n")&&(s=s.slice(1)),n=!0;continue}const c=a(s,K);t(s.slice(0,s.length-c.length)),r=c;break}}},flush:()=>{r&&(n?e(r):t(r),r="")}}})(e=>{p+=e,r(e)},e=>{m+=e,n(e)});try{M=performance.now();const e=s();Promise.resolve(e).catch(()=>{});const n=(await Q(e,l,"Model did not start"))[Symbol.asyncIterator]();for(;;){if(c()){Z(n);break}let e;try{const t=n.next();Promise.resolve(t).catch(()=>{}),e=await Q(t,y?u:l,y?"Model stopped responding":"Model did not reply")}catch(e){if(e instanceof H&&(m||p)){d?.(),Z(n),t&&console.log("Local chat stalled",e);break}throw e}if(e.done)break;const a=e.value,i=a?.choices?.[0],s=i?.delta,g="string"==typeof s?.reasoning_content?s.reasoning_content:"string"==typeof s?.reasoning?s.reasoning:"",w=!!g||!!s?.content||!!i?.finish_reason,v=a?.timings?.prompt_per_second;if(w){if(y||(_(a?.prompt_progress),b||T(),y=!0,N()),!h&&"number"==typeof v&&Number.isFinite(v)&&v>0&&(h=!0,D(v)),i?.finish_reason&&(f=i.finish_reason),g&&(p+=g,r(g)),s?.content&&O.feed(s.content),g||s?.content){const e=performance.now();k||(P=e),k+=1,k>1&&e>P&&o?.((0,j.rNum)(1e3*k/(e-P)))}}else _(a?.prompt_progress),!h&&"number"==typeof v&&Number.isFinite(v)&&v>0&&(h=!0,D(v),N())}O.flush()}catch(e){if(t&&console.log("Local chat failed",e),e instanceof H&&!c())throw e}finally{N()}const E=c()?void 0:m||void 0;return t&&(console.log("Local chat reply",e.id,E?"****":""),console.log("Local chat finish",e.id,f||"none",m.length,p.length)),E},ee=async({model:e,params:t,start:r,stopped:o,onStall:a})=>{const i=await(async(e,t,r=128)=>{const n=[];for(const o of e){if("string"==typeof o.content){n.push(o);continue}const e=[];for(const n of o.content)e.push("image"==n.type?{type:"image",url:await O(n.url,t,r)}:n);n.push({role:"user",content:e})}return n})(((e,t=E)=>{let r=0,o=t.maxImages,a=t.maxAudio;const i=t.maxContentLength,s=e.filter(e=>"string"==typeof e.content&&!!e.content.trim()||!(e.role!=n.user||!e.images?.length&&!e.audio?.length)),c=[],l=[];for(let e=s.length-1;e>=0;e--){const u=s[e],d=("string"==typeof u.content?u.content:"").slice(0,i),g=u.role==n.user?(u.images||[]).filter(e=>"string"==typeof e&&!!e).slice(0,Math.max(0,o)):[],m=u.role==n.user?(u.audio||[]).filter(e=>"string"==typeof e&&!!e).slice(0,Math.max(0,a)):[];if(d||g.length||m.length){if(d&&r+d.length>t.promptCharBudget)break;r+=d.length,o-=g.length,a-=m.length,u.role==n.system?c.unshift(d):u.role==n.assistant?l.unshift({role:"assistant",content:d}):l.unshift({role:"user",content:W(d,g,m)})}}for(;l.length&&"user"!=l[0].role;)l.shift();const u=[];for(const e of l){const t=u[u.length-1];"assistant"==t?.role&&"assistant"==e.role?t.content=`${t.content}\n${e.content}`:"user"==t?.role&&"user"==e.role?t.content=G(t.content,e.content):"assistant"==e.role?u.push({role:"assistant",content:e.content}):u.push({role:"user",content:e.content})}const d=c.join("\n\n"),g=[];return d&&g.push({role:"system",content:d}),g.push(...u),g})(t.messages,t.limits),e.litert?N:void 0,t.limits.imageTokens),s=C({model:e,limits:t.limits,messages:i,reasoning:t.reasoning});return t.logging&&((e,t)=>{console.log("Local chat call",e.id,t.map(({role:e,content:t})=>({role:e,content:"****",...Array.isArray(t)?{images:t.filter(e=>"image"==e.type).length,audio:t.filter(e=>"audio"==e.type).length}:{}})))})(e,s.messages),await X({model:e,logging:t.logging,onReason:t.onReason,onText:t.onText,onSpeed:t.onSpeed,onPromptSpeed:t.onPromptSpeed,promptTokens:L(s.messages,t.limits.imageTokens),start:()=>r(s.messages,s.maxTokens),stopped:o,onStall:a,firstTimeoutMs:z(s.messages)?Y:J})};let te=!1;const re=33554432,ne=new Set([d.quota,d.notAllowed,d.notSupported,d.invalidState,d.typeMismatch,d.security]),oe=new Map,ae=new Set,ie=e=>{let t=0;const r=(e.split("/").pop()||"model").replace(/[^\w.-]+/g,"_");for(let r=0;r<e.length;r++)t=31*t+e.charCodeAt(r)>>>0;return`${t.toString(16)}-${r}`},se=e=>{const t=/^part-(\d+)$/.exec(e);return t?Number(t[1]):-1},ce=async()=>{if(!te)if("undefined"!=typeof navigator&&navigator.storage?.getDirectory)try{return await navigator.storage.getDirectory()}catch{return}else te=!0},le=async()=>{try{if("undefined"==typeof navigator||!navigator.storage?.estimate)return;const e=await navigator.storage.estimate();return"number"==typeof e.quota&&e.quota>0?e.quota-(e.usage||0):void 0}catch{return}},ue=async(e,t)=>{try{return await e.getDirectoryHandle(t)}catch{return}},de=async e=>{if(e)try{const t=await e.getFile(),r=JSON.parse(await t.text());return{total:Number(r.total)||0,etag:`${r.etag||""}`,complete:!0===r.complete}}catch{return}},ge=async(e,t)=>{try{const r=await e.getFileHandle("meta.json",{create:!0}),n=await r.createWritable();await n.write(JSON.stringify(t)),await n.close()}catch{}},me=async function*(e){for await(const t of e)yield t},pe=async e=>{try{for await(const[t,r]of me(e))"file"==r.kind&&se(t)>=0&&await e.removeEntry(t).catch(()=>{})}catch{}},fe=async(e,t)=>{try{const r=await(await e.getFileHandle(t)).getFile(),n=await de(await e.getFileHandle(`${t}.json`).catch(()=>{}));if(!n)return;return{file:r,size:r.size,total:n.total,etag:n.etag,complete:n.total?r.size>=n.total:!0===n.complete}}catch{return}},ye=async(e,t)=>{const r=await ue(e,t);if(r){const e=await(async e=>await de(await e.getFileHandle("meta.json").catch(()=>{})))(r),t=await(async e=>{const t=[];try{for await(const[r,n]of me(e)){const e=se(r);if("file"!=n.kind||e<0)continue;const o=await n.getFile();t.push({part:{start:e,size:o.size},file:o})}}catch{return}const r=(e=>{let t=0;const r=[];for(const n of[...e].sort((e,t)=>e.start-t.start))if(n.size){if(n.start!=t)break;r.push(n),t+=n.size}return r})(t.map(e=>e.part)),n=new Set(r.map(e=>e.start)),o=t.filter(e=>n.has(e.part.start)).sort((e,t)=>e.part.start-t.part.start).map(e=>e.file);if(o.length)return{file:1==o.length?o[0]:new Blob(o),size:r.reduce((e,t)=>e+t.size,0)}})(r),n=e?.total||0,o=t?.size??0,a=t?.file??new Blob;return{file:n&&o>n?a.slice(0,n):a,size:o,total:n,etag:e?.etag||"",complete:n?o>=n:!0===e?.complete}}return await fe(e,t)},he=(e,t)=>{const r=e.headers.get("content-range"),n=/bytes (\d+)-/.exec(r||""),o=/\/(\d+)\s*$/.exec(r||""),a=e.headers.get("etag")||"";if(206==e.status){const e=n?Number(n[1]):t.size,r=o?Number(o[1]):t.total;if(e!=t.size)return;if(t.total&&r&&t.total!=r)return;if(t.etag&&a&&t.etag!=a)return;return{start:e,total:r||t.total,etag:a||t.etag}}if(!t.etag||!a||t.etag==a)return{start:0,total:q(e)||t.total,etag:a||t.etag}},we=async({dir:e,start:t,skip:r,total:n,body:o,onProgress:a,onChunk:i})=>{let c,l,u=t,d=0,g=r;const m=async()=>{const t=await e.getFileHandle((e=>`part-${e}`)(u),{create:!0});l=await t.createWritable(),d=0},p=async()=>{const e=l;l=void 0,e&&await e.close()};try{const e=o.getReader();for(c=e;;){const{done:r,value:o}=await e.read();if(r)break;i();let c=0;for(g&&(c=Math.min(g,o.byteLength),g-=c);c<o.byteLength;){l||await m();const e=Math.min(re-d,o.byteLength-c);await l.write({type:"write",position:d,data:o.slice(c,c+e)}),c+=e,d+=e,u+=e,d==re&&await p()}u>t&&a(n?u/n:0,s.download)}await p()}catch(e){throw await p().catch(()=>{}),await(c?.cancel().catch(()=>{})),e}return u},be=e=>e?.name==d.quota,ve=e=>{const t=async()=>{const t=await ce();if(t)try{return await t.getDirectoryHandle(e,{create:!0})}catch{return}};return{stored:async e=>{const r=await t();return r?await ye(r,ie(e)):void 0},download:async({url:r,signal:n,onProgress:o})=>{if(ae.has(r))throw new DOMException("Storage is full",d.quota);const a=`${e}|${r}`,i=oe.get(a);if(i)return await i;const c=await t();if(!c)return;const l=(async(e,t,r,n)=>{const o=ie(t),a=await fe(e,o);if(a?.complete)return a;let i=await ue(e,o);i||(await e.removeEntry(o).catch(()=>{}),await e.removeEntry(`${o}.json`).catch(()=>{}),i=await e.getDirectoryHandle(o,{create:!0}));let c=0,l=0,u=!1;for(;;){if(r?.aborted)throw new Error("Cancelled");const a=await ye(e,o);if(a?.complete)return a;const g=a?.size??0,m=a?.total||0,p=a?.etag||"";if(g>c)c=g,l=0;else if(++l>4)throw new Error("Model download failed");g&&m&&n(g/m,s.download);const f=m?Math.min(g+re,m)-1:g+re-1,y=new AbortController,h=()=>y.abort(),w={size:g,total:m,etag:p};let b,v=setTimeout(h,3e4);r?.addEventListener("abort",h,{once:!0});try{if(b=await fetch(t,{signal:y.signal,headers:{Range:`bytes=${g}-${f}`}}),416==b.status){if(await(b.body?.cancel().catch(()=>{})),m&&g>=m){await ge(i,{total:m,etag:p,complete:!0});continue}await pe(i),await ge(i,{total:0,etag:"",complete:!1});continue}if(!b.ok||!b.body)throw await(b.body?.cancel().catch(()=>{})),new Error("Model download failed");const r=he(b,w);if(!r){await b.body.cancel().catch(()=>{}),await pe(i),await ge(i,{total:0,etag:"",complete:!1});continue}await ge(i,{total:r.total,etag:r.etag,complete:!1});const a=0==r.start?g:0,s=r.start+a;if(!u&&r.total>s){u=!0;const e=await le();if(null!=e&&e<r.total-s)throw await b.body.cancel().catch(()=>{}),new DOMException("Storage is full",d.quota)}const c=await we({dir:i,start:s,skip:a,total:r.total,body:b.body,onProgress:n,onChunk:()=>{clearTimeout(v),v=setTimeout(h,3e4)}});if(!r.total){await ge(i,{total:c,etag:r.etag,complete:!0});const t=await ye(e,o);if(t)return t}}catch(e){if(r?.aborted)throw new Error("Cancelled");if(e instanceof DOMException&&ne.has(e.name))throw e;await new Promise(e=>setTimeout(e,250+500*l))}finally{clearTimeout(v),r?.removeEventListener("abort",h)}}})(c,r,n,o).catch(e=>{throw be(e)&&ae.add(r),e}).finally(()=>{oe.delete(a)});return oe.set(a,l),await l},remove:async e=>{ae.delete(e);const r=await t();r&&await(async(e,t)=>{await e.removeEntry(t,{recursive:!0}).catch(()=>{}),await e.removeEntry(`${t}.json`).catch(()=>{})})(r,ie(e))},purge:async()=>{ae.clear();const t=await ce();t&&await t.removeEntry(e,{recursive:!0}).catch(()=>{})}}},Se=(e,...t)=>{!0===e&&console.log(...t)};let xe=!1,Me=0;const je="litertlm-models",ke=ve("litert-store"),Pe={num_output_candidates:1,wait_for_weight_uploads:!0,num_decode_steps_per_sync:1,sequence_batch_size:0,supported_lora_ranks:[],max_top_k:40,enable_decode_logits:!1,enable_external_embeddings:!1,use_submodel:!1,use_autosized_ringbuffers:!0};let De=1,Te=!1,Ne=0;const _e=new WeakSet,Oe=(...e)=>{xe&&console.log(...e)},Ee=(...e)=>{xe&&console.error(...e)},Le=e=>e.replace(/<\|channel>thought\n?[\s\S]*?<channel\|>/g,"").replace(/<\|channel>thought[\s\S]*$/,"").trim(),Ce=async()=>{const e=performance.now(),t=e-Ne;if(Ne=e,!Te)return;const r=Math.round(((e,t=1)=>Math.min(500,Math.max(0,e*(1/t-1))))(t,De));r<1||(await new Promise(e=>setTimeout(e,r)),Ne=performance.now())},Ae=(e=1)=>{De=e>0?e:1,Te=!0,Ne=performance.now()},Re=async()=>{try{if("undefined"==typeof caches)return;return await caches.open(je)}catch{return}},$e=new Map,Ue=(e,t,r)=>{let n=0;return e.pipeThrough(new TransformStream({transform:(e,o)=>{n+=e.byteLength,r(t?n/t:0,s.download),o.enqueue(e)}}))},qe=async(e,t=!0)=>{const r=[];for(const n of e){if("string"==typeof n.content){r.push({role:n.role,content:n.content});continue}const e=[];for(const r of n.content)"text"!=r.type?t?e.push({type:r.type,data:await _(r.url)}):e.push({type:"text",text:`[${r.type}]`}):e.push({type:"text",text:r.text});r.push({role:n.role,content:e})}return r},Be=(e,t)=>{if(e.role!=t.role)return!1;if("string"==typeof e.content||"string"==typeof t.content)return"string"==typeof e.content&&"string"==typeof t.content&&Le(e.content)==Le(t.content);if(e.content.length!=t.content.length)return!1;for(let r=0;r<e.content.length;r++){const n=e.content[r],o=t.content[r];if(n.type!=o.type)return!1;if("text"==n.type&&"text"==o.type){if(Le(n.text)!=Le(o.text))return!1}else{if("text"==n.type||"text"==o.type)return!1;if(!!n.url!=!!o.url)return!1}}return!0},ze=async function*({engine:e,mod:t,params:r,messages:n,maxTokens:o,session:a}){const i=n[n.length-1],s=$(r.limits,r.reasoning,r.temperature,o);if("user"!=i?.role)throw new Error("No user turn");const c=n.slice(0,-1),l=(await qe([i]))[0];if(!l)throw new Error("Empty prompt");let u;const d=a.reasoning==r.reasoning&&a.maxTokens==s.max_tokens,g=!!a.conversation&&((e,t)=>{const r="system"==e[0]?.role?e[0]:void 0,n="system"==t[0]?.role?t[0]:void 0;if(!r!=!n)return!1;if(r&&n&&!Be(r,n))return!1;const o=r?e.slice(1):e,a=n?t.slice(1):t;if(!a.length||a.length>o.length)return!1;const i=o.length-a.length;for(let e=0;e<a.length;e++)if(!Be(o[i+e],a[e]))return!1;return!0})(a.sent,c);if(d&&g&&a.conversation)Se(xe,"LiteRT conversation reused",a.sent.length),u=a.conversation;else{const n=await qe(c,!1);a.conversation=void 0,a.sent=[];const o=performance.now();u=await e.createConversation({sessionConfig:{maxOutputTokens:s.max_tokens,samplerParams:{type:t.SamplerType.TOP_K,temperature:s.temperature,k:40,p:.95}},preface:{...n.length?{messages:n}:{},extra_context:{enable_thinking:r.reasoning}},prefillPrefaceOnInit:n.length>0}),Se(xe,"LiteRT conversation created",n.length,Math.round(performance.now()-o),"flags",d,"history",g),a.conversation=u,a.reasoning=r.reasoning,a.maxTokens=s.max_tokens,a.sent=[...c]}a.sent.push(i);let m,p=!1,f=!0,y="";const h=()=>{m&&m.cancel().catch(()=>{});try{Promise.resolve(u.cancel()).catch(()=>{})}catch{}};r.signal?.addEventListener("abort",h,{once:!0});try{if(r.signal?.aborted)return;const e=u.sendMessageStreaming(l).getReader();for(m=e;;){const t=performance.now(),{done:n,value:o}=await e.read().catch(e=>{if(r.signal?.aborted)return{done:!0,value:void 0};throw e}),a=performance.now()-t;if(n)break;const i=f;f=!1,i&&(Se(xe,"LiteRT first chunk",Math.round(a)),Ae(r.limits.gpuShare));let s="string"==typeof o.content?o.content:"";const c={};if(Array.isArray(o.content))for(const e of o.content)"text"==e.type&&(s+=e.text);s&&(c.content=s,y+=s);const l=o.channels?.thought;l&&(c.reasoning=l),(c.content||c.reasoning)&&(yield{choices:[{delta:c}]})}p=!0}finally{Te=!1,r.signal?.removeEventListener("abort",h),p&&y?a.sent.push({role:"assistant",content:y}):(a.conversation=void 0,a.sent=[])}},Ie={backend:i.gpu,startLLM:async({model:e,limits:t,onProgress:n,signal:o,logging:a})=>{xe=!0===a;const c=e.litert;if(!c)throw new Error("Model has no LiteRT artifact");const l=w(e),u=await r.e(520).then(()=>r(507)),d=globalThis,g=d.Module;d.Module={print:Oe,printErr:Ee};try{await u.getOrLoadGlobalLiteRtLm(T)}finally{d.Module=g}if(o?.aborted)throw new Error("Cancelled");const m=u.getGlobalLiteRtLm(),p=m.liteRtLmWasm;if(await m.setupDefaultWebGpuDevice(),o?.aborted)throw new Error("Cancelled");const f=p.preinitializedWebGPUDevice;if(!f)throw new Error("No WebGPU device");if(!_e.has(f)){const e=(({device:e,pace:t})=>new Proxy(e,{get:(e,r)=>{if("createBuffer"==r)return(...n)=>{const o=Reflect.get(e,r,e).apply(e,n),a=o.mapAsync;try{o.mapAsync=async(...e)=>{await a.apply(o,e),await t()}}catch{}return o};const n=Reflect.get(e,r,e);return"function"==typeof n?n.bind(e):n}}))({device:f,pace:Ce});_e.add(f),_e.add(e),p.preinitializedWebGPUDevice=e}let y,h=!1;const b=U(c.repo,c.file),v=await Re(),S=v?await v.match(b):void 0;if(S?.body)y=S.body;else{const e=await ke.stored(b);e?.complete&&(y=e.file.stream())}if(!y){const e=await ke.download({url:b,signal:o,onProgress:n}).catch(e=>{if(o?.aborted)throw new Error("Cancelled");a&&console.log("Local model store failed",e),h=be(e)});e&&(y=e.file.stream())}if(!y&&v&&!h)try{await(async(e,t,r,n)=>{const o=$e.get(e);if(o)return await o;const a=(async()=>{const o=await fetch(e,{signal:r});if(!o.ok||!o.body)throw new Error("Model download failed");const a=q(o),i=Ue(o.body,a,n);await t.put(e,new Response(i,{headers:{"content-type":"application/octet-stream",...a?{"content-length":`${a}`}:{}}}))})().finally(()=>{$e.delete(e)});return $e.set(e,a),await a})(b,v,o,n);const e=await v.match(b);e?.body&&(y=e.body)}catch(e){if(o?.aborted)throw new Error("Cancelled");a&&console.log("Local model cache failed",e)}if(y||(y=await(async(e,t,r)=>{const n=await fetch(e,{signal:t});if(!n.ok||!n.body)throw new Error("Model download failed");return Ue(n.body,q(n),r)})(b,o,n)),o?.aborted)throw new Error("Cancelled");n(1,s.load);const x=await u.Engine.create((({model:e,limits:t,contextSize:r,source:n,mod:o})=>{const a=e.litert;return{model:n,mainExecutorSettings:{maxNumTokens:r,...a?.vision?{maxNumImages:Math.max(1,t.maxImages)}:{},backendConfig:Pe},...a?.vision?{visionBackend:o.Backend.GPU,maxVisionTokensPerImage:70,minVisionTokensPerImage:70}:{},...a?.audio?{audioBackend:o.Backend.CPU}:{}}})({model:e,limits:t,contextSize:l,source:y,mod:u}));Me+=1;const M=()=>{Me=Math.max(0,Me-1),Me||(e=>{try{const t=e.getGlobalLiteRtLm().liteRtLmWasm,r=t.preinitializedWebGPUDevice;t.preinitializedWebGPUDevice=void 0,t.WebGPU&&(t.WebGPU.preinitializedDeviceId=void 0),r?.destroy?.()}catch{}try{e.unloadLiteRtLm()}catch{}})(u)};try{const e=performance.now(),t=await x.createConversation();await t.delete(),Se(xe,"LiteRT conversation warm-up",Math.round(performance.now()-e))}catch(e){Se(xe,"LiteRT conversation warm-up failed",e)}if(o?.aborted)throw await x.delete(),M(),new Error("Cancelled");const k={sent:[],reasoning:!1,maxTokens:0};return{model:e,backend:i.gpu,contextSize:l,chat:t=>(async({engine:e,model:t,mod:r,params:n,session:o})=>{xe=!0===n.logging;const a=()=>{try{o.conversation?.cancel()}catch{}o.conversation=void 0,o.sent=[]};try{const i=await ee({model:t,params:n,stopped:()=>!!n.signal?.aborted,onStall:a,start:async(a,i)=>{if(n.signal?.aborted)throw new Error("Cancelled");if(z(a)&&!t.litert?.vision)throw new Error("Model does not accept images");if(I(a)&&!t.litert?.audio)throw new Error("Model does not accept audio");return ze({engine:e,mod:r,params:n,messages:a,maxTokens:i,session:o})}}),s=o.conversation;if(s&&n.onPromptSpeed&&!n.signal?.aborted){const e=await s.getBenchmarkInfo().catch(()=>{}),t=e?.lastPrefillTokensPerSecond;"number"==typeof t&&Number.isFinite(t)&&t>0&&n.onPromptSpeed((0,j.rNum)(t))}return i}catch(e){throw a(),e}})({engine:x,model:e,mod:u,params:t,session:k}),unload:async()=>{const e=k.conversation;k.conversation=void 0,k.sent=[];try{await(e?.delete())}catch{}await x.delete(),M()}}},cached:async e=>{const t=e.litert;if(!t)return!1;const r=U(t.repo,t.file),[n,o]=await Promise.all([Re(),ke.stored(r)]);if(o?.complete)return!0;try{return!(!n||!await n.match(r))}catch{return!1}},purge:async()=>{try{await ke.purge(),"undefined"!=typeof caches&&await caches.delete(je)}catch{}}};let Ke,Fe,We="",Ve=!1;const Ge=ve("wllama-store"),Je=[g.qwen3_vl_2b_instruct,g.qwen3_vl_2b_instruct_q3],Ye=e=>e.cpu?.mmproj&&Je.includes(e.id)?{image_min_tokens:16,image_max_tokens:128}:{},He=e=>`${e.wasm}|${e.compatWasm}|${e.compatWorker}`,Qe=e=>{const t={wasm:k,compatWasm:P,compatWorker:D};return{wasm:e?.wasm||t.wasm,compatWasm:e?.compatWasm||t.compatWasm,compatWorker:e?.compatWorker||t.compatWorker}},Ze=e=>{const t=e=>(...t)=>{Ve&&("string"==typeof t[0]&&t[0].includes("ggml_webgpu: Failed to get an adapter")||e(...t))};return{...e,log:t(e.log),warn:t(e.warn),error:t(e.error)}},Xe=async()=>{if(Ke)return Ke;const e=await r.e(924).then(()=>r(577)),t=Fe||Qe(),n=new e.Wllama({default:t.wasm},{logger:Ze(e.LoggerWithoutDebug)});return Fe||(Fe=t,We=He(t)),n.setCompat({wasm:t.compatWasm,worker:t.compatWorker}),Ke=n,n},et=async()=>{const e=Ke;Ke=void 0;try{await(e?.exit())}catch{}},tt=(e,t)=>e.name.includes(t)||!!e.metadata?.originalURL?.includes(t),rt=e=>{const t=e.cpu;return t?[{name:t.file,url:U(t.repo,t.file)},...t.mmproj?[{name:t.mmproj.file,url:U(t.mmproj.repo??t.repo,t.mmproj.file)}]:[]]:[]},nt=async e=>{const t=rt(e);if(!t.length)return!1;for(const e of t){const t=await Ge.stored(e.url);if(!t?.complete)return!1}return!0},ot=async(e,t,r,n)=>{const o=await fetch(e,{signal:n,headers:{Range:`bytes=${t}-${r-1}`}});if(206!=o.status)throw await(o.body?.cancel().catch(()=>{})),new Error("Model range failed");return await o.arrayBuffer()},at=async(e,t)=>{const r=await fetch(e,{method:"HEAD",signal:t});await(r.body?.cancel().catch(()=>{}));const n=Number(r.headers.get("content-length"))||0;if(!r.ok||!n)throw new Error("Model size unknown");return n},it=({url:e,stored:t,storedSize:r,total:n,signal:o})=>{const a=Math.max(0,Math.min(r,n));return{size:n,slice:(r,i)=>({arrayBuffer:async()=>{const s=Math.max(0,Math.min(r??0,n)),c=Math.max(s,Math.min(i??n,n));if(c<=s)return new ArrayBuffer(0);if(t&&c<=a)return await t.slice(s,c).arrayBuffer();if(!t||s>=a)return await ot(e,s,c,o);const l=await t.slice(s,a).arrayBuffer(),u=await ot(e,a,c,o),d=new Uint8Array(l.byteLength+u.byteLength);return d.set(new Uint8Array(l)),d.set(new Uint8Array(u),l.byteLength),d.buffer}})}},st=async({model:e,signal:t,onProgress:r})=>{const n=rt(e),o=[];for(let e=0;e<n.length;e++){if(t?.aborted)throw new Error("Cancelled");const a=await Ge.download({url:n[e].url,signal:t,onProgress:(t,o)=>r((e+t)/n.length,o)});if(!a)return;o.push(a.file)}return o.length?o:void 0},ct=async e=>{const t=[];for(const r of e){if("string"==typeof r.content){"system"==r.role?t.push({role:"system",content:r.content}):"assistant"==r.role?t.push({role:"assistant",content:r.content}):t.push({role:"user",content:r.content});continue}const e=[];for(const t of r.content)"text"==t.type?e.push({type:"text",text:t.text}):e.push({type:t.type,data:await _(t.url)});t.push({role:"user",content:e})}return t},lt={backend:i.cpu,startLLM:async({model:e,limits:t,onProgress:r,signal:n,logging:o,assets:a})=>{Ve=!0===o;const c=w(e),l=e.cpu;if(!l)throw new Error("Model has no CPU artifact");const u=Qe(a),d=He(u);Ke&&d!=We&&await et(),Fe=u,We=d;const g="undefined"!=typeof navigator?navigator.hardwareConcurrency:0,m=Math.min((e=>{const t=e||4;return Math.max(1,t-Math.max(1,Math.floor(t/5)))})(g),t.maxThreads),p=await Xe(),f=await nt(e),y=l.mmproj?.file;if(n?.aborted)throw await et(),new Error("Cancelled");if(!f&&y){const e=await p.cacheManager.list(),t=e.some(e=>tt(e,l.file)),r=e.some(e=>tt(e,y));t&&!r&&await p.cacheManager.deleteMany(e=>tt(e,l.file))}const h={n_ctx:c,n_threads:m,n_parallel:1,warmup:!0,...e.reasoning?{reasoning_budget_tokens:t.maxThinkingTokens}:{reasoning_budget_tokens:0},n_gpu_layers:0,jinja:!0,ctx_shift:!0,n_keep:Math.max(64,Math.round(c/16)),...Ye(e)};try{let t=f?await st({model:e,signal:n,onProgress:r}):void 0;t||(t=await(async(e,t)=>{const r=rt(t);if(!r.length)return;const n=(await e.modelManager.getModels().catch(()=>[])).find(e=>e.url==r[0].url);return n?await n.open().catch(()=>{}):void 0})(p,e)),t||(t=await st({model:e,signal:n,onProgress:r}).catch(e=>{if(n?.aborted)throw new Error("Cancelled");o&&console.log("Local model store failed",e)})),t||(t=await(async(e,t)=>{const r=[];for(const n of rt(e)){if(t?.aborted)throw new Error("Cancelled");const e=await Ge.stored(n.url),o=e?.total||await at(n.url,t);if(!o)throw new Error("Model size unknown");r.push(it({url:n.url,stored:e?.file,storedSize:Math.min(e?.size||0,o),total:o,signal:t}))}return r})(e,n)),r(1,s.load),await p.loadModel(t,h)}catch(e){throw await et(),e}if(n?.aborted)throw await et(),new Error("Cancelled");const b=p.getLoadedContextInfo();if(!b.n_ctx)throw await et(),new Error("Failed to create model context");return Se(o,"CPU engine ready",e.id,"cores","undefined"!=typeof navigator?navigator.hardwareConcurrency:0,"isolated","undefined"!=typeof crossOriginIsolated&&crossOriginIsolated,"requested",m,"multithread",p.isMultithread(),"active",p.getNumThreads(),"context",b.n_ctx,"batch",b.n_batch,"ubatch",b.n_ubatch),{model:e,backend:i.cpu,contextSize:c,chat:t=>(async(e,t,r)=>{if(Ve=!0===r.logging,e.isModelLoaded())return await ee({model:t,params:r,stopped:()=>!!r.signal?.aborted,start:async(n,o)=>{if(z(n)&&!e.supportInputModality("image"))throw new Error("Model does not accept images");if(I(n)&&!e.supportInputModality("audio"))throw new Error("Model does not accept audio");return await e.createChatCompletion({messages:await ct(n),...$(r.limits,r.reasoning,r.temperature,o),timings_per_token:!0,return_progress:!0,...r.repeatPenalty?{penalty_repeat:r.repeatPenalty}:{},abortSignal:r.signal,...t.reasoning||Je.includes(t.id)?{chat_template_kwargs:{enable_thinking:r.reasoning}}:{}})}})})(p,e,t),unload:async()=>{if(Ke==p)await et();else try{await p.exit()}catch{}}}},cached:async e=>{try{return!!e.cpu&&(!!await nt(e)||await(async(e,t)=>{const r=rt(t),n=await e.modelManager.getModels().catch(()=>[]);return!!r.length&&n.some(e=>e.url==r[0].url)})(await Xe(),e))}catch{return!1}},purge:async()=>{try{await Ge.purge()}catch{}try{const e=await Xe();await e.cacheManager.clear()}catch{}}},ut=((e={})=>{let t,r,n,o=a.idle;const c=e.engines?.cpu||lt,l=e.engines?.litert||Ie,u=new Map,d=new Map,g=new Map,m=new Map,p=new Map,f=new Map,y=new Map,h=new Map,w=new Map,b=t=>{if(e.backend!=i.none)return e.backend==i.cpu?t.cpu?c:void 0:e.backend==i.gpu?t.litert?l:void 0:t.litert&&"undefined"!=typeof navigator&&navigator.gpu&&"undefined"!=typeof WebAssembly?l:!t.cpu||"undefined"==typeof window&&"undefined"==typeof self&&"undefined"==typeof Worker||"undefined"==typeof WebAssembly?void 0:c},v=e=>e?u.get(e):t?u.get(t.id):void 0,S=e=>{o=e},x=async e=>{const r=u.get(e);r&&(u.delete(e),t?.id==e&&(t=[...u.values()].pop()?.model),u.size||d.size||S(a.idle),await r.unload())},M=async()=>{for(const e of[...u.keys()])await x(e)},j=(e,t,r)=>{const n={percent:Math.max(0,Math.min(1,t)),phase:r||s.download};p.set(e,n);for(const t of m.get(e)??[])t.report(n.percent,n.phase)},k=e=>{y.set(e,(y.get(e)??0)+1),f.get(e)?.abort(),f.delete(e);const t=d.get(e);t&&g.set(e,t),d.delete(e),m.delete(e),p.delete(e),h.set(e,a.idle),o!=a.downloading||d.size||u.size||S(a.idle)},P=(e,t,r)=>{const n=d.get(e);return n?new Promise(o=>{let a=!1;const i={report:t,settle:e=>{a||(a=!0,r?.removeEventListener("abort",s),o(e))}},s=()=>{((e,t)=>{const r=m.get(e);r&&m.set(e,r.filter(e=>e!=t)),queueMicrotask(()=>{!m.get(e)?.length&&d.has(e)&&k(e)})})(e,i),i.settle(!1)},c=m.get(e);c?c.push(i):m.set(e,[i]),r?.aborted?s():r?.addEventListener("abort",s,{once:!0}),n.attempt.then(i.settle,()=>i.settle(!1))}):Promise.resolve(!1)},D=async e=>{if(e)await x(e);else{for(const e of[...d.keys()])k(e);p.clear(),h.clear(),w.clear(),r=void 0,S(a.idle),await M()}};return{load:async({model:e,limits:n,assets:o,logging:i,signal:c,onProgress:l})=>{if(c?.aborted)return!1;if(u.has(e.id))return t=e,!0;if(d.has(e.id)){const t=p.get(e.id);return t&&l(t.percent,t.phase),await P(e.id,l,c)}const v=b(e);if(!v){const t="Model is not supported on this device";return r=t,w.set(e.id,t),h.set(e.id,a.unsupported),S(a.unsupported),!1}const x=[...d.values(),...g.values()];for(const e of x)k(e.model.id);const D=(y.get(e.id)??0)+1;let T;y.set(e.id,D);const N=(async()=>{if(await Promise.all(x.map(e=>e.attempt.catch(()=>!1))),D!=y.get(e.id))return!1;if(await(async()=>{try{if("undefined"==typeof navigator)return;await(navigator.storage?.persist?.())}catch{}})(),D!=y.get(e.id))return!1;if(await M(),D!=y.get(e.id))return!1;const c=await v.cached(e);if(D!=y.get(e.id))return!1;r=void 0,w.delete(e.id),h.set(e.id,a.downloading),S(a.downloading),j(e.id,0,s.download),c&&j(e.id,1,s.load);const l=new AbortController;f.set(e.id,l);try{const c=await v.startLLM({model:e,limits:n,logging:i,signal:l.signal,assets:o,onProgress:(t,r)=>{D==y.get(e.id)&&j(e.id,t,r)}});return D!=y.get(e.id)||l.signal.aborted?(await c.unload(),!1):(u.set(e.id,c),t=e,r=void 0,w.delete(e.id),h.set(e.id,a.ready),S(a.ready),j(e.id,1,s.load),!0)}catch(t){if(D!=y.get(e.id))return!1;const n=`${t?.message||`${t}`}`;return r=n,w.set(e.id,n),h.set(e.id,a.error),S(a.error),i&&console.log("Local model failed",t),!1}finally{f.get(e.id)==l&&f.delete(e.id)}})(),_=N.finally(()=>{g.get(e.id)==T&&g.delete(e.id),d.get(e.id)==T&&(d.delete(e.id),m.delete(e.id),p.delete(e.id))});return T={model:e,attempt:_},d.set(e.id,T),m.set(e.id,[]),await P(e.id,l,c)},chat:async e=>{if(!v(e.model))return;for(;n;)await n.catch(()=>{});const r=v(e.model);if(!r)return;t?.id!=r.model.id&&(t=r.model);const o=r.chat(e);n=o;try{return await o}finally{n==o&&(n=void 0)}},unload:D,clear:async()=>{const e=[...d.values(),...g.values()].map(e=>e.attempt);await D(),await Promise.all(e.map(e=>e.catch(()=>{}))),await Promise.all([c.purge(),l.purge()])},ready:e=>!!v(e),loading:e=>e?d.has(e):d.size>0,status:e=>v(e)?a.ready:e?d.has(e)?h.get(e)??a.downloading:w.has(e)?h.get(e)??a.error:a.idle:o,backend:e=>v(e)?.backend??i.none,error:e=>e?w.get(e):r,model:()=>t}})(),dt=(e,t,r)=>{const n=e.status(t),i=b(t);return{...t?{model:t}:{},availability:n==a.ready?o.online:n==a.error||n==a.unsupported?o.offline:o.away,status:n,backend:e.backend(t),supportsImages:!!i&&x(i),supportsAudio:!!i&&M(i),ready:e.ready(t),loading:e.loading(t),requesting:r.requesting,phase:r.phase,percent:r.percent,...r.error?{error:r.error}:{}}},gt=(e=>{let t,r=0;const o=t=>t.input.onStatus?.(dt(e,t.model??t.input.model,t));return i=>{t?.controller.abort();const c=e.ready(i.model),l={token:++r,input:i,controller:new AbortController,percent:c?100:0,phase:c?s.load:s.download,requesting:!1,cancelled:!1};return t=l,o(l),(async t=>{const{input:a}=t,i=!0===a.logging,c=await S(a.model);if(t.model=c?.id,t.token!=r)return;const l=a.messages.some(e=>e.role!=n.system&&"string"==typeof e.content&&!!e.content.trim()),u=a.messages.some(e=>e.role==n.user&&!!e.images?.some(e=>"string"==typeof e&&!!e)),d=a.messages.some(e=>e.role==n.user&&!!e.audio?.some(e=>"string"==typeof e&&!!e)),g=l||u||d;if(!c)return t.error="Unknown model",void o(t);if(!g)return t.error="No prompt",void o(t);const m=x(c),p=M(c);if(!(l||u&&m||d&&p))return d&&!p?t.error="Model does not accept audio":u&&!m&&(t.error="Model does not accept images"),void o(t);const f=R(a.limits,!!c.litert),y=await e.load({model:c,limits:f,logging:i,signal:t.controller.signal,onProgress:(e,n)=>{t.token==r&&(t.percent=Math.round(100*e),t.phase=n,o(t))}}).catch(e=>(t.token==r&&(t.error=`${e?.message||`${e}`}`),!1));if(t.token!=r)return;if(t.cancelled)return void o(t);if(!y)return t.error||(t.error=e.error(c.id)||"Model not ready"),void o(t);const h=u&&!m||d&&!p?a.messages.map(({images:e,audio:t,...r})=>({...r,...e&&m?{images:e}:{},...t&&p?{audio:t}:{}})):a.messages;t.requesting=!0,t.error=void 0,t.percent=100,t.phase=s.load,o(t);let w,b="",v="";try{w=await e.chat({model:c.id,messages:h,limits:f,reasoning:!0===a.reasoning,logging:i,onReason:e=>{t.token!=r||t.cancelled||(b+=e,a.onThinking?.(b))},onText:e=>{t.token!=r||t.cancelled||(v+=e,a.onResponse?.(v))},onSpeed:e=>{t.token!=r||t.cancelled||a.onSpeed?.(e)},onPromptSpeed:e=>{t.token!=r||t.cancelled||a.onPromptSpeed?.(e)},signal:t.controller.signal})}catch(n){if(t.token!=r)return;return t.requesting=!1,t.error=`${n?.message||`${n}`}`,t.cancelled||await e.unload(c.id).catch(()=>{}),void o(t)}t.token==r&&(t.requesting=!1,w||t.cancelled||(t.error="No reply",await e.unload(c.id).catch(()=>{})),o(t))})(l),()=>(t=>{t.token==r&&(t.cancelled=!0,t.controller.abort(),t.model&&e.status(t.model)==a.ready?e.unload(t.model).then(()=>o(t)):queueMicrotask(()=>o(t)))})(l)}})(ut),mt=(ft=ut,async(e={})=>{const t=await S(e.model),r=r=>e.onStatus?.(dt(ft,t?.id,r));if(!t)return r({requesting:!1,phase:s.download,percent:0,error:"Unknown model"}),!1;let n,o=0,a=s.download;const i=ft.ready(t.id);return await ft.load({model:t,limits:R(e.limits,!!t.litert),logging:!0===e.logging,onProgress:(e,t)=>{o=Math.round(100*e),a=t,r({requesting:!1,phase:a,percent:o})}}).catch(e=>(n=`${e?.message||`${e}`}`,!1))?(i&&r({requesting:!1,phase:s.load,percent:100}),!0):(r({requesting:!1,phase:a,percent:o,error:n||ft.error(t.id)||"Model not ready"}),!1)}),pt=async()=>{await ut.clear()};var ft,yt=r(167);let ht;const wt="degreesign-chat-estimates-v1",bt={analyze:95,describe:25,translate:15,tags:6,translateTags:4},vt=()=>ht??=(0,yt.readData)(wt)??{},St=e=>{const t=e.map(e=>({operation:e,est:vt()[e]??bt[e]}));return{totalEst:t.reduce((e,t)=>e+t.est,0),breakdown:t}},xt=({operation:e,seconds:t})=>{t>0&&(ht={...vt(),[e]:t},(0,yt.saveData)({key:wt,data:ht}))},Mt=["You are describer of images","in detailed efficient manner.","You share descriptions after replacing","euphemisms with all specific terms.","You include visible organs/limbs,","with pose and actions, only for living things.","You always describe the overall nature,","state, pose, acts, positions, and locations.","You always give priority to interesting,","unusual, shocking, explicit,","or weird facts about the image.","You never: lie, use vague referrals,","use a general term when a precise term exists,","use euphemisms, nor include any part","of the message in your response."].join(" "),jt=["Describe this image in one detail blunt","concise paragraph, prioritize most","head-turning elements over mundane elements."].join(" "),kt=e=>["You tag photos for a private photo gallery.","Read each numbered image description below","and reply with exactly one line per number.","Each line is the number, a colon,",`then exactly ${e}`,"comma separated single word tags","for the most prominent concrete","elements the photo shows.","Tag its main subjects, objects,","actions and place, never the medium or","filler ideas such as photo, image,","picture, scene, object, background or colour.","Produce the tags even if the","photo is extreme or explicit.","Always add the first tag as",'"nsfw" if the photo is',"flirty, suggestive or explicit.","Write every tag in English as one word.","Reply with the numbered lines only,","in the form: 1. tag, tag, tag"].join(" "),Pt=e=>["You translate the tags of",`a private photo gallery into ${e}.`,"Read each numbered English tag","below and reply with exactly one line per tag.","Each line is the number, a colon,",`then the tag in ${e}:`,"one single word, without articles or explanation.","Use only letters.","Reply with the numbered","lines only, without quotes."].join(" "),Dt=["You are a precise translator.","Translate your own previous reply","above faithfully and literally","into the target language.","Never translate the user's","request or instructions.","Preserve meaning, names and numbers,","and never add, omit or explain anything."].join(" "),Tt=e=>["Now please translate your previous",`reply above faithfully into ${e}.`,"Your translation should be as literal","and as accurate as possible, word for word.","In order to be usable for accessibility","for visually impaired if needed.","Reply only by the translation","without any addition or explanation"].join(" "),Nt=g.qwen3_vl_2b_instruct,_t="CANNOT_TRANSLATE",Ot=e=>{const t=e.trim().toLowerCase();return!!t&&!/^(en|eng|english)([-_]|$)/.test(t)},Et=e=>"string"==typeof e?e.toLowerCase().replace(/[^\p{L}]+/gu,"").slice(0,20):"",Lt=async({service:e,limits:t,logging:r,signal:n,onStatus:o,model:a})=>{const i=(t,r)=>o?.(dt(e,t,r)),c=b(a)??await S();if(!c)return Se(r,"Model missing",a),i(a||Nt,{requesting:!1,phase:s.download,percent:0,error:"Unknown model"}),{error:"Unknown model"};const l=await(async o=>{let a,c=0,l=-1,u=s.download;Se(r,"Describe load start",o.id,t.maxReplyTokens);if(await e.load({model:o,limits:t,logging:r,signal:n,onProgress:(e,t)=>{c=Math.round(100*e),u=t,c!=l&&(l=c,Se(r,"Describe load progress",o.id,c,u)),i(o.id,{requesting:!1,phase:u,percent:c})}}).catch(e=>(a=`${e?.message||`${e}`}`,!1)))return Se(r,"Describe load ready",o.id),void i(o.id,{requesting:!1,phase:s.load,percent:100});const d=a||e.error(o.id)||"Model not ready";return Se(r,"Describe load failed",o.id,d),i(o.id,{requesting:!1,phase:u,percent:c,error:d}),d})(c);return l?{error:l}:n?.aborted?{aborted:!0}:(i(c.id,{requesting:!0,phase:s.load,percent:100}),{report:i,generate:async({model:o,messages:a,stage:c,repeatPenalty:l,temperature:u,limits:d,onSpeed:g,onText:m})=>{let p="";const f=Date.now();if(Se(r,"Describe generate start",c,o,a.length),!n?.aborted)try{const i=await e.chat({model:o,messages:a,limits:d?{...t,...d}:t,reasoning:!1,...l?{repeatPenalty:l}:{},...void 0===u?{}:{temperature:u},logging:r,signal:n,onReason:e=>{Se(r,"Describe reason",c,o,e)},onText:e=>{p+=e,Se(r,"Describe text",c,o,e),m?.(p)},onSpeed:e=>{Se(r,"Describe speed",c,o,e),g?.(e)}});return Se(r,"Describe generate reply",c,o,Date.now()-f,i?.length??0,i),i}catch(e){if(Se(r,"Describe generate failed",c,o,e),n?.aborted)return;throw i(o,{requesting:!1,phase:s.load,percent:100,error:`${e?.message||`${e}`}`}),e}},model:c})},Ct=e=>async t=>{const r=!0===t.logging,o=R({maxReplyTokens:128,imageTokens:192,...t.limits});t.onEstimate?.(St([c.analyze,c.describe])),Se(r,"Describe image start",t.image.length);const a=await Lt({service:e,limits:o,logging:r,signal:t.signal,onStatus:t.onStatus,model:Nt});if("error"in a)throw new Error(a.error);if("aborted"in a)return"";let i,l="";const{report:u,generate:d,model:g}=a,m=Date.now();try{l=(await d({model:g.id,messages:[{role:n.system,content:t.systemRulesOverride||Mt},{role:n.user,content:jt,images:[t.image]}],stage:"describe",repeatPenalty:1,temperature:.1,onSpeed:t.onSpeed,onText:e=>{i??=Date.now(),t.onText?.(e)}})||"").trim()}catch(e){if(t.signal?.aborted)return"";throw e}const p=Date.now();return Se(r,"Describe image done",p-m,l),u(g.id,{requesting:!1,phase:s.load,percent:100}),l?(xt({operation:c.analyze,seconds:((i??p)-m)/1e3}),xt({operation:c.describe,seconds:(p-(i??m))/1e3}),l):(Se(r,"Describe image empty"),u(g.id,{requesting:!1,phase:s.load,percent:100,error:"No description"}),"")},At=e=>async t=>{const r=t.tags.map(e=>({...e})),o=t.targetLanguage.trim(),a=t.targetCode.trim()||"en",i=!0===t.logging;if(!r.length||"en"==a||!Ot(o))return r;t.onEstimate?.(St([c.translateTags]));const u=R({maxReplyTokens:256,...t.limits}),d=await Lt({service:e,limits:u,logging:i,signal:t.signal,onStatus:t.onStatus,model:t.model});if("error"in d||"aborted"in d)return r;const{report:g,generate:m,model:p}=d,f=Date.now(),y=r.map((e,t)=>`${t+1}. ${e.en}`).join("\n");try{((e,t,r)=>{if("en"!=r)for(const n of e.matchAll(/^\s*(\d+)\s*[:.\-]\s*(.+)$/gm)){const e=t[Number(n[1])-1],o=Et(n[2]);e&&o&&o!=e.en&&(e[r]=o)}})((await m({model:p.id,messages:[{role:n.system,content:Pt(o)},{role:n.user,content:y}],stage:l.translateTags,limits:{maxReplyTokens:256},onText:t.onText})||"").trim(),r,a),xt({operation:c.translateTags,seconds:(Date.now()-f)/1e3})}catch(e){Se(i,"Enhance tag translate failed",e)}return g(p.id,{requesting:!1,phase:s.load,percent:100}),r},Rt=e=>async t=>{const r=t.descriptionEN.trim(),o=t.targetLanguage.trim(),a=t.targetCode.trim()||"en",i=!1!==t.withTags,u=!1!==t.withDescription,d=!0===t.logging,g=At(e),m=!!r&&u&&"en"!=a&&Ot(o),p=i&&"en"!=a&&Ot(o),f=[...m?[c.translate]:[],...i?[c.tags]:[],...p?[c.translateTags]:[]],y={description:r,translated:!1,tags:[],nsfw:void 0};if(Se(d,"Enhance start",r.length,o,a),!r||!f.length)return y;t.onEstimate?.(St(f));const h=R({maxReplyTokens:256,...t.limits}),w=await Lt({service:e,limits:h,logging:d,signal:t.signal,onStatus:t.onStatus,model:t.model});if("error"in w||"aborted"in w)return y;const{report:b,generate:v,model:S}=w;if(m){t.onStage?.(l.translate);const e=Date.now();try{const a=(await v({model:S.id,messages:[{role:n.system,content:Dt},{role:n.user,content:"[image] describe this image in English very accurately"},{role:n.assistant,content:r},{role:n.user,content:Tt(o)}],stage:l.translate,limits:{maxReplyTokens:256},onSpeed:t.onSpeed,onText:e=>t.onText?.(e,l.translate)})||"").trim(),i=a.replace(/[^a-z]/gi,"").toUpperCase().includes(_t.replace(/[^a-z]/gi,""));a&&!i&&(y.description=a,y.translated=!0),xt({operation:c.translate,seconds:(Date.now()-e)/1e3})}catch(e){Se(d,"Enhance translate failed",e)}}if(i){t.onStage?.(l.tags);const e=Date.now();try{const o=(e=>{const t=[],r=e=>{const r=(e=>"string"==typeof e?e.toLowerCase().replace(/[^a-z]+/g,"").slice(0,20):"")(e);r.length<2||t.some(e=>e.en==r)||t.push({en:r})};for(const t of e.matchAll(/^\s*\d+\s*[:.\-]\s*(.+)$/gm))for(const e of(t[1]||"").split(/[,;\n]+/))for(const t of e.split(/\s+/))r(t);if(!t.length)for(const t of e.split(/[,;\n]+/))for(const e of t.split(/\s+/))r(e);return t})((await v({model:S.id,messages:[{role:n.system,content:kt(3)},{role:n.user,content:r}],stage:l.tags,limits:{maxReplyTokens:128},onSpeed:t.onSpeed,onText:e=>t.onText?.(e,l.tags)})||"").trim());y.nsfw=o.some(e=>"nsfw"==e.en),y.tags=o.filter(e=>"nsfw"!=e.en).slice(0,3),xt({operation:c.tags,seconds:(Date.now()-e)/1e3}),Se(d,"Enhance tags",y.tags)}catch(e){Se(d,"Enhance tags failed",e)}}return p&&y.tags.length&&(t.onStage?.(l.translateTags),y.tags=await g({tags:y.tags,targetLanguage:o,targetCode:a,model:S.id,signal:t.signal,limits:t.limits,logging:d,onStatus:t.onStatus,onText:e=>t.onText?.(e,l.translateTags)})),b(S.id,{requesting:!1,phase:s.load,percent:100}),y},$t=Ct(ut),Ut=Rt(ut),qt=At(ut),Bt=e=>{const t=e.trim().toLowerCase();return!!t&&!/^(en|eng|english)([-_]|$)/.test(t)},zt=(e=>{const t=Ct(e),r=Rt(e);return async e=>{let n;const o=[],a=e.targetLanguage.trim()||"en",i=async()=>n??=await v();for(let n=0;n<e.images.length&&!e.signal?.aborted;n++){e.currentIndex?.(n);let s="";const c=Date.now(),u=e.images[n];try{s=await t({image:u,systemRulesOverride:e.additionalRules,signal:e.signal,limits:e.limits,logging:e.logging,onStatus:e.onStatus,onSpeed:t=>e.onSpeed?.(n,t),onText:t=>e.onText?.(n,t,"describe")})}catch{}const d=Math.max(0,Date.now()-c);if(!s){o.push({descriptionEN:"",description:"",durationMs:d}),e.currentIndex?.(n,"",void 0,d);continue}e.currentIndex?.(n,s,void 0,d);let m=s;if(Bt(e.targetLanguage)&&await i())try{const t=await r({descriptionEN:s,targetLanguage:e.targetLanguage,targetCode:a,withTags:!1,withDescription:!0,model:g.gemma4_e2b_limited,signal:e.signal,limits:e.limits,logging:e.logging,onStatus:e.onStatus,onSpeed:t=>e.onSpeed?.(n,t),onText:(t,r)=>{r==l.translate&&e.onText?.(n,t,"translate")}});t.translated&&(m=t.description)}catch{}if(o.push({descriptionEN:s,description:m,durationMs:d}),e.currentIndex?.(n,s,m,d),e.signal?.aborted)break}return o}})(ut),It=(e=>{const t=Rt(e);return async e=>{const r=[...e.descriptions],n=e.targetLanguage.trim(),o=n||"en";if(!r.length||!Bt(n))return r;if(!await v())return r;for(let a=0;a<r.length&&!e.signal?.aborted;a++){const i=r[a]||"";if(!i){e.currentIndex?.(a,i,i);continue}let s=i;try{const r=await t({descriptionEN:i,targetLanguage:n,targetCode:o,withTags:!1,withDescription:!0,model:g.gemma4_e2b_limited,signal:e.signal,limits:e.limits,logging:e.logging,onStatus:e.onStatus,onSpeed:t=>e.onSpeed?.(a,t),onText:(t,r)=>{r==l.translate&&e.onText?.(a,t,"translate")}});r.translated&&(s=r.description)}catch{}r[a]=s,e.currentIndex?.(a,i,s)}return r}})(ut),Kt=/^[0-9+\-*/%^().]+$/,Ft=e=>{let t=0;const r=e=>!!e&&e>="0"&&e<="9",n=e=>{throw new Error(e)},o=()=>{let o;for("("==e[t]?(t++,o=s(),")"!=e[t]&&n("Unbalanced parentheses"),t++):o=(()=>{const o=t;for(;r(e[t]);)t++;let a="";const i=e.slice(o,t);if("."==e[t]){t++;const n=t;for(;r(e[t]);)t++;a=e.slice(n,t)}return i||a?Number(`${i||"0"}.${a||"0"}`):n("Expected a number")})();"%"==e[t];)t++,o/=100;return o},a=()=>"+"==e[t]?(t++,a()):"-"==e[t]?(t++,-a()):(()=>{const r=o();return"^"!=e[t]?r:(t++,r**a())})(),i=()=>{let r=a();for(;"*"==e[t]||"/"==e[t];){const o=e[t];t++;const i=a();"*"==o?r*=i:(i||n("Division by zero"),r/=i)}return r},s=()=>{let r=i();for(;"+"==e[t]||"-"==e[t];){const n=e[t];t++;const o=i();r="+"==n?r+o:r-o}return r},c=s();return t<e.length&&n("Unexpected character"),Number.isFinite(c)||n("Result is not a finite number"),c},Wt={name:"calculate",description:"Evaluate an arithmetic expression. Supports + - * / % ^ and parentheses; % divides by 100.",parameters:{type:"object",properties:{expression:{type:"string",description:"Arithmetic expression, for example 2*(3+4)"}},required:["expression"]},execute:e=>{const t=e.expression;if("string"!=typeof t)throw new Error("Missing expression");return(e=>{if(e.trim().length>200)throw new Error("Expression is too long");const t=(e=>e.replace(/×/g,"*").replace(/÷/g,"/").replace(/−/g,"-").replace(/,/g,"").replace(/\s+/g,""))(e);if(!t)throw new Error("Expression is empty");if(!Kt.test(t))throw new Error("Unsupported character");const r=Ft(t);return{expression:t,result:Math.abs(r)>=1e5?(0,j.pNum)(r)??r:(0,j.rNum)(r,12)}})(t)}};let Vt,Gt={},Jt=0,Yt=!1,Ht=!1;const Qt="degreesign-chat-prices-v1",Zt="EUR",Xt=5*j.oneMin,er=30*j.oneSec,tr=e=>{const t={};for(const[r,n]of Object.entries(e??{}))"number"==typeof n&&Number.isFinite(n)&&(t[r.trim().toUpperCase()]=n);return t},rr=(e,t)=>e&&e.sourceAt>t.sourceAt?e:t,nr=async({fiat:e,crypto:t})=>{try{const r=await fetch("https://srv.coinexams.com/data.json");if(!r.ok)throw new Error(`Price feed failed with ${r.status}`);const n=await r.json(),o=Date.now(),a=e?((e,t)=>{const r=tr(e.rates?.current),n=tr(e.rates?.yesterday);if(Object.keys(r).length)return{fetchedAt:t,sourceAt:Number(e.rates?.date)||t,rates:r,yesterday:n}})(n,o):void 0,i=t?((e,t)=>{const r=e.coins??{},n={},o={};for(const[e,t]of Object.entries(r)){const r=e.trim().toUpperCase(),a=t?.pr,i=t?.yst;"number"==typeof a&&Number.isFinite(a)&&(n[r]=a),"number"==typeof i&&Number.isFinite(i)&&(o[r]=i)}if(Object.keys(n).length)return{fetchedAt:t,sourceAt:Number(e.date)||t,prices:n,yesterday:o}})(n,o):void 0;if(e&&!a)throw new Error("Price feed is unavailable");if(t&&!i)throw new Error("Price feed is unavailable");a&&(Gt.fiat=rr(Gt.fiat,a)),i&&(Gt.crypto=rr(Gt.crypto,i)),Jt=0,Yt=!1,(()=>{try{if("undefined"==typeof localStorage)return;localStorage.setItem(Qt,JSON.stringify(Gt))}catch{}})()}catch(e){throw Jt=Date.now(),Yt=!0,e}},or=e=>!!Gt.crypto&&(e in Gt.crypto.prices||e in Gt.crypto.yesterday),ar=e=>!!Gt.fiat&&(e in Gt.fiat.rates||e in Gt.fiat.yesterday),ir=async e=>{const t=(e=>{const t={fiat:!1,crypto:!1};for(const r of e){if(r==Zt)continue;const e=or(r)||ar(r);!or(r)&&e||(t.crypto=!0),or(r)||(t.fiat=!0)}return t})(e),r=Date.now(),n=t.fiat&&r-(Gt.fiat?.fetchedAt??0)>=j.oneHr,o=t.crypto&&r-(Gt.crypto?.fetchedAt??0)>=Xt;(n||o)&&("undefined"!=typeof navigator&&!1===navigator.onLine||Jt&&r-Jt<er||(Vt||(Vt=nr({fiat:n,crypto:o}).catch(()=>{}).finally(()=>{Vt=void 0})),await Vt))},sr=e=>{if(e==Zt)return 1;const t=Gt.crypto?.yesterday[e],r=Gt.fiat?.yesterday[e];return t||(r?1/r:void 0)},cr=(e,t)=>{if("string"!=typeof e||!e.trim())throw new Error(`Missing ${t}`);return e.trim().toUpperCase()},lr=e=>Math.abs(e)>=1e5?(0,j.pNum)(e)??e:(0,j.rNum)(e,8),ur=async e=>{(()=>{if(!Ht){Ht=!0;try{if("undefined"==typeof localStorage)return;const e=localStorage.getItem(Qt);if(!e)return;const t=JSON.parse(e);Gt={...t.fiat?{fiat:t.fiat}:{},...t.crypto?{crypto:t.crypto}:{}}}catch{}}})();const t=cr(e.from,"from"),r=void 0===e.to||null===e.to?Zt:cr(e.to,"to"),n=(e=>{if(null==e)return 1;if("number"!=typeof e||!Number.isFinite(e))throw new Error("Invalid amount");return e})(e.amount);await ir([t,r]);const o=e=>{const t=(e=>{if(e==Zt)return 1;const t=Gt.crypto?.prices[e],r=Gt.fiat?.rates[e];return t||(r?1/r:void 0)})(e);if(void 0!==t)return t;if(!Gt.fiat&&!Gt.crypto)throw new Error("Prices unavailable offline");if(or(e)||ar(e))throw new Error(`Unavailable quote for ${e}`);throw new Error(`Unknown symbol ${e}`)},a=o(t),i=o(r),s=sr(t),c=sr(r),l=a/i,u=s&&c?s/c:void 0,d=void 0===u?void 0:l-u,g=void 0===u?void 0:100*(l/u-1),m=(e=>{const t=[];for(const r of e)r!=Zt&&(or(r)?Gt.crypto&&t.push(Gt.crypto.sourceAt):ar(r)&&Gt.fiat&&t.push(Gt.fiat.sourceAt));return t})([t,r]),p=m.length?Math.min(...m):Date.now();return{from:t,to:r,amount:n,rate:lr(l),...void 0===u?{}:{previousRate:lr(u),change:lr(d??0),changePercent:(0,j.rNum)(g??0,4)},result:lr(n*l),updatedAt:new Date(p).toISOString(),stale:Yt&&!(!Gt.fiat&&!Gt.crypto)}},dr={name:"currency",description:"Get the EUR price of a fiat currency, crypto coin or metal, or convert an amount. Returns the 24-hour change.",parameters:{type:"object",properties:{from:{type:"string",description:"Currency, coin or metal to convert from"},to:{type:"string",description:"Currency, coin or metal to convert to, EUR by default"},amount:{type:"number",description:"Amount to convert, 1 by default"}},required:["from"]},execute:e=>ur(e)},gr={amp:"&",apos:"'",gt:">",lt:"<",nbsp:" ",quot:'"',hellip:"...",mdash:"-",ndash:"-",ldquo:'"',lsquo:"'",rdquo:'"',rsquo:"'"},mr=(e,t,r,n)=>"number"==typeof e&&Number.isFinite(e)?Math.min(r,Math.max(t,e)):n,pr=(e,t)=>e.replace(/<[^>]*>/g," ").replace(/&(#x?[0-9a-f]+|[a-z]+);/gi,(e,t)=>{const r=(e=>{if(e.startsWith("#")){const t="x"==e[1]||"X"==e[1],r=parseInt(t?e.slice(2):e.slice(1),t?16:10);return r>0&&r<=1114111?String.fromCodePoint(r):e}return gr[e.toLowerCase()]??e})(t);return r==t?e:r}).replace(/\s+/g," ").trim().slice(0,Math.max(0,t)).trim(),fr=/^[a-z]{2,3}(-[a-z]{2,4})?$/i,yr=async(e,t)=>{const r=new AbortController,n=setTimeout(()=>r.abort(),t);try{const t=await fetch(e,{signal:r.signal});if(!t.ok)throw new Error(`Search failed with ${t.status}`);return await t.json()}catch(e){if(r.signal.aborted)throw new Error(`Search timed out after ${t} ms`);throw e}finally{clearTimeout(n)}},hr=(e={})=>{const t=((e={})=>{const t=e.language?.trim()??"";return{provider:e.provider==p.duckduckgo?p.duckduckgo:p.wikipedia,language:fr.test(t)?t:"en",limit:Math.round(mr(e.limit,1,20,3)),snippetLength:Math.round(mr(e.snippetLength,1,4e3,400)),timeout:mr(e.timeout,1e3,3e4,8e3)}})(e);return{name:"websearch",description:t.provider==p.duckduckgo?"Search DuckDuckGo for an instant answer and related topics.":"Search Wikipedia and return a few matching articles.",parameters:{type:"object",properties:{query:{type:"string",description:"What to search for"}},required:["query"]},execute:async e=>{const r="string"==typeof e.query?e.query.trim():"";if(!r)throw new Error("Missing query");const n=t.provider==p.duckduckgo?await(async(e,t)=>{const r=`https://api.duckduckgo.com/?format=json&no_html=1&skip_disambig=1&q=${encodeURIComponent(t)}`,n=await yr(r,e.timeout),o=[],a=new Set,i=(t,r,n)=>{t&&n&&!a.has(t)&&(a.add(t),o.push({title:pr(r||n,200),url:t,snippet:pr(n,e.snippetLength)}))},s=e=>{for(const t of e)t.Topics?s(t.Topics):i(t.FirstURL,t.Text,t.Text)};i(n.AbstractURL,n.Heading||n.AbstractText,n.AbstractText);for(const e of n.Results??[])i(e.FirstURL,e.Text,e.Text);return s(n.RelatedTopics??[]),o.slice(0,e.limit)})(t,r):await(async(e,t)=>{const r=`https://${e.language}.wikipedia.org`,n=`${r}/w/rest.php/v1/search/page?q=${encodeURIComponent(t)}&limit=${e.limit}`,o=await yr(n,e.timeout),a=[];for(const t of o.pages??[]){const n=t.key;n&&a.push({title:pr(t.title??n,200),url:`${r}/wiki/${encodeURIComponent(n)}`,snippet:pr(`${t.description??""} ${t.excerpt??""}`,e.snippetLength)})}return a})(t,r);return n}}},wr=(e,t)=>{const r=[];for(const n of e)n==m.websearch?r.push(hr(t)):n==m.calculate?r.push(Wt):n==m.currency&&r.push(dr);return r},br=128;export{m as BuiltinTool,g as ChatModelId,u as ChatPreloadField,o as ChatStatus,l as DescriptionEnhancedStage,c as EstimateOperation,i as LlmBackend,s as LlmPhase,n as LlmRole,a as LlmStatus,p as WebSearchProvider,wr as builtinTools,Wt as calculateTool,pt as clearModelCache,gt as createChat,dr as currencyTool,$t as describeImage,zt as describeImages,Nt as describeModelId,It as describeTranslated,Ut as descriptionEnhanced,v as gpuAdapter,br as imageReplyTokens,mt as preloadModel,qt as translateTags,hr as webSearchTool};
@@ -11,6 +11,8 @@ litertContextWindow = 32768, // max 32_768
11
11
  mobileLitertContextWindow = 16384, // max 32_768
12
12
  /** Whether this client is mobile */
13
13
  mobileDevice: (nav?: MobileNavigator) => boolean,
14
+ /** Context window of one model */
15
+ contextWindow: (model: ChatModel) => number,
14
16
  /** Find catalog entry by id */
15
17
  findLlmModel: (id?: string) => ChatModel | undefined,
16
18
  /** Whether browser has WebGPU adapter */
@@ -23,4 +25,4 @@ resolveLlmModel: (id?: ChatModelId) => Promise<ChatModel | undefined>,
23
25
  supportsImages: (model: ChatModel) => boolean,
24
26
  /** Whether a model accepts audio */
25
27
  supportsAudio: (model: ChatModel) => boolean;
26
- export { llmModels, cpuContextWindow, mobileCpuContextWindow, litertContextWindow, mobileLitertContextWindow, mobileDevice, findLlmModel, gpuAdapter, defaultLlmModel, resolveLlmModel, supportsImages, supportsAudio, };
28
+ export { llmModels, cpuContextWindow, mobileCpuContextWindow, litertContextWindow, mobileLitertContextWindow, contextWindow, mobileDevice, findLlmModel, gpuAdapter, defaultLlmModel, resolveLlmModel, supportsImages, supportsAudio, };
@@ -5,7 +5,7 @@ defaultLlmLimits: LlmLimits,
5
5
  /** Merge budgets over backend defaults */
6
6
  resolveLlmLimits: (overrides?: Partial<LlmLimits>, gpu?: boolean) => LlmLimits,
7
7
  /** Sampling options for every stream */
8
- replyOptions: (limits: LlmLimits, reasoning: boolean, temperature?: number) => {
8
+ replyOptions: (limits: LlmLimits, reasoning: boolean, temperature?: number, maxTokens?: number) => {
9
9
  stream: true;
10
10
  temperature: number;
11
11
  max_tokens: number;
@@ -4,7 +4,7 @@ declare const
4
4
  /** Smallest Gemma 4 vision budget */
5
5
  visionTokens = 70,
6
6
  /** GPU busy share of time */
7
- gpuShare = 0.5,
7
+ gpuShare = 1,
8
8
  /** Most rest per readback */
9
9
  maxRestMs = 500;
10
10
  declare const
@@ -21,7 +21,7 @@ toLitertMessages: (messages: EngineMessage[], keepMedia?: boolean) => Promise<Li
21
21
  /** Whether conversation holds incoming history */
22
22
  continuesHistory: (sent: EngineMessage[], history: EngineMessage[]) => boolean,
23
23
  /** Stream LiteRT reply as chunks */
24
- streamLitert: ({ engine, mod, params, messages, session, }: StreamLitertParams) => AsyncGenerator<EngineChunk>,
24
+ streamLitert: ({ engine, mod, params, messages, maxTokens, session, }: StreamLitertParams) => AsyncGenerator<EngineChunk>,
25
25
  /** Engine settings with vision budget */
26
26
  litertSettings: ({ model, limits, contextSize, source, mod, }: LitertSettingsParams) => LitertSettings, litertEngine: LlmEngine;
27
27
  export { cacheModel, continuesHistory, gpuShare, litertEngine, litertSettings, maxRestMs, releaseDevice, restFor, streamLitert, throttledDevice, toLitertMessages, visionTokens, };