@degreesign/chat 1.4.0 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -112,6 +112,7 @@ const cancel = createChat({
112
112
  onResponse: (text) => renderReply(text),
113
113
  // onThinking: (text) => renderThinking(text),
114
114
  // onSpeed: (tokensPerSecond) => renderSpeed(tokensPerSecond),
115
+ // onPromptSpeed: (tokensPerSecond) => renderPromptSpeed(tokensPerSecond),
115
116
  // onStatus: (snapshot) => renderStatus(snapshot),
116
117
  });
117
118
 
@@ -123,13 +124,17 @@ await clearModelCache();
123
124
 
124
125
  Without `model` the package picks the GPU model when the browser provides a
125
126
  WebGPU adapter and the CPU model when it does not. `limits`, `reasoning`,
126
- `onThinking`, `onSpeed` and `onStatus` are optional per call; see the API
127
- below.
127
+ `onThinking`, `onSpeed`, `onPromptSpeed` and `onStatus` are optional per call;
128
+ see the API below.
128
129
 
129
130
  There is no promise and no controller object on `createChat`. Every result
130
131
  arrives through `onResponse`, and `onStatus` reports `requesting: false` when
131
132
  the reply ends. `onSpeed` reports the streamed generation speed in tokens per
132
133
  second, measured from the first token so prompt processing is excluded.
134
+ `onPromptSpeed` streams the prompt processing speed while the prompt is
135
+ evaluated, then reports the final value at the first generated token. It uses
136
+ the engine prefill progress or stream timings, and falls back to a running
137
+ estimate when the engine exposes neither.
133
138
  `preloadModel` is the one promise: it resolves once the model is loaded, or
134
139
  `false` when it cannot load.
135
140
 
@@ -319,6 +324,7 @@ from this device.
319
324
  | `onThinking?` | Receives the accumulated reasoning text as it streams. |
320
325
  | `onResponse` | Receives the accumulated reply text as it streams. Required. |
321
326
  | `onSpeed?` | Receives the current generation speed in tokens per second. |
327
+ | `onPromptSpeed?` | Receives live prompt processing speed in tokens per second. |
322
328
  | `onStatus?` | Receives a `ChatStatusSnapshot` on every state change. |
323
329
 
324
330
  Without `model` the package picks the GPU build when the browser provides a
@@ -668,7 +674,8 @@ model files in the origin private file system as numbered parts, under
668
674
  `wllama-store` for the CPU engine and `litert-store` for the GPU engine. The GPU
669
675
  engine also reads a Cache Storage entry under `litertlm-models` when an older
670
676
  version stored the file. A quota failure keeps the parts already stored, so
671
- freeing disk lets the next attempt resume.
677
+ freeing disk lets the next attempt resume, and the running load streams the
678
+ model from the network so the assistant still starts.
672
679
 
673
680
  Both engines store the files before they load them, and one download serves
674
681
  every caller. A failed load, a cancelled call or a repeated `createChat` reads
@@ -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_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_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=>e?g.find(t=>t.id==e):void 0,f=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)}},h=async e=>p(e??await(async()=>(d||(d=(async()=>await f()?c.gemma4_e2b_limited:c.qwen3_vl_2b)()),await d))()),y=e=>!!e.cpu?.mmproj||!0===e.litert?.vision,w=e=>!!e.cpu?.mmproj?.audio||!0===e.litert?.audio,b=new URL("./../assets/wllama/wllama.wasm",import.meta.url).href,v=new URL("./../assets/wllama/compat/wllama.wasm",import.meta.url).href,x=new URL("./../assets/wllama/compat/wllama.js",import.meta.url).href,M=new URL("./../assets/litert/litertlm_wasm_internal.js",import.meta.url).href,j=(new URL("./../assets/litert/litertlm_wasm_internal.wasm",import.meta.url).href,{width:384,height:384}),k=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},_=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 P=r(155);const T={maxReplyTokens:250,maxThinkingTokens:128,maxReasoningTokens:320,maxImages:2,imageTokens:128,maxAudio:1,maxContentLength:1e3,promptCharBudget:1e4,maxThreads:32,gpuShare:.5},S=(e,t,r)=>"number"==typeof e&&Number.isFinite(e)&&e>=r?Math.floor(e):t,O=(e={},t=!1)=>{const r=T;return{maxReplyTokens:S(e.maxReplyTokens,r.maxReplyTokens,1),maxThinkingTokens:S(e.maxThinkingTokens,r.maxThinkingTokens,1),maxReasoningTokens:S(e.maxReasoningTokens,t?1200:r.maxReasoningTokens,1),maxImages:S(e.maxImages,r.maxImages,0),imageTokens:S(e.imageTokens,r.imageTokens,1),maxAudio:S(e.maxAudio,r.maxAudio,0),maxContentLength:S(e.maxContentLength,r.maxContentLength,1),promptCharBudget:S(e.promptCharBudget,r.promptCharBudget,1),maxThreads:S(e.maxThreads,r.maxThreads,1),gpuShare:"number"==typeof e.gpuShare&&Number.isFinite(e.gpuShare)&&e.gpuShare>0?Math.min(1,Math.max(.05,e.gpuShare)):r.gpuShare}},D=(e,t,r=.7)=>({stream:!0,temperature:r,max_tokens:t?e.maxReasoningTokens:e.maxReplyTokens}),N=(e,t)=>`https://huggingface.co/${e}/resolve/main/${t}`,C=e=>Number(e.headers.get("content-length"))||0,E=(e,t)=>e.some(e=>Array.isArray(e.content)&&e.content.some(e=>e.type==t)),L=e=>E(e,"image"),A=e=>E(e,"audio"),R=["<|channel>thought\n","<|channel>thought","..."],$=["<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,q=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[...q(e),{type:"text",text:"\n"},...q(t)]){const e=r[r.length-1];"text"==n.type&&"text"==e?.type?e.text+=n.text:r.push(n)}return r},I=m()?3e6:3e5,F=Math.max(I,84e4);class W extends Error{}const V=async(e,t,r)=>{let n;try{return await Promise.race([e,new Promise((e,o)=>{n=setTimeout(()=>o(new W(r)),t)})])}finally{n&&clearTimeout(n)}},B=e=>{try{Promise.resolve(e.next?.()).catch(()=>{}).finally(()=>{try{Promise.resolve(e.return?.()).catch(()=>{})}catch{}})}catch{}},G=async({model:e,logging:t,onReason:r,onText:n,onSpeed:o,start:a,stopped:i,firstTimeoutMs:s=I,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,$);if(t>=0){t&&e(s.slice(0,t)),s=s.slice(t+i.length),n=!1;continue}const c=a(s,$);e(s.slice(0,s.length-c.length)),r=c;break}{const{at:e,tag:i}=o(s,R);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,R);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 V(e,s,"Model did not start"))[Symbol.asyncIterator]();for(;;){if(i()){B(n);break}let e;try{const t=n.next();Promise.resolve(t).catch(()=>{}),e=await V(t,m?c:s,m?"Model stopped responding":"Model did not reply")}catch(e){if(e instanceof W&&(u||d)){l?.(),B(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,P.rNum)(1e3*p/(e-f)))}}h.flush()}catch(e){if(t&&console.log("Local chat failed",e),e instanceof W&&!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},Q=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 _(n.url,t,r)}:n);n.push({role:"user",content:e})}return n})(((e,t=T)=>{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?j: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 G({model:e,logging:t.logging,onReason:t.onReason,onText:t.onText,onSpeed:t.onSpeed,start:()=>r(i),stopped:o,onStall:a,firstTimeoutMs:L(i)?F:I})},Y=33554432,H=new Map;let J=!1;const Z=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}`},K=e=>{const t=/^part-(\d+)$/.exec(e);return t?Number(t[1]):-1},X=async()=>{if(!J)if("undefined"!=typeof navigator&&navigator.storage?.getDirectory)try{return await navigator.storage.getDirectory()}catch{return}else J=!0},ee=async(e,t)=>{try{return await e.getDirectoryHandle(t)}catch{return}},te=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}},re=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{}},ne=async function*(e){for await(const t of e)yield t},oe=async e=>{try{for await(const[t,r]of ne(e))"file"==r.kind&&K(t)>=0&&await e.removeEntry(t).catch(()=>{})}catch{}},ae=async(e,t)=>{try{const r=await(await e.getFileHandle(t)).getFile(),n=await te(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}},ie=async(e,t)=>{const r=await ee(e,t);if(r){const e=await(async e=>await te(await e.getFileHandle("meta.json").catch(()=>{})))(r),t=await(async e=>{const t=[];try{for await(const[r,n]of ne(e)){const e=K(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 ae(e,t)},se=(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:C(e)||t.total,etag:a||t.etag}},ce=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(Y-u,o.byteLength-p);await c.write({type:"write",position:u,data:o.subarray(p,p+e)}),p+=e,u+=e,l+=e,u==Y&&await m()}l>t&&a(n?l/n:0,s.download)}await m()}catch(e){throw await m(),e}return l},le=e=>["NotAllowedError","NotSupportedError"].includes(e?.name||""),ue=e=>{const t=async()=>{const t=await X();if(t)try{return await t.getDirectoryHandle(e,{create:!0})}catch{return}};return{stored:async e=>{const r=await t();return r?await ie(r,Z(e)):void 0},download:async({url:r,signal:n,onProgress:o})=>{const a=`${e}|${r}`,i=H.get(a);if(i)return await i;const c=await t();if(!c)return;const l=(async(e,t,r,n)=>{const o=Z(t),a=await ae(e,o);if(a?.complete)return a;let i=await ee(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 ie(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+Y,d)-1:u+Y-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 re(i,{total:d,etag:g,complete:!0});continue}await oe(i),await re(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=se(y,h);if(!r){await y.body.cancel().catch(()=>{}),await oe(i),await re(i,{total:0,etag:"",complete:!1});continue}await re(i,{total:r.total,etag:r.etag,complete:!1});const a=0==r.start?u:0,s=await ce({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 re(i,{total:s,etag:r.etag,complete:!0});const t=await ie(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(()=>{H.delete(a)});return H.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,Z(e))},purge:async()=>{const t=await X();t&&await t.removeEntry(e,{recursive:!0}).catch(()=>{})}}},de=(e,...t)=>{!0===e&&console.log(...t)},ge="litertlm-models",me=.5,pe=ue("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=me,ve=!1,xe=0;const Me=(...e)=>{he&&console.log(...e)},je=(...e)=>{he&&console.error(...e)},ke=e=>e.replace(/<\|channel>thought\n?[\s\S]*?<channel\|>/g,"").replace(/<\|channel>thought[\s\S]*$/,"").trim(),_e=async()=>{const e=performance.now(),t=e-xe;if(xe=e,!ve)return;const r=Math.round(((e,t=.5)=>Math.min(500,Math.max(0,e*(1/t-1))))(t,be));r<1||(await new Promise(e=>setTimeout(e,r)),xe=performance.now())},Pe=(e=.5)=>{be=e>0?e:me,ve=!0,xe=performance.now()},Te=async()=>{try{if("undefined"==typeof caches)return;return await caches.open(ge)}catch{return}},Se=new Map,Oe=(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)}}))},De=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 k(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},Ne=(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&&ke(e.content)==ke(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(ke(n.text)!=ke(o.text))return!1}else{if("text"==n.type||"text"==o.type)return!1;if(!!n.url!=!!o.url)return!1}}return!0},Ce=async function*({engine:e,mod:t,params:r,messages:n,session:o}){const a=n[n.length-1],i=D(r.limits,r.reasoning,r.temperature);if("user"!=a?.role)throw new Error("No user turn");const s=n.slice(0,-1),c=(await De([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&&!Ne(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(!Ne(o[i+e],a[e]))return!1;return!0})(o.sent,s);let d;if(l&&u&&o.conversation)de(he,"LiteRT conversation reused",o.sent.length),d=o.conversation;else{const n=await De(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}),de(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&&(de(he,"LiteRT first chunk",Math.round(a)),Pe(r.limits.gpuShare));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{ve=!1,r.signal?.removeEventListener("abort",h),m&&f?o.sent.push({role:"assistant",content:f}):(o.conversation=void 0,o.sent=[])}},Ee={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:Me,printErr:je};try{await u.getOrLoadGlobalLiteRtLm(M)}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:_e});we.add(h),we.add(e),f.preinitializedWebGPUDevice=e}const y=N(c.repo,c.file),w=await Te();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(!le(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=Se.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=C(o),i=Oe(o.body,a,n);await t.put(e,new Response(i,{headers:{"content-type":"application/octet-stream",...a?{"content-length":`${a}`}:{}}}))})().finally(()=>{Se.delete(e)});return Se.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 Oe(n.body,C(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 j=()=>{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(),de(he,"LiteRT conversation warm-up",Math.round(performance.now()-e))}catch(e){de(he,"LiteRT conversation warm-up failed",e)}if(o?.aborted)throw await x.delete(),j(),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 Q({model:t,params:n,stopped:()=>!!n.signal?.aborted,onStall:a,start:async a=>{if(n.signal?.aborted)throw new Error("Cancelled");if(L(a)&&!t.litert?.vision)throw new Error("Model does not accept images");if(A(a)&&!t.litert?.audio)throw new Error("Model does not accept audio");return Ce({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(),j()}}},cached:async e=>{const t=e.litert;if(!t)return!1;const r=N(t.repo,t.file),[n,o]=await Promise.all([Te(),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(ge)}catch{}}},Le=ue("wllama-store"),Ae=[c.qwen3_vl_2b_instruct,c.qwen3_vl_2b_instruct_q3],Re=e=>e.cpu?.mmproj&&Ae.includes(e.id)?{image_min_tokens:16,image_max_tokens:128}:{};let $e,Ue,qe="",ze=!1;const Ie=e=>`${e.wasm}|${e.compatWasm}|${e.compatWorker}`,Fe=e=>{const t={wasm:b,compatWasm:v,compatWorker:x};return{wasm:e?.wasm||t.wasm,compatWasm:e?.compatWasm||t.compatWasm,compatWorker:e?.compatWorker||t.compatWorker}},We=e=>{const t=e=>(...t)=>{ze&&("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)}},Ve=async()=>{if($e)return $e;const e=await r.e(924).then(()=>r(577)),t=Ue||Fe(),n=new e.Wllama({default:t.wasm},{logger:We(e.LoggerWithoutDebug)});return Ue||(Ue=t,qe=Ie(t)),n.setCompat({wasm:t.compatWasm,worker:t.compatWorker}),$e=n,n},Be=async()=>{const e=$e;$e=void 0;try{await(e?.exit())}catch{}},Ge=(e,t)=>e.name.includes(t)||!!e.metadata?.originalURL?.includes(t),Qe=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)}]:[]]:[]},Ye=async e=>{const t=Qe(e);if(!t.length)return!1;for(const e of t){const t=await Le.stored(e.url);if(!t?.complete)return!1}return!0},He=async(e,t)=>{const r=await e.cacheManager.list();return Qe(t).every(e=>r.some(t=>Ge(t,e.name)))},Je=async({model:e,signal:t,onProgress:r})=>{const n=Qe(e),o=[];for(let e=0;e<n.length;e++){if(t?.aborted)throw new Error("Cancelled");const a=await Le.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},Ze=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 k(t.url)});t.push({role:"user",content:e})}return t},Ke={backend:i.cpu,startLLM:async({model:e,limits:t,onProgress:r,signal:n,logging:o,assets:a})=>{ze=!0===o;const c=m()?4096:8192,l=e.cpu;if(!l)throw new Error("Model has no CPU artifact");const u=Fe(a),d=Ie(u);$e&&d!=qe&&await Be(),Ue=u,qe=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 Ve(),h=await Ye(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 Be(),new Error("Cancelled");if(!h&&y){const e=await f.cacheManager.list(),t=e.some(e=>Ge(e,l.file)),r=e.some(e=>Ge(e,y));t&&!r&&await f.cacheManager.deleteMany(e=>Ge(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)),...Re(e)};try{let t=h?await Je({model:e,signal:n,onProgress:r}):void 0;t||h||await He(f,e).catch(()=>!1)||(t=await Je({model:e,signal:n,onProgress:r}).catch(e=>{if(n?.aborted)throw new Error("Cancelled");if(!le(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 Be(),e}if(n?.aborted)throw await Be(),new Error("Cancelled");const x=f.getLoadedContextInfo();if(!x.n_ctx)throw await Be(),new Error("Failed to create model context");return de(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(ze=!0===r.logging,e.isModelLoaded())return await Q({model:t,params:r,stopped:()=>!!r.signal?.aborted,start:async n=>{if(L(n)&&!e.supportInputModality("image"))throw new Error("Model does not accept images");if(A(n)&&!e.supportInputModality("audio"))throw new Error("Model does not accept audio");return await e.createChatCompletion({messages:await Ze(n),...D(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($e==f)await Be();else try{await f.exit()}catch{}}}},cached:async e=>{try{return!!e.cpu&&(!!await Ye(e)||await He(await Ve(),e))}catch{return!1}},purge:async()=>{try{await Le.purge()}catch{}try{const e=await Ve();await e.cacheManager.clear()}catch{}}},Xe=((e={})=>{const t=e.engines?.cpu||Ke,r=e.engines?.litert||Ee,n=new Map,o=new Map,c=new Map,l=new Map,u=new Map,d=new Map,g=new Map,m=new Map,p=new Map;let f,h,y,w=a.idle;const b=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},v=e=>e?n.get(e):f?n.get(f.id):void 0,x=e=>{w=e},M=async e=>{const t=n.get(e);t&&(n.delete(e),f?.id==e&&(f=[...n.values()].pop()?.model),n.size||o.size||x(a.idle),await t.unload())},j=async()=>{for(const e of[...n.keys()])await M(e)},k=(e,t,r)=>{const n={percent:Math.max(0,Math.min(1,t)),phase:r||s.download};u.set(e,n);for(const t of l.get(e)??[])t.report(n.percent,n.phase)},_=e=>{g.set(e,(g.get(e)??0)+1),d.get(e)?.abort(),d.delete(e);const t=o.get(e);t&&c.set(e,t),o.delete(e),l.delete(e),u.delete(e),m.set(e,a.idle),w!=a.downloading||o.size||n.size||x(a.idle)},P=(e,t,r)=>{const n=o.get(e);return n?new Promise(a=>{let i=!1;const s={report:t,settle:e=>{i||(i=!0,r?.removeEventListener("abort",c),a(e))}},c=()=>{((e,t)=>{const r=l.get(e);r&&l.set(e,r.filter(e=>e!=t)),queueMicrotask(()=>{!l.get(e)?.length&&o.has(e)&&_(e)})})(e,s),s.settle(!1)},u=l.get(e);u?u.push(s):l.set(e,[s]),r?.aborted?c():r?.addEventListener("abort",c,{once:!0}),n.attempt.then(s.settle,()=>s.settle(!1))}):Promise.resolve(!1)},T=async e=>{if(e)await M(e);else{for(const e of[...o.keys()])_(e);u.clear(),m.clear(),p.clear(),h=void 0,x(a.idle),await j()}};return{load:async({model:e,limits:t,assets:r,logging:i,signal:y,onProgress:w})=>{if(y?.aborted)return!1;if(n.has(e.id))return f=e,!0;if(o.has(e.id)){const t=u.get(e.id);return t&&w(t.percent,t.phase),await P(e.id,w,y)}const v=b(e);if(!v){const t="Model is not supported on this device";return h=t,p.set(e.id,t),m.set(e.id,a.unsupported),x(a.unsupported),!1}const M=[...o.values(),...c.values()];for(const e of M)_(e.model.id);const T=(g.get(e.id)??0)+1;g.set(e.id,T);const S=(async()=>{if(await Promise.all(M.map(e=>e.attempt.catch(()=>!1))),T!=g.get(e.id))return!1;if(await(async()=>{try{if("undefined"==typeof navigator)return;await(navigator.storage?.persist?.())}catch{}})(),T!=g.get(e.id))return!1;if(await j(),T!=g.get(e.id))return!1;const o=await v.cached(e);if(T!=g.get(e.id))return!1;h=void 0,p.delete(e.id),m.set(e.id,a.downloading),x(a.downloading),k(e.id,0,s.download),o&&k(e.id,1,s.load);const c=new AbortController;d.set(e.id,c);try{const o=await v.startLLM({model:e,limits:t,logging:i,signal:c.signal,assets:r,onProgress:(t,r)=>{T==g.get(e.id)&&k(e.id,t,r)}});return T!=g.get(e.id)||c.signal.aborted?(await o.unload(),!1):(n.set(e.id,o),f=e,h=void 0,p.delete(e.id),m.set(e.id,a.ready),x(a.ready),k(e.id,1,s.load),!0)}catch(t){if(T!=g.get(e.id))return!1;const r=`${t?.message||`${t}`}`;return h=r,p.set(e.id,r),m.set(e.id,a.error),x(a.error),i&&console.log("Local model failed",t),!1}finally{d.get(e.id)==c&&d.delete(e.id)}})();let O;const D=S.finally(()=>{c.get(e.id)==O&&c.delete(e.id),o.get(e.id)==O&&(o.delete(e.id),l.delete(e.id),u.delete(e.id))});return O={model:e,attempt:D},o.set(e.id,O),l.set(e.id,[]),await P(e.id,w,y)},chat:async e=>{if(!v(e.model))return;for(;y;)await y.catch(()=>{});const t=v(e.model);if(!t)return;f?.id!=t.model.id&&(f=t.model);const r=t.chat(e);y=r;try{return await r}finally{y==r&&(y=void 0)}},unload:T,clear:async()=>{const e=[...o.values(),...c.values()].map(e=>e.attempt);await T(),await Promise.all(e.map(e=>e.catch(()=>{}))),await Promise.all([t.purge(),r.purge()])},ready:e=>!!v(e),loading:e=>e?o.has(e):o.size>0,status:e=>v(e)?a.ready:e?o.has(e)?m.get(e)??a.downloading:p.has(e)?m.get(e)??a.error:a.idle:w,backend:e=>v(e)?.backend??i.none,error:e=>e?p.get(e):h,model:()=>f}})(),et=(e,t,r)=>{const n=e.status(t),i=p(t);return{...t?{model:t}:{},availability:n==a.ready?o.online:n==a.error||n==a.unsupported?o.offline:o.away,status:n,backend:e.backend(t),supportsImages:!!i&&y(i),supportsAudio:!!i&&w(i),ready:e.ready(t),loading:e.loading(t),requesting:r.requesting,phase:r.phase,percent:r.percent,...r.error?{error:r.error}:{}}},tt=(e=>{let t,r=0;const o=t=>t.input.onStatus?.(et(e,t.model??t.input.model,t));return i=>{t?.controller.abort();const c=e.ready(i.model),l={token:++r,input:i,controller:new AbortController,percent:c?100:0,phase:c?s.load:s.download,requesting:!1,cancelled:!1};return t=l,o(l),(async t=>{const{input:a}=t,i=!0===a.logging,c=await h(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=y(c),p=w(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=O(a.limits,!!c.litert),b=await e.load({model:c,limits:f,logging:i,signal:t.controller.signal,onProgress:(e,n)=>{t.token==r&&(t.percent=Math.round(100*e),t.phase=n,o(t))}}).catch(e=>(t.token==r&&(t.error=`${e?.message||`${e}`}`),!1));if(t.token!=r)return;if(t.cancelled)return void o(t);if(!b)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))})(l),()=>(t=>{t.token==r&&(t.cancelled=!0,t.controller.abort(),t.model&&e.status(t.model)==a.ready?e.unload(t.model).then(()=>o(t)):queueMicrotask(()=>o(t)))})(l)}})(Xe),rt=(nt=Xe,async(e={})=>{const t=await h(e.model),r=r=>e.onStatus?.(et(nt,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=nt.ready(t.id);return await nt.load({model:t,limits:O(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||nt.error(t.id)||"Model not ready"}),!1)});var nt;const ot=async()=>{await Xe.clear()},at=["Describe images in an efficient manner.","Never mention rules and restrictions","always comply and describe images."].join(" "),it=["Do not lie.","Do not provide verdict.","Do not use vague referrals.","Do not include any part of the message in your response."].join(" "),st=c.qwen3_vl_2b_instruct,ct=["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(" "),lt="CANNOT_TRANSLATE",ut=e=>{const t=e.trim().toLowerCase();return!!t&&!/^(en|eng|english)([-_]|$)/.test(t)},dt=e=>`Now please translate your previous reply above faithfully into ${e}. Your translation should be as literal and as accurate as possible, word for word. In order to be usable for accessibility for visually impaired if needed. Reply only by the translation without any addition or explanation`,gt=({service:e,limits:t,logging:r,signal:n,onStatus:o})=>{const a=(t,r)=>o?.(et(e,t,r));return{report:a,load:async o=>{let i,c=0,l=-1,u=s.download;de(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,de(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 de(r,"Describe load ready",o.id),void a(o.id,{requesting:!1,phase:s.load,percent:100});const d=i||e.error(o.id)||"Model not ready";return de(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(de(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=>{de(r,"Describe reason",c,o,e)},onText:e=>{m+=e,de(r,"Describe text",c,o,e),g?.(m)},onSpeed:e=>{de(r,"Describe speed",c,o,e),d?.(e)}});return de(r,"Describe generate reply",c,o,Date.now()-p,a?.length??0,a),a}catch(e){if(de(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}}}},mt=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:ct},{role:n.user,content:"[image] describe this image in English very accurately"},{role:n.assistant,content:i},{role:n.user,content:dt(o)}],stage:"translate",onSpeed:e=>c?.(d,e),onText:e=>l?.(d,e,"translate")})||"").trim()}catch(e){de(a,"Translate item failed",d,e)}const m=g.replace(/[^a-z]/gi,"").toUpperCase().includes(lt.replace(/[^a-z]/gi,""));g&&!m&&(u[d]=g),s?.(d,i,u[d])}return u},pt=(e=>async t=>{const{images:r,currentIndex:o,signal:a}=t,i=[],l=!0===t.logging;if(de(l,"Describe start",r.length,t.targetLanguage),!r.length)return de(l,"Describe empty"),i;const u=p(st),d=st,g=O({maxReplyTokens:128,imageTokens:192,...t.limits}),{report:m,load:h,generate:y}=gt({service:e,limits:g,logging:l,signal:a,onStatus:t.onStatus});de(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 de(l,"Describe model missing",d),m(d,{requesting:!1,phase:s.download,percent:0,error:"Unknown model"}),new Error("Unknown model");const b=await h(u);if(b)throw de(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];de(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:`${at}${t.additionalRules?` ${t.additionalRules} `:" "}${it}`},{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){de(l,"Describe image failed",e,t)}const d=Date.now()-a;de(l,"Describe english",e,d,c),c?(i.push({descriptionEN:c,description:c,durationMs:d}),o?.(e,c,void 0,d)):(de(l,"Describe empty",e),i.push({descriptionEN:"",description:"",durationMs:d}),o?.(e,"",void 0,d))}const v=i.filter(e=>!!e.descriptionEN).length;if(de(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=ut(x)&&await f()?p(c.gemma4_e2b_limited):void 0,j=M?await h(M):void 0;if(M&&!j){if(a?.aborted)return i;m(M.id,{requesting:!0,phase:s.load,percent:100}),await mt({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})(Xe),ft=(e=>async t=>{const r=[...t.descriptions],n=t.targetLanguage.trim(),o=!0===t.logging;if(de(o,"Translate start",r.length,n),!r.length||!ut(n))return de(o,"Translate skipped"),r;const a=O({maxReplyTokens:128,...t.limits}),{report:i,load:l,generate:u}=gt({service:e,limits:a,logging:o,signal:t.signal,onStatus:t.onStatus}),d=await f()?p(c.gemma4_e2b_limited):void 0;if(!d)return de(o,"Translate no gpu"),r;const g=await l(d);if(g)return de(o,"Translate stop",g),r;if(t.signal?.aborted)return r;i(d.id,{requesting:!0,phase:s.load,percent:100});const m=await mt({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})(Xe),ht=/^[0-9+\-*/%^().]+$/,yt=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},wt={name:"calculate",description:"Evaluate an arithmetic expression. Supports + - * / % ^ and parentheses; % divides by 100.",parameters:{type:"object",properties:{expression:{type:"string",description:"Arithmetic expression, for example 2*(3+4)"}},required:["expression"]},execute:e=>{const t=e.expression;if("string"!=typeof t)throw new Error("Missing expression");return(e=>{if(e.trim().length>200)throw new Error("Expression is too long");const t=(e=>e.replace(/×/g,"*").replace(/÷/g,"/").replace(/−/g,"-").replace(/,/g,"").replace(/\s+/g,""))(e);if(!t)throw new Error("Expression is empty");if(!ht.test(t))throw new Error("Unsupported character");const r=yt(t);return{expression:t,result:Math.abs(r)>=1e5?(0,P.pNum)(r)??r:(0,P.rNum)(r,12)}})(t)}},bt="degreesign-chat-prices-v1",vt="EUR",xt=5*P.oneMin,Mt=30*P.oneSec;let jt,kt={},_t=0,Pt=!1,Tt=!1;const St=e=>{const t={};for(const[r,n]of Object.entries(e??{}))"number"==typeof n&&Number.isFinite(n)&&(t[r.trim().toUpperCase()]=n);return t},Ot=(e,t)=>e&&e.sourceAt>t.sourceAt?e:t,Dt=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=St(e.rates?.current),n=St(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&&(kt.fiat=Ot(kt.fiat,a)),i&&(kt.crypto=Ot(kt.crypto,i)),_t=0,Pt=!1,(()=>{try{if("undefined"==typeof localStorage)return;localStorage.setItem(bt,JSON.stringify(kt))}catch{}})()}catch(e){throw _t=Date.now(),Pt=!0,e}},Nt=e=>!!kt.crypto&&(e in kt.crypto.prices||e in kt.crypto.yesterday),Ct=e=>!!kt.fiat&&(e in kt.fiat.rates||e in kt.fiat.yesterday),Et=async e=>{const t=(e=>{const t={fiat:!1,crypto:!1};for(const r of e){if(r==vt)continue;const e=Nt(r)||Ct(r);!Nt(r)&&e||(t.crypto=!0),Nt(r)||(t.fiat=!0)}return t})(e),r=Date.now(),n=t.fiat&&r-(kt.fiat?.fetchedAt??0)>=P.oneHr,o=t.crypto&&r-(kt.crypto?.fetchedAt??0)>=xt;(n||o)&&("undefined"!=typeof navigator&&!1===navigator.onLine||_t&&r-_t<Mt||(jt||(jt=Dt({fiat:n,crypto:o}).catch(()=>{}).finally(()=>{jt=void 0})),await jt))},Lt=e=>{if(e==vt)return 1;const t=kt.crypto?.yesterday[e],r=kt.fiat?.yesterday[e];return t||(r?1/r:void 0)},At=(e,t)=>{if("string"!=typeof e||!e.trim())throw new Error(`Missing ${t}`);return e.trim().toUpperCase()},Rt=e=>Math.abs(e)>=1e5?(0,P.pNum)(e)??e:(0,P.rNum)(e,8),$t=async e=>{(()=>{if(!Tt){Tt=!0;try{if("undefined"==typeof localStorage)return;const e=localStorage.getItem(bt);if(!e)return;const t=JSON.parse(e);kt={...t.fiat?{fiat:t.fiat}:{},...t.crypto?{crypto:t.crypto}:{}}}catch{}}})();const t=At(e.from,"from"),r=void 0===e.to||null===e.to?vt:At(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 Et([t,r]);const o=e=>{const t=(e=>{if(e==vt)return 1;const t=kt.crypto?.prices[e],r=kt.fiat?.rates[e];return t||(r?1/r:void 0)})(e);if(void 0!==t)return t;if(!kt.fiat&&!kt.crypto)throw new Error("Prices unavailable offline");if(Nt(e)||Ct(e))throw new Error(`Unavailable quote for ${e}`);throw new Error(`Unknown symbol ${e}`)},a=o(t),i=o(r),s=Lt(t),c=Lt(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!=vt&&(Nt(r)?kt.crypto&&t.push(kt.crypto.sourceAt):Ct(r)&&kt.fiat&&t.push(kt.fiat.sourceAt));return t})([t,r]),p=m.length?Math.min(...m):Date.now();return{from:t,to:r,amount:n,rate:Rt(l),...void 0===u?{}:{previousRate:Rt(u),change:Rt(d??0),changePercent:(0,P.rNum)(g??0,4)},result:Rt(n*l),updatedAt:new Date(p).toISOString(),stale:Pt&&!(!kt.fiat&&!kt.crypto)}},Ut={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=>$t(e)},qt={amp:"&",apos:"'",gt:">",lt:"<",nbsp:" ",quot:'"',hellip:"...",mdash:"-",ndash:"-",ldquo:'"',lsquo:"'",rdquo:'"',rsquo:"'"},zt=(e,t,r,n)=>"number"==typeof e&&Number.isFinite(e)?Math.min(r,Math.max(t,e)):n,It=(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 qt[e.toLowerCase()]??e})(t);return r==t?e:r}).replace(/\s+/g," ").trim().slice(0,Math.max(0,t)).trim(),Ft=/^[a-z]{2,3}(-[a-z]{2,4})?$/i,Wt=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)}},Vt=(e={})=>{const t=((e={})=>{const t=e.language?.trim()??"";return{provider:e.provider==u.duckduckgo?u.duckduckgo:u.wikipedia,language:Ft.test(t)?t:"en",limit:Math.round(zt(e.limit,1,20,3)),snippetLength:Math.round(zt(e.snippetLength,1,4e3,400)),timeout:zt(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 Wt(r,e.timeout),o=[],a=new Set,i=(t,r,n)=>{t&&n&&!a.has(t)&&(a.add(t),o.push({title:It(r||n,200),url:t,snippet:It(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 Wt(n,e.timeout),a=[];for(const t of o.pages??[]){const n=t.key;n&&a.push({title:It(t.title??n,200),url:`${r}/wiki/${encodeURIComponent(n)}`,snippet:It(`${t.description??""} ${t.excerpt??""}`,e.snippetLength)})}return a})(t,r);return n}}},Bt=(e,t)=>{const r=[];for(const n of e)n==l.websearch?r.push(Vt(t)):n==l.calculate?r.push(wt):n==l.currency&&r.push(Ut);return r},Gt=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,Bt as builtinTools,wt as calculateTool,ot as clearModelCache,tt as createChat,Ut as currencyTool,pt as describeImages,st as describeModelId,ft as describeTranslated,f as gpuAdapter,Gt as imageReplyTokens,rt as preloadModel,Vt 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,d;let g;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.quota="QuotaExceededError",e.notAllowed="NotAllowedError",e.notSupported="NotSupportedError",e.invalidState="InvalidStateError",e.typeMismatch="TypeMismatchError",e.security="SecurityError"}(c||(c={})),function(e){e.qwen3_vl_2b="qwen3-vl-2b",e.qwen3_vl_2b_instruct="qwen3-vl-2b-instruct",e.qwen3_vl_2b_instruct_q3="qwen3-vl-2b-instruct-q3",e.gemma4_e2b_limited="gemma4-e2b-limited"}(l||(l={})),function(e){e.websearch="websearch",e.calculate="calculate",e.currency="currency"}(u||(u={})),function(e){e.wikipedia="wikipedia",e.duckduckgo="duckduckgo"}(d||(d={}));const m=[{id:l.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:l.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:l.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:l.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}}],p=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},f=e=>e?m.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(e??await(async()=>(g||(g=(async()=>await h()?l.gemma4_e2b_limited:l.qwen3_vl_2b)()),await g))()),w=e=>!!e.cpu?.mmproj||!0===e.litert?.vision,b=e=>!!e.cpu?.mmproj?.audio||!0===e.litert?.audio;var v=r(155);const x=new URL("./../assets/wllama/wllama.wasm",import.meta.url).href,M=new URL("./../assets/wllama/compat/wllama.wasm",import.meta.url).href,j=new URL("./../assets/wllama/compat/wllama.js",import.meta.url).href,k=new URL("./../assets/litert/litertlm_wasm_internal.js",import.meta.url).href,_=(new URL("./../assets/litert/litertlm_wasm_internal.wasm",import.meta.url).href,{width:384,height:384}),S=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}},T={maxReplyTokens:250,maxThinkingTokens:128,maxReasoningTokens:320,maxImages:2,imageTokens:128,maxAudio:1,maxContentLength:1e3,promptCharBudget:1e4,maxThreads:32,gpuShare:.5},O=(e,t)=>{let r=0;for(const n of e)if("string"!=typeof n.content)for(const e of n.content)r+="text"==e.type?e.text.length/4:t;else r+=n.content.length/4;return Math.round(r)},D=(e,t,r)=>"number"==typeof e&&Number.isFinite(e)&&e>=r?Math.floor(e):t,N=(e={},t=!1)=>{const r=T;return{maxReplyTokens:D(e.maxReplyTokens,r.maxReplyTokens,1),maxThinkingTokens:D(e.maxThinkingTokens,r.maxThinkingTokens,1),maxReasoningTokens:D(e.maxReasoningTokens,t?1200:r.maxReasoningTokens,1),maxImages:D(e.maxImages,r.maxImages,0),imageTokens:D(e.imageTokens,r.imageTokens,1),maxAudio:D(e.maxAudio,r.maxAudio,0),maxContentLength:D(e.maxContentLength,r.maxContentLength,1),promptCharBudget:D(e.promptCharBudget,r.promptCharBudget,1),maxThreads:D(e.maxThreads,r.maxThreads,1),gpuShare:"number"==typeof e.gpuShare&&Number.isFinite(e.gpuShare)&&e.gpuShare>0?Math.min(1,Math.max(.05,e.gpuShare)):r.gpuShare}},C=(e,t,r=.7)=>({stream:!0,temperature:r,max_tokens:t?e.maxReasoningTokens:e.maxReplyTokens}),E=(e,t)=>`https://huggingface.co/${e}/resolve/main/${t}`,L=e=>Number(e.headers.get("content-length"))||0,A=(e,t)=>e.some(e=>Array.isArray(e.content)&&e.content.some(e=>e.type==t)),R=e=>A(e,"image"),$=e=>A(e,"audio"),q=["<|channel>thought\n","<|channel>thought","..."],U=["<channel|>","..."],I=(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,F=(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},W=p()?3e6:3e5,V=Math.max(W,84e4);class B extends Error{}const G=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.next?.()).catch(()=>{}).finally(()=>{try{Promise.resolve(e.return?.()).catch(()=>{})}catch{}})}catch{}},Y=async({model:e,logging:t,onReason:r,onText:n,onSpeed:o,onPromptSpeed:a,promptTokens:i,start:s,stopped:c,firstTimeoutMs:l=W,idleTimeoutMs:u=3e4,onStall:d})=>{let g,m="",p="",f="",h=!1,y=!1,w=!1,b=0,x=0,M=0,j=0,k=0,_=0,S=0;const P=e=>{!Number.isFinite(e)||e<=0||(b=(0,v.rNum)(e),a?.(b))},T=()=>{if(h||w||!i)return;const e=performance.now()-k;e>0&&P(1e3*i/e)},O=()=>{null!=g&&(clearInterval(g),g=void 0)},D=e=>{if(!e)return;const t=performance.now(),r=e.n_prompt_tokens_processed??e.processed;if("number"!=typeof r||r<=0)return;w=!0,O();let n=0;n="number"==typeof e.time_ms&&e.time_ms>0?1e3*r/e.time_ms:x?1e3*(r-M)/Math.max(1,t-x):1e3*r/Math.max(1,t-k),t-j<500||(j=t,x=t,M=r,P(n))};a&&i&&(g=setInterval(T,500));const N=((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,q);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,q);t(s.slice(0,s.length-c.length)),r=c;break}}},flush:()=>{r&&(n?e(r):t(r),r="")}}})(e=>{p+=e,r(e)},e=>{m+=e,n(e)});try{k=performance.now();const e=s();Promise.resolve(e).catch(()=>{});const n=(await G(e,l,"Model did not start"))[Symbol.asyncIterator]();for(;;){if(c()){Q(n);break}let e;try{const t=n.next();Promise.resolve(t).catch(()=>{}),e=await G(t,h?u:l,h?"Model stopped responding":"Model did not reply")}catch(e){if(e instanceof B&&(m||p)){d?.(),Q(n),t&&console.log("Local chat stalled",e);break}throw e}if(e.done)break;const a=e.value,i=a?.choices?.[0],s=i?.delta,g="string"==typeof s?.reasoning_content?s.reasoning_content:"string"==typeof s?.reasoning?s.reasoning:"",w=!!g||!!s?.content||!!i?.finish_reason,x=a?.timings?.prompt_per_second;if(w){if(h||(D(a?.prompt_progress),b||T(),h=!0,O()),!y&&"number"==typeof x&&Number.isFinite(x)&&x>0&&(y=!0,P(x)),i?.finish_reason&&(f=i.finish_reason),g&&(p+=g,r(g)),s?.content&&N.feed(s.content),g||s?.content){const e=performance.now();_||(S=e),_+=1,_>1&&e>S&&o?.((0,v.rNum)(1e3*_/(e-S)))}}else D(a?.prompt_progress),!y&&"number"==typeof x&&Number.isFinite(x)&&x>0&&(y=!0,P(x),O())}N.flush()}catch(e){if(t&&console.log("Local chat failed",e),e instanceof B&&!c())throw e}finally{O()}const C=c()?void 0:m||void 0;return t&&(console.log("Local chat reply",e.id,C?"****":""),console.log("Local chat finish",e.id,f||"none",m.length,p.length)),C},H=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=T)=>{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:I(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=F(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?_: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 Y({model:e,logging:t.logging,onReason:t.onReason,onText:t.onText,onSpeed:t.onSpeed,onPromptSpeed:t.onPromptSpeed,promptTokens:O(i,t.limits.imageTokens),start:()=>r(i),stopped:o,onStall:a,firstTimeoutMs:R(i)?V:W})};const J=33554432,Z=new Set([c.quota,c.notAllowed,c.notSupported,c.invalidState,c.typeMismatch,c.security]),K=new Map,X=new Set;let ee=!1;const te=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}`},re=e=>{const t=/^part-(\d+)$/.exec(e);return t?Number(t[1]):-1},ne=async()=>{if(!ee)if("undefined"!=typeof navigator&&navigator.storage?.getDirectory)try{return await navigator.storage.getDirectory()}catch{return}else ee=!0},oe=async()=>{try{if("undefined"==typeof navigator||!navigator.storage?.estimate)return;const e=await navigator.storage.estimate();return"number"==typeof e.quota&&e.quota>0?e.quota-(e.usage||0):void 0}catch{return}},ae=async(e,t)=>{try{return await e.getDirectoryHandle(t)}catch{return}},ie=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}},se=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{}},ce=async function*(e){for await(const t of e)yield t},le=async e=>{try{for await(const[t,r]of ce(e))"file"==r.kind&&re(t)>=0&&await e.removeEntry(t).catch(()=>{})}catch{}},ue=async(e,t)=>{try{const r=await(await e.getFileHandle(t)).getFile(),n=await ie(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}},de=async(e,t)=>{const r=await ae(e,t);if(r){const e=await(async e=>await ie(await e.getFileHandle("meta.json").catch(()=>{})))(r),t=await(async e=>{const t=[];try{for await(const[r,n]of ce(e)){const e=re(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 ue(e,t)},ge=(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:L(e)||t.total,etag:a||t.etag}},me=async({dir:e,start:t,skip:r,total:n,body:o,onProgress:a,onChunk:i})=>{let c,l,u=t,d=0,g=r;const m=async()=>{const t=await e.getFileHandle((e=>`part-${e}`)(u),{create:!0});l=await t.createWritable(),d=0},p=async()=>{const e=l;l=void 0,e&&await e.close()};try{const e=o.getReader();for(c=e;;){const{done:r,value:o}=await e.read();if(r)break;i();let c=0;for(g&&(c=Math.min(g,o.byteLength),g-=c);c<o.byteLength;){l||await m();const e=Math.min(J-d,o.byteLength-c);await l.write({type:"write",position:d,data:o.subarray(c,c+e)}),c+=e,d+=e,u+=e,d==J&&await p()}u>t&&a(n?u/n:0,s.download)}await p()}catch(e){throw await p().catch(()=>{}),await(c?.cancel().catch(()=>{})),e}return u},pe=e=>e?.name==c.quota,fe=e=>{const t=async()=>{const t=await ne();if(t)try{return await t.getDirectoryHandle(e,{create:!0})}catch{return}};return{stored:async e=>{const r=await t();return r?await de(r,te(e)):void 0},download:async({url:r,signal:n,onProgress:o})=>{if(X.has(r))throw new DOMException("Storage is full",c.quota);const a=`${e}|${r}`,i=K.get(a);if(i)return await i;const l=await t();if(!l)return;const u=(async(e,t,r,n)=>{const o=te(t),a=await ue(e,o);if(a?.complete)return a;let i=await ae(e,o);i||(await e.removeEntry(o).catch(()=>{}),await e.removeEntry(`${o}.json`).catch(()=>{}),i=await e.getDirectoryHandle(o,{create:!0}));let l=0,u=0,d=!1;for(;;){if(r?.aborted)throw new Error("Cancelled");const a=await de(e,o);if(a?.complete)return a;const g=a?.size??0,m=a?.total||0,p=a?.etag||"";if(g>l)l=g,u=0;else if(++u>4)throw new Error("Model download failed");g&&m&&n(g/m,s.download);const f=m?Math.min(g+J,m)-1:g+J-1,h=new AbortController,y=()=>h.abort(),w={size:g,total:m,etag:p};let b,v=setTimeout(y,3e4);r?.addEventListener("abort",y,{once:!0});try{if(b=await fetch(t,{signal:h.signal,headers:{Range:`bytes=${g}-${f}`}}),416==b.status){if(await(b.body?.cancel().catch(()=>{})),m&&g>=m){await se(i,{total:m,etag:p,complete:!0});continue}await le(i),await se(i,{total:0,etag:"",complete:!1});continue}if(!b.ok||!b.body)throw await(b.body?.cancel().catch(()=>{})),new Error("Model download failed");const r=ge(b,w);if(!r){await b.body.cancel().catch(()=>{}),await le(i),await se(i,{total:0,etag:"",complete:!1});continue}await se(i,{total:r.total,etag:r.etag,complete:!1});const a=0==r.start?g:0,s=r.start+a;if(!d&&r.total>s){d=!0;const e=await oe();if(null!=e&&e<r.total-s)throw await b.body.cancel().catch(()=>{}),new DOMException("Storage is full",c.quota)}const l=await me({dir:i,start:s,skip:a,total:r.total,body:b.body,onProgress:n,onChunk:()=>{clearTimeout(v),v=setTimeout(y,3e4)}});if(!r.total){await se(i,{total:l,etag:r.etag,complete:!0});const t=await de(e,o);if(t)return t}}catch(e){if(r?.aborted)throw new Error("Cancelled");if(e instanceof DOMException&&Z.has(e.name))throw e;await new Promise(e=>setTimeout(e,250+500*u))}finally{clearTimeout(v),r?.removeEventListener("abort",y)}}})(l,r,n,o).catch(e=>{throw pe(e)&&X.add(r),e}).finally(()=>{K.delete(a)});return K.set(a,u),await u},remove:async e=>{X.delete(e);const r=await t();r&&await(async(e,t)=>{await e.removeEntry(t,{recursive:!0}).catch(()=>{}),await e.removeEntry(`${t}.json`).catch(()=>{})})(r,te(e))},purge:async()=>{X.clear();const t=await ne();t&&await t.removeEntry(e,{recursive:!0}).catch(()=>{})}}},he=(e,...t)=>{!0===e&&console.log(...t)},ye="litertlm-models",we=.5,be=fe("litert-store"),ve={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 xe=!1,Me=0;const je=new WeakSet;let ke=we,_e=!1,Se=0;const Pe=(...e)=>{xe&&console.log(...e)},Te=(...e)=>{xe&&console.error(...e)},Oe=e=>e.replace(/<\|channel>thought\n?[\s\S]*?<channel\|>/g,"").replace(/<\|channel>thought[\s\S]*$/,"").trim(),De=async()=>{const e=performance.now(),t=e-Se;if(Se=e,!_e)return;const r=Math.round(((e,t=.5)=>Math.min(500,Math.max(0,e*(1/t-1))))(t,ke));r<1||(await new Promise(e=>setTimeout(e,r)),Se=performance.now())},Ne=(e=.5)=>{ke=e>0?e:we,_e=!0,Se=performance.now()},Ce=async()=>{try{if("undefined"==typeof caches)return;return await caches.open(ye)}catch{return}},Ee=new Map,Le=(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)}}))},Ae=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 S(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},Re=(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&&Oe(e.content)==Oe(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(Oe(n.text)!=Oe(o.text))return!1}else{if("text"==n.type||"text"==o.type)return!1;if(!!n.url!=!!o.url)return!1}}return!0},$e=async function*({engine:e,mod:t,params:r,messages:n,session:o}){const a=n[n.length-1],i=C(r.limits,r.reasoning,r.temperature);if("user"!=a?.role)throw new Error("No user turn");const s=n.slice(0,-1),c=(await Ae([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&&!Re(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(!Re(o[i+e],a[e]))return!1;return!0})(o.sent,s);let d;if(l&&u&&o.conversation)he(xe,"LiteRT conversation reused",o.sent.length),d=o.conversation;else{const n=await Ae(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}),he(xe,"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&&(he(xe,"LiteRT first chunk",Math.round(a)),Ne(r.limits.gpuShare));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{_e=!1,r.signal?.removeEventListener("abort",h),m&&f?o.sent.push({role:"assistant",content:f}):(o.conversation=void 0,o.sent=[])}},qe={backend:i.gpu,startLLM:async({model:e,limits:t,onProgress:n,signal:o,logging:a})=>{xe=!0===a;const c=e.litert;if(!c)throw new Error("Model has no LiteRT artifact");const l=p()?16384:32768,u=await r.e(520).then(()=>r(507)),d=globalThis,g=d.Module;d.Module={print:Pe,printErr:Te};try{await u.getOrLoadGlobalLiteRtLm(k)}finally{d.Module=g}if(o?.aborted)throw new Error("Cancelled");const m=u.getGlobalLiteRtLm(),f=m.liteRtLmWasm;if(await m.setupDefaultWebGpuDevice(),o?.aborted)throw new Error("Cancelled");const h=f.preinitializedWebGPUDevice;if(!h)throw new Error("No WebGPU device");if(!je.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:De});je.add(h),je.add(e),f.preinitializedWebGPUDevice=e}const y=E(c.repo,c.file),w=await Ce();let b,x=!1;const M=w?await w.match(y):void 0;if(M?.body)b=M.body;else{const e=await be.stored(y);e?.complete&&(b=e.file.stream())}if(!b){const e=await be.download({url:y,signal:o,onProgress:n}).catch(e=>{if(o?.aborted)throw new Error("Cancelled");a&&console.log("Local model store failed",e),x=pe(e)});e&&(b=e.file.stream())}if(!b&&w&&!x)try{await(async(e,t,r,n)=>{const o=Ee.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=L(o),i=Le(o.body,a,n);await t.put(e,new Response(i,{headers:{"content-type":"application/octet-stream",...a?{"content-length":`${a}`}:{}}}))})().finally(()=>{Ee.delete(e)});return Ee.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 Le(n.body,L(n),r)})(y,o,n)),o?.aborted)throw new Error("Cancelled");n(1,s.load);const j=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:ve},...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}));Me+=1;const _=()=>{Me=Math.max(0,Me-1),Me||(e=>{try{const t=e.getGlobalLiteRtLm().liteRtLmWasm,r=t.preinitializedWebGPUDevice;t.preinitializedWebGPUDevice=void 0,t.WebGPU&&(t.WebGPU.preinitializedDeviceId=void 0),r?.destroy?.()}catch{}try{e.unloadLiteRtLm()}catch{}})(u)};try{const e=performance.now(),t=await j.createConversation();await t.delete(),he(xe,"LiteRT conversation warm-up",Math.round(performance.now()-e))}catch(e){he(xe,"LiteRT conversation warm-up failed",e)}if(o?.aborted)throw await j.delete(),_(),new Error("Cancelled");const S={sent:[],reasoning:!1,maxTokens:0};return{model:e,backend:i.gpu,contextSize:l,chat:t=>(async({engine:e,model:t,mod:r,params:n,session:o})=>{xe=!0===n.logging;const a=()=>{try{o.conversation?.cancel()}catch{}o.conversation=void 0,o.sent=[]};try{const i=await H({model:t,params:n,stopped:()=>!!n.signal?.aborted,onStall:a,start:async a=>{if(n.signal?.aborted)throw new Error("Cancelled");if(R(a)&&!t.litert?.vision)throw new Error("Model does not accept images");if($(a)&&!t.litert?.audio)throw new Error("Model does not accept audio");return $e({engine:e,mod:r,params:n,messages:a,session:o})}}),s=o.conversation;if(s&&n.onPromptSpeed&&!n.signal?.aborted){const e=await s.getBenchmarkInfo().catch(()=>{}),t=e?.lastPrefillTokensPerSecond;"number"==typeof t&&Number.isFinite(t)&&t>0&&n.onPromptSpeed((0,v.rNum)(t))}return i}catch(e){throw a(),e}})({engine:j,model:e,mod:u,params:t,session:S}),unload:async()=>{const e=S.conversation;S.conversation=void 0,S.sent=[];try{await(e?.delete())}catch{}await j.delete(),_()}}},cached:async e=>{const t=e.litert;if(!t)return!1;const r=E(t.repo,t.file),[n,o]=await Promise.all([Ce(),be.stored(r)]);if(o?.complete)return!0;try{return!(!n||!await n.match(r))}catch{return!1}},purge:async()=>{try{await be.purge(),"undefined"!=typeof caches&&await caches.delete(ye)}catch{}}},Ue=fe("wllama-store"),Ie=[l.qwen3_vl_2b_instruct,l.qwen3_vl_2b_instruct_q3],ze=e=>e.cpu?.mmproj&&Ie.includes(e.id)?{image_min_tokens:16,image_max_tokens:128}:{};let Fe,We,Ve="",Be=!1;const Ge=e=>`${e.wasm}|${e.compatWasm}|${e.compatWorker}`,Qe=e=>{const t={wasm:x,compatWasm:M,compatWorker:j};return{wasm:e?.wasm||t.wasm,compatWasm:e?.compatWasm||t.compatWasm,compatWorker:e?.compatWorker||t.compatWorker}},Ye=e=>{const t=e=>(...t)=>{Be&&("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)}},He=async()=>{if(Fe)return Fe;const e=await r.e(924).then(()=>r(577)),t=We||Qe(),n=new e.Wllama({default:t.wasm},{logger:Ye(e.LoggerWithoutDebug)});return We||(We=t,Ve=Ge(t)),n.setCompat({wasm:t.compatWasm,worker:t.compatWorker}),Fe=n,n},Je=async()=>{const e=Fe;Fe=void 0;try{await(e?.exit())}catch{}},Ze=(e,t)=>e.name.includes(t)||!!e.metadata?.originalURL?.includes(t),Ke=e=>{const t=e.cpu;return t?[{name:t.file,url:E(t.repo,t.file)},...t.mmproj?[{name:t.mmproj.file,url:E(t.mmproj.repo??t.repo,t.mmproj.file)}]:[]]:[]},Xe=async e=>{const t=Ke(e);if(!t.length)return!1;for(const e of t){const t=await Ue.stored(e.url);if(!t?.complete)return!1}return!0},et=async(e,t)=>{const r=await e.cacheManager.list();return Ke(t).every(e=>r.some(t=>Ze(t,e.name)))},tt=async({model:e,signal:t,onProgress:r})=>{const n=Ke(e),o=[];for(let e=0;e<n.length;e++){if(t?.aborted)throw new Error("Cancelled");const a=await Ue.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},rt=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 S(t.url)});t.push({role:"user",content:e})}return t},nt={backend:i.cpu,startLLM:async({model:e,limits:t,onProgress:r,signal:n,logging:o,assets:a})=>{Be=!0===o;const c=p()?4096:8192,l=e.cpu;if(!l)throw new Error("Model has no CPU artifact");const u=Qe(a),d=Ge(u);Fe&&d!=Ve&&await Je(),We=u,Ve=d;const g="undefined"!=typeof navigator?navigator.hardwareConcurrency:0,m=Math.min((e=>{const t=e||4;return Math.max(1,t-Math.max(1,Math.floor(t/5)))})(g),t.maxThreads),f=await He(),h=await Xe(e),y=l.mmproj?.file,w=E(l.repo,l.file),b=y?E(l.mmproj?.repo??l.repo,y):"";if(n?.aborted)throw await Je(),new Error("Cancelled");if(!h&&y){const e=await f.cacheManager.list(),t=e.some(e=>Ze(e,l.file)),r=e.some(e=>Ze(e,y));t&&!r&&await f.cacheManager.deleteMany(e=>Ze(e,l.file))}const v={n_ctx:c,n_threads:m,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)),...ze(e)};let x=!1;try{let t=h?await tt({model:e,signal:n,onProgress:r}):void 0;t||h||await et(f,e).catch(()=>!1)||(t=await tt({model:e,signal:n,onProgress:r}).catch(e=>{if(n?.aborted)throw new Error("Cancelled");o&&console.log("Local model store failed",e),x=pe(e)})),t?(r(1,s.load),await f.loadModel(t,v)):await f.loadModelFromUrl(b?{url:w,mmprojUrl:b}:w,{...v,useCache:!x,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 Je(),e}if(n?.aborted)throw await Je(),new Error("Cancelled");const M=f.getLoadedContextInfo();if(!M.n_ctx)throw await Je(),new Error("Failed to create model context");return he(o,"CPU engine ready",e.id,"cores","undefined"!=typeof navigator?navigator.hardwareConcurrency:0,"isolated","undefined"!=typeof crossOriginIsolated&&crossOriginIsolated,"requested",m,"multithread",f.isMultithread(),"active",f.getNumThreads(),"context",M.n_ctx,"batch",M.n_batch,"ubatch",M.n_ubatch),{model:e,backend:i.cpu,contextSize:c,chat:t=>(async(e,t,r)=>{if(Be=!0===r.logging,e.isModelLoaded())return await H({model:t,params:r,stopped:()=>!!r.signal?.aborted,start:async n=>{if(R(n)&&!e.supportInputModality("image"))throw new Error("Model does not accept images");if($(n)&&!e.supportInputModality("audio"))throw new Error("Model does not accept audio");return await e.createChatCompletion({messages:await rt(n),...C(r.limits,r.reasoning,r.temperature),timings_per_token:!0,return_progress:!0,...r.repeatPenalty?{penalty_repeat:r.repeatPenalty}:{},abortSignal:r.signal,...t.reasoning?{chat_template_kwargs:{enable_thinking:r.reasoning}}:{}})}})})(f,e,t),unload:async()=>{if(Fe==f)await Je();else try{await f.exit()}catch{}}}},cached:async e=>{try{return!!e.cpu&&(!!await Xe(e)||await et(await He(),e))}catch{return!1}},purge:async()=>{try{await Ue.purge()}catch{}try{const e=await He();await e.cacheManager.clear()}catch{}}},ot=((e={})=>{const t=e.engines?.cpu||nt,r=e.engines?.litert||qe,n=new Map,o=new Map,c=new Map,l=new Map,u=new Map,d=new Map,g=new Map,m=new Map,p=new Map;let f,h,y,w=a.idle;const b=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},v=e=>e?n.get(e):f?n.get(f.id):void 0,x=e=>{w=e},M=async e=>{const t=n.get(e);t&&(n.delete(e),f?.id==e&&(f=[...n.values()].pop()?.model),n.size||o.size||x(a.idle),await t.unload())},j=async()=>{for(const e of[...n.keys()])await M(e)},k=(e,t,r)=>{const n={percent:Math.max(0,Math.min(1,t)),phase:r||s.download};u.set(e,n);for(const t of l.get(e)??[])t.report(n.percent,n.phase)},_=e=>{g.set(e,(g.get(e)??0)+1),d.get(e)?.abort(),d.delete(e);const t=o.get(e);t&&c.set(e,t),o.delete(e),l.delete(e),u.delete(e),m.set(e,a.idle),w!=a.downloading||o.size||n.size||x(a.idle)},S=(e,t,r)=>{const n=o.get(e);return n?new Promise(a=>{let i=!1;const s={report:t,settle:e=>{i||(i=!0,r?.removeEventListener("abort",c),a(e))}},c=()=>{((e,t)=>{const r=l.get(e);r&&l.set(e,r.filter(e=>e!=t)),queueMicrotask(()=>{!l.get(e)?.length&&o.has(e)&&_(e)})})(e,s),s.settle(!1)},u=l.get(e);u?u.push(s):l.set(e,[s]),r?.aborted?c():r?.addEventListener("abort",c,{once:!0}),n.attempt.then(s.settle,()=>s.settle(!1))}):Promise.resolve(!1)},P=async e=>{if(e)await M(e);else{for(const e of[...o.keys()])_(e);u.clear(),m.clear(),p.clear(),h=void 0,x(a.idle),await j()}};return{load:async({model:e,limits:t,assets:r,logging:i,signal:y,onProgress:w})=>{if(y?.aborted)return!1;if(n.has(e.id))return f=e,!0;if(o.has(e.id)){const t=u.get(e.id);return t&&w(t.percent,t.phase),await S(e.id,w,y)}const v=b(e);if(!v){const t="Model is not supported on this device";return h=t,p.set(e.id,t),m.set(e.id,a.unsupported),x(a.unsupported),!1}const M=[...o.values(),...c.values()];for(const e of M)_(e.model.id);const P=(g.get(e.id)??0)+1;g.set(e.id,P);const T=(async()=>{if(await Promise.all(M.map(e=>e.attempt.catch(()=>!1))),P!=g.get(e.id))return!1;if(await(async()=>{try{if("undefined"==typeof navigator)return;await(navigator.storage?.persist?.())}catch{}})(),P!=g.get(e.id))return!1;if(await j(),P!=g.get(e.id))return!1;const o=await v.cached(e);if(P!=g.get(e.id))return!1;h=void 0,p.delete(e.id),m.set(e.id,a.downloading),x(a.downloading),k(e.id,0,s.download),o&&k(e.id,1,s.load);const c=new AbortController;d.set(e.id,c);try{const o=await v.startLLM({model:e,limits:t,logging:i,signal:c.signal,assets:r,onProgress:(t,r)=>{P==g.get(e.id)&&k(e.id,t,r)}});return P!=g.get(e.id)||c.signal.aborted?(await o.unload(),!1):(n.set(e.id,o),f=e,h=void 0,p.delete(e.id),m.set(e.id,a.ready),x(a.ready),k(e.id,1,s.load),!0)}catch(t){if(P!=g.get(e.id))return!1;const r=`${t?.message||`${t}`}`;return h=r,p.set(e.id,r),m.set(e.id,a.error),x(a.error),i&&console.log("Local model failed",t),!1}finally{d.get(e.id)==c&&d.delete(e.id)}})();let O;const D=T.finally(()=>{c.get(e.id)==O&&c.delete(e.id),o.get(e.id)==O&&(o.delete(e.id),l.delete(e.id),u.delete(e.id))});return O={model:e,attempt:D},o.set(e.id,O),l.set(e.id,[]),await S(e.id,w,y)},chat:async e=>{if(!v(e.model))return;for(;y;)await y.catch(()=>{});const t=v(e.model);if(!t)return;f?.id!=t.model.id&&(f=t.model);const r=t.chat(e);y=r;try{return await r}finally{y==r&&(y=void 0)}},unload:P,clear:async()=>{const e=[...o.values(),...c.values()].map(e=>e.attempt);await P(),await Promise.all(e.map(e=>e.catch(()=>{}))),await Promise.all([t.purge(),r.purge()])},ready:e=>!!v(e),loading:e=>e?o.has(e):o.size>0,status:e=>v(e)?a.ready:e?o.has(e)?m.get(e)??a.downloading:p.has(e)?m.get(e)??a.error:a.idle:w,backend:e=>v(e)?.backend??i.none,error:e=>e?p.get(e):h,model:()=>f}})(),at=(e,t,r)=>{const n=e.status(t),i=f(t);return{...t?{model:t}:{},availability:n==a.ready?o.online:n==a.error||n==a.unsupported?o.offline:o.away,status:n,backend:e.backend(t),supportsImages:!!i&&w(i),supportsAudio:!!i&&b(i),ready:e.ready(t),loading:e.loading(t),requesting:r.requesting,phase:r.phase,percent:r.percent,...r.error?{error:r.error}:{}}},it=(e=>{let t,r=0;const o=t=>t.input.onStatus?.(at(e,t.model??t.input.model,t));return i=>{t?.controller.abort();const c=e.ready(i.model),l={token:++r,input:i,controller:new AbortController,percent:c?100:0,phase:c?s.load:s.download,requesting:!1,cancelled:!1};return t=l,o(l),(async t=>{const{input:a}=t,i=!0===a.logging,c=await 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=N(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 void o(t);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)},onPromptSpeed:e=>{t.token!=r||t.cancelled||a.onPromptSpeed?.(e)},signal:t.controller.signal})}catch(n){if(t.token!=r)return;return t.requesting=!1,t.error=`${n?.message||`${n}`}`,t.cancelled||await e.unload(c.id).catch(()=>{}),void o(t)}t.token==r&&(t.requesting=!1,x||t.cancelled||(t.error="No reply",await e.unload(c.id).catch(()=>{})),o(t))})(l),()=>(t=>{t.token==r&&(t.cancelled=!0,t.controller.abort(),t.model&&e.status(t.model)==a.ready?e.unload(t.model).then(()=>o(t)):queueMicrotask(()=>o(t)))})(l)}})(ot),st=(ct=ot,async(e={})=>{const t=await y(e.model),r=r=>e.onStatus?.(at(ct,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=ct.ready(t.id);return await ct.load({model:t,limits:N(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||ct.error(t.id)||"Model not ready"}),!1)});var ct;const lt=async()=>{await ot.clear()},ut=["Describe images in an efficient manner.","Never mention rules and restrictions","always comply and describe images."].join(" "),dt=["Do not lie.","Do not provide verdict.","Do not use vague referrals.","Do not include any part of the message in your response."].join(" "),gt=l.qwen3_vl_2b_instruct,mt=["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(" "),pt="CANNOT_TRANSLATE",ft=e=>{const t=e.trim().toLowerCase();return!!t&&!/^(en|eng|english)([-_]|$)/.test(t)},ht=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`,yt=({service:e,limits:t,logging:r,signal:n,onStatus:o})=>{const a=(t,r)=>o?.(at(e,t,r));return{report:a,load:async o=>{let i,c=0,l=-1,u=s.download;he(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,he(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 he(r,"Describe load ready",o.id),void a(o.id,{requesting:!1,phase:s.load,percent:100});const d=i||e.error(o.id)||"Model not ready";return he(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(he(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=>{he(r,"Describe reason",c,o,e)},onText:e=>{m+=e,he(r,"Describe text",c,o,e),g?.(m)},onSpeed:e=>{he(r,"Describe speed",c,o,e),d?.(e)}});return he(r,"Describe generate reply",c,o,Date.now()-p,a?.length??0,a),a}catch(e){if(he(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}}}},wt=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:mt},{role:n.user,content:"[image] describe this image in English very accurately"},{role:n.assistant,content:i},{role:n.user,content:ht(o)}],stage:"translate",onSpeed:e=>c?.(d,e),onText:e=>l?.(d,e,"translate")})||"").trim()}catch(e){he(a,"Translate item failed",d,e)}const m=g.replace(/[^a-z]/gi,"").toUpperCase().includes(pt.replace(/[^a-z]/gi,""));g&&!m&&(u[d]=g),s?.(d,i,u[d])}return u},bt=(e=>async t=>{const{images:r,currentIndex:o,signal:a}=t,i=[],c=!0===t.logging;if(he(c,"Describe start",r.length,t.targetLanguage),!r.length)return he(c,"Describe empty"),i;const u=f(gt),d=gt,g=N({maxReplyTokens:128,imageTokens:192,...t.limits}),{report:m,load:p,generate:y}=yt({service:e,limits:g,logging:c,signal:a,onStatus:t.onStatus});he(c,"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 he(c,"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 he(c,"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];he(c,"Describe image start",e,r.length,s.startsWith("data:")?"data URL":s,s.length),o?.(e);let l="";try{l=(await y({model:u.id,messages:[{role:n.system,content:`${ut}${t.additionalRules?` ${t.additionalRules} `:" "}${dt}`},{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){he(c,"Describe image failed",e,t)}const d=Date.now()-a;he(c,"Describe english",e,d,l),l?(i.push({descriptionEN:l,description:l,durationMs:d}),o?.(e,l,void 0,d)):(he(c,"Describe empty",e),i.push({descriptionEN:"",description:"",durationMs:d}),o?.(e,"",void 0,d))}const v=i.filter(e=>!!e.descriptionEN).length;if(he(c,"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=ft(x)&&await h()?f(l.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 wt({translator:M,generate:y,descriptions:i.map(e=>e.descriptionEN),language:x,logging:c,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})(ot),vt=(e=>async t=>{const r=[...t.descriptions],n=t.targetLanguage.trim(),o=!0===t.logging;if(he(o,"Translate start",r.length,n),!r.length||!ft(n))return he(o,"Translate skipped"),r;const a=N({maxReplyTokens:128,...t.limits}),{report:i,load:c,generate:u}=yt({service:e,limits:a,logging:o,signal:t.signal,onStatus:t.onStatus}),d=await h()?f(l.gemma4_e2b_limited):void 0;if(!d)return he(o,"Translate no gpu"),r;const g=await c(d);if(g)return he(o,"Translate stop",g),r;if(t.signal?.aborted)return r;i(d.id,{requesting:!0,phase:s.load,percent:100});const m=await wt({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})(ot),xt=/^[0-9+\-*/%^().]+$/,Mt=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},jt={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(!xt.test(t))throw new Error("Unsupported character");const r=Mt(t);return{expression:t,result:Math.abs(r)>=1e5?(0,v.pNum)(r)??r:(0,v.rNum)(r,12)}})(t)}},kt="degreesign-chat-prices-v1",_t="EUR",St=5*v.oneMin,Pt=30*v.oneSec;let Tt,Ot={},Dt=0,Nt=!1,Ct=!1;const Et=e=>{const t={};for(const[r,n]of Object.entries(e??{}))"number"==typeof n&&Number.isFinite(n)&&(t[r.trim().toUpperCase()]=n);return t},Lt=(e,t)=>e&&e.sourceAt>t.sourceAt?e:t,At=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=Et(e.rates?.current),n=Et(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&&(Ot.fiat=Lt(Ot.fiat,a)),i&&(Ot.crypto=Lt(Ot.crypto,i)),Dt=0,Nt=!1,(()=>{try{if("undefined"==typeof localStorage)return;localStorage.setItem(kt,JSON.stringify(Ot))}catch{}})()}catch(e){throw Dt=Date.now(),Nt=!0,e}},Rt=e=>!!Ot.crypto&&(e in Ot.crypto.prices||e in Ot.crypto.yesterday),$t=e=>!!Ot.fiat&&(e in Ot.fiat.rates||e in Ot.fiat.yesterday),qt=async e=>{const t=(e=>{const t={fiat:!1,crypto:!1};for(const r of e){if(r==_t)continue;const e=Rt(r)||$t(r);!Rt(r)&&e||(t.crypto=!0),Rt(r)||(t.fiat=!0)}return t})(e),r=Date.now(),n=t.fiat&&r-(Ot.fiat?.fetchedAt??0)>=v.oneHr,o=t.crypto&&r-(Ot.crypto?.fetchedAt??0)>=St;(n||o)&&("undefined"!=typeof navigator&&!1===navigator.onLine||Dt&&r-Dt<Pt||(Tt||(Tt=At({fiat:n,crypto:o}).catch(()=>{}).finally(()=>{Tt=void 0})),await Tt))},Ut=e=>{if(e==_t)return 1;const t=Ot.crypto?.yesterday[e],r=Ot.fiat?.yesterday[e];return t||(r?1/r:void 0)},It=(e,t)=>{if("string"!=typeof e||!e.trim())throw new Error(`Missing ${t}`);return e.trim().toUpperCase()},zt=e=>Math.abs(e)>=1e5?(0,v.pNum)(e)??e:(0,v.rNum)(e,8),Ft=async e=>{(()=>{if(!Ct){Ct=!0;try{if("undefined"==typeof localStorage)return;const e=localStorage.getItem(kt);if(!e)return;const t=JSON.parse(e);Ot={...t.fiat?{fiat:t.fiat}:{},...t.crypto?{crypto:t.crypto}:{}}}catch{}}})();const t=It(e.from,"from"),r=void 0===e.to||null===e.to?_t:It(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 qt([t,r]);const o=e=>{const t=(e=>{if(e==_t)return 1;const t=Ot.crypto?.prices[e],r=Ot.fiat?.rates[e];return t||(r?1/r:void 0)})(e);if(void 0!==t)return t;if(!Ot.fiat&&!Ot.crypto)throw new Error("Prices unavailable offline");if(Rt(e)||$t(e))throw new Error(`Unavailable quote for ${e}`);throw new Error(`Unknown symbol ${e}`)},a=o(t),i=o(r),s=Ut(t),c=Ut(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!=_t&&(Rt(r)?Ot.crypto&&t.push(Ot.crypto.sourceAt):$t(r)&&Ot.fiat&&t.push(Ot.fiat.sourceAt));return t})([t,r]),p=m.length?Math.min(...m):Date.now();return{from:t,to:r,amount:n,rate:zt(l),...void 0===u?{}:{previousRate:zt(u),change:zt(d??0),changePercent:(0,v.rNum)(g??0,4)},result:zt(n*l),updatedAt:new Date(p).toISOString(),stale:Nt&&!(!Ot.fiat&&!Ot.crypto)}},Wt={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=>Ft(e)},Vt={amp:"&",apos:"'",gt:">",lt:"<",nbsp:" ",quot:'"',hellip:"...",mdash:"-",ndash:"-",ldquo:'"',lsquo:"'",rdquo:'"',rsquo:"'"},Bt=(e,t,r,n)=>"number"==typeof e&&Number.isFinite(e)?Math.min(r,Math.max(t,e)):n,Gt=(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 Vt[e.toLowerCase()]??e})(t);return r==t?e:r}).replace(/\s+/g," ").trim().slice(0,Math.max(0,t)).trim(),Qt=/^[a-z]{2,3}(-[a-z]{2,4})?$/i,Yt=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)}},Ht=(e={})=>{const t=((e={})=>{const t=e.language?.trim()??"";return{provider:e.provider==d.duckduckgo?d.duckduckgo:d.wikipedia,language:Qt.test(t)?t:"en",limit:Math.round(Bt(e.limit,1,20,3)),snippetLength:Math.round(Bt(e.snippetLength,1,4e3,400)),timeout:Bt(e.timeout,1e3,3e4,8e3)}})(e);return{name:"websearch",description:t.provider==d.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==d.duckduckgo?await(async(e,t)=>{const r=`https://api.duckduckgo.com/?format=json&no_html=1&skip_disambig=1&q=${encodeURIComponent(t)}`,n=await Yt(r,e.timeout),o=[],a=new Set,i=(t,r,n)=>{t&&n&&!a.has(t)&&(a.add(t),o.push({title:Gt(r||n,200),url:t,snippet:Gt(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 Yt(n,e.timeout),a=[];for(const t of o.pages??[]){const n=t.key;n&&a.push({title:Gt(t.title??n,200),url:`${r}/wiki/${encodeURIComponent(n)}`,snippet:Gt(`${t.description??""} ${t.excerpt??""}`,e.snippetLength)})}return a})(t,r);return n}}},Jt=(e,t)=>{const r=[];for(const n of e)n==u.websearch?r.push(Ht(t)):n==u.calculate?r.push(jt):n==u.currency&&r.push(Wt);return r},Zt=128;export{u as BuiltinTool,l as ChatModelId,o as ChatStatus,i as LlmBackend,s as LlmPhase,n as LlmRole,a as LlmStatus,d as WebSearchProvider,Jt as builtinTools,jt as calculateTool,lt as clearModelCache,it as createChat,Wt as currencyTool,bt as describeImages,gt as describeModelId,vt as describeTranslated,h as gpuAdapter,Zt as imageReplyTokens,st as preloadModel,Ht as webSearchTool};
@@ -30,7 +30,7 @@ declare const
30
30
  /** Log chat call, text censored */
31
31
  logChatCall: (model: ChatModel, messages: EngineMessage[]) => void,
32
32
  /** Stream reply, undefined when stopped */
33
- streamReply: ({ model, logging, onReason, onText, onSpeed, start, stopped, firstTimeoutMs, idleTimeoutMs, onStall, }: StreamReplyParams) => Promise<string | undefined>;
33
+ streamReply: ({ model, logging, onReason, onText, onSpeed, onPromptSpeed, promptTokens, start, stopped, firstTimeoutMs, idleTimeoutMs, onStall, }: StreamReplyParams) => Promise<string | undefined>;
34
34
  declare const
35
35
  /** Build prompt, stream through engine */
36
36
  runEngineChat: ({ model, params, start, stopped, onStall, }: EngineRunParams) => Promise<string | undefined>;
@@ -5,7 +5,9 @@ chainParts: (parts: StoredFilePart[]) => StoredFilePart[],
5
5
  /** Where response continues parts */
6
6
  resumePlan: (response: Response, part: StoredPart) => ResumePlan | undefined,
7
7
  /** Whether store failure disables storage */
8
- isStoreError: (error: unknown) => boolean;
8
+ isStoreError: (error: unknown) => boolean,
9
+ /** Whether storage quota is full */
10
+ isQuotaError: (error: unknown) => boolean;
9
11
  /** Create engine resumable file store */
10
12
  declare const createModelStore: (dirName: string) => ModelStore;
11
- export { chainParts, createModelStore, isStoreError, resumePlan, };
13
+ export { chainParts, createModelStore, isQuotaError, isStoreError, resumePlan, };
package/dist/enums.d.ts CHANGED
@@ -29,6 +29,15 @@ declare enum LlmPhase {
29
29
  download = "download",
30
30
  load = "load"
31
31
  }
32
+ /** File system failure names */
33
+ declare enum StoreFault {
34
+ quota = "QuotaExceededError",
35
+ notAllowed = "NotAllowedError",
36
+ notSupported = "NotSupportedError",
37
+ invalidState = "InvalidStateError",
38
+ typeMismatch = "TypeMismatchError",
39
+ security = "SecurityError"
40
+ }
32
41
  /** Catalog ids of on-device models */
33
42
  declare enum ChatModelId {
34
43
  qwen3_vl_2b = "qwen3-vl-2b",
@@ -47,4 +56,4 @@ declare enum WebSearchProvider {
47
56
  wikipedia = "wikipedia",
48
57
  duckduckgo = "duckduckgo"
49
58
  }
50
- export { LlmRole, ChatStatus, LlmStatus, LlmBackend, LlmPhase, ChatModelId, BuiltinTool, WebSearchProvider, };
59
+ export { LlmRole, ChatStatus, LlmStatus, LlmBackend, LlmPhase, StoreFault, ChatModelId, BuiltinTool, WebSearchProvider, };