@degreesign/chat 1.1.0 → 1.2.0
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 +62 -12
- package/dist/browser/chat.min.mjs +1 -1
- package/dist/chat.d.ts +4 -4
- package/dist/describe.d.ts +15 -6
- package/dist/engines/engine.d.ts +12 -12
- package/dist/engines/images.d.ts +8 -8
- package/dist/engines/litert.d.ts +22 -10
- package/dist/engines/store.d.ts +4 -4
- package/dist/engines/threads.d.ts +1 -1
- package/dist/engines/wllama.d.ts +4 -4
- package/dist/enums.d.ts +6 -6
- package/dist/index.d.ts +1 -1
- package/dist/log.d.ts +1 -1
- package/dist/models.d.ts +13 -11
- package/dist/node/chat.node.min.js +1 -1
- package/dist/node/chat.node.min.mjs +1 -1
- package/dist/tools/calculator.d.ts +2 -2
- package/dist/tools/currency.d.ts +3 -3
- package/dist/tools/index.d.ts +1 -1
- package/dist/tools/search.d.ts +3 -3
- package/dist/tools/text.d.ts +3 -3
- package/dist/types.d.ts +216 -173
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
# @degreesign/chat
|
|
2
2
|
|
|
3
|
-
One-shot on-device AI chat for browsers, workers and Node,
|
|
4
|
-
engine
|
|
5
|
-
package
|
|
3
|
+
One-shot on-device AI chat for browsers, workers and Node, using wllama CPU
|
|
4
|
+
engine and LiteRT-LM WebGPU engine.
|
|
5
|
+
The package is an A-Z solution for local AI chat and more.
|
|
6
|
+
Includes voice transcription to many languages
|
|
7
|
+
and a super accurate image vision function.
|
|
8
|
+
The package manages download of AI models automatically,
|
|
9
|
+
with auto resume for low network connections.
|
|
10
|
+
|
|
11
|
+
`@degreesign/chat` is plug and play solution for any UI.
|
|
6
12
|
|
|
7
13
|
[](https://www.npmjs.com/package/@degreesign/chat)
|
|
8
14
|
[](#licensing)
|
|
@@ -25,6 +31,7 @@ package loads one model, streams one reply and reports status.
|
|
|
25
31
|
- [Node.js](#nodejs)
|
|
26
32
|
- [React](#react)
|
|
27
33
|
- [Types](#types)
|
|
34
|
+
- [Testing](#testing)
|
|
28
35
|
- [Architecture](#architecture)
|
|
29
36
|
- [FAQ](#faq)
|
|
30
37
|
- [Licensing](#licensing)
|
|
@@ -224,6 +231,13 @@ model. A lost device needs a page or model reload; later calls cannot reuse it.
|
|
|
224
231
|
A phone or tablet resolves Gemma to the text-only browser build, so it never
|
|
225
232
|
starts the vision or audio encoder.
|
|
226
233
|
|
|
234
|
+
While a reply streams, the GPU engine rests after every token readback, so the
|
|
235
|
+
card stays near 70% of wall time instead of pegging at 100% and starving the
|
|
236
|
+
desktop compositor. The rest applies after the prefill, so the first token is
|
|
237
|
+
not delayed. Unloading releases the WebGPU device and resets the LiteRT wasm,
|
|
238
|
+
because a deleted engine leaves both unusable; a later load rebuilds them from
|
|
239
|
+
the stored model file without downloading it again.
|
|
240
|
+
|
|
227
241
|
## Public API
|
|
228
242
|
|
|
229
243
|
```ts
|
|
@@ -232,6 +246,7 @@ preloadModel(input?: ChatPreloadInput): Promise<boolean>
|
|
|
232
246
|
describeImages(input: DescribeImagesInput): Promise<ImageDescription[]>
|
|
233
247
|
describeTranslated(input: DescribeTranslatedInput): Promise<string[]>
|
|
234
248
|
describeModelId: ChatModelId
|
|
249
|
+
imageReplyTokens: number
|
|
235
250
|
clearModelCache(): Promise<void>
|
|
236
251
|
```
|
|
237
252
|
|
|
@@ -318,15 +333,17 @@ adapter exists and `targetLanguage` is not English, the English descriptions
|
|
|
318
333
|
are then translated one by one with `gemma4_e2b_limited`. Without a GPU, when
|
|
319
334
|
the translation model cannot load, or when the translator replies
|
|
320
335
|
`CANNOT_TRANSLATE`, `description` stays equal to `descriptionEN`. Both the
|
|
321
|
-
description and translation calls use
|
|
322
|
-
`limits.maxReplyTokens` overrides it. The describer
|
|
323
|
-
|
|
324
|
-
models leave the engine image limits
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
336
|
+
description and translation calls use the `imageReplyTokens` budget of 128
|
|
337
|
+
tokens unless `limits.maxReplyTokens` overrides it. The describer requests
|
|
338
|
+
192 vision tokens for its image resize; the CPU engine keeps its instruct
|
|
339
|
+
window at 16 to 128 tokens, and other models leave the engine image limits
|
|
340
|
+
unset.
|
|
341
|
+
|
|
342
|
+
The describer receives a system message that asks for every element of the
|
|
343
|
+
image and adds rules against lying, verdicts and vague referrals.
|
|
344
|
+
`DescribeImagesInput.additionalRules` appends host rules to that message. The
|
|
345
|
+
translator translates its own previous reply, never the user's instruction,
|
|
346
|
+
preserving meaning, names and numbers without adding or omitting anything.
|
|
330
347
|
|
|
331
348
|
`DescribeImagesInput`:
|
|
332
349
|
|
|
@@ -499,6 +516,11 @@ GPU_ARTISAN build Google ships for browsers. The smaller file is what keeps a
|
|
|
499
516
|
mobile tab alive at the end of the model load, and a desktop can ask for it
|
|
500
517
|
too, trading vision and audio for 600 MB less download.
|
|
501
518
|
|
|
519
|
+
The WebGPU engine asks for a 32768 token context on a desktop and 16384 on a
|
|
520
|
+
phone, both multiples of 1024. Its int8 KV cache holds the full desktop window
|
|
521
|
+
in about 300 MB, so the larger window stays a small part of the 2 GB model
|
|
522
|
+
footprint.
|
|
523
|
+
|
|
502
524
|
The WebGPU engine keeps one LiteRT conversation for consecutive turns. When the
|
|
503
525
|
next prompt continues that history, only the new user turn is sent. A changed
|
|
504
526
|
history opens a fresh conversation, and older images and audio become `[image]`
|
|
@@ -712,6 +734,34 @@ const useReply = () => {
|
|
|
712
734
|
The public enums are `ChatModelId`, `LlmRole`, `ChatStatus`, `LlmStatus`,
|
|
713
735
|
`LlmBackend` and `LlmPhase`.
|
|
714
736
|
|
|
737
|
+
## Testing
|
|
738
|
+
|
|
739
|
+
The suites live in `test/` and run against the local checkout.
|
|
740
|
+
|
|
741
|
+
`yarn test:instruct` starts a local llama.cpp server with the Qwen3-VL 2B
|
|
742
|
+
Instruct Q3_K_M build:
|
|
743
|
+
|
|
744
|
+
```bash
|
|
745
|
+
yarn test:instruct
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
It runs `llama serve` on `http://127.0.0.1:8080` with a 160k context, 4
|
|
749
|
+
threads and CPU inference. llama.cpp
|
|
750
|
+
downloads the weights on first run and caches them outside the repository.
|
|
751
|
+
llama.cpp runs about 10x faster than wllama, so prefer the live server
|
|
752
|
+
whenever a test needs real inference. Keep the server in its own terminal
|
|
753
|
+
while the live and image suites run.
|
|
754
|
+
|
|
755
|
+
The image suite bundles the browser harness, serves it from `test/drive.cjs`
|
|
756
|
+
and proxies `/llama/` to the server on port 8080, so start `test:instruct`
|
|
757
|
+
first:
|
|
758
|
+
|
|
759
|
+
```bash
|
|
760
|
+
yarn test:images
|
|
761
|
+
```
|
|
762
|
+
|
|
763
|
+
The fake-engine harness needs no server and never reaches the network.
|
|
764
|
+
|
|
715
765
|
## Architecture
|
|
716
766
|
|
|
717
767
|
An interactive map of the package lives at
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! For license information please see chat.min.mjs.LICENSE.txt */
|
|
2
|
-
var e={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;let d;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.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="gemma4-e2b",e.gemma4_e2b_limited="gemma4-e2b-limited"}(c||(c={})),function(e){e.websearch="websearch",e.calculate="calculate",e.currency="currency"}(l||(l={})),function(e){e.wikipedia="wikipedia",e.duckduckgo="duckduckgo"}(u||(u={}));const g=[{id:c.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:c.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:c.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:c.gemma4_e2b,reasoning:!0,litert:{repo:"litert-community/gemma-4-E2B-it-litert-lm",file:"gemma-4-E2B-it.litertlm",vision:!0,audio:!0}},{id:c.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}}],m=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},p=(e,t=m())=>e==c.gemma4_e2b&&t?c.gemma4_e2b_limited:e,f=e=>e?g.find(t=>t.id==e):void 0,h=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)}},y=async e=>f(p(e??await(async()=>(d||(d=(async()=>await h()?p(c.gemma4_e2b):c.qwen3_vl_2b)()),await d))())),w=e=>!!e.cpu?.mmproj||!0===e.litert?.vision,b=e=>!!e.cpu?.mmproj?.audio||!0===e.litert?.audio,v=new URL("./../assets/wllama/wllama.wasm",import.meta.url).href,x=new URL("./../assets/wllama/compat/wllama.wasm",import.meta.url).href,M=new URL("./../assets/wllama/compat/wllama.js",import.meta.url).href,j=new URL("./../assets/litert/litertlm_wasm_internal.js",import.meta.url).href,k=(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)=>{if(!e||"function"!=typeof fetch||"function"!=typeof createImageBitmap)return e;try{const r=await fetch(e),n=await createImageBitmap(await r.blob()),o=t??((e,t)=>{const r=e/Math.max(1,t);let n=32,o=32,a=1/0,i=1/0;for(let e=1;e<=128;e++){const t=Math.ceil(128/e),s=Math.floor(136/e);for(let c=t;c<=s;c++){const t=c*e,s=Math.abs(c/e-r);(s<a-1e-9||Math.abs(s-a)<=1e-9&&t<i)&&(n=32*c,o=32*e,a=s,i=t)}}return{width:n,height:o}})(n.width,n.height),a=n.width/Math.max(1,n.height),i=o.width/o.height,s=Math.min(n.width,a>i?n.height*i:n.width),c=Math.min(n.height,a>i?n.height:n.width/i),l=(n.width-s)/2,u=(n.height-c)/2,d=((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})(o.width,o.height),g=d?d.getContext("2d"):null;if(!d||!g||n.width<1||n.height<1)return n.close(),e;if(g.drawImage(n,l,u,s,c,0,0,o.width,o.height),n.close(),(e=>"undefined"!=typeof OffscreenCanvas&&e instanceof OffscreenCanvas)(d)){const t=await d.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 d.toDataURL("image/jpeg",.85)}catch{return e}};var S=r(155);const P={maxReplyTokens:250,maxThinkingTokens:128,maxReasoningTokens:320,maxImages:2,maxAudio:1,maxContentLength:1e3,promptCharBudget:1e4,maxThreads:32},O=(e,t,r)=>"number"==typeof e&&Number.isFinite(e)&&e>=r?Math.floor(e):t,D=(e={},t=!1)=>{const r=P;return{maxReplyTokens:O(e.maxReplyTokens,r.maxReplyTokens,1),maxThinkingTokens:O(e.maxThinkingTokens,r.maxThinkingTokens,1),maxReasoningTokens:O(e.maxReasoningTokens,t?1200:r.maxReasoningTokens,1),maxImages:O(e.maxImages,r.maxImages,0),maxAudio:O(e.maxAudio,r.maxAudio,0),maxContentLength:O(e.maxContentLength,r.maxContentLength,1),promptCharBudget:O(e.promptCharBudget,r.promptCharBudget,1),maxThreads:O(e.maxThreads,r.maxThreads,1)}},C=(e,t)=>({stream:!0,temperature:.7,max_tokens:t?e.maxReasoningTokens:e.maxReplyTokens}),N=(e,t)=>`https://huggingface.co/${e}/resolve/main/${t}`,E=e=>Number(e.headers.get("content-length"))||0,L=(e,t)=>e.some(e=>Array.isArray(e.content)&&e.content.some(e=>e.type==t)),A=e=>L(e,"image"),R=e=>L(e,"audio"),$=["<|channel>thought\n","<|channel>thought","..."],q=["<channel|>","..."],U=(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,I=e=>"string"==typeof e?e?[{type:"text",text:e}]:[]:e,z=(e,t)=>{if("string"==typeof e&&"string"==typeof t)return`${e}\n${t}`;const r=[];for(const n of[...I(e),{type:"text",text:"\n"},...I(t)]){const e=r[r.length-1];"text"==n.type&&"text"==e?.type?e.text+=n.text:r.push(n)}return r},F=m()?3e6:3e5,V=Math.max(F,84e4);class B extends Error{}const W=async(e,t,r)=>{let n;try{return await Promise.race([e,new Promise((e,o)=>{n=setTimeout(()=>o(new B(r)),t)})])}finally{n&&clearTimeout(n)}},Q=e=>{try{Promise.resolve(e.return?.()).catch(()=>{})}catch{}},Y=async({model:e,logging:t,onReason:r,onText:n,onSpeed:o,start:a,stopped:i,firstTimeoutMs:s=F,idleTimeoutMs:c=3e4,onStall:l})=>{let u="",d="",g="",m=!1,p=0,f=0;const h=((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,q);if(t>=0){t&&e(s.slice(0,t)),s=s.slice(t+i.length),n=!1;continue}const c=a(s,q);e(s.slice(0,s.length-c.length)),r=c;break}{const{at:e,tag:i}=o(s,$);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,$);t(s.slice(0,s.length-c.length)),r=c;break}}},flush:()=>{r&&(n?e(r):t(r),r="")}}})(e=>{d+=e,r(e)},e=>{u+=e,n(e)});try{const e=(await W(a(),s,"Model did not start"))[Symbol.asyncIterator]();for(;;){if(i()){Q(e);break}let n;try{n=await W(e.next(),m?c:s,m?"Model stopped responding":"Model did not reply")}catch(r){if(r instanceof B&&(u||d)){l?.(),Q(e),t&&console.log("Local chat stalled",r);break}throw r}if(n.done)break;m=!0;const a=n.value?.choices?.[0],y=a?.delta,w="string"==typeof y?.reasoning_content?y.reasoning_content:"string"==typeof y?.reasoning?y.reasoning:"";if(a?.finish_reason&&(g=a.finish_reason),w&&(d+=w,r(w)),y?.content&&h.feed(y.content),w||y?.content){const e=performance.now();p||(f=e),p+=1,p>1&&e>f&&o?.((0,S.rNum)(1e3*p/(e-f)))}}h.flush()}catch(e){if(t&&console.log("Local chat failed",e),e instanceof B&&!i())throw e}const y=i()?void 0:u||void 0;return t&&(console.log("Local chat reply",e.id,y?"****":""),console.log("Local chat finish",e.id,g||"none",u.length,d.length)),y},G=async({model:e,params:t,start:r,stopped:o,onStall:a})=>{const i=await(async(e,t)=>{const r=[];for(const n of e){if("string"==typeof n.content){r.push(n);continue}const e=[];for(const r of n.content)e.push("image"==r.type?{type:"image",url:await T(r.url,t)}:r);r.push({role:"user",content:e})}return r})(((e,t=P)=>{const r=t.maxContentLength,o=e.filter(e=>"string"==typeof e.content&&!!e.content.trim()||!(e.role!=n.user||!e.images?.length&&!e.audio?.length)),a=[],i=[];let s=0,c=t.maxImages,l=t.maxAudio;for(let e=o.length-1;e>=0;e--){const u=o[e],d=("string"==typeof u.content?u.content:"").slice(0,r),g=u.role==n.user?(u.images||[]).filter(e=>"string"==typeof e&&!!e).slice(0,Math.max(0,c)):[],m=u.role==n.user?(u.audio||[]).filter(e=>"string"==typeof e&&!!e).slice(0,Math.max(0,l)):[];if(d||g.length||m.length){if(d&&s+d.length>t.promptCharBudget)break;s+=d.length,c-=g.length,l-=m.length,u.role==n.system?a.unshift(d):u.role==n.assistant?i.unshift({role:"assistant",content:d}):i.unshift({role:"user",content:U(d,g,m)})}}for(;i.length&&"user"!=i[0].role;)i.shift();const u=[];for(const e of i){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=z(t.content,e.content):"assistant"==e.role?u.push({role:"assistant",content:e.content}):u.push({role:"user",content:e.content})}const d=a.join("\n\n"),g=[];return d&&g.push({role:"system",content:d}),g.push(...u),g})(t.messages,t.limits),e.litert?k:void 0);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 Y({model:e,logging:t.logging,onReason:t.onReason,onText:t.onText,onSpeed:t.onSpeed,start:()=>r(i),stopped:o,onStall:a,firstTimeoutMs:A(i)?V:F})},H=33554432,J=new Map;let Z=!1;const K=e=>{const t=(e.split("/").pop()||"model").replace(/[^\w.-]+/g,"_");let r=0;for(let t=0;t<e.length;t++)r=31*r+e.charCodeAt(t)>>>0;return`${r.toString(16)}-${t}`},X=e=>{const t=/^part-(\d+)$/.exec(e);return t?Number(t[1]):-1},ee=async()=>{if(!Z)if("undefined"!=typeof navigator&&navigator.storage?.getDirectory)try{return await navigator.storage.getDirectory()}catch{return}else Z=!0},te=async(e,t)=>{try{return await e.getDirectoryHandle(t)}catch{return}},re=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}},ne=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{}},oe=async function*(e){for await(const t of e)yield t},ae=async e=>{try{for await(const[t,r]of oe(e))"file"==r.kind&&X(t)>=0&&await e.removeEntry(t).catch(()=>{})}catch{}},ie=async(e,t)=>{try{const r=await(await e.getFileHandle(t)).getFile(),n=await re(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}},se=async(e,t)=>{const r=await te(e,t);if(r){const e=await(async e=>await re(await e.getFileHandle("meta.json").catch(()=>{})))(r),t=await(async e=>{const t=[];try{for await(const[r,n]of oe(e)){const e=X(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=>{const t=[];let r=0;for(const n of[...e].sort((e,t)=>e.start-t.start))if(n.size){if(n.start!=r)break;t.push(n),r+=n.size}return t})(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 ie(e,t)},ce=(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(e)||t.total,etag:a||t.etag}},le=async({dir:e,start:t,skip:r,total:n,body:o,onProgress:a,onChunk:i})=>{let c,l=t,u=0,d=r;const g=async()=>{const t=await e.getFileHandle((e=>`part-${e}`)(l),{create:!0});c=await t.createWritable(),u=0},m=async()=>{const e=c;c=void 0,e&&await e.close().catch(()=>{})};try{const e=o.getReader();for(;;){const{done:r,value:o}=await e.read();if(r)break;i();let p=0;for(d&&(p=Math.min(d,o.byteLength),d-=p);p<o.byteLength;){c||await g();const e=Math.min(H-u,o.byteLength-p);await c.write({type:"write",position:u,data:o.subarray(p,p+e)}),p+=e,u+=e,l+=e,u==H&&await m()}l>t&&a(n?l/n:0,s.download)}await m()}catch(e){throw await m(),e}return l},ue=e=>["NotAllowedError","NotSupportedError"].includes(e?.name||""),de=e=>{const t=async()=>{const t=await ee();if(t)try{return await t.getDirectoryHandle(e,{create:!0})}catch{return}};return{stored:async e=>{const r=await t();return r?await se(r,K(e)):void 0},download:async({url:r,signal:n,onProgress:o})=>{const a=`${e}|${r}`,i=J.get(a);if(i)return await i;const c=await t();if(!c)return;const l=(async(e,t,r,n)=>{const o=K(t),a=await ie(e,o);if(a?.complete)return a;let i=await te(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;for(;;){if(r?.aborted)throw new Error("Cancelled");const a=await se(e,o);if(a?.complete)return a;const u=a?.size??0,d=a?.total||0,g=a?.etag||"";if(u>c)c=u,l=0;else if(++l>4)throw new Error("Model download failed");u&&d&&n(u/d,s.download);const m=d?Math.min(u+H,d)-1:u+H-1,p=new AbortController,f=()=>p.abort(),h={size:u,total:d,etag:g};let y,w=setTimeout(f,3e4);r?.addEventListener("abort",f,{once:!0});try{if(y=await fetch(t,{signal:p.signal,headers:{Range:`bytes=${u}-${m}`}}),416==y.status){if(await(y.body?.cancel().catch(()=>{})),d&&u>=d){await ne(i,{total:d,etag:g,complete:!0});continue}await ae(i),await ne(i,{total:0,etag:"",complete:!1});continue}if(!y.ok||!y.body)throw await(y.body?.cancel().catch(()=>{})),new Error("Model download failed");const r=ce(y,h);if(!r){await y.body.cancel().catch(()=>{}),await ae(i),await ne(i,{total:0,etag:"",complete:!1});continue}await ne(i,{total:r.total,etag:r.etag,complete:!1});const a=0==r.start?u:0,s=await le({dir:i,start:r.start+a,skip:a,total:r.total,body:y.body,onProgress:n,onChunk:()=>{clearTimeout(w),w=setTimeout(f,3e4)}});if(!r.total){await ne(i,{total:s,etag:r.etag,complete:!0});const t=await se(e,o);if(t)return t}}catch(e){if(r?.aborted)throw new Error("Cancelled");if(e instanceof DOMException&&["QuotaExceededError","NotAllowedError","NotSupportedError","InvalidStateError","TypeMismatchError","SecurityError"].includes(e.name))throw e;await new Promise(e=>setTimeout(e,250+500*l))}finally{clearTimeout(w),r?.removeEventListener("abort",f)}}})(c,r,n,o).finally(()=>{J.delete(a)});return J.set(a,l),await l},remove:async e=>{const r=await t();r&&await(async(e,t)=>{await e.removeEntry(t,{recursive:!0}).catch(()=>{}),await e.removeEntry(`${t}.json`).catch(()=>{})})(r,K(e))},purge:async()=>{const t=await ee();t&&await t.removeEntry(e,{recursive:!0}).catch(()=>{})}}},ge=(e,...t)=>{!0===e&&console.log(...t)},me="litertlm-models",pe=de("litert-store"),fe={num_output_candidates:1,wait_for_weight_uploads:!0,num_decode_steps_per_sync:3,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 he=!1,ye=0;const we=(...e)=>{he&&console.log(...e)},be=(...e)=>{he&&console.error(...e)},ve=e=>e.replace(/<\|channel>thought\n?[\s\S]*?<channel\|>/g,"").replace(/<\|channel>thought[\s\S]*$/,"").trim(),xe=async()=>{try{if("undefined"==typeof caches)return;return await caches.open(me)}catch{return}},Me=new Map,je=(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)}}))},ke=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},_e=(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&&ve(e.content)==ve(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(ve(n.text)!=ve(o.text))return!1}else{if("text"==n.type||"text"==o.type)return!1;if(!!n.url!=!!o.url)return!1}}return!0},Te=async function*({engine:e,mod:t,params:r,messages:n,session:o}){const a=n[n.length-1],i=C(r.limits,r.reasoning);if("user"!=a?.role)throw new Error("No user turn");const s=n.slice(0,-1),c=(await ke([a]))[0];if(!c)throw new Error("Empty prompt");const l=o.reasoning==r.reasoning&&o.maxTokens==i.max_tokens,u=!!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&&!_e(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(!_e(o[i+e],a[e]))return!1;return!0})(o.sent,s);let d;if(l&&u&&o.conversation)ge(he,"LiteRT conversation reused",o.sent.length),d=o.conversation;else{const n=await ke(s,!1);o.conversation=void 0,o.sent=[];const a=performance.now();d=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}),ge(he,"LiteRT conversation created",n.length,Math.round(performance.now()-a),"flags",l,"history",u),o.conversation=d,o.reasoning=r.reasoning,o.maxTokens=i.max_tokens,o.sent=[...s]}o.sent.push(a);let g,m=!1,p=!0,f="";const h=(()=>{let e=0;return async t=>{if(!(t>0))return;if(e+=.25*t,e<12)return;const r=Math.min(120,e);e-=r,await new Promise(e=>setTimeout(e,Math.round(r)))}})(),y=()=>{g&&g.cancel().catch(()=>{});try{d.cancel()}catch{}};r.signal?.addEventListener("abort",y,{once:!0});try{if(r.signal?.aborted)return;const e=d.sendMessageStreaming(c).getReader();for(g=e;;){const t=performance.now(),{done:r,value:n}=await e.read(),o=performance.now()-t;if(r)break;const a=p;p=!1,a&&ge(he,"LiteRT first chunk",Math.round(o));const i={};let s="string"==typeof n.content?n.content:"";if(Array.isArray(n.content))for(const e of n.content)"text"==e.type&&(s+=e.text);s&&(i.content=s,f+=s);const c=n.channels?.thought;c&&(i.reasoning=c),(i.content||i.reasoning)&&(yield{choices:[{delta:i}]}),a||await h(o)}m=!0}finally{r.signal?.removeEventListener("abort",y),m&&f?o.sent.push({role:"assistant",content:f}):(o.conversation=void 0,o.sent=[])}},Se={backend:i.gpu,startLLM:async({model:e,limits:t,onProgress:n,signal:o,logging:a})=>{he=!0===a;const c=e.litert;if(!c)throw new Error("Model has no LiteRT artifact");const l=await r.e(520).then(()=>r(507)),u=globalThis,d=u.Module;u.Module={print:we,printErr:be};try{await l.getOrLoadGlobalLiteRtLm(j)}finally{u.Module=d}if(o?.aborted)throw new Error("Cancelled");const g=N(c.repo,c.file),m=await xe();let p;const f=m?await m.match(g):void 0;if(f?.body)p=f.body;else{const e=await pe.stored(g);e?.complete&&(p=e.file.stream())}if(!p){const e=await pe.download({url:g,signal:o,onProgress:n}).catch(e=>{if(o?.aborted)throw new Error("Cancelled");if(!ue(e))throw e;a&&console.log("Local model store failed",e)});e&&(p=e.file.stream())}if(!p&&m)try{await(async(e,t,r,n)=>{const o=Me.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=E(o),i=je(o.body,a,n);await t.put(e,new Response(i,{headers:{"content-type":"application/octet-stream",...a?{"content-length":`${a}`}:{}}}))})().finally(()=>{Me.delete(e)});return Me.set(e,a),await a})(g,m,o,n);const e=await m.match(g);e?.body&&(p=e.body)}catch(e){if(o?.aborted)throw new Error("Cancelled");a&&console.log("Local model cache failed",e)}if(p||(p=await(async(e,t,r)=>{const n=await fetch(e,{signal:t});if(!n.ok||!n.body)throw new Error("Model download failed");return je(n.body,E(n),r)})(g,o,n)),o?.aborted)throw new Error("Cancelled");n(1,s.load);const h=await l.Engine.create((({model:e,limits:t,source:r,mod:n})=>{const o=e.litert;return{model:r,mainExecutorSettings:{maxNumTokens:4096,...o?.vision?{maxNumImages:Math.max(1,t.maxImages)}:{},backendConfig:fe},...o?.vision?{visionBackend:n.Backend.GPU,maxVisionTokensPerImage:70,minVisionTokensPerImage:70}:{},...o?.audio?{audioBackend:n.Backend.CPU}:{}}})({model:e,limits:t,source:p,mod:l}));ye+=1;const y=()=>{ye=Math.max(0,ye-1),ye||(e=>{try{e.getGlobalLiteRtLm().liteRtLmWasm.preinitializedWebGPUDevice=void 0}catch{}})(l)};try{const e=performance.now(),t=await h.createConversation();await t.delete(),ge(he,"LiteRT conversation warm-up",Math.round(performance.now()-e))}catch(e){ge(he,"LiteRT conversation warm-up failed",e)}if(o?.aborted)throw await h.delete(),y(),new Error("Cancelled");const w={sent:[],reasoning:!1,maxTokens:0};return{model:e,backend:i.gpu,contextSize:4096,chat:t=>(async({engine:e,model:t,mod:r,params:n,session:o})=>{he=!0===n.logging;const a=()=>{try{o.conversation?.cancel()}catch{}o.conversation=void 0,o.sent=[]};try{return await G({model:t,params:n,stopped:()=>!!n.signal?.aborted,onStall:a,start:async a=>{if(n.signal?.aborted)throw new Error("Cancelled");if(A(a)&&!t.litert?.vision)throw new Error("Model does not accept images");if(R(a)&&!t.litert?.audio)throw new Error("Model does not accept audio");return Te({engine:e,mod:r,params:n,messages:a,session:o})}})}catch(e){throw a(),e}})({engine:h,model:e,mod:l,params:t,session:w}),unload:async()=>{const e=w.conversation;w.conversation=void 0,w.sent=[];try{await(e?.delete())}catch{}await h.delete(),y()}}},cached:async e=>{const t=e.litert;if(!t)return!1;const r=N(t.repo,t.file),[n,o]=await Promise.all([xe(),pe.stored(r)]);if(o?.complete)return!0;try{return!(!n||!await n.match(r))}catch{return!1}},purge:async()=>{try{await pe.purge(),"undefined"!=typeof caches&&await caches.delete(me)}catch{}}},Pe=de("wllama-store"),Oe=[c.qwen3_vl_2b_instruct,c.qwen3_vl_2b_instruct_q3],De=e=>e.cpu?.mmproj&&Oe.includes(e.id)?{image_min_tokens:16,image_max_tokens:128}:{};let Ce,Ne,Ee="",Le=!1;const Ae=e=>`${e.wasm}|${e.compatWasm}|${e.compatWorker}`,Re=e=>{const t={wasm:v,compatWasm:x,compatWorker:M};return{wasm:e?.wasm||t.wasm,compatWasm:e?.compatWasm||t.compatWasm,compatWorker:e?.compatWorker||t.compatWorker}},$e=e=>{const t=e=>(...t)=>{Le&&("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)}},qe=async()=>{if(Ce)return Ce;const e=await r.e(924).then(()=>r(577)),t=Ne||Re(),n=new e.Wllama({default:t.wasm},{logger:$e(e.LoggerWithoutDebug)});return Ne||(Ne=t,Ee=Ae(t)),n.setCompat({wasm:t.compatWasm,worker:t.compatWorker}),Ce=n,n},Ue=async()=>{const e=Ce;Ce=void 0;try{await(e?.exit())}catch{}},Ie=(e,t)=>e.name.includes(t)||!!e.metadata?.originalURL?.includes(t),ze=e=>{const t=e.cpu;return t?[{name:t.file,url:N(t.repo,t.file)},...t.mmproj?[{name:t.mmproj.file,url:N(t.mmproj.repo??t.repo,t.mmproj.file)}]:[]]:[]},Fe=async e=>{const t=ze(e);if(!t.length)return!1;for(const e of t){const t=await Pe.stored(e.url);if(!t?.complete)return!1}return!0},Ve=async(e,t)=>{const r=await e.cacheManager.list();return ze(t).every(e=>r.some(t=>Ie(t,e.name)))},Be=async({model:e,signal:t,onProgress:r})=>{const n=ze(e),o=[];for(let e=0;e<n.length;e++){if(t?.aborted)throw new Error("Cancelled");const a=await Pe.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},We=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},Qe={backend:i.cpu,startLLM:async({model:e,limits:t,onProgress:r,signal:n,logging:o,assets:a})=>{Le=!0===o;const c=m()?4096:8192,l=e.cpu;if(!l)throw new Error("Model has no CPU artifact");const u=Re(a),d=Ae(u);Ce&&d!=Ee&&await Ue(),Ne=u,Ee=d;const g="undefined"!=typeof navigator?navigator.hardwareConcurrency:0,p=Math.min((e=>{const t=e||4;return Math.max(1,t-Math.max(1,Math.floor(t/5)))})(g),t.maxThreads),f=await qe(),h=await Fe(e),y=l.mmproj?.file,w=N(l.repo,l.file),b=y?N(l.mmproj?.repo??l.repo,y):"";if(n?.aborted)throw await Ue(),new Error("Cancelled");if(!h&&y){const e=await f.cacheManager.list(),t=e.some(e=>Ie(e,l.file)),r=e.some(e=>Ie(e,y));t&&!r&&await f.cacheManager.deleteMany(e=>Ie(e,l.file))}const v={n_ctx:c,n_threads:p,n_parallel:1,warmup:!0,reasoning_budget_tokens:t.maxThinkingTokens,n_gpu_layers:0,jinja:!0,...De(e)};try{let t=h?await Be({model:e,signal:n,onProgress:r}):void 0;t||h||await Ve(f,e).catch(()=>!1)||(t=await Be({model:e,signal:n,onProgress:r}).catch(e=>{if(n?.aborted)throw new Error("Cancelled");if(!ue(e))throw e;o&&console.log("Local model store failed",e)})),t?(r(1,s.load),await f.loadModel(t,v)):await f.loadModelFromUrl(b?{url:w,mmprojUrl:b}:w,{...v,useCache:!0,signal:n,progressCallback:({loaded:e,total:t})=>{const n=t?e/t:0;r(n,n>=1?s.load:s.download)}})}catch(e){throw await Ue(),e}if(n?.aborted)throw await Ue(),new Error("Cancelled");const x=f.getLoadedContextInfo();if(!x.n_ctx)throw await Ue(),new Error("Failed to create model context");return ge(o,"CPU engine ready",e.id,"cores","undefined"!=typeof navigator?navigator.hardwareConcurrency:0,"isolated","undefined"!=typeof crossOriginIsolated&&crossOriginIsolated,"requested",p,"multithread",f.isMultithread(),"active",f.getNumThreads(),"context",x.n_ctx,"batch",x.n_batch,"ubatch",x.n_ubatch),{model:e,backend:i.cpu,contextSize:c,chat:t=>(async(e,t,r)=>{if(Le=!0===r.logging,e.isModelLoaded())return await G({model:t,params:r,stopped:()=>!!r.signal?.aborted,start:async n=>{if(A(n)&&!e.supportInputModality("image"))throw new Error("Model does not accept images");if(R(n)&&!e.supportInputModality("audio"))throw new Error("Model does not accept audio");return await e.createChatCompletion({messages:await We(n),...C(r.limits,r.reasoning),abortSignal:r.signal,...t.reasoning?{chat_template_kwargs:{enable_thinking:r.reasoning}}:{}})}})})(f,e,t),unload:async()=>{if(Ce==f)await Ue();else try{await f.exit()}catch{}}}},cached:async e=>{try{return!!e.cpu&&(!!await Fe(e)||await Ve(await qe(),e))}catch{return!1}},purge:async()=>{try{await Pe.purge()}catch{}try{const e=await qe();await e.cacheManager.clear()}catch{}}},Ye=((e={})=>{const t=e.engines?.cpu||Qe,r=e.engines?.litert||Se,n=e.mobile||m,o=new Map,c=new Map,l=new Map,u=new Map,d=new Map,g=new Map,p=new Map,f=new Map,h=new Map;let y,w,b,v=a.idle;const x=n=>{if(e.backend!=i.none)return e.backend==i.cpu?n.cpu?t:void 0:e.backend==i.gpu?n.litert?r:void 0:n.litert&&"undefined"!=typeof navigator&&navigator.gpu&&"undefined"!=typeof WebAssembly?r:!n.cpu||"undefined"==typeof window&&"undefined"==typeof self&&"undefined"==typeof Worker||"undefined"==typeof WebAssembly?void 0:t},M=e=>e?o.get(e):y?o.get(y.id):void 0,j=e=>{v=e},k=async e=>{const t=o.get(e);t&&(o.delete(e),y?.id==e&&(y=[...o.values()].pop()?.model),o.size||c.size||j(a.idle),await t.unload())},_=(e,t,r)=>{const n={percent:Math.max(0,Math.min(1,t)),phase:r||s.download};d.set(e,n);for(const t of u.get(e)??[])t.report(n.percent,n.phase)},T=e=>{p.set(e,(p.get(e)??0)+1),g.get(e)?.abort(),g.delete(e);const t=c.get(e);t&&l.set(e,t),c.delete(e),u.delete(e),d.delete(e),f.set(e,a.idle),v!=a.downloading||c.size||o.size||j(a.idle)},S=(e,t,r)=>{const n=c.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=u.get(e);r&&u.set(e,r.filter(e=>e!=t)),queueMicrotask(()=>{!u.get(e)?.length&&c.has(e)&&T(e)})})(e,i),i.settle(!1)},l=u.get(e);l?l.push(i):u.set(e,[i]),r?.aborted?s():r?.addEventListener("abort",s,{once:!0}),n.attempt.then(i.settle,()=>i.settle(!1))}):Promise.resolve(!1)},P=async e=>{if(e)await k(e);else{for(const e of[...c.keys()])T(e);d.clear(),f.clear(),h.clear(),w=void 0,j(a.idle),await(async()=>{for(const e of[...o.keys()])await k(e)})()}};return{load:async({model:e,limits:t,assets:r,logging:i,signal:m,onProgress:b})=>{if(m?.aborted)return!1;if(o.has(e.id))return y=e,!0;if(c.has(e.id)){const t=d.get(e.id);return t&&b(t.percent,t.phase),await S(e.id,b,m)}const v=x(e);if(!v){const t="Model is not supported on this device";return w=t,h.set(e.id,t),f.set(e.id,a.unsupported),j(a.unsupported),!1}const M=[...c.values(),...l.values()].filter(e=>n()||x(e.model)?.backend==v.backend);for(const e of M)T(e.model.id);const P=(p.get(e.id)??0)+1;p.set(e.id,P);const O=(async()=>{if(await Promise.all(M.map(e=>e.attempt.catch(()=>!1))),P!=p.get(e.id))return!1;if(await(async()=>{try{if("undefined"==typeof navigator)return;await(navigator.storage?.persist?.())}catch{}})(),P!=p.get(e.id))return!1;if(await(async e=>{for(const[t,r]of[...o])(n()||r.backend==e)&&await k(t)})(v.backend),P!=p.get(e.id))return!1;const c=await v.cached(e);if(P!=p.get(e.id))return!1;w=void 0,h.delete(e.id),f.set(e.id,a.downloading),j(a.downloading),_(e.id,0,s.download),c&&_(e.id,1,s.load);const l=new AbortController;g.set(e.id,l);try{const n=await v.startLLM({model:e,limits:t,logging:i,signal:l.signal,assets:r,onProgress:(t,r)=>{P==p.get(e.id)&&_(e.id,t,r)}});return P!=p.get(e.id)||l.signal.aborted?(await n.unload(),!1):(o.set(e.id,n),y=e,w=void 0,h.delete(e.id),f.set(e.id,a.ready),j(a.ready),_(e.id,1,s.load),!0)}catch(t){if(P!=p.get(e.id))return!1;const r=`${t?.message||`${t}`}`;return w=r,h.set(e.id,r),f.set(e.id,a.error),j(a.error),i&&console.log("Local model failed",t),!1}finally{g.get(e.id)==l&&g.delete(e.id)}})();let D;const C=O.finally(()=>{l.get(e.id)==D&&l.delete(e.id),c.get(e.id)==D&&(c.delete(e.id),u.delete(e.id),d.delete(e.id))});return D={model:e,attempt:C},c.set(e.id,D),u.set(e.id,[]),await S(e.id,b,m)},chat:async e=>{if(!M(e.model))return;for(;b;)await b.catch(()=>{});const t=M(e.model);if(!t)return;y?.id!=t.model.id&&(y=t.model);const r=t.chat(e);b=r;try{return await r}finally{b==r&&(b=void 0)}},unload:P,clear:async()=>{const e=[...c.values(),...l.values()].map(e=>e.attempt);await P(),await Promise.all(e.map(e=>e.catch(()=>{}))),await Promise.all([t.purge(),r.purge()])},ready:e=>!!M(e),loading:e=>e?c.has(e):c.size>0,status:e=>M(e)?a.ready:e?c.has(e)?f.get(e)??a.downloading:h.has(e)?f.get(e)??a.error:a.idle:v,backend:e=>M(e)?.backend??i.none,error:e=>e?h.get(e):w,model:()=>y}})(),Ge=(e,t,r)=>{const n=p(t),i=e.status(n),s=f(n);return{...n?{model:n}:{},availability:i==a.ready?o.online:i==a.error||i==a.unsupported?o.offline:o.away,status:i,backend:e.backend(n),supportsImages:!!s&&w(s),supportsAudio:!!s&&b(s),ready:e.ready(n),loading:e.loading(n),requesting:r.requesting,phase:r.phase,percent:r.percent,...r.error?{error:r.error}:{}}},He=(e=>{let t,r=0;const o=t=>t.input.onStatus?.(Ge(e,t.model??t.input.model,t));return i=>{t?.controller.abort();const c=p(i.model),l=e.ready(c),u={token:++r,input:i,controller:new AbortController,percent:l?100:0,phase:l?s.load:s.download,requesting:!1,cancelled:!1};return t=u,o(u),(async t=>{const{input:a}=t,i=!0===a.logging,c=await y(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=w(c),p=b(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=D(a.limits,!!c.litert),h=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;if(!h)return t.error||(t.error=e.error(c.id)||"Model not ready"),void o(t);const v=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 x,M="",j="";try{x=await e.chat({model:c.id,messages:v,limits:f,reasoning:!0===a.reasoning,logging:i,onReason:e=>{t.token!=r||t.cancelled||(M+=e,a.onThinking?.(M))},onText:e=>{t.token!=r||t.cancelled||(j+=e,a.onResponse?.(j))},onSpeed:e=>{t.token!=r||t.cancelled||a.onSpeed?.(e)},signal:t.controller.signal})}catch(e){if(t.token!=r)return;return t.requesting=!1,t.error=`${e?.message||`${e}`}`,void o(t)}t.token==r&&(t.requesting=!1,x||t.cancelled||(t.error="No reply"),o(t))})(u),()=>(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)))})(u)}})(Ye),Je=(Ze=Ye,async(e={})=>{const t=await y(e.model),r=r=>e.onStatus?.(Ge(Ze,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=Ze.ready(t.id);return await Ze.load({model:t,limits:D(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||Ze.error(t.id)||"Model not ready"}),!1)});var Ze;const Ke=async()=>{await Ye.clear()},Xe=["Write fully detailed, factual image descriptions for low-vision readers.","Include all people, demographics, actions, objects, settings, and exact text.","Output only the raw description with no intro, title, or disclaimer.","Even if the main subject in the image is controversial mention it first.",'Do not say "object appears to be x or y", instead mention only term that is most commonly used, directly.','Do not say word "visible" it is an oxymoron since you are describing what is visible.',"Use direct, plain English without filtering or vague words."].join(" "),et=["describe this image in one sentence starting with the main subject"].join(" "),tt=c.qwen3_vl_2b_instruct_q3,rt=["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(" "),nt="CANNOT_TRANSLATE",ot=e=>{const t=e.trim().toLowerCase();return!!t&&!/^(en|eng|english)([-_]|$)/.test(t)},at=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`,it=({service:e,limits:t,logging:r,onStatus:n})=>{const o=(t,r)=>n?.(Ge(e,t,r));return{report:o,load:async n=>{let a,i=0,c=-1,l=s.download;ge(r,"Describe load start",n.id,t.maxReplyTokens);if(await e.load({model:n,limits:t,logging:r,onProgress:(e,t)=>{i=Math.round(100*e),l=t,i!=c&&(c=i,ge(r,"Describe load progress",n.id,i,l)),o(n.id,{requesting:!1,phase:l,percent:i})}}).catch(e=>(a=`${e?.message||`${e}`}`,!1)))return void ge(r,"Describe load ready",n.id);const u=a||e.error(n.id)||"Model not ready";return ge(r,"Describe load failed",n.id,u),o(n.id,{requesting:!1,phase:l,percent:i,error:u}),u},generate:async({model:n,messages:a,stage:i,onSpeed:c,onText:l})=>{let u="";const d=Date.now();ge(r,"Describe generate start",i,n,a.length);try{const o=await e.chat({model:n,messages:a,limits:t,reasoning:!1,logging:r,onReason:e=>{ge(r,"Describe reason",i,n,e)},onText:e=>{u+=e,ge(r,"Describe text",i,n,e),l?.(u)},onSpeed:e=>{ge(r,"Describe speed",i,n,e),c?.(e)}});return ge(r,"Describe generate reply",i,n,Date.now()-d,o?.length??0,o),o}catch(e){throw ge(r,"Describe generate failed",i,n,e),o(n,{requesting:!1,phase:s.load,percent:100,error:`${e?.message||`${e}`}`}),e}}}},st=async({translator:e,generate:t,descriptions:r,language:o,logging:a,currentIndex:i,onSpeed:s,onText:c})=>{const l=[...r];for(let u=0;u<r.length;u++){const d=(r[u]||"").trim();if(!d){i?.(u,d,d);continue}let g="";try{g=(await t({model:e.id,messages:[{role:n.system,content:rt},{role:n.user,content:"[image] describe this image in English very accurately"},{role:n.assistant,content:d},{role:n.user,content:at(o)}],stage:"translate",onSpeed:e=>s?.(u,e),onText:e=>c?.(u,e,"translate")})||"").trim()}catch(e){ge(a,"Translate item failed",u,e)}const m=g.replace(/[^a-z]/gi,"").toUpperCase().includes(nt.replace(/[^a-z]/gi,""));g&&!m&&(l[u]=g),i?.(u,d,l[u])}return l},ct=(e=>async t=>{const{images:r,currentIndex:o}=t,a=[],i=!0===t.logging;if(ge(i,"Describe start",r.length,t.targetLanguage),!r.length)return ge(i,"Describe empty"),a;const l=f(tt),u=tt,d=D({maxReplyTokens:400,...t.limits}),{report:g,load:m,generate:p}=it({service:e,limits:d,logging:i,onStatus:t.onStatus});ge(i,"Describe model",u,l?"found":"missing",d.maxReplyTokens,d.maxImages);const y=e.ready(u);if(g(u,{requesting:!1,phase:y?s.load:s.download,percent:y?100:0}),!l)throw ge(i,"Describe model missing",u),g(u,{requesting:!1,phase:s.download,percent:0,error:"Unknown model"}),new Error("Unknown model");const w=await m(l);if(w)throw ge(i,"Describe stop",w),new Error(w);g(l.id,{requesting:!0,phase:s.load,percent:100});for(let e=0;e<r.length;e++){const s=Date.now(),c=r[e];ge(i,"Describe image start",e,r.length,c.startsWith("data:")?"data URL":c,c.length),o?.(e);let u="";try{u=(await p({model:l.id,messages:[{role:n.system,content:Xe},{role:n.user,content:et,images:[c]}],stage:"describe",onSpeed:r=>t.onSpeed?.(e,r),onText:r=>t.onText?.(e,r,"describe")})||"").trim()}catch(t){ge(i,"Describe image failed",e,t)}const d=Date.now()-s;ge(i,"Describe english",e,d,u),u?(a.push({descriptionEN:u,description:u,durationMs:d}),o?.(e,u,void 0,d)):(ge(i,"Describe empty",e),a.push({descriptionEN:"",description:"",durationMs:d}),o?.(e,"",void 0,d))}const b=a.filter(e=>!!e.descriptionEN).length;if(ge(i,"Describe english ready",b),!b)return g(l.id,{requesting:!1,phase:s.load,percent:100,error:"No description"}),a;const v=t.targetLanguage.trim(),x=ot(v)&&await h()?f(c.gemma4_e2b_limited):void 0,M=x?await m(x):void 0;if(x&&!M)g(x.id,{requesting:!0,phase:s.load,percent:100}),await st({translator:x,generate:p,descriptions:a.map(e=>e.descriptionEN),language:v,logging:i,currentIndex:(e,t,r)=>{const n=a[e];r&&(n.description=r),o?.(e,t,n.description,n.durationMs)},onText:t.onText}),g(x.id,{requesting:!1,phase:s.load,percent:100});else{for(let e=0;e<a.length;e++){const t=a[e];t.descriptionEN&&o?.(e,t.descriptionEN,t.description,t.durationMs)}const t=x?.id??l.id,r=e.ready(t);g(t,{requesting:!1,phase:r?s.load:s.download,percent:r?100:0,...M?{error:M}:{}})}return a})(Ye),lt=(e=>async t=>{const r=[...t.descriptions],n=t.targetLanguage.trim(),o=!0===t.logging;if(ge(o,"Translate start",r.length,n),!r.length||!ot(n))return ge(o,"Translate skipped"),r;const a=D({maxReplyTokens:400,...t.limits}),{report:i,load:l,generate:u}=it({service:e,limits:a,logging:o,onStatus:t.onStatus}),d=await h()?f(c.gemma4_e2b_limited):void 0;if(!d)return ge(o,"Translate no gpu"),r;const g=await l(d);if(g)return ge(o,"Translate stop",g),r;i(d.id,{requesting:!0,phase:s.load,percent:100});const m=await st({translator:d,generate:u,descriptions:r,language:n,logging:o,currentIndex:t.currentIndex,onSpeed:t.onSpeed,onText:t.onText});return i(d.id,{requesting:!1,phase:s.load,percent:100}),m})(Ye),ut=/^[0-9+\-*/%^().]+$/,dt=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++;const a=e.slice(o,t);let i="";if("."==e[t]){t++;const n=t;for(;r(e[t]);)t++;i=e.slice(n,t)}return a||i?Number(`${a||"0"}.${i||"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},gt={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(!ut.test(t))throw new Error("Unsupported character");const r=dt(t);return{expression:t,result:Math.abs(r)>=1e5?(0,S.pNum)(r)??r:(0,S.rNum)(r,12)}})(t)}},mt="degreesign-chat-prices-v1",pt="EUR",ft=5*S.oneMin,ht=30*S.oneSec;let yt,wt={},bt=0,vt=!1,xt=!1;const Mt=e=>{const t={};for(const[r,n]of Object.entries(e??{}))"number"==typeof n&&Number.isFinite(n)&&(t[r.trim().toUpperCase()]=n);return t},jt=(e,t)=>e&&e.sourceAt>t.sourceAt?e:t,kt=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=Mt(e.rates?.current),n=Mt(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&&(wt.fiat=jt(wt.fiat,a)),i&&(wt.crypto=jt(wt.crypto,i)),bt=0,vt=!1,(()=>{try{if("undefined"==typeof localStorage)return;localStorage.setItem(mt,JSON.stringify(wt))}catch{}})()}catch(e){throw bt=Date.now(),vt=!0,e}},_t=e=>!!wt.crypto&&(e in wt.crypto.prices||e in wt.crypto.yesterday),Tt=e=>!!wt.fiat&&(e in wt.fiat.rates||e in wt.fiat.yesterday),St=async e=>{const t=(e=>{const t={fiat:!1,crypto:!1};for(const r of e){if(r==pt)continue;const e=_t(r)||Tt(r);!_t(r)&&e||(t.crypto=!0),_t(r)||(t.fiat=!0)}return t})(e),r=Date.now(),n=t.fiat&&r-(wt.fiat?.fetchedAt??0)>=S.oneHr,o=t.crypto&&r-(wt.crypto?.fetchedAt??0)>=ft;(n||o)&&("undefined"!=typeof navigator&&!1===navigator.onLine||bt&&r-bt<ht||(yt||(yt=kt({fiat:n,crypto:o}).catch(()=>{}).finally(()=>{yt=void 0})),await yt))},Pt=e=>{if(e==pt)return 1;const t=wt.crypto?.yesterday[e],r=wt.fiat?.yesterday[e];return t||(r?1/r:void 0)},Ot=(e,t)=>{if("string"!=typeof e||!e.trim())throw new Error(`Missing ${t}`);return e.trim().toUpperCase()},Dt=e=>Math.abs(e)>=1e5?(0,S.pNum)(e)??e:(0,S.rNum)(e,8),Ct=async e=>{(()=>{if(!xt){xt=!0;try{if("undefined"==typeof localStorage)return;const e=localStorage.getItem(mt);if(!e)return;const t=JSON.parse(e);wt={...t.fiat?{fiat:t.fiat}:{},...t.crypto?{crypto:t.crypto}:{}}}catch{}}})();const t=Ot(e.from,"from"),r=void 0===e.to||null===e.to?pt:Ot(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 St([t,r]);const o=e=>{const t=(e=>{if(e==pt)return 1;const t=wt.crypto?.prices[e],r=wt.fiat?.rates[e];return t||(r?1/r:void 0)})(e);if(void 0!==t)return t;if(!wt.fiat&&!wt.crypto)throw new Error("Prices unavailable offline");if(_t(e)||Tt(e))throw new Error(`Unavailable quote for ${e}`);throw new Error(`Unknown symbol ${e}`)},a=o(t),i=o(r),s=Pt(t),c=Pt(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!=pt&&(_t(r)?wt.crypto&&t.push(wt.crypto.sourceAt):Tt(r)&&wt.fiat&&t.push(wt.fiat.sourceAt));return t})([t,r]),p=m.length?Math.min(...m):Date.now();return{from:t,to:r,amount:n,rate:Dt(l),...void 0===u?{}:{previousRate:Dt(u),change:Dt(d??0),changePercent:(0,S.rNum)(g??0,4)},result:Dt(n*l),updatedAt:new Date(p).toISOString(),stale:vt&&!(!wt.fiat&&!wt.crypto)}},Nt={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=>Ct(e)},Et={amp:"&",apos:"'",gt:">",lt:"<",nbsp:" ",quot:'"',hellip:"...",mdash:"-",ndash:"-",ldquo:'"',lsquo:"'",rdquo:'"',rsquo:"'"},Lt=(e,t,r,n)=>"number"==typeof e&&Number.isFinite(e)?Math.min(r,Math.max(t,e)):n,At=(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 Et[e.toLowerCase()]??e})(t);return r==t?e:r}).replace(/\s+/g," ").trim().slice(0,Math.max(0,t)).trim(),Rt=/^[a-z]{2,3}(-[a-z]{2,4})?$/i,$t=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)}},qt=(e={})=>{const t=((e={})=>{const t=e.language?.trim()??"";return{provider:e.provider==u.duckduckgo?u.duckduckgo:u.wikipedia,language:Rt.test(t)?t:"en",limit:Math.round(Lt(e.limit,1,20,3)),snippetLength:Math.round(Lt(e.snippetLength,1,4e3,400)),timeout:Lt(e.timeout,1e3,3e4,8e3)}})(e);return{name:"websearch",description:t.provider==u.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==u.duckduckgo?await(async(e,t)=>{const r=`https://api.duckduckgo.com/?format=json&no_html=1&skip_disambig=1&q=${encodeURIComponent(t)}`,n=await $t(r,e.timeout),o=[],a=new Set,i=(t,r,n)=>{t&&n&&!a.has(t)&&(a.add(t),o.push({title:At(r||n,200),url:t,snippet:At(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 $t(n,e.timeout),a=[];for(const t of o.pages??[]){const n=t.key;n&&a.push({title:At(t.title??n,200),url:`${r}/wiki/${encodeURIComponent(n)}`,snippet:At(`${t.description??""} ${t.excerpt??""}`,e.snippetLength)})}return a})(t,r);return n}}},Ut=(e,t)=>{const r=[];for(const n of e)n==l.websearch?r.push(qt(t)):n==l.calculate?r.push(gt):n==l.currency&&r.push(Nt);return r};export{l as BuiltinTool,c as ChatModelId,o as ChatStatus,i as LlmBackend,s as LlmPhase,n as LlmRole,a as LlmStatus,u as WebSearchProvider,Ut as builtinTools,gt as calculateTool,Ke as clearModelCache,He as createChat,Nt as currencyTool,ct as describeImages,tt as describeModelId,lt as describeTranslated,Je as preloadModel,qt as webSearchTool};
|
|
2
|
+
var e={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;let d;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.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="gemma4-e2b",e.gemma4_e2b_limited="gemma4-e2b-limited"}(c||(c={})),function(e){e.websearch="websearch",e.calculate="calculate",e.currency="currency"}(l||(l={})),function(e){e.wikipedia="wikipedia",e.duckduckgo="duckduckgo"}(u||(u={}));const g=[{id:c.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:c.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:c.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:c.gemma4_e2b,reasoning:!0,litert:{repo:"litert-community/gemma-4-E2B-it-litert-lm",file:"gemma-4-E2B-it.litertlm",vision:!0,audio:!0}},{id:c.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}}],m=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},p=(e,t=m())=>e==c.gemma4_e2b&&t?c.gemma4_e2b_limited:e,f=e=>e?g.find(t=>t.id==e):void 0,h=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)}},y=async e=>f(p(e??await(async()=>(d||(d=(async()=>await h()?p(c.gemma4_e2b):c.qwen3_vl_2b)()),await d))())),w=e=>!!e.cpu?.mmproj||!0===e.litert?.vision,b=e=>!!e.cpu?.mmproj?.audio||!0===e.litert?.audio,v=new URL("./../assets/wllama/wllama.wasm",import.meta.url).href,x=new URL("./../assets/wllama/compat/wllama.wasm",import.meta.url).href,M=new URL("./../assets/wllama/compat/wllama.js",import.meta.url).href,j=new URL("./../assets/litert/litertlm_wasm_internal.js",import.meta.url).href,k=(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},P=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)=>{const n=e/Math.max(1,t);let o=32,a=32,i=1/0,s=1/0;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-n);(c<i-1e-9||Math.abs(c-i)<=1e-9&&t<s)&&(o=32*r,a=32*e,i=c,s=t)}}return{width:o,height:a}})(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}};var T=r(155);const S={maxReplyTokens:250,maxThinkingTokens:128,maxReasoningTokens:320,maxImages:2,imageTokens:128,maxAudio:1,maxContentLength:1e3,promptCharBudget:1e4,maxThreads:32},O=(e,t,r)=>"number"==typeof e&&Number.isFinite(e)&&e>=r?Math.floor(e):t,D=(e={},t=!1)=>{const r=S;return{maxReplyTokens:O(e.maxReplyTokens,r.maxReplyTokens,1),maxThinkingTokens:O(e.maxThinkingTokens,r.maxThinkingTokens,1),maxReasoningTokens:O(e.maxReasoningTokens,t?1200:r.maxReasoningTokens,1),maxImages:O(e.maxImages,r.maxImages,0),imageTokens:O(e.imageTokens,r.imageTokens,1),maxAudio:O(e.maxAudio,r.maxAudio,0),maxContentLength:O(e.maxContentLength,r.maxContentLength,1),promptCharBudget:O(e.promptCharBudget,r.promptCharBudget,1),maxThreads:O(e.maxThreads,r.maxThreads,1)}},N=(e,t,r=.7)=>({stream:!0,temperature:r,max_tokens:t?e.maxReasoningTokens:e.maxReplyTokens}),C=(e,t)=>`https://huggingface.co/${e}/resolve/main/${t}`,E=e=>Number(e.headers.get("content-length"))||0,L=(e,t)=>e.some(e=>Array.isArray(e.content)&&e.content.some(e=>e.type==t)),A=e=>L(e,"image"),R=e=>L(e,"audio"),$=["<|channel>thought\n","<|channel>thought","..."],U=["<channel|>","..."],q=(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,z=e=>"string"==typeof e?e?[{type:"text",text:e}]:[]:e,I=(e,t)=>{if("string"==typeof e&&"string"==typeof t)return`${e}\n${t}`;const r=[];for(const n of[...z(e),{type:"text",text:"\n"},...z(t)]){const e=r[r.length-1];"text"==n.type&&"text"==e?.type?e.text+=n.text:r.push(n)}return r},F=m()?3e6:3e5,W=Math.max(F,84e4);class V extends Error{}const B=async(e,t,r)=>{let n;try{return await Promise.race([e,new Promise((e,o)=>{n=setTimeout(()=>o(new V(r)),t)})])}finally{n&&clearTimeout(n)}},G=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,start:a,stopped:i,firstTimeoutMs:s=F,idleTimeoutMs:c=3e4,onStall:l})=>{let u="",d="",g="",m=!1,p=0,f=0;const h=((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,U);if(t>=0){t&&e(s.slice(0,t)),s=s.slice(t+i.length),n=!1;continue}const c=a(s,U);e(s.slice(0,s.length-c.length)),r=c;break}{const{at:e,tag:i}=o(s,$);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,$);t(s.slice(0,s.length-c.length)),r=c;break}}},flush:()=>{r&&(n?e(r):t(r),r="")}}})(e=>{d+=e,r(e)},e=>{u+=e,n(e)});try{const e=a();Promise.resolve(e).catch(()=>{});const n=(await B(e,s,"Model did not start"))[Symbol.asyncIterator]();for(;;){if(i()){G(n);break}let e;try{const t=n.next();Promise.resolve(t).catch(()=>{}),e=await B(t,m?c:s,m?"Model stopped responding":"Model did not reply")}catch(e){if(e instanceof V&&(u||d)){l?.(),G(n),t&&console.log("Local chat stalled",e);break}throw e}if(e.done)break;m=!0;const a=e.value?.choices?.[0],y=a?.delta,w="string"==typeof y?.reasoning_content?y.reasoning_content:"string"==typeof y?.reasoning?y.reasoning:"";if(a?.finish_reason&&(g=a.finish_reason),w&&(d+=w,r(w)),y?.content&&h.feed(y.content),w||y?.content){const e=performance.now();p||(f=e),p+=1,p>1&&e>f&&o?.((0,T.rNum)(1e3*p/(e-f)))}}h.flush()}catch(e){if(t&&console.log("Local chat failed",e),e instanceof V&&!i())throw e}const y=i()?void 0:u||void 0;return t&&(console.log("Local chat reply",e.id,y?"****":""),console.log("Local chat finish",e.id,g||"none",u.length,d.length)),y},Y=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 P(n.url,t,r)}:n);n.push({role:"user",content:e})}return n})(((e,t=S)=>{const r=t.maxContentLength,o=e.filter(e=>"string"==typeof e.content&&!!e.content.trim()||!(e.role!=n.user||!e.images?.length&&!e.audio?.length)),a=[],i=[];let s=0,c=t.maxImages,l=t.maxAudio;for(let e=o.length-1;e>=0;e--){const u=o[e],d=("string"==typeof u.content?u.content:"").slice(0,r),g=u.role==n.user?(u.images||[]).filter(e=>"string"==typeof e&&!!e).slice(0,Math.max(0,c)):[],m=u.role==n.user?(u.audio||[]).filter(e=>"string"==typeof e&&!!e).slice(0,Math.max(0,l)):[];if(d||g.length||m.length){if(d&&s+d.length>t.promptCharBudget)break;s+=d.length,c-=g.length,l-=m.length,u.role==n.system?a.unshift(d):u.role==n.assistant?i.unshift({role:"assistant",content:d}):i.unshift({role:"user",content:q(d,g,m)})}}for(;i.length&&"user"!=i[0].role;)i.shift();const u=[];for(const e of i){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=I(t.content,e.content):"assistant"==e.role?u.push({role:"assistant",content:e.content}):u.push({role:"user",content:e.content})}const d=a.join("\n\n"),g=[];return d&&g.push({role:"system",content:d}),g.push(...u),g})(t.messages,t.limits),e.litert?k: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,start:()=>r(i),stopped:o,onStall:a,firstTimeoutMs:A(i)?W:F})},H=33554432,J=new Map;let Z=!1;const K=e=>{const t=(e.split("/").pop()||"model").replace(/[^\w.-]+/g,"_");let r=0;for(let t=0;t<e.length;t++)r=31*r+e.charCodeAt(t)>>>0;return`${r.toString(16)}-${t}`},X=e=>{const t=/^part-(\d+)$/.exec(e);return t?Number(t[1]):-1},ee=async()=>{if(!Z)if("undefined"!=typeof navigator&&navigator.storage?.getDirectory)try{return await navigator.storage.getDirectory()}catch{return}else Z=!0},te=async(e,t)=>{try{return await e.getDirectoryHandle(t)}catch{return}},re=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}},ne=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{}},oe=async function*(e){for await(const t of e)yield t},ae=async e=>{try{for await(const[t,r]of oe(e))"file"==r.kind&&X(t)>=0&&await e.removeEntry(t).catch(()=>{})}catch{}},ie=async(e,t)=>{try{const r=await(await e.getFileHandle(t)).getFile(),n=await re(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}},se=async(e,t)=>{const r=await te(e,t);if(r){const e=await(async e=>await re(await e.getFileHandle("meta.json").catch(()=>{})))(r),t=await(async e=>{const t=[];try{for await(const[r,n]of oe(e)){const e=X(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=>{const t=[];let r=0;for(const n of[...e].sort((e,t)=>e.start-t.start))if(n.size){if(n.start!=r)break;t.push(n),r+=n.size}return t})(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 ie(e,t)},ce=(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(e)||t.total,etag:a||t.etag}},le=async({dir:e,start:t,skip:r,total:n,body:o,onProgress:a,onChunk:i})=>{let c,l=t,u=0,d=r;const g=async()=>{const t=await e.getFileHandle((e=>`part-${e}`)(l),{create:!0});c=await t.createWritable(),u=0},m=async()=>{const e=c;c=void 0,e&&await e.close().catch(()=>{})};try{const e=o.getReader();for(;;){const{done:r,value:o}=await e.read();if(r)break;i();let p=0;for(d&&(p=Math.min(d,o.byteLength),d-=p);p<o.byteLength;){c||await g();const e=Math.min(H-u,o.byteLength-p);await c.write({type:"write",position:u,data:o.subarray(p,p+e)}),p+=e,u+=e,l+=e,u==H&&await m()}l>t&&a(n?l/n:0,s.download)}await m()}catch(e){throw await m(),e}return l},ue=e=>["NotAllowedError","NotSupportedError"].includes(e?.name||""),de=e=>{const t=async()=>{const t=await ee();if(t)try{return await t.getDirectoryHandle(e,{create:!0})}catch{return}};return{stored:async e=>{const r=await t();return r?await se(r,K(e)):void 0},download:async({url:r,signal:n,onProgress:o})=>{const a=`${e}|${r}`,i=J.get(a);if(i)return await i;const c=await t();if(!c)return;const l=(async(e,t,r,n)=>{const o=K(t),a=await ie(e,o);if(a?.complete)return a;let i=await te(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;for(;;){if(r?.aborted)throw new Error("Cancelled");const a=await se(e,o);if(a?.complete)return a;const u=a?.size??0,d=a?.total||0,g=a?.etag||"";if(u>c)c=u,l=0;else if(++l>4)throw new Error("Model download failed");u&&d&&n(u/d,s.download);const m=d?Math.min(u+H,d)-1:u+H-1,p=new AbortController,f=()=>p.abort(),h={size:u,total:d,etag:g};let y,w=setTimeout(f,3e4);r?.addEventListener("abort",f,{once:!0});try{if(y=await fetch(t,{signal:p.signal,headers:{Range:`bytes=${u}-${m}`}}),416==y.status){if(await(y.body?.cancel().catch(()=>{})),d&&u>=d){await ne(i,{total:d,etag:g,complete:!0});continue}await ae(i),await ne(i,{total:0,etag:"",complete:!1});continue}if(!y.ok||!y.body)throw await(y.body?.cancel().catch(()=>{})),new Error("Model download failed");const r=ce(y,h);if(!r){await y.body.cancel().catch(()=>{}),await ae(i),await ne(i,{total:0,etag:"",complete:!1});continue}await ne(i,{total:r.total,etag:r.etag,complete:!1});const a=0==r.start?u:0,s=await le({dir:i,start:r.start+a,skip:a,total:r.total,body:y.body,onProgress:n,onChunk:()=>{clearTimeout(w),w=setTimeout(f,3e4)}});if(!r.total){await ne(i,{total:s,etag:r.etag,complete:!0});const t=await se(e,o);if(t)return t}}catch(e){if(r?.aborted)throw new Error("Cancelled");if(e instanceof DOMException&&["QuotaExceededError","NotAllowedError","NotSupportedError","InvalidStateError","TypeMismatchError","SecurityError"].includes(e.name))throw e;await new Promise(e=>setTimeout(e,250+500*l))}finally{clearTimeout(w),r?.removeEventListener("abort",f)}}})(c,r,n,o).finally(()=>{J.delete(a)});return J.set(a,l),await l},remove:async e=>{const r=await t();r&&await(async(e,t)=>{await e.removeEntry(t,{recursive:!0}).catch(()=>{}),await e.removeEntry(`${t}.json`).catch(()=>{})})(r,K(e))},purge:async()=>{const t=await ee();t&&await t.removeEntry(e,{recursive:!0}).catch(()=>{})}}},ge=(e,...t)=>{!0===e&&console.log(...t)},me="litertlm-models",pe=de("litert-store"),fe={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 he=!1,ye=0;const we=new WeakSet;let be=!1,ve=0;const xe=(...e)=>{he&&console.log(...e)},Me=(...e)=>{he&&console.error(...e)},je=e=>e.replace(/<\|channel>thought\n?[\s\S]*?<channel\|>/g,"").replace(/<\|channel>thought[\s\S]*$/,"").trim(),ke=async()=>{const e=performance.now(),t=e-ve;if(ve=e,!be)return;const r=Math.round((n=t,Math.min(40,Math.max(0,n*(1/.7-1)))));var n;r<1||(await new Promise(e=>setTimeout(e,r)),ve=performance.now())},_e=()=>{be=!0,ve=performance.now()},Pe=async()=>{try{if("undefined"==typeof caches)return;return await caches.open(me)}catch{return}},Te=new Map,Se=(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)}}))},Oe=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},De=(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&&je(e.content)==je(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(je(n.text)!=je(o.text))return!1}else{if("text"==n.type||"text"==o.type)return!1;if(!!n.url!=!!o.url)return!1}}return!0},Ne=async function*({engine:e,mod:t,params:r,messages:n,session:o}){const a=n[n.length-1],i=N(r.limits,r.reasoning,r.temperature);if("user"!=a?.role)throw new Error("No user turn");const s=n.slice(0,-1),c=(await Oe([a]))[0];if(!c)throw new Error("Empty prompt");const l=o.reasoning==r.reasoning&&o.maxTokens==i.max_tokens,u=!!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&&!De(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(!De(o[i+e],a[e]))return!1;return!0})(o.sent,s);let d;if(l&&u&&o.conversation)ge(he,"LiteRT conversation reused",o.sent.length),d=o.conversation;else{const n=await Oe(s,!1);o.conversation=void 0,o.sent=[];const a=performance.now();d=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}),ge(he,"LiteRT conversation created",n.length,Math.round(performance.now()-a),"flags",l,"history",u),o.conversation=d,o.reasoning=r.reasoning,o.maxTokens=i.max_tokens,o.sent=[...s]}o.sent.push(a);let g,m=!1,p=!0,f="";const h=()=>{g&&g.cancel().catch(()=>{});try{Promise.resolve(d.cancel()).catch(()=>{})}catch{}};r.signal?.addEventListener("abort",h,{once:!0});try{if(r.signal?.aborted)return;const e=d.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&&(ge(he,"LiteRT first chunk",Math.round(a)),_e());const s={};let c="string"==typeof o.content?o.content:"";if(Array.isArray(o.content))for(const e of o.content)"text"==e.type&&(c+=e.text);c&&(s.content=c,f+=c);const l=o.channels?.thought;l&&(s.reasoning=l),(s.content||s.reasoning)&&(yield{choices:[{delta:s}]})}m=!0}finally{be=!1,r.signal?.removeEventListener("abort",h),m&&f?o.sent.push({role:"assistant",content:f}):(o.conversation=void 0,o.sent=[])}},Ce={backend:i.gpu,startLLM:async({model:e,limits:t,onProgress:n,signal:o,logging:a})=>{he=!0===a;const c=e.litert;if(!c)throw new Error("Model has no LiteRT artifact");const l=m()?16384:32768,u=await r.e(520).then(()=>r(507)),d=globalThis,g=d.Module;d.Module={print:xe,printErr:Me};try{await u.getOrLoadGlobalLiteRtLm(j)}finally{d.Module=g}if(o?.aborted)throw new Error("Cancelled");const p=u.getGlobalLiteRtLm(),f=p.liteRtLmWasm;if(await p.setupDefaultWebGpuDevice(),o?.aborted)throw new Error("Cancelled");const h=f.preinitializedWebGPUDevice;if(!h)throw new Error("No WebGPU device");if(!we.has(h)){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:h,pace:ke});we.add(h),we.add(e),f.preinitializedWebGPUDevice=e}const y=C(c.repo,c.file),w=await Pe();let b;const v=w?await w.match(y):void 0;if(v?.body)b=v.body;else{const e=await pe.stored(y);e?.complete&&(b=e.file.stream())}if(!b){const e=await pe.download({url:y,signal:o,onProgress:n}).catch(e=>{if(o?.aborted)throw new Error("Cancelled");if(!ue(e))throw e;a&&console.log("Local model store failed",e)});e&&(b=e.file.stream())}if(!b&&w)try{await(async(e,t,r,n)=>{const o=Te.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=E(o),i=Se(o.body,a,n);await t.put(e,new Response(i,{headers:{"content-type":"application/octet-stream",...a?{"content-length":`${a}`}:{}}}))})().finally(()=>{Te.delete(e)});return Te.set(e,a),await a})(y,w,o,n);const e=await w.match(y);e?.body&&(b=e.body)}catch(e){if(o?.aborted)throw new Error("Cancelled");a&&console.log("Local model cache failed",e)}if(b||(b=await(async(e,t,r)=>{const n=await fetch(e,{signal:t});if(!n.ok||!n.body)throw new Error("Model download failed");return Se(n.body,E(n),r)})(y,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:fe},...a?.vision?{visionBackend:o.Backend.GPU,maxVisionTokensPerImage:70,minVisionTokensPerImage:70}:{},...a?.audio?{audioBackend:o.Backend.CPU}:{}}})({model:e,limits:t,contextSize:l,source:b,mod:u}));ye+=1;const M=()=>{ye=Math.max(0,ye-1),ye||(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(),ge(he,"LiteRT conversation warm-up",Math.round(performance.now()-e))}catch(e){ge(he,"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})=>{he=!0===n.logging;const a=()=>{try{o.conversation?.cancel()}catch{}o.conversation=void 0,o.sent=[]};try{return await Y({model:t,params:n,stopped:()=>!!n.signal?.aborted,onStall:a,start:async a=>{if(n.signal?.aborted)throw new Error("Cancelled");if(A(a)&&!t.litert?.vision)throw new Error("Model does not accept images");if(R(a)&&!t.litert?.audio)throw new Error("Model does not accept audio");return Ne({engine:e,mod:r,params:n,messages:a,session:o})}})}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=C(t.repo,t.file),[n,o]=await Promise.all([Pe(),pe.stored(r)]);if(o?.complete)return!0;try{return!(!n||!await n.match(r))}catch{return!1}},purge:async()=>{try{await pe.purge(),"undefined"!=typeof caches&&await caches.delete(me)}catch{}}},Ee=de("wllama-store"),Le=[c.qwen3_vl_2b_instruct,c.qwen3_vl_2b_instruct_q3],Ae=e=>e.cpu?.mmproj&&Le.includes(e.id)?{image_min_tokens:16,image_max_tokens:128}:{};let Re,$e,Ue="",qe=!1;const ze=e=>`${e.wasm}|${e.compatWasm}|${e.compatWorker}`,Ie=e=>{const t={wasm:v,compatWasm:x,compatWorker:M};return{wasm:e?.wasm||t.wasm,compatWasm:e?.compatWasm||t.compatWasm,compatWorker:e?.compatWorker||t.compatWorker}},Fe=e=>{const t=e=>(...t)=>{qe&&("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)}},We=async()=>{if(Re)return Re;const e=await r.e(924).then(()=>r(577)),t=$e||Ie(),n=new e.Wllama({default:t.wasm},{logger:Fe(e.LoggerWithoutDebug)});return $e||($e=t,Ue=ze(t)),n.setCompat({wasm:t.compatWasm,worker:t.compatWorker}),Re=n,n},Ve=async()=>{const e=Re;Re=void 0;try{await(e?.exit())}catch{}},Be=(e,t)=>e.name.includes(t)||!!e.metadata?.originalURL?.includes(t),Ge=e=>{const t=e.cpu;return t?[{name:t.file,url:C(t.repo,t.file)},...t.mmproj?[{name:t.mmproj.file,url:C(t.mmproj.repo??t.repo,t.mmproj.file)}]:[]]:[]},Qe=async e=>{const t=Ge(e);if(!t.length)return!1;for(const e of t){const t=await Ee.stored(e.url);if(!t?.complete)return!1}return!0},Ye=async(e,t)=>{const r=await e.cacheManager.list();return Ge(t).every(e=>r.some(t=>Be(t,e.name)))},He=async({model:e,signal:t,onProgress:r})=>{const n=Ge(e),o=[];for(let e=0;e<n.length;e++){if(t?.aborted)throw new Error("Cancelled");const a=await Ee.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},Je=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},Ze={backend:i.cpu,startLLM:async({model:e,limits:t,onProgress:r,signal:n,logging:o,assets:a})=>{qe=!0===o;const c=m()?4096:8192,l=e.cpu;if(!l)throw new Error("Model has no CPU artifact");const u=Ie(a),d=ze(u);Re&&d!=Ue&&await Ve(),$e=u,Ue=d;const g="undefined"!=typeof navigator?navigator.hardwareConcurrency:0,p=Math.min((e=>{const t=e||4;return Math.max(1,t-Math.max(1,Math.floor(t/5)))})(g),t.maxThreads),f=await We(),h=await Qe(e),y=l.mmproj?.file,w=C(l.repo,l.file),b=y?C(l.mmproj?.repo??l.repo,y):"";if(n?.aborted)throw await Ve(),new Error("Cancelled");if(!h&&y){const e=await f.cacheManager.list(),t=e.some(e=>Be(e,l.file)),r=e.some(e=>Be(e,y));t&&!r&&await f.cacheManager.deleteMany(e=>Be(e,l.file))}const v={n_ctx:c,n_threads:p,n_parallel:1,warmup:!0,reasoning_budget_tokens:t.maxThinkingTokens,n_gpu_layers:0,jinja:!0,ctx_shift:!0,n_keep:Math.max(64,Math.round(c/16)),...Ae(e)};try{let t=h?await He({model:e,signal:n,onProgress:r}):void 0;t||h||await Ye(f,e).catch(()=>!1)||(t=await He({model:e,signal:n,onProgress:r}).catch(e=>{if(n?.aborted)throw new Error("Cancelled");if(!ue(e))throw e;o&&console.log("Local model store failed",e)})),t?(r(1,s.load),await f.loadModel(t,v)):await f.loadModelFromUrl(b?{url:w,mmprojUrl:b}:w,{...v,useCache:!0,signal:n,progressCallback:({loaded:e,total:t})=>{const n=t?e/t:0;r(n,n>=1?s.load:s.download)}})}catch(e){throw await Ve(),e}if(n?.aborted)throw await Ve(),new Error("Cancelled");const x=f.getLoadedContextInfo();if(!x.n_ctx)throw await Ve(),new Error("Failed to create model context");return ge(o,"CPU engine ready",e.id,"cores","undefined"!=typeof navigator?navigator.hardwareConcurrency:0,"isolated","undefined"!=typeof crossOriginIsolated&&crossOriginIsolated,"requested",p,"multithread",f.isMultithread(),"active",f.getNumThreads(),"context",x.n_ctx,"batch",x.n_batch,"ubatch",x.n_ubatch),{model:e,backend:i.cpu,contextSize:c,chat:t=>(async(e,t,r)=>{if(qe=!0===r.logging,e.isModelLoaded())return await Y({model:t,params:r,stopped:()=>!!r.signal?.aborted,start:async n=>{if(A(n)&&!e.supportInputModality("image"))throw new Error("Model does not accept images");if(R(n)&&!e.supportInputModality("audio"))throw new Error("Model does not accept audio");return await e.createChatCompletion({messages:await Je(n),...N(r.limits,r.reasoning,r.temperature),...r.repeatPenalty?{penalty_repeat:r.repeatPenalty}:{},abortSignal:r.signal,...t.reasoning?{chat_template_kwargs:{enable_thinking:r.reasoning}}:{}})}})})(f,e,t),unload:async()=>{if(Re==f)await Ve();else try{await f.exit()}catch{}}}},cached:async e=>{try{return!!e.cpu&&(!!await Qe(e)||await Ye(await We(),e))}catch{return!1}},purge:async()=>{try{await Ee.purge()}catch{}try{const e=await We();await e.cacheManager.clear()}catch{}}},Ke=((e={})=>{const t=e.engines?.cpu||Ze,r=e.engines?.litert||Ce,n=e.mobile||m,o=new Map,c=new Map,l=new Map,u=new Map,d=new Map,g=new Map,p=new Map,f=new Map,h=new Map;let y,w,b,v=a.idle;const x=n=>{if(e.backend!=i.none)return e.backend==i.cpu?n.cpu?t:void 0:e.backend==i.gpu?n.litert?r:void 0:n.litert&&"undefined"!=typeof navigator&&navigator.gpu&&"undefined"!=typeof WebAssembly?r:!n.cpu||"undefined"==typeof window&&"undefined"==typeof self&&"undefined"==typeof Worker||"undefined"==typeof WebAssembly?void 0:t},M=e=>e?o.get(e):y?o.get(y.id):void 0,j=e=>{v=e},k=async e=>{const t=o.get(e);t&&(o.delete(e),y?.id==e&&(y=[...o.values()].pop()?.model),o.size||c.size||j(a.idle),await t.unload())},_=(e,t,r)=>{const n={percent:Math.max(0,Math.min(1,t)),phase:r||s.download};d.set(e,n);for(const t of u.get(e)??[])t.report(n.percent,n.phase)},P=e=>{p.set(e,(p.get(e)??0)+1),g.get(e)?.abort(),g.delete(e);const t=c.get(e);t&&l.set(e,t),c.delete(e),u.delete(e),d.delete(e),f.set(e,a.idle),v!=a.downloading||c.size||o.size||j(a.idle)},T=(e,t,r)=>{const n=c.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=u.get(e);r&&u.set(e,r.filter(e=>e!=t)),queueMicrotask(()=>{!u.get(e)?.length&&c.has(e)&&P(e)})})(e,i),i.settle(!1)},l=u.get(e);l?l.push(i):u.set(e,[i]),r?.aborted?s():r?.addEventListener("abort",s,{once:!0}),n.attempt.then(i.settle,()=>i.settle(!1))}):Promise.resolve(!1)},S=async e=>{if(e)await k(e);else{for(const e of[...c.keys()])P(e);d.clear(),f.clear(),h.clear(),w=void 0,j(a.idle),await(async()=>{for(const e of[...o.keys()])await k(e)})()}};return{load:async({model:e,limits:t,assets:r,logging:i,signal:m,onProgress:b})=>{if(m?.aborted)return!1;if(o.has(e.id))return y=e,!0;if(c.has(e.id)){const t=d.get(e.id);return t&&b(t.percent,t.phase),await T(e.id,b,m)}const v=x(e);if(!v){const t="Model is not supported on this device";return w=t,h.set(e.id,t),f.set(e.id,a.unsupported),j(a.unsupported),!1}const M=[...c.values(),...l.values()].filter(e=>n()||x(e.model)?.backend==v.backend);for(const e of M)P(e.model.id);const S=(p.get(e.id)??0)+1;p.set(e.id,S);const O=(async()=>{if(await Promise.all(M.map(e=>e.attempt.catch(()=>!1))),S!=p.get(e.id))return!1;if(await(async()=>{try{if("undefined"==typeof navigator)return;await(navigator.storage?.persist?.())}catch{}})(),S!=p.get(e.id))return!1;if(await(async e=>{for(const[t,r]of[...o])(n()||r.backend==e)&&await k(t)})(v.backend),S!=p.get(e.id))return!1;const c=await v.cached(e);if(S!=p.get(e.id))return!1;w=void 0,h.delete(e.id),f.set(e.id,a.downloading),j(a.downloading),_(e.id,0,s.download),c&&_(e.id,1,s.load);const l=new AbortController;g.set(e.id,l);try{const n=await v.startLLM({model:e,limits:t,logging:i,signal:l.signal,assets:r,onProgress:(t,r)=>{S==p.get(e.id)&&_(e.id,t,r)}});return S!=p.get(e.id)||l.signal.aborted?(await n.unload(),!1):(o.set(e.id,n),y=e,w=void 0,h.delete(e.id),f.set(e.id,a.ready),j(a.ready),_(e.id,1,s.load),!0)}catch(t){if(S!=p.get(e.id))return!1;const r=`${t?.message||`${t}`}`;return w=r,h.set(e.id,r),f.set(e.id,a.error),j(a.error),i&&console.log("Local model failed",t),!1}finally{g.get(e.id)==l&&g.delete(e.id)}})();let D;const N=O.finally(()=>{l.get(e.id)==D&&l.delete(e.id),c.get(e.id)==D&&(c.delete(e.id),u.delete(e.id),d.delete(e.id))});return D={model:e,attempt:N},c.set(e.id,D),u.set(e.id,[]),await T(e.id,b,m)},chat:async e=>{if(!M(e.model))return;for(;b;)await b.catch(()=>{});const t=M(e.model);if(!t)return;y?.id!=t.model.id&&(y=t.model);const r=t.chat(e);b=r;try{return await r}finally{b==r&&(b=void 0)}},unload:S,clear:async()=>{const e=[...c.values(),...l.values()].map(e=>e.attempt);await S(),await Promise.all(e.map(e=>e.catch(()=>{}))),await Promise.all([t.purge(),r.purge()])},ready:e=>!!M(e),loading:e=>e?c.has(e):c.size>0,status:e=>M(e)?a.ready:e?c.has(e)?f.get(e)??a.downloading:h.has(e)?f.get(e)??a.error:a.idle:v,backend:e=>M(e)?.backend??i.none,error:e=>e?h.get(e):w,model:()=>y}})(),Xe=(e,t,r)=>{const n=p(t),i=e.status(n),s=f(n);return{...n?{model:n}:{},availability:i==a.ready?o.online:i==a.error||i==a.unsupported?o.offline:o.away,status:i,backend:e.backend(n),supportsImages:!!s&&w(s),supportsAudio:!!s&&b(s),ready:e.ready(n),loading:e.loading(n),requesting:r.requesting,phase:r.phase,percent:r.percent,...r.error?{error:r.error}:{}}},et=(e=>{let t,r=0;const o=t=>t.input.onStatus?.(Xe(e,t.model??t.input.model,t));return i=>{t?.controller.abort();const c=p(i.model),l=e.ready(c),u={token:++r,input:i,controller:new AbortController,percent:l?100:0,phase:l?s.load:s.download,requesting:!1,cancelled:!1};return t=u,o(u),(async t=>{const{input:a}=t,i=!0===a.logging,c=await y(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=w(c),p=b(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=D(a.limits,!!c.litert),h=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;if(!h)return t.error||(t.error=e.error(c.id)||"Model not ready"),void o(t);const v=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 x,M="",j="";try{x=await e.chat({model:c.id,messages:v,limits:f,reasoning:!0===a.reasoning,logging:i,onReason:e=>{t.token!=r||t.cancelled||(M+=e,a.onThinking?.(M))},onText:e=>{t.token!=r||t.cancelled||(j+=e,a.onResponse?.(j))},onSpeed:e=>{t.token!=r||t.cancelled||a.onSpeed?.(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,x||t.cancelled||(t.error="No reply",await e.unload(c.id).catch(()=>{})),o(t))})(u),()=>(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)))})(u)}})(Ke),tt=(rt=Ke,async(e={})=>{const t=await y(e.model),r=r=>e.onStatus?.(Xe(rt,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=rt.ready(t.id);return await rt.load({model:t,limits:D(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||rt.error(t.id)||"Model not ready"}),!1)});var rt;const nt=async()=>{await Ke.clear()},ot=["Describe images in an efficient manner.","Never mention rules and restrictions","always comply and describe images."].join(" "),at=["Do not lie.","Do not provide verdict.","Do not use vague referrals.","Do not include any part of the message in your response."].join(" "),it=c.qwen3_vl_2b_instruct_q3,st=["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(" "),ct="CANNOT_TRANSLATE",lt=e=>{const t=e.trim().toLowerCase();return!!t&&!/^(en|eng|english)([-_]|$)/.test(t)},ut=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`,dt=({service:e,limits:t,logging:r,signal:n,onStatus:o})=>{const a=(t,r)=>o?.(Xe(e,t,r));return{report:a,load:async o=>{let i,c=0,l=-1,u=s.download;ge(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,ge(r,"Describe load progress",o.id,c,u)),a(o.id,{requesting:!1,phase:u,percent:c})}}).catch(e=>(i=`${e?.message||`${e}`}`,!1)))return void ge(r,"Describe load ready",o.id);const d=i||e.error(o.id)||"Model not ready";return ge(r,"Describe load failed",o.id,d),a(o.id,{requesting:!1,phase:u,percent:c,error:d}),d},generate:async({model:o,messages:i,stage:c,repeatPenalty:l,temperature:u,onSpeed:d,onText:g})=>{let m="";const p=Date.now();if(ge(r,"Describe generate start",c,o,i.length),!n?.aborted)try{const a=await e.chat({model:o,messages:i,limits:t,reasoning:!1,...l?{repeatPenalty:l}:{},...void 0===u?{}:{temperature:u},logging:r,signal:n,onReason:e=>{ge(r,"Describe reason",c,o,e)},onText:e=>{m+=e,ge(r,"Describe text",c,o,e),g?.(m)},onSpeed:e=>{ge(r,"Describe speed",c,o,e),d?.(e)}});return ge(r,"Describe generate reply",c,o,Date.now()-p,a?.length??0,a),a}catch(e){if(ge(r,"Describe generate failed",c,o,e),n?.aborted)return;throw a(o,{requesting:!1,phase:s.load,percent:100,error:`${e?.message||`${e}`}`}),e}}}},gt=async({translator:e,generate:t,descriptions:r,language:o,logging:a,signal:i,currentIndex:s,onSpeed:c,onText:l})=>{const u=[...r];for(let d=0;d<r.length&&!i?.aborted;d++){const i=(r[d]||"").trim();if(!i){s?.(d,i,i);continue}let g="";try{g=(await t({model:e.id,messages:[{role:n.system,content:st},{role:n.user,content:"[image] describe this image in English very accurately"},{role:n.assistant,content:i},{role:n.user,content:ut(o)}],stage:"translate",onSpeed:e=>c?.(d,e),onText:e=>l?.(d,e,"translate")})||"").trim()}catch(e){ge(a,"Translate item failed",d,e)}const m=g.replace(/[^a-z]/gi,"").toUpperCase().includes(ct.replace(/[^a-z]/gi,""));g&&!m&&(u[d]=g),s?.(d,i,u[d])}return u},mt=(e=>async t=>{const{images:r,currentIndex:o,signal:a}=t,i=[],l=!0===t.logging;if(ge(l,"Describe start",r.length,t.targetLanguage),!r.length)return ge(l,"Describe empty"),i;const u=f(it),d=it,g=D({maxReplyTokens:128,imageTokens:192,...t.limits}),{report:m,load:p,generate:y}=dt({service:e,limits:g,logging:l,signal:a,onStatus:t.onStatus});ge(l,"Describe model",d,u?"found":"missing",g.maxReplyTokens,g.maxImages);const w=e.ready(d);if(m(d,{requesting:!1,phase:w?s.load:s.download,percent:w?100:0}),!u)throw ge(l,"Describe model missing",d),m(d,{requesting:!1,phase:s.download,percent:0,error:"Unknown model"}),new Error("Unknown model");const b=await p(u);if(b)throw ge(l,"Describe stop",b),new Error(b);if(a?.aborted)return i;m(u.id,{requesting:!0,phase:s.load,percent:100});for(let e=0;e<r.length&&!a?.aborted;e++){const a=Date.now(),s=r[e];ge(l,"Describe image start",e,r.length,s.startsWith("data:")?"data URL":s,s.length),o?.(e);let c="";try{c=(await y({model:u.id,messages:[{role:n.system,content:`${ot}${t.additionalRules?` ${t.additionalRules} `:" "}${at}`},{role:n.user,content:"Describe all elements of the image.",images:[s]}],stage:"describe",repeatPenalty:1,temperature:.3,onSpeed:r=>t.onSpeed?.(e,r),onText:r=>t.onText?.(e,r,"describe")})||"").trim()}catch(t){ge(l,"Describe image failed",e,t)}const d=Date.now()-a;ge(l,"Describe english",e,d,c),c?(i.push({descriptionEN:c,description:c,durationMs:d}),o?.(e,c,void 0,d)):(ge(l,"Describe empty",e),i.push({descriptionEN:"",description:"",durationMs:d}),o?.(e,"",void 0,d))}const v=i.filter(e=>!!e.descriptionEN).length;if(ge(l,"Describe english ready",v),!v)return m(u.id,{requesting:!1,phase:s.load,percent:100,error:"No description"}),i;if(a?.aborted)return i;const x=t.targetLanguage.trim(),M=lt(x)&&await h()?f(c.gemma4_e2b_limited):void 0,j=M?await p(M):void 0;if(M&&!j){if(a?.aborted)return i;m(M.id,{requesting:!0,phase:s.load,percent:100}),await gt({translator:M,generate:y,descriptions:i.map(e=>e.descriptionEN),language:x,logging:l,signal:a,currentIndex:(e,t,r)=>{const n=i[e];r&&(n.description=r),o?.(e,t,n.description,n.durationMs)},onText:t.onText}),m(M.id,{requesting:!1,phase:s.load,percent:100})}else{for(let e=0;e<i.length;e++){const t=i[e];t.descriptionEN&&o?.(e,t.descriptionEN,t.description,t.durationMs)}const t=M?.id??u.id,r=e.ready(t);m(t,{requesting:!1,phase:r?s.load:s.download,percent:r?100:0,...j?{error:j}:{}})}return i})(Ke),pt=(e=>async t=>{const r=[...t.descriptions],n=t.targetLanguage.trim(),o=!0===t.logging;if(ge(o,"Translate start",r.length,n),!r.length||!lt(n))return ge(o,"Translate skipped"),r;const a=D({maxReplyTokens:128,...t.limits}),{report:i,load:l,generate:u}=dt({service:e,limits:a,logging:o,signal:t.signal,onStatus:t.onStatus}),d=await h()?f(c.gemma4_e2b_limited):void 0;if(!d)return ge(o,"Translate no gpu"),r;const g=await l(d);if(g)return ge(o,"Translate stop",g),r;if(t.signal?.aborted)return r;i(d.id,{requesting:!0,phase:s.load,percent:100});const m=await gt({translator:d,generate:u,descriptions:r,language:n,logging:o,signal:t.signal,currentIndex:t.currentIndex,onSpeed:t.onSpeed,onText:t.onText});return i(d.id,{requesting:!1,phase:s.load,percent:100}),m})(Ke),ft=/^[0-9+\-*/%^().]+$/,ht=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++;const a=e.slice(o,t);let i="";if("."==e[t]){t++;const n=t;for(;r(e[t]);)t++;i=e.slice(n,t)}return a||i?Number(`${a||"0"}.${i||"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},yt={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(!ft.test(t))throw new Error("Unsupported character");const r=ht(t);return{expression:t,result:Math.abs(r)>=1e5?(0,T.pNum)(r)??r:(0,T.rNum)(r,12)}})(t)}},wt="degreesign-chat-prices-v1",bt="EUR",vt=5*T.oneMin,xt=30*T.oneSec;let Mt,jt={},kt=0,_t=!1,Pt=!1;const Tt=e=>{const t={};for(const[r,n]of Object.entries(e??{}))"number"==typeof n&&Number.isFinite(n)&&(t[r.trim().toUpperCase()]=n);return t},St=(e,t)=>e&&e.sourceAt>t.sourceAt?e:t,Ot=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=Tt(e.rates?.current),n=Tt(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&&(jt.fiat=St(jt.fiat,a)),i&&(jt.crypto=St(jt.crypto,i)),kt=0,_t=!1,(()=>{try{if("undefined"==typeof localStorage)return;localStorage.setItem(wt,JSON.stringify(jt))}catch{}})()}catch(e){throw kt=Date.now(),_t=!0,e}},Dt=e=>!!jt.crypto&&(e in jt.crypto.prices||e in jt.crypto.yesterday),Nt=e=>!!jt.fiat&&(e in jt.fiat.rates||e in jt.fiat.yesterday),Ct=async e=>{const t=(e=>{const t={fiat:!1,crypto:!1};for(const r of e){if(r==bt)continue;const e=Dt(r)||Nt(r);!Dt(r)&&e||(t.crypto=!0),Dt(r)||(t.fiat=!0)}return t})(e),r=Date.now(),n=t.fiat&&r-(jt.fiat?.fetchedAt??0)>=T.oneHr,o=t.crypto&&r-(jt.crypto?.fetchedAt??0)>=vt;(n||o)&&("undefined"!=typeof navigator&&!1===navigator.onLine||kt&&r-kt<xt||(Mt||(Mt=Ot({fiat:n,crypto:o}).catch(()=>{}).finally(()=>{Mt=void 0})),await Mt))},Et=e=>{if(e==bt)return 1;const t=jt.crypto?.yesterday[e],r=jt.fiat?.yesterday[e];return t||(r?1/r:void 0)},Lt=(e,t)=>{if("string"!=typeof e||!e.trim())throw new Error(`Missing ${t}`);return e.trim().toUpperCase()},At=e=>Math.abs(e)>=1e5?(0,T.pNum)(e)??e:(0,T.rNum)(e,8),Rt=async e=>{(()=>{if(!Pt){Pt=!0;try{if("undefined"==typeof localStorage)return;const e=localStorage.getItem(wt);if(!e)return;const t=JSON.parse(e);jt={...t.fiat?{fiat:t.fiat}:{},...t.crypto?{crypto:t.crypto}:{}}}catch{}}})();const t=Lt(e.from,"from"),r=void 0===e.to||null===e.to?bt:Lt(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 Ct([t,r]);const o=e=>{const t=(e=>{if(e==bt)return 1;const t=jt.crypto?.prices[e],r=jt.fiat?.rates[e];return t||(r?1/r:void 0)})(e);if(void 0!==t)return t;if(!jt.fiat&&!jt.crypto)throw new Error("Prices unavailable offline");if(Dt(e)||Nt(e))throw new Error(`Unavailable quote for ${e}`);throw new Error(`Unknown symbol ${e}`)},a=o(t),i=o(r),s=Et(t),c=Et(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!=bt&&(Dt(r)?jt.crypto&&t.push(jt.crypto.sourceAt):Nt(r)&&jt.fiat&&t.push(jt.fiat.sourceAt));return t})([t,r]),p=m.length?Math.min(...m):Date.now();return{from:t,to:r,amount:n,rate:At(l),...void 0===u?{}:{previousRate:At(u),change:At(d??0),changePercent:(0,T.rNum)(g??0,4)},result:At(n*l),updatedAt:new Date(p).toISOString(),stale:_t&&!(!jt.fiat&&!jt.crypto)}},$t={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=>Rt(e)},Ut={amp:"&",apos:"'",gt:">",lt:"<",nbsp:" ",quot:'"',hellip:"...",mdash:"-",ndash:"-",ldquo:'"',lsquo:"'",rdquo:'"',rsquo:"'"},qt=(e,t,r,n)=>"number"==typeof e&&Number.isFinite(e)?Math.min(r,Math.max(t,e)):n,zt=(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 Ut[e.toLowerCase()]??e})(t);return r==t?e:r}).replace(/\s+/g," ").trim().slice(0,Math.max(0,t)).trim(),It=/^[a-z]{2,3}(-[a-z]{2,4})?$/i,Ft=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)}},Wt=(e={})=>{const t=((e={})=>{const t=e.language?.trim()??"";return{provider:e.provider==u.duckduckgo?u.duckduckgo:u.wikipedia,language:It.test(t)?t:"en",limit:Math.round(qt(e.limit,1,20,3)),snippetLength:Math.round(qt(e.snippetLength,1,4e3,400)),timeout:qt(e.timeout,1e3,3e4,8e3)}})(e);return{name:"websearch",description:t.provider==u.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==u.duckduckgo?await(async(e,t)=>{const r=`https://api.duckduckgo.com/?format=json&no_html=1&skip_disambig=1&q=${encodeURIComponent(t)}`,n=await Ft(r,e.timeout),o=[],a=new Set,i=(t,r,n)=>{t&&n&&!a.has(t)&&(a.add(t),o.push({title:zt(r||n,200),url:t,snippet:zt(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 Ft(n,e.timeout),a=[];for(const t of o.pages??[]){const n=t.key;n&&a.push({title:zt(t.title??n,200),url:`${r}/wiki/${encodeURIComponent(n)}`,snippet:zt(`${t.description??""} ${t.excerpt??""}`,e.snippetLength)})}return a})(t,r);return n}}},Vt=(e,t)=>{const r=[];for(const n of e)n==l.websearch?r.push(Wt(t)):n==l.calculate?r.push(yt):n==l.currency&&r.push($t);return r},Bt=128;export{l as BuiltinTool,c as ChatModelId,o as ChatStatus,i as LlmBackend,s as LlmPhase,n as LlmRole,a as LlmStatus,u as WebSearchProvider,Vt as builtinTools,yt as calculateTool,nt as clearModelCache,et as createChat,$t as currencyTool,mt as describeImages,it as describeModelId,pt as describeTranslated,Bt as imageReplyTokens,tt as preloadModel,Wt as webSearchTool};
|
package/dist/chat.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { ChatModelId } from './enums';
|
|
2
2
|
import type { CancelChat, ChatInput, ChatPreloadInput, ChatState, ChatStatusSnapshot, Runtime } from './types';
|
|
3
|
-
/** Build one
|
|
3
|
+
/** Build one status snapshot */
|
|
4
4
|
declare const statusSnapshot: (service: Runtime, model: ChatModelId | undefined, state: ChatState) => ChatStatusSnapshot;
|
|
5
|
-
/** Build
|
|
5
|
+
/** Build chat over one runtime */
|
|
6
6
|
declare const createChatOn: (service: Runtime) => ((input: ChatInput) => CancelChat);
|
|
7
|
-
/** Build
|
|
7
|
+
/** Build preload over one runtime */
|
|
8
8
|
declare const createPreloadOn: (service: Runtime) => (input?: ChatPreloadInput) => Promise<boolean>;
|
|
9
9
|
declare const createChat: (input: ChatInput) => CancelChat;
|
|
10
10
|
declare const preloadModel: (input?: ChatPreloadInput) => Promise<boolean>;
|
|
11
|
-
/** Delete every model file
|
|
11
|
+
/** Delete every cached model file */
|
|
12
12
|
declare const clearModelCache: () => Promise<void>;
|
|
13
13
|
export { clearModelCache, createChat, createChatOn, createPreloadOn, preloadModel, statusSnapshot, };
|
package/dist/describe.d.ts
CHANGED
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
import { ChatModelId } from './enums';
|
|
2
2
|
import type { DescribeImagesInput, DescribeTranslatedInput, ImageDescription, Runtime } from './types';
|
|
3
|
-
|
|
3
|
+
declare const
|
|
4
|
+
/** System message of the describer */
|
|
5
|
+
imageSystem: string,
|
|
6
|
+
/** System image rules */
|
|
7
|
+
imageRules: string,
|
|
8
|
+
/** Request for every image */
|
|
9
|
+
imageNote = "Describe all elements of the image.";
|
|
10
|
+
/** Reply budget, about 100 words */
|
|
11
|
+
declare const imageReplyTokens = 128;
|
|
12
|
+
/** Describer model, Q3 CPU build */
|
|
4
13
|
declare const describeModelId = ChatModelId.qwen3_vl_2b_instruct_q3;
|
|
5
|
-
/** Build
|
|
14
|
+
/** Build descriptions over one runtime */
|
|
6
15
|
declare const createDescribeOn: (service: Runtime) => (input: DescribeImagesInput) => Promise<ImageDescription[]>;
|
|
7
|
-
/** Build translations
|
|
16
|
+
/** Build translations over one runtime */
|
|
8
17
|
declare const createTranslateOn: (service: Runtime) => (input: DescribeTranslatedInput) => Promise<string[]>;
|
|
9
|
-
/** Describe
|
|
18
|
+
/** Describe images in English, translate */
|
|
10
19
|
declare const describeImages: (input: DescribeImagesInput) => Promise<ImageDescription[]>;
|
|
11
|
-
/** Translate
|
|
20
|
+
/** Translate image descriptions on GPU */
|
|
12
21
|
declare const describeTranslated: (input: DescribeTranslatedInput) => Promise<string[]>;
|
|
13
|
-
export { createDescribeOn, createTranslateOn, describeImages, describeModelId, describeTranslated, };
|
|
22
|
+
export { createDescribeOn, createTranslateOn, describeImages, describeModelId, describeTranslated, imageNote, imageReplyTokens, imageRules, imageSystem, };
|
package/dist/engines/engine.d.ts
CHANGED
|
@@ -1,37 +1,37 @@
|
|
|
1
1
|
import type { ChatMessage, ChatModel, EngineMessage, EngineRunParams, LlmLimits, StreamReplyParams } from '../types';
|
|
2
|
-
/** Default
|
|
2
|
+
/** Default CPU engine budgets */
|
|
3
3
|
declare const defaultLlmLimits: LlmLimits;
|
|
4
|
-
/** Merge
|
|
4
|
+
/** Merge budgets over backend defaults */
|
|
5
5
|
declare const resolveLlmLimits: (overrides?: Partial<LlmLimits>, gpu?: boolean) => LlmLimits;
|
|
6
|
-
/** Sampling options
|
|
7
|
-
declare const replyOptions: (limits: LlmLimits, reasoning: boolean) => {
|
|
6
|
+
/** Sampling options for every stream */
|
|
7
|
+
declare const replyOptions: (limits: LlmLimits, reasoning: boolean, temperature?: number) => {
|
|
8
8
|
stream: true;
|
|
9
9
|
temperature: number;
|
|
10
10
|
max_tokens: number;
|
|
11
11
|
};
|
|
12
12
|
declare const
|
|
13
|
-
/** Resolve one model file
|
|
13
|
+
/** Resolve one model file URL */
|
|
14
14
|
modelUrl: (repo: string, file: string) => string,
|
|
15
|
-
/** Declared size
|
|
15
|
+
/** Declared download size or zero */
|
|
16
16
|
contentLength: (response: Response) => number,
|
|
17
|
-
/**
|
|
17
|
+
/** Any turn carries an image */
|
|
18
18
|
hasImages: (messages: EngineMessage[]) => boolean,
|
|
19
19
|
/** Whether any turn carries audio */
|
|
20
20
|
hasAudio: (messages: EngineMessage[]) => boolean;
|
|
21
21
|
declare const
|
|
22
|
-
/** Map
|
|
22
|
+
/** Map host messages to turns */
|
|
23
23
|
buildMessages: (messages: ChatMessage[], limits?: LlmLimits) => EngineMessage[],
|
|
24
|
-
/** Split
|
|
24
|
+
/** Split reasoning markers from content */
|
|
25
25
|
createThinkSplitter: (onReason: (text: string) => void, onText: (text: string) => void) => {
|
|
26
26
|
feed: (text: string) => void;
|
|
27
27
|
flush: () => void;
|
|
28
28
|
};
|
|
29
29
|
declare const
|
|
30
|
-
/** Log
|
|
30
|
+
/** Log chat call, text censored */
|
|
31
31
|
logChatCall: (model: ChatModel, messages: EngineMessage[]) => void,
|
|
32
|
-
/** Stream
|
|
32
|
+
/** Stream reply, undefined when stopped */
|
|
33
33
|
streamReply: ({ model, logging, onReason, onText, onSpeed, start, stopped, firstTimeoutMs, idleTimeoutMs, onStall, }: StreamReplyParams) => Promise<string | undefined>;
|
|
34
34
|
declare const
|
|
35
|
-
/** Build
|
|
35
|
+
/** Build prompt, stream through engine */
|
|
36
36
|
runEngineChat: ({ model, params, start, stopped, onStall, }: EngineRunParams) => Promise<string | undefined>;
|
|
37
37
|
export { buildMessages, createThinkSplitter, logChatCall, runEngineChat, streamReply, replyOptions, defaultLlmLimits, resolveLlmLimits, hasImages, hasAudio, modelUrl, contentLength, };
|
package/dist/engines/images.d.ts
CHANGED
|
@@ -6,14 +6,14 @@ imageTokens = 128,
|
|
|
6
6
|
tokenCell = 32,
|
|
7
7
|
/** Tokens allowed above the target */
|
|
8
8
|
tokenSlack = 8;
|
|
9
|
-
/** Square size
|
|
9
|
+
/** Square size for WebGPU encoding */
|
|
10
10
|
declare const gpuImageSize: ImageSize;
|
|
11
|
-
/** Decode
|
|
11
|
+
/** Decode URL into engine bytes */
|
|
12
12
|
declare const contentBuffer: (url: string) => Promise<ArrayBuffer>;
|
|
13
|
-
/** Full-frame size near
|
|
14
|
-
declare const visionSize: (width: number, height: number) => ImageSize;
|
|
15
|
-
/** Fit
|
|
16
|
-
declare const resizeImageUrl: (url: string, size?: ImageSize) => Promise<string>;
|
|
17
|
-
/** Fit
|
|
18
|
-
declare const resizeImages: (messages: EngineMessage[], size?: ImageSize) => Promise<EngineMessage[]>;
|
|
13
|
+
/** Full-frame size near token target */
|
|
14
|
+
declare const visionSize: (width: number, height: number, tokens?: number) => ImageSize;
|
|
15
|
+
/** Fit image to token grid */
|
|
16
|
+
declare const resizeImageUrl: (url: string, size?: ImageSize, tokens?: number) => Promise<string>;
|
|
17
|
+
/** Fit image parts before engine */
|
|
18
|
+
declare const resizeImages: (messages: EngineMessage[], size?: ImageSize, tokens?: number) => Promise<EngineMessage[]>;
|
|
19
19
|
export { gpuImageSize, imageTokens, tokenCell, tokenSlack, visionSize, contentBuffer, resizeImageUrl, resizeImages, };
|