0?n/r:null}function Cn(e,t){if(!Array.isArray(e)||e.length===0)return null;const n=[...e].sort((s,i)=>s-i),r=(n.length-1)*t,a=Math.floor(r),o=Math.ceil(r);return a===o?n[a]:n[a]+(n[o]-n[a])*(r-a)}function Mn(e){if(Array.isArray(e))return e.map(Mn);if(e&&typeof e=="object"){const t={};for(const n of Object.keys(e).sort())t[n]=Mn(e[n]);return t}return e}function zn(e){return JSON.stringify(Mn(e))}function Ks(e){return!!e&&pt.some(t=>e.inFlight===t.inFlight&&e.groupSteps===t.groupSteps)}function Vs(e){return Ce(e,"groupSteps")}function qs(e,t=null){const n=Ce(e,"groupSteps");return t==null?n:Math.min(n,Ce(t,"carry groupSteps"))}function Js(e,t){const n=Ce(e,"carry groupSteps"),r=Ce(t,"groupStepsFinal");return Math.min(n,r)}function Qs(e){return e===1/0?"inf":bt(e,"policy.tokenBudget")}function Sr(e,t,n){return t.map(r=>bt(Cn(e,r),n))}function Xs(e){const t=new Map;for(const n of e){const r=Ce(n,"plannedSourceBuckets value");t.set(r,(t.get(r)??0)+1)}return[...t.entries()].sort((n,r)=>n[0]-r[0]).map(([n,r])=>[n,bt(r,"bucket count")])}function Ys({batchSizes:e,plannedSourceBuckets:t,sourceTokenLengths:n,modelId:r,weightsId:a,dtype:o,policy:s}={}){if(!Array.isArray(e)||e.length===0)throw new Error("batchSizes must be a non-empty array");const i=e.map(p=>Ce(p,"batchSizes value"));if(!Array.isArray(t)||t.length!==i.length)throw new Error("plannedSourceBuckets must align with batchSizes");if(!Array.isArray(n))throw new Error("sourceTokenLengths must be an array");const u=i.reduce((p,f)=>p+f,0);if(n.length!==u)throw new Error("sourceTokenLengths must contain one value per planned row");const l=n.map(p=>Ce(p,"sourceTokenLengths value"));if(!s||typeof s!="object")throw new Error("policy must be an object");return{protocolRev:We,rowCountBand:bt(u,"rowCount"),batchCountBand:bt(i.length,"batchCount"),plannedSourceBucketHistogram:Xs(t),batchSizeQuantiles:Sr(i,[.25,.5,.75],"batchSize quantile"),sourceTokenQuantiles:Sr(l,[.25,.5,.75,.9],"sourceToken quantile"),model:[ce(r,"modelId"),ce(a,"weightsId"),ce(o,"dtype",32)],policy:{pack:s.pack===!0,kvPlanner:ce(s.kvPlanner,"policy.kvPlanner"),tokenBudgetBand:Qs(s.tokenBudget),immediates:ce(s.immediates,"policy.immediates",32),uniformPool:s.uniformPool===!0}}}function Zs(e){if(!e||typeof e!="object")throw new Error("signature must be an object");return zn(e)}function ei(e,t=Gn,n=null){if(!Array.isArray(e)||e.length===0)throw new Error("batch cost list must be non-empty");const r=e.map(f=>Z(f,"batch cost"));if(!Array.isArray(t)||t.length===0||t.some(f=>!Number.isFinite(f)||f<=0||f>=1))throw new Error("sample quantiles must be finite values between zero and one");let a=null;if(n!=null){if(!Array.isArray(n)||n.length!==r.length)throw new Error("batch regions must align with batch costs");a=n.map((f,m)=>{if(Number.isInteger(f)&&f>0||typeof f=="string"&&f.length>0&&f.length<=64)return f;throw new Error(`batch region at index ${m} is invalid`)})}if(r.length<=t.length)return r.map((f,m)=>m);const o=r.reduce((f,m)=>f+m,0);let s=0;const i=r.map(f=>{const m=(s+f/2)/o;return s+=f,m}),u=new Set,l=new Set,p=a?Math.min(t.length,new Set(a.map(String)).size):0;for(const f of t){let m=null;const d=a&&l.sizef-m)}function Kt(e){return`${typeof e}:${String(e)}`}function ti(e,t){return typeof e=="number"&&typeof t=="number"?e-t:typeof e=="number"?-1:typeof t=="number"?1:String(e).localeCompare(String(t))}function ln(e,t,n){return e.filter(({index:r})=>!n.has(r)).map(r=>({...r,distance:Math.abs(r.center-t)})).sort((r,a)=>r.distance-a.distance||r.index-a.index)[0]??null}function wr(e,t){const n=e.entries.filter(({index:o})=>t.has(o));if(n.length===0)return null;const r=n.reduce((o,s)=>o+s.cost,0);return n.reduce((o,s)=>o+s.center*s.cost,0)/r<.5?.75:.25}function un(e){return[...e].sort((t,n)=>n.mass-t.mass||ti(t.region,n.region)||t.entries[0].index-n.entries[0].index)}function ni(e,t,n=null){if(!Array.isArray(e)||e.length===0)throw new Error("batch cost list must be non-empty");const r=e.map(C=>Z(C,"batch cost"));if(!Array.isArray(t)||t.length===0)throw new Error("sample batch indices must be a non-empty array");const a=t.map(C=>{if(!Number.isInteger(C)||C<0||C>=r.length)throw new Error("sample batch index is out of range");return C});if(new Set(a).size!==a.length)throw new Error("sample batch indices contain a duplicate");if(r.length-a.length<2)throw new Error("confirmation planning requires two unused batches");let o;if(n==null)o=new Array(r.length).fill("all");else{if(!Array.isArray(n)||n.length!==r.length)throw new Error("batch regions must align with batch costs");o=n.map((C,L)=>{if(Number.isInteger(C)&&C>0||typeof C=="string"&&C.length>0&&C.length<=64)return C;throw new Error(`batch region at index ${L} is invalid`)})}const s=new Map;for(let C=0;CKt(o[C]))),f=C=>C.entries.some(({index:L})=>!l.has(L)),d=un(i.filter(C=>p.has(C.key)&&f(C)))[0];if(!d)throw new Error("confirmation planning requires an unused stability batch");const v=wr(d,u),y=ln(d.entries,v,l);if(!y)throw new Error("confirmation planning could not select a stability batch");l.add(y.index);let h=un(i.filter(C=>!p.has(C.key)&&f(C)))[0]??null,S=.5;h||(h=un(i.filter(L=>p.has(L.key)&&L.key!==d.key&&f(L)))[0]??null,h&&(S=wr(h,u)));let M;if(h)M=ln(h.entries,S,l);else{let C=0;const L=r.reduce((G,fe)=>G+fe,0),z=r.map((G,fe)=>{const me={index:fe,cost:G,center:(C+G/2)/L};return C+=G,me});M=ln(z,.5,l)}if(!M)throw new Error("confirmation planning could not select a coverage batch");return Object.freeze([Object.freeze({role:"stability",batchIndex:y.index,region:o[y.index]}),Object.freeze({role:"coverage",batchIndex:M.index,region:o[M.index]})])}function ri(e,t){if(!Array.isArray(e)||e.length===0)throw new Error("batch cost list must be non-empty");const n=e.map(l=>Z(l,"batch cost"));if(!Array.isArray(t)||t.length===0)throw new Error("sample batch indices must be a non-empty array");const r=t.map(l=>{if(!Number.isInteger(l)||l<0||l>=n.length)throw new Error("sample batch indices must address the batch cost list");return l});if(new Set(r).size!==r.length)throw new Error("sample batch indices must not contain duplicates");r.sort((l,p)=>l-p);const a=n.reduce((l,p)=>l+p,0);let o=0;const s=n.map(l=>{const p=(o+l/2)/a;return o+=l,p}),i=r.map(l=>s[l]),u=new Array(r.length).fill(0);for(let l=0;lMath.abs(s[l]-d)),f=Math.min(...p),m=p.map((d,v)=>({distance:d,owner:v})).filter(({distance:d})=>Math.abs(d-f)<=Number.EPSILON*8);for(const{owner:d}of m)u[d]+=n[l]/m.length}return u.map(l=>l/a)}function oi({fileMode:e=!1,pack:t=!1,isMobile:n=!1,uncachedRows:r=0,plannedBatches:a=0,kernelTuneSource:o=null,manualOverrides:s={},memorySafe:i=!1}={}){if(!e)return{eligible:!1,reason:"typed-text"};if(!t)return{eligible:!1,reason:"packing-disabled"};if(n)return{eligible:!1,reason:"mobile-v1-skip"};for(const u of Fs){const l=s?.[u];if(l!=null)return{eligible:!1,reason:`manual-override:${u}`}}return o==="partial"?{eligible:!1,reason:"kernel-autotune-partial"}:o!=="measured"&&o!=="cache"?{eligible:!1,reason:"kernel-autotune-untrusted"}:i?!Number.isInteger(r)||r0||typeof e?.region=="number"&&Number.isFinite(e.region))&&Number.isFinite(e?.baselineWallMs)&&e.baselineWallMs>0&&Number.isFinite(e?.candidateWallMs)&&e.candidateWallMs>0&&Number.isFinite(e?.baselineDecodeMs)&&e.baselineDecodeMs>0&&Number.isFinite(e?.candidateDecodeMs)&&e.candidateDecodeMs>0}function vt(e){return Number.isInteger(e)&&e>=0}function xn(e){if(!Array.isArray(e)||e.length===0)return{pairCount:0,wallGain:null,decodeGain:null,medianWallGain:null,medianDecodeGain:null,weightedWallGain:null,weightedDecodeGain:null,favorableRegions:0,complete:!1,exact:!1,shrinkFree:!1};const t=e.some(g=>g?.weight!==void 0),r=(!t||e.every(g=>Number.isFinite(g?.weight)&&g.weight>0))&&e.every(io),a=r&&e.every(g=>g.complete===!0),o=e.every(g=>g.exact===!0),i=e.every(g=>vt(g.baselineSubmitShrinks)&&vt(g.candidateSubmitShrinks))&&e.every(g=>g.baselineSubmitShrinks===0&&g.candidateSubmitShrinks===0),u=r?e.map(g=>Vt(g.baselineWallMs,g.candidateWallMs)):[],l=r?e.map(g=>Vt(g.baselineDecodeMs,g.candidateDecodeMs)):[],p=t&&r?e.map(g=>g.weight):[],f=yt(u),m=yt(l),d=t?vr(u,p):null,v=t?vr(l,p):null,y=new Set;return r&&e.forEach((g,h)=>{u[h]>0&&y.add(String(g.region))}),{pairCount:e.length,wallGain:d===null?f:Math.min(f,d),decodeGain:v===null?m:Math.min(m,v),medianWallGain:f,medianDecodeGain:m,weightedWallGain:d,weightedDecodeGain:v,favorableRegions:y.size,complete:a,exact:o,shrinkFree:i}}function ai(e,t="base"){if(!Array.isArray(e)||e.length===0)throw new Error("screen results must be a non-empty array");const n=e.find(a=>a?.id===t);if(!n)throw new Error(`screen results are missing baseline ${t}`);const r=e.filter(a=>a?.id!==t&&a?.exact===!0&&a?.submitShrinks===0&&Number.isFinite(a?.score)&&a.score>0).sort((a,o)=>a.score-o.score||String(a.id).localeCompare(String(o.id)))[0]??null;return{base:n,candidate:r}}function Er({screenPairs:e,confirmationPairs:t=[]}={}){const n=xn(e),r=Array.isArray(t)?t:[],a=xn(r),o=Array.isArray(t)&&r.length<=Ze.length&&r.every((h,S)=>h?.role===Ze[S]),s=r.every(io),i=s?r.map(h=>Vt(h.baselineWallMs,h.candidateWallMs)):[],u=s?r.map(h=>Vt(h.baselineDecodeMs,h.candidateDecodeMs)):[],l=i.length>0?Math.min(...i):null,p=Number.isFinite(n.wallGain)?Math.min(n.wallGain,...i):n.wallGain,f=Number.isFinite(n.decodeGain)?Math.min(n.decodeGain,...u):n.decodeGain,m=[...Array.isArray(e)?e:[],...r],d=m.every(h=>vt(h?.baselineSubmitShrinks)&&vt(h?.candidateSubmitShrinks)&&h.baselineSubmitShrinks===0&&h.candidateSubmitShrinks===0),v=m.every(h=>h?.exact===!0),y={promote:!1,reason:null,wallGain:p,screenWallGain:n.wallGain,confirmationMinWallGain:l,decodeGain:f,favorableRegions:n.favorableRegions,confirmationCount:Array.isArray(t)?r.filter(h=>h?.complete===!0).length:0,requiredConfirmations:Ze.length,completedRoles:r.filter(h=>h?.complete===!0).map(h=>h.role)};return!n.complete||!o||r.length>0&&!a.complete?{...y,reason:"incomplete"}:d?v?n.favorableRegions=Bs?n.decodeGain>=0?i.some(h=>h<=0)||u.some(h=>h<0)?{...y,reason:"confirmation-regression"}:i.some(h=>hZ(u,"run cost"));Z(r,"safetyFactor");const i=s.reduce((u,l)=>u+a*(l/o),0);return{rawGpuMs:i,projectedMs:i*r,runCount:s.length}}function si({kernelReferenceMs:e,kernelReferenceCost:t,sampleCosts:n,armCount:r=De.length,confirmationRounds:a=2,pretokenizeMs:o=0,safetyFactor:s=Qt}={}){const i=Z(e,"kernelReferenceMs"),u=Z(t,"kernelReferenceCost");if(!Array.isArray(n)||n.length===0)throw new Error("sampleCosts must be a non-empty array");const l=n.map(d=>Z(d,"sample cost"));if(Ce(r,"armCount"),!Number.isInteger(a)||a<0)throw new Error("confirmationRounds must be a non-negative integer");Ge(o,"pretokenizeMs"),Z(s,"safetyFactor");const p=l.flatMap(d=>Array(r).fill(d)),f=a*2;p.push(...Array(f).fill(yt(l)));const m=An({referenceMs:i,referenceCost:u,runCosts:p,safetyFactor:s});return{rawGpuMs:m.rawGpuMs,rawProjectedMs:o+m.rawGpuMs,projectedMs:o+m.projectedMs,screenRuns:l.length*r,confirmationRuns:f,completeRuns:p.length,runCosts:p}}function ii(e,t=Jt,n=Un){const r=e?.projectedMs,a=e?.rawProjectedMs;if(!Number.isFinite(r)||r<0||!Number.isFinite(t)||t<=0||!Number.isFinite(n)||n<0||n>=t)return{admit:!1,reason:"invalid-projection",projectedMs:Number.isFinite(r)?r:null,rawProjectedMs:Number.isFinite(a)?a:null,budgetMs:Number.isFinite(t-n)?t-n:null,admission:null};const o=t-n,s=r<=o,i=!s&&Number.isFinite(a)&&a>=0&&a<=o,u=s||i;return{admit:u,reason:u?null:"projected-over-budget",projectedMs:r,rawProjectedMs:Number.isFinite(a)?a:null,budgetMs:o,admission:s?"full":i?"pilot":null}}function ci({elapsedMs:e,projectedRunMs:t,deadlineMs:n=Jt,marginMs:r=Un,safetyFactor:a=Qt}={}){if(!(Number.isFinite(e)&&e>=0&&Number.isFinite(t)&&t>0&&Number.isFinite(n)&&n>0&&Number.isFinite(r)&&r>=0&&Number.isFinite(a)&&a>0))return{admit:!1,reason:"invalid-projection",projectedEndMs:null,remainingMs:Number.isFinite(n-e)?n-e:null};const s=e+t*a+r;return{admit:s<=n,reason:s<=n?null:"projected-over-budget",projectedEndMs:s,remainingMs:n-e}}function dn({elapsedMs:e,deadlineMs:t=Jt}={}){Ge(e,"elapsedMs"),Z(t,"deadlineMs");const n=Math.max(0,e-t);return{elapsedMs:e,deadlineMs:t,deadlineExceeded:n>0,overrunMs:n}}function co({adapterKey:e,modelId:t,weightsId:n,dtype:r,browserMajor:a,kernelTuneId:o,modes:s,signature:i}={}){if(!Number.isInteger(a)||a<0)throw new Error(`browserMajor must be a non-negative integer, got ${a}`);if(!s||typeof s!="object"||Array.isArray(s))throw new Error("modes must be an object");if(!i||typeof i!="object")throw new Error("signature must be an object");const u={};for(const[l,p]of Object.entries(s)){if(!Us.has(l))throw new Error(`modes contains unknown key ${l}`);if(js.has(l)){if(typeof p!="boolean")throw new Error(`modes.${l} must be boolean`);u[l]=p}else l==="tokenBudget"?u[l]=p===1/0?"inf":Z(p,"modes.tokenBudget"):u[l]=ce(p,`modes.${l}`)}return zn({protocolRev:We,adapterKey:ce(e,"adapterKey"),modelId:ce(t,"modelId"),weightsId:ce(n,"weightsId"),dtype:ce(r,"dtype",32),browserMajor:a,kernelTuneId:ce(o,"kernelTuneId"),modes:u,signature:i})}function li(e={}){const t=zn({amortizationRev:Et,scheduleIdentity:co(e)});return ce(t,"observation identity",Qe)}function lo(e){let t=2166136261;for(let n=0;n>>0).toString(16).padStart(8,"0")}function ui(e){return ce(e,"cache identity",Qe),`moxhi.schedule.v${We}.${lo(e)}`}function di(e){return ce(e,"observation scope identity",Qe),`moxhi.schedule-observation.v${Et}.${lo(e)}`}function Nn(e,t="observedShape"){if(e!=null){if(!e||typeof e!="object")throw new Error(`${t} must be an object`);if(Z(e.targetTokenP50,`${t}.targetTokenP50`),Z(e.targetTokenP90,`${t}.targetTokenP90`),e.targetTokenP901)throw new Error(`${t}.compactionRate must be between zero and one`)}}function St(e){if(!e||typeof e!="object"||Array.isArray(e))throw new Error("cache entry must be an object");if(!Number.isInteger(e.protocolRev)||e.protocolRev<=0)throw new Error("cache entry protocolRev must be a positive integer");if(ce(e.identity,"cache entry identity",Qe),ce(e.scopeKey,"cache entry scopeKey",512),ce(e.kernelTuneId,"cache entry kernelTuneId",512),ce(e.signatureKey,"cache entry signatureKey",Qe),Ge(e.createdAt,"cache entry createdAt"),Ge(e.lastUsedAt,"cache entry lastUsedAt"),!_s.has(e.ttlClass))throw new Error(`cache entry ttlClass is invalid: ${e.ttlClass}`);if(!Ds.has(e.verdict))throw new Error(`cache entry verdict is invalid: ${e.verdict}`);if(!Ks(e.schedule))throw new Error("cache entry schedule is not a version-1 arm");if(!Number.isInteger(e.screenSubmitShrinks)||e.screenSubmitShrinks<0)throw new Error("cache entry screenSubmitShrinks must be a non-negative integer");const t=e.schedule.inFlight===Le.inFlight&&e.schedule.groupSteps===Le.groupSteps,n=Gs.has(e.verdict);if(n&&e.ttlClass!=="negative"||!n&&e.ttlClass!=="normal")throw new Error("cache entry ttlClass does not match its verdict");if(e.verdict==="selected"){if(t)throw new Error("selected cache verdict must use a non-default schedule");if(e.screenSubmitShrinks!==0)throw new Error("selected cache verdict requires zero-shrink proof")}else if(!t)throw new Error("non-selected cache verdict must use the default schedule");if(e.verdict==="keep-default"&&e.screenSubmitShrinks!==0)throw new Error("keep-default cache verdict requires zero-shrink proof");if(e.verdict==="safety-fallback"&&e.screenSubmitShrinks===0)throw new Error("safety-fallback cache verdict requires a submit shrink");if(n&&e.screenSubmitShrinks!==0)throw new Error("negative cache verdict cannot contain completed shrink evidence");if(Nn(e.observedShape),e.invalidatedReason!==void 0&&(typeof e.invalidatedReason!="string"||e.invalidatedReason.length===0||e.invalidatedReason.length>128))throw new Error("cache entry invalidatedReason is invalid");if(!e.evidence||typeof e.evidence!="object"||Array.isArray(e.evidence))throw new Error("cache entry evidence must be an object");for(const[a,o]of Object.entries(e.evidence)){if(!zs.has(a))throw new Error(`cache entry evidence contains unknown key ${a}`);if(Hs.has(a)){if(!Number.isInteger(o)||o<0)throw new Error(`cache entry evidence.${a} must be a non-negative integer`)}else if(Ws.has(a))Ge(o,`cache entry evidence.${a}`);else if(a==="exact"){if(typeof o!="boolean")throw new Error("cache entry evidence.exact must be boolean")}else if(!Number.isFinite(o))throw new Error(`cache entry evidence.${a} must be finite`)}if(e.verdict==="selected"&&e.evidence.confirmationCount!==Ze.length)throw new Error("selected cache verdict requires both confirmation roles");let r;try{r=JSON.stringify(e.evidence??null).length}catch{throw new Error("cache entry evidence is not serializable")}if(r>Os)throw new Error("cache entry evidence exceeds the bounded payload limit");return e}function uo(e){e.forEach(St);const t=new Map;for(const n of e){const r=(t.get(n.scopeKey)??0)+1;if(r>jn)throw new Error("cache entries exceed the per-scope LRU bound");t.set(n.scopeKey,r)}}function hi({identity:e,scopeKey:t,kernelTuneId:n,signatureKey:r,createdAt:a,lastUsedAt:o=a,ttlClass:s,verdict:i,schedule:u,observedShape:l=null,screenSubmitShrinks:p=0,evidence:f={}}={}){const m={protocolRev:We,identity:e,scopeKey:t,kernelTuneId:n,signatureKey:r,createdAt:a,lastUsedAt:o,ttlClass:s,verdict:i,schedule:u&&{inFlight:u.inFlight,groupSteps:u.groupSteps},observedShape:l?{...l}:null,screenSubmitShrinks:p,evidence:{...f}};return St(m),m}function fi(e){if(!Array.isArray(e)||e.length>Ht)throw new Error(`cache entries must be an array of at most ${Ht}`);return uo(e),JSON.stringify({schema:ao,entries:e})}function mi(e){if(e==null||e==="")return{status:"miss",entries:[]};try{const t=JSON.parse(e);return t?.schema!==ao||!Array.isArray(t.entries)||t.entries.length>Ht?{status:"corrupt",entries:[]}:(uo(t.entries),{status:null,entries:t.entries})}catch{return{status:"corrupt",entries:[]}}}function kr(e,t){return Math.max(e,t)/Math.min(e,t)}function ho(e,t){try{Nn(e,"storedShape"),Nn(t,"currentShape")}catch{return!0}return!e||!t?!1:kr(e.targetTokenP50,t.targetTokenP50)>yr||kr(e.targetTokenP90,t.targetTokenP90)>yr}function pi(e,{now:t=Date.now(),identity:n,kernelTuneId:r,signatureKey:a,observedShape:o=null}={}){try{St(e)}catch{return{status:"corrupt-entry",entry:null}}if(e.protocolRev!==We)return{status:"protocol-mismatch",entry:null};if(e.invalidatedReason)return{status:e.invalidatedReason,entry:null};if(e.identity!==n)return{status:"identity-mismatch",entry:null};if(e.kernelTuneId!==r)return{status:"kernel-tune-mismatch",entry:null};if(e.signatureKey!==a)return{status:"signature-mismatch",entry:null};const s=e.ttlClass==="negative"?$s:ro,i=t-e.createdAt;return!Number.isFinite(t)||i<0||i>=s?{status:"expired",entry:null}:o&&e.observedShape&&ho(e.observedShape,o)?{status:"shape-drift",entry:null}:{status:null,entry:e}}function Cr(e,t,n=jn){if(!Array.isArray(e))throw new Error("cache entries must be an array");St(t),Ce(n,"maxPerScope");const r=e.map(s=>St(s)).filter(s=>s.identity!==t.identity);r.push(t);const a=new Map;for(const s of r){const i=a.get(s.scopeKey)??[];i.push(s),a.set(s.scopeKey,i)}const o=[];for(const s of a.values())s.sort((i,u)=>u.lastUsedAt-i.lastUsedAt||u.createdAt-i.createdAt||i.identity.localeCompare(u.identity)),o.push(...s.slice(0,n));return o.sort((s,i)=>i.lastUsedAt-s.lastUsedAt||i.createdAt-s.createdAt||s.identity.localeCompare(i.identity)).slice(0,Ht)}function hn(e,t){if(!Array.isArray(e))throw new Error("cache entries must be an array");return ce(t,"cache identity",Qe),e.filter(n=>n?.identity!==t)}const gi=new Set(["amortizationRev","protocolRev","identity","scopeKey","kernelTuneId","signatureKey","createdAt","lastUsedAt","schedule","profiledWallMs","profiledDecodeMs","rowCount","batchCount","tokenCount","submitShrinks"]);function lt(e){if(!e||typeof e!="object"||Array.isArray(e))throw new Error("observation entry must be an object");for(const t of Object.keys(e))if(!gi.has(t))throw new Error(`observation entry contains unknown key ${t}`);if(!Number.isInteger(e.amortizationRev)||e.amortizationRev<=0)throw new Error("observation entry amortizationRev must be a positive integer");if(!Number.isInteger(e.protocolRev)||e.protocolRev<=0)throw new Error("observation entry protocolRev must be a positive integer");if(ce(e.identity,"observation entry identity",Qe),ce(e.scopeKey,"observation entry scopeKey",512),ce(e.kernelTuneId,"observation entry kernelTuneId",512),ce(e.signatureKey,"observation entry signatureKey",Qe),Ge(e.createdAt,"observation entry createdAt"),Ge(e.lastUsedAt,"observation entry lastUsedAt"),e.lastUsedAtoo)throw new Error("observations exceed the per-scope LRU bound");t.set(n.scopeKey,r)}}function bi({amortizationRev:e,protocolRev:t,identity:n,scopeKey:r,kernelTuneId:a,signatureKey:o,createdAt:s,lastUsedAt:i=s,schedule:u=Le,profiledWallMs:l,profiledDecodeMs:p,rowCount:f,batchCount:m,tokenCount:d,submitShrinks:v=0,...y}={}){const g=Object.keys(y)[0];if(g)throw new Error(`observation entry contains unknown key ${g}`);const h={amortizationRev:Et,protocolRev:We,identity:n,scopeKey:r,kernelTuneId:a,signatureKey:o,createdAt:s,lastUsedAt:i,schedule:u&&{inFlight:u.inFlight,groupSteps:u.groupSteps},profiledWallMs:l,profiledDecodeMs:p,rowCount:f,batchCount:m,tokenCount:d,submitShrinks:v};return lt(h),h}function yi(e){if(!Array.isArray(e)||e.length>Wt)throw new Error(`observations must be an array of at most ${Wt}`);return fo(e),JSON.stringify({schema:so,entries:e})}function Mr(e){if(e==null||e==="")return{status:"miss",entries:[]};try{const t=JSON.parse(e);return t?.schema!==so||!Array.isArray(t.entries)||t.entries.length>Wt||Object.keys(t).some(n=>!["schema","entries"].includes(n))?{status:"corrupt",entries:[]}:(fo(t.entries),{status:null,entries:t.entries})}catch{return{status:"corrupt",entries:[]}}}function vi(e,{now:t=Date.now(),identity:n,kernelTuneId:r,signatureKey:a}={}){try{lt(e)}catch{return{status:"corrupt-entry",entry:null}}return e.amortizationRev!==Et?{status:"amortization-mismatch",entry:null}:e.protocolRev!==We?{status:"protocol-mismatch",entry:null}:e.identity!==n?{status:"identity-mismatch",entry:null}:e.kernelTuneId!==r?{status:"kernel-tune-mismatch",entry:null}:e.signatureKey!==a?{status:"signature-mismatch",entry:null}:!Number.isFinite(t)||t=Ls?{status:"expired",entry:null}:{status:null,entry:e}}function xr(e,t,n=oo){if(!Array.isArray(e))throw new Error("observations must be an array");lt(t),Ce(n,"maxPerScope");const r=e.map(s=>lt(s)).filter(s=>s.identity!==t.identity);r.push(t);const a=new Map;for(const s of r){const i=a.get(s.scopeKey)??[];i.push(s),a.set(s.scopeKey,i)}const o=[];for(const s of a.values())s.sort((i,u)=>u.lastUsedAt-i.lastUsedAt||u.createdAt-i.createdAt||i.identity.localeCompare(u.identity)),o.push(...s.slice(0,n));return o.sort((s,i)=>i.lastUsedAt-s.lastUsedAt||i.createdAt-s.createdAt||s.identity.localeCompare(i.identity)).slice(0,Wt)}function fn(e){return{status:"needs-baseline-observation",reason:e,admit:!1,observedProfiledWallMs:null,minimumExpectedSavingMs:null,projectedWorstCaseScreenMs:null,paybackRatio:null}}function Si({observation:e=null,projection:t=null,promotionGain:n=no}={}){if(!e)return fn("missing-observation");try{lt(e)}catch{return fn("invalid-observation")}const r=t?.projectedMs;if(!(Number.isFinite(r)&&r>0&&Number.isFinite(n)&&n>0&&n<=1))return fn("invalid-projection");const a=e.profiledWallMs,o=a*n,s=o/r,i=o>=r;return{status:i?"admitted":"unamortized",reason:i?null:"insufficient-payback",admit:i,observedProfiledWallMs:a,minimumExpectedSavingMs:o,projectedWorstCaseScreenMs:r,paybackRatio:s}}function wi(e,t,{required:n=!1,max:r=1/0}={}){if(!Array.isArray(e)||n&&e.length===0)throw new Error(`${t} must be ${n?"a non-empty":"an"} array`);if(e.length>r)throw new Error(`${t} exceeds its bounded size`);const a=e.map(o=>{if(!Number.isInteger(o)||o<0)throw new Error(`${t} must contain non-negative integers`);return o});if(new Set(a).size!==a.length)throw new Error(`${t} must not contain duplicates`);return[...a].sort((o,s)=>o-s)}function Ei(e){if(!Array.isArray(e))throw new Error("confirmationPlan must be an array");if(e.length>Ze.length)throw new Error("confirmationPlan exceeds its bounded size");const t=e.map((n,r)=>{if(!n||typeof n!="object"||Array.isArray(n))throw new Error(`confirmationPlan[${r}] must be an object`);if(Object.keys(n).some(i=>!["role","batchIndex","region"].includes(i)))throw new Error(`confirmationPlan[${r}] contains an unknown key`);const o=Ze[r];if(n.role!==o)throw new Error(`confirmationPlan[${r}] must have role ${o}`);if(!Number.isInteger(n.batchIndex)||n.batchIndex<0)throw new Error(`confirmationPlan[${r}].batchIndex must be non-negative`);if(!(Number.isInteger(n.region)&&n.region>0||typeof n.region=="string"&&n.region.length>0&&n.region.length<=64))throw new Error(`confirmationPlan[${r}].region is invalid`);return{role:n.role,batchIndex:n.batchIndex,region:n.region}});if(new Set(t.map(({batchIndex:n})=>n)).size!==t.length)throw new Error("confirmationPlan batch indices must not contain duplicates");return t}function ki(e,t){const n=t%e.length;return[...e.slice(n),...e.slice(0,n)]}function Ar(e,t=e.groupSteps){return{inFlight:e.inFlight,groupSteps:qs(e.groupSteps,t)}}function Ci(e,t){return`${e}:${t}`}function Mi(e){if(!Array.isArray(e)||e.length===0)throw new Error("runBatch rows must be a non-empty array");const t=e.map((n,r)=>{if(!n||typeof n!="object"||!Array.isArray(n.ids)||n.ids.length<2||n.ids.some(a=>!Number.isInteger(a)||a<0)||typeof n.forcedEos!="boolean")throw new Error(`runBatch rows[${r}] is invalid`);return[n.ids,n.forcedEos]});return{fingerprint:JSON.stringify(t),targetTokenLengths:e.map(n=>n.ids.length-1)}}function xi(e,t){if(!e||typeof e!="object"||Array.isArray(e))throw new Error("runBatch result must be an object");if(e.cleanupComplete!==!0)throw new Error("runBatch cleanupComplete evidence must be true");const n=Ce(e.groupStepsStart,"runBatch groupStepsStart"),r=Ce(e.groupStepsFinal,"runBatch groupStepsFinal");if(n!==t.groupSteps)throw new Error("runBatch groupStepsStart does not match the admitted schedule");if(r>n)throw new Error("runBatch groupStepsFinal must not grow");if(!vt(e.submitShrinks))throw new Error("runBatch submitShrinks must be a non-negative integer");if(e.submitShrinks===0&&r!==n||e.submitShrinks>0&&r>=n)throw new Error("runBatch submitShrinks and groupStepsFinal are inconsistent");if(!Number.isInteger(e.compactions)||e.compactions<0)throw new Error("runBatch compactions must be a non-negative integer");return{...Mi(e.rows),groupStepsStart:n,groupStepsFinal:r,submitShrinks:e.submitShrinks,wallMs:Z(e.wallMs,"runBatch wallMs"),decodeMs:Z(e.decodeMs,"runBatch decodeMs"),compactions:e.compactions}}function Ai(e){return De.map(t=>{const n=e.get(t.id),r=yt(n.records.map(s=>s.wallMs)),a=yt(n.records.map(s=>s.decodeMs)),o={id:t.id,status:n.status==="pending"&&n.records.length>0?"partial":n.status,completedRuns:n.records.length,submitShrinks:n.records.reduce((s,i)=>s+i.submitShrinks,0)};return r!==null&&(o.medianWallMs=r),a!==null&&(o.medianDecodeMs=a),o})}function Ni(e){if(!e||e.records.length===0)return null;const t=e.records.filter(r=>r.phase==="screen"),n=t.flatMap(r=>r.targetTokenLengths);return n.length===0?null:{targetTokenP50:Cn(n,.5),targetTokenP90:Cn(n,.9),compactionRate:t.filter(r=>r.compactions>0).length/t.length}}function Ti(e){if(!e||typeof e!="object"||Array.isArray(e))throw new Error("safetyOptions must be an object");if(Z(e.submitBudgetMs,"safetyOptions.submitBudgetMs"),typeof e.encSplitSubmits!="boolean")throw new Error("safetyOptions.encSplitSubmits must be boolean");return Object.freeze({...e})}function Nr(e){const t=e();if(!Number.isFinite(t))throw new Error("schedule tuner clock must be finite");return t}function Tr({decision:e=null,sampleCount:t=0,confirmationCount:n=0,tuneMs:r,projectedMs:a,actualMs:o,overrunMs:s,exact:i=!1,includePerformance:u=!0}){const l={sampleCount:t,confirmationCount:n,tuneMs:r,projectedMs:a,actualMs:o,overrunMs:s,exact:i};return u&&(l.favorableRegions=e?.favorableRegions??0,Number.isFinite(e?.wallGain)&&(l.wallGain=e.wallGain),Number.isFinite(e?.screenWallGain)&&(l.screenWallGain=e.screenWallGain),Number.isFinite(e?.confirmationMinWallGain)&&(l.confirmationMinWallGain=e.confirmationMinWallGain),Number.isFinite(e?.decodeGain)&&(l.decodeGain=e.decodeGain)),l}async function mo({sampleBatchIndices:e,confirmationPlan:t=[],workloadBatchCosts:n,batchRegions:r=null,kernelReferenceMs:a,kernelReferenceCost:o,safetyOptions:s,pretokenize:i,estimateBatch:u,runBatch:l,now:p=Date.now,isCancelled:f=()=>!1,isDeviceHealthy:m=()=>!1,deadlineMs:d=Jt,marginMs:v=Un,safetyFactor:y=Qt,pretokenizeEstimateMs:g=0}={}){const h=wi(e,"sampleBatchIndices",{required:!0,max:Gn.length}),S=Ei(t);if(S.some(({batchIndex:E})=>h.includes(E)))throw new Error("confirmationPlan batches must be unused by the screen");const M=ri(n,h),C=new Map(h.map((E,A)=>[E,M[A]]));let L=null;if(r!=null){if(!Array.isArray(r)||r.length===0)throw new Error("batchRegions must be a non-empty array");if(L=r.map((A,F)=>{if(Number.isInteger(A)&&A>0||typeof A=="string"&&A.length>0&&A.length<=64)return A;throw new Error(`batchRegions[${F}] is invalid`)}),Math.max(...h,...S.map(({batchIndex:A})=>A))>=L.length)throw new Error("batchRegions must cover every screen and confirmation batch");for(const A of S)if(Kt(A.region)!==Kt(L[A.batchIndex]))throw new Error(`confirmationPlan ${A.role} region does not match batchRegions`)}for(const[E,A]of[[i,"pretokenize"],[u,"estimateBatch"],[l,"runBatch"],[p,"now"],[f,"isCancelled"],[m,"isDeviceHealthy"]])if(typeof E!="function")throw new Error(`${A} must be a function`);if(Z(a,"kernelReferenceMs"),Z(o,"kernelReferenceCost"),Z(d,"deadlineMs"),Ge(v,"marginMs"),v>=d)throw new Error("marginMs must be below deadlineMs");Z(y,"safetyFactor"),Ge(g,"pretokenizeEstimateMs");const z=Ti(s),G=new Map(De.map(E=>[E.id,{arm:E,carry:Vs(E.groupSteps),status:"pending",records:[]}])),fe=h.flatMap((E,A)=>ki(De,A).map(F=>({phase:"screen",batchIndex:E,samplePosition:A,region:L?.[E]??`sample-${A+1}`,arm:F}))),me=new Map,we=async(E,A)=>{const F=Ci(E,A.id);if(me.has(F))return me.get(F);const O=Z(await u(E,Ar(A)),`estimateBatch(${E}, ${A.id})`);return me.set(F,O),O};let w=null,V=null,ge=0,Ee=null,J=0,k=!1,B=[];const _=[],I=()=>{if(Ee===null)return 0;const E=Nr(p)-Ee;if(!Number.isFinite(E)||E<0)throw new Error("schedule tuner clock must be monotonic");return E},N=({verdict:E,reason:A=E,schedule:F=Le,source:O="default",cacheable:te,ttlClass:Q,decision:W=null,exact:be=!1,includeCandidateEvidence:ye=!0,includeObservedShape:Ke=!0})=>{const ae=I(),Ie=dn({elapsedMs:ae,deadlineMs:d}),tt=Tr({decision:W,sampleCount:k?h.length:B.length,confirmationCount:_.length,tuneMs:ae,projectedMs:ge,actualMs:ae,overrunMs:Ie.overrunMs,exact:be,includePerformance:!0}),nt=te?Tr({decision:W,sampleCount:k?h.length:B.length,confirmationCount:_.length,tuneMs:ae,projectedMs:ge,actualMs:ae,overrunMs:Ie.overrunMs,exact:be,includePerformance:Q!=="negative"}):{};return{protocolRev:We,verdict:E,reason:A,schedule:{inFlight:F.inFlight,groupSteps:F.groupSteps},source:O,screenSubmitShrinks:J,scheduleTuneMs:ae,evidence:tt,confirmationPlan:S.map(kt=>({...kt})),completedConfirmationRoles:W?.completedRoles?[...W.completedRoles]:[],candidateEvidence:ye?Ai(G):[],observedShape:Ke?Ni(G.get("base")):null,projection:{preGate:w?{rawGpuMs:w.rawGpuMs,rawProjectedMs:w.rawProjectedMs,projectedMs:w.projectedMs,runCount:w.runCount,budgetMs:w.budgetMs,admission:w.admission}:null,postPilot:V?{...V}:null},deadline:Ie,cache:{cacheable:te,ttlClass:Q,evidence:nt}}},T=()=>N({verdict:"cancelled",cacheable:!1,ttlClass:null,includeCandidateEvidence:!1,includeObservedShape:!1}),j=E=>N({verdict:E,cacheable:!0,ttlClass:"negative",includeCandidateEvidence:!1,includeObservedShape:!1});if(f())return T();const $=[];for(const E of fe){if(f())return T();$.push(await we(E.batchIndex,E.arm))}const ee=An({referenceMs:a,referenceCost:o,runCosts:$,safetyFactor:y});w={...ee,rawProjectedMs:g+ee.rawGpuMs,projectedMs:g+ee.projectedMs},ge=w.projectedMs;const pe=ii(w,d,v);if(w.budgetMs=pe.budgetMs,w.admission=pe.admission,!pe.admit)return j("projected-over-budget");Ee=Nr(p);const Me=[...new Set([...h,...S.map(({batchIndex:E})=>E)])].sort((E,A)=>E-A);for(const E of Me)if(f()||(await i(E),f()))return T();if(I()>=d)return j("timeout");let oe={ms:a,cost:o};const K=async E=>{if(f())return{terminal:T()};const A=I();if(A>=d)return{terminal:j("timeout")};const F=G.get(E.arm.id),O=Ar(E.arm,F.carry),te=await we(E.batchIndex,E.arm),Q=oe.ms*(te/oe.cost),W=ci({elapsedMs:A,projectedRunMs:Q,deadlineMs:d,marginMs:v,safetyFactor:y});if(!W.admit)return Number.isFinite(W.projectedEndMs)&&(ge=W.projectedEndMs),{terminal:j("projected-over-budget")};let be;try{be=await l(E.batchIndex,O,z)}catch(ae){if(f())return{terminal:T()};if(E.arm.id==="base"||!await m(ae))throw ae;return F.status="error",dn({elapsedMs:I(),deadlineMs:d}).deadlineExceeded?{terminal:j("admission-overrun")}:{candidateError:!0}}const ye=xi(be,O);if(f())return{terminal:T()};if(ye.submitShrinks>0){J+=ye.submitShrinks;const ae={...ye};return delete ae.fingerprint,F.status="submit-shrink",F.records.push({phase:E.phase,batchIndex:E.batchIndex,region:E.region,...ae}),{terminal:N({verdict:"safety-fallback",reason:"submit-shrink",source:"measured",cacheable:!0,ttlClass:"normal",exact:!1})}}return F.carry=Js(F.carry,ye.groupStepsFinal),dn({elapsedMs:I(),deadlineMs:d}).deadlineExceeded?{terminal:j("admission-overrun")}:{trial:{...ye,cost:te}}},P=new Map,Re=(E,A)=>{const F=G.get(E.arm.id),{fingerprint:O,...te}=A,Q={phase:"screen",batchIndex:E.batchIndex,region:E.region,...te};F.records.push(Q);const W=P.get(E.batchIndex)??new Map;if(W.set(E.arm.id,O),P.set(E.batchIndex,W),E.arm.id==="base")for(const be of De.slice(1)){const ye=W.get(be.id);ye!==void 0&&ye!==O&&(G.get(be.id).status="output-mismatch")}else{const be=W.get("base");be!==void 0&&be!==O&&(F.status="output-mismatch")}},x=fe[0],le=await K(x);if(le.terminal)return le.terminal;Re(x,le.trial),oe={ms:le.trial.wallMs,cost:le.trial.cost};const ue=$.slice(1);if(ue.length>0){const E=An({referenceMs:oe.ms,referenceCost:oe.cost,runCosts:ue,safetyFactor:y}),A=I(),F=A+E.rawGpuMs+v,O=A+E.projectedMs+v,te=O<=d,Q=!te&&F<=d;if(V={rawGpuMs:E.rawGpuMs,projectedMs:E.projectedMs,runCount:E.runCount,rawProjectedEndMs:F,projectedEndMs:O,admission:te?"full":Q?"per-run":null},ge=V.projectedEndMs,!te&&!Q)return j("projected-over-budget")}let H=x.batchIndex;for(const E of fe.slice(1)){E.batchIndex!==H&&(P.delete(H),H=E.batchIndex);const A=G.get(E.arm.id);if(E.arm.id!=="base"&&A.status!=="pending")continue;const F=await K(E);if(F.terminal)return F.terminal;F.candidateError||Re(E,F.trial)}P.clear(),k=!0,G.get("base").status="complete";for(const E of De.slice(1)){const A=G.get(E.id),F=A.records.filter(O=>O.phase==="screen");A.status==="pending"&&(A.status=F.length===h.length?"complete":"incomplete")}const xe=new Map,he=E=>{const A=G.get(E.id);return h.map(F=>{const O=G.get("base").records.find(Q=>Q.phase==="screen"&&Q.batchIndex===F),te=A.records.find(Q=>Q.phase==="screen"&&Q.batchIndex===F);return{region:O.region,weight:C.get(F),baselineWallMs:O.wallMs,candidateWallMs:te.wallMs,baselineDecodeMs:O.decodeMs,candidateDecodeMs:te.decodeMs,complete:!0,exact:!0,baselineSubmitShrinks:O.submitShrinks,candidateSubmitShrinks:te.submitShrinks}})},Ae=De.map(E=>{const A=G.get(E.id),F=A.records.filter(Q=>Q.phase==="screen"),O=E.id==="base"||A.status==="complete";let te=1;if(E.id!=="base"&&O){const Q=he(E);xe.set(E.id,Q);const W=xn(Q);te=1-(W.weightedWallGain??W.wallGain)}return{id:E.id,score:te,exact:O,submitShrinks:F.reduce((Q,W)=>Q+W.submitShrinks,0)}}),{candidate:X}=ai(Ae);if(!X)return N({verdict:"keep-default",reason:"no-exact-candidate",source:"measured",cacheable:!0,ttlClass:"normal",exact:!1});const Y=G.get(X.id).arm,Ne=G.get(X.id);B=xe.get(X.id);let q=Er({screenPairs:B});if(q.reason!=="needs-confirmation")return N({verdict:"keep-default",reason:q.reason,source:"measured",cacheable:!0,ttlClass:"normal",decision:q,exact:!0});for(let E=0;En.inFlight===e.inFlight&&n.groupSteps===e.groupSteps);if(!t)throw new Error("decodeScheduleOverride must be a version-1 schedule arm");return{inFlight:t.inFlight,groupSteps:t.groupSteps}}function Pr(e=null){return e==="shadow"?"shadow":e==="1"||e==="apply"?"apply":e==="auto"?"auto":"off"}function $i(e,t,n,r={}){const a=e??{},o=["dModel","heads","headDim","ffn","encLayers","decLayers","vocab","maxPos","srcCap","decodeCap"].map(l=>t[l]??"").join("x"),s=`${r.subgroupMinSize??0}-${r.subgroupMaxSize??0}`,i=r.immediates==="on"?"on":"off",u=r.uniformPool===!0||r.uniformPool==="on"||r.uniformPool==="b64"?"b64":"off";return[`moxhi.autotune.v${Kr}`,a.vendor??"",a.architecture??"",a.device??"",`sg${s}`,o,n,`imm${i}`,`pool${u}`,r.browserMajor??"unknown"].join("|")}const Li=720*3600*1e3;function Oi(e){if(e==null)return{parsed:null,status:"miss"};try{const t=JSON.parse(e);return!t||typeof t!="object"||Array.isArray(t)?{parsed:null,status:"corrupt"}:{parsed:t,status:null}}catch{return{parsed:null,status:"corrupt"}}}function Fi(e,t,n=Date.now(),r=Li){const a=Date.parse(e?.date??""),o=n-a;return!Number.isFinite(a)||o<0||o>=r?{status:"expired",measuredAt:null}:oa(e?.tuned,t)?{status:null,measuredAt:a}:{status:"safety-rejected",measuredAt:null}}function _i(e,t){return aa(e,t)?"accepted":"mismatch"}const Di=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,Gi=e=>typeof e=="string"&&Di.test(e)?e:null,ht=(e,{priorTuneId:t=null,cachedUs:n=null,currentUs:r=null,error:a=null}={})=>({status:e,priorTuneId:t,cachedUs:n,currentUs:r,error:a});function Ui(e){return e.map((t,n)=>n).sort((t,n)=>e[t]-e[n])}function ji(e,t=192,n=576){return Math.max(t,Math.min(n,Math.floor(t*224/e)))}function Wn({ua:e="",maxTouchPoints:t=0}={}){const n=typeof e=="string"?e:"";return/iPhone|iPad|iPod|Android/.test(n)||/Macintosh/.test(n)&&t>1}function zi({ua:e=""}={}){return/Android/.test(typeof e=="string"?e:"")}function po({ua:e="",maxTouchPoints:t=0,capParam:n=null}={}){const r=Math.floor(Number(n));return Number.isFinite(r)&&r>=1?Math.min(r,2048):Wn({ua:e,maxTouchPoints:t})?192:576}function go({ua:e="",maxTouchPoints:t=0,budgetParam:n=null}={}){if(typeof n=="string"&&n.trim()==="0")return 1/0;const r=Math.floor(Number(n));return n!==""&&n!==null&&n!==void 0&&Number.isFinite(r)&&r>=1?Math.min(r,1024*1024):Wn({ua:e,maxTouchPoints:t})?16*1024:1/0}const Rr="moxhi-mobile-kv-v2";function bo(e=null){if(e==null||String(e).trim()==="")return{mode:"auto",capacity:null};const t=String(e).trim();if(t==="0")return{mode:"legacy",capacity:null};if(!/^\d+$/.test(t))return{mode:"legacy",capacity:null};const n=Number(t);return!Number.isInteger(n)||n<1||n>Bn?{mode:"legacy",capacity:null}:{mode:"forced",capacity:n}}function Hi(e,{modelId:t="",mobile:n=!1,plannerParam:r=null,kvcapParam:a=null,tokenBudget:o=1/0}={}){if(!Number.isInteger(e)||e<1)throw new Error(`file KV policy: bad S=${e}`);const s=bo(a),i=r==="1"&&n&&t==="moxhi"&&s.mode!=="legacy",u=s.mode==="forced"?s.capacity:null;if(!i)return{rowCap:null,tokenBudget:o,kvCapacity:u,label:u?`forced-kv${u}`:"legacy-full-kv",autoRows:!1};let l=192,p=Bn,f=o;return e<=32?(l=384,p=64,f=1/0):e<=64?(l=192,p=112,f=1/0):e<=96&&(l=192,p=128,f=1/0),{rowCap:l,tokenBudget:f,kvCapacity:u??p,label:u?`${Rr}+forced-kv${u}`:Rr,autoRows:!0}}function Wi({modelId:e="",ua:t="",maxTouchPoints:n=0,plannerParam:r=null,kvcapParam:a=null,capParam:o=null,budgetParam:s=null}={}){const i=Wn({ua:t,maxTouchPoints:n}),u=bo(a),l=r==="1"&&i&&e==="moxhi"&&u.mode!=="legacy",p=go({ua:t,maxTouchPoints:n,budgetParam:s}),f=po({ua:t,maxTouchPoints:n,capParam:o}),m=o!=null&&String(o).trim()!==""&&Number.isFinite(Number(o))&&Math.floor(Number(o))>=1,d=l&&!m?576:f,v=g=>Hi(g,{modelId:e,mobile:i,plannerParam:r,kvcapParam:a,tokenBudget:p}),y=v(32);return{mobile:i,autoRows:l,absCap:d,tokenBudget:p,forcedCapacity:u.mode==="forced"?u.capacity:null,policyLabel:y.label,policyForS:v,kvCapacityForS:g=>v(g).kvCapacity}}function Ki({param:e=null}={}){return e==="1"}function Br(){return po({ua:navigator.userAgent??"",maxTouchPoints:navigator.maxTouchPoints??0,capParam:new URLSearchParams(location.search).get("cap")})}function Vi(){return go({ua:navigator.userAgent??"",maxTouchPoints:navigator.maxTouchPoints??0,budgetParam:new URLSearchParams(location.search).get("tokenbudget")})}function yo(e,t,n,r=192,a=576,o=1/0,s=null){const i=[],u=[];for(let l=0;lC)break;f=v,m=y,p++}i.push([l,p]),u.push(m),l=p}return{ranges:i,buckets:u}}function qi(e,t,n,r=192,a=576,o=1/0,s=null){return yo(e,t,n,r,a,o,s).ranges}function Ji(){return Ki({param:new URLSearchParams(location.search).get("inplacecompact")})}const Be=e=>Math.round(e*10)/10,mn=e=>Math.round(e*100)/100;async function Qi(e,t=globalThis.crypto){if(!t?.subtle?.digest)throw new Error("SHA-256 unavailable");const n=new TextEncoder().encode(String(e));return[...new Uint8Array(await t.subtle.digest("SHA-256",n))].map(a=>a.toString(16).padStart(2,"0")).join("")}function Xi(e,t=null){if(!Array.isArray(e))throw new Error("aggregateBatchProfile needs an array");const n=e.reduce((o,s)=>o+(Number(s.ms)||0),0),r=e.reduce((o,s)=>o+(Number(s.decodeMs)||0),0),a={};for(const o of e){if(!Number.isInteger(o.S)||o.S<1)throw new Error(`aggregateBatchProfile: bad S=${o.S}`);const s=a[o.S]??={batches:0,rows:0,tokens:0,compactions:0,kvGrows:0,kvGrowsWithPending:0,kvGrowBindGroupsPurged:0,ms:0,encoderMs:0,decodeMs:0,maxB:0,maxCap:0,maxSteps:0,maxSourceTokenArea:0,minInitialKvCapacity:1/0,maxInitialKvCapacity:0,maxFinalKvCapacity:0,logicalArenaPeakMB:0,submittedArenaPeakMB:0};s.batches++,s.rows+=Number(o.B)||0,s.tokens+=Number(o.tokens)||0,s.compactions+=Number(o.compactions)||0,s.kvGrows+=Number(o.kvGrows)||0,s.kvGrowsWithPending+=Number(o.kvGrowsWithPending)||0,s.kvGrowBindGroupsPurged+=Number(o.kvGrowBindGroupsPurged)||0,s.ms+=Number(o.ms)||0,s.encoderMs+=Number(o.encoderMs)||0,s.decodeMs+=Number(o.decodeMs)||0,s.maxB=Math.max(s.maxB,Number(o.B)||0),s.maxCap=Math.max(s.maxCap,Number(o.cap)||0),s.maxSteps=Math.max(s.maxSteps,Number(o.steps)||0);const i=Number(o.initialKvCapacity)||0;i>0&&(s.minInitialKvCapacity=Math.min(s.minInitialKvCapacity,i)),s.maxInitialKvCapacity=Math.max(s.maxInitialKvCapacity,i),s.maxFinalKvCapacity=Math.max(s.maxFinalKvCapacity,Number(o.finalKvCapacity)||0),s.maxSourceTokenArea=Math.max(s.maxSourceTokenArea,(Number(o.B)||0)*o.S),s.logicalArenaPeakMB=Math.max(s.logicalArenaPeakMB,Number(o.logicalArenaPeakMB)||0),s.submittedArenaPeakMB=Math.max(s.submittedArenaPeakMB,Number(o.submittedArenaPeakMB)||0)}for(const o of Object.values(a))Number.isFinite(o.minInitialKvCapacity)||(o.minInitialKvCapacity=0),o.ms=Be(o.ms),o.encoderMs=Be(o.encoderMs),o.decodeMs=Be(o.decodeMs),o.batchWallPct=n>0?mn(o.ms/n*100):0,o.decodeSharePct=r>0?mn(o.decodeMs/r*100):0,o.fileWallPct=Number.isFinite(t)&&t>0?mn(o.ms/t*100):null;return{profiledMs:Be(n),profiledDecodeMs:Be(r),sBuckets:a}}const Tn=64,Yi=Tn;function Gt(e,t="unknown"){return(String(e??"").trim()||t).slice(0,96)}function Zi(e={},{subgroupMinSize:t=0,subgroupMaxSize:n=0}={}){return[Gt(e.vendor),Gt(e.architecture),Gt(e.device),`sg${Number(t)||0}-${Number(n)||0}`].join("|")}function ec({batchSize:e,plannedS:t,maxChars:n}={}){if(!Number.isInteger(e)||e<1)throw new Error(`schedule batchSize must be positive, got ${e}`);if(!Number.isInteger(t)||t<1)throw new Error(`schedule plannedS must be positive, got ${t}`);if(!Number.isFinite(n)||n<0)throw new Error(`schedule maxChars must be non-negative, got ${n}`);const r=ua(n),a=Math.sqrt(e/Tn),o=Math.max(1,t/96);return Tn*a*r*o}function Ir(e,t){const n=[...e].sort((s,i)=>s-i),r=(n.length-1)*t,a=Math.floor(r),o=Math.ceil(r);return a===o?n[a]:n[a]+(n[o]-n[a])*(r-a)}function tc(e,t,n){return e.length===0||n<1?null:{targetTokenP50:Ir(e,.5),targetTokenP90:Ir(e,.9),compactionRate:t/n}}function pn(e,t){if(!e?.getItem)return null;try{return e.getItem(t)}catch{return null}}function ct(e,t,n){if(e)try{n.length===0?e.removeItem?.(t):e.setItem?.(t,fi(n))}catch{}}function $t(e,t,n){if(!e)return!1;try{if(n.length===0){if(typeof e.removeItem!="function")return!1;e.removeItem(t)}else{if(typeof e.setItem!="function")return!1;e.setItem(t,yi(n))}return!0}catch{return!1}}function Lt({selectedSchedule:e,telemetry:t,cacheHit:n=!1,cachedObservedShape:r=null,driftBatchIndices:a=[],invalidate:o=()=>{},recordBaselineObservation:s=()=>!1}){return{selectedSchedule:{inFlight:e.inFlight,groupSteps:e.groupSteps},telemetry:t,cacheHit:n,cachedObservedShape:r,driftBatchIndices:[...a],invalidate:o,recordBaselineObservation:s}}async function nc({enabled:e=!1,amortizationPolicy:t="bypass",configuredSchedule:n=Le,eligibilityInput:r={},buildWorkload:a,adapterKey:o,modelId:s,weightsId:i,dtype:u,browserMajor:l,kernelTuneId:p,modes:f,scopeKey:m,kernelReferenceMs:d,kernelReferenceCost:v=Yi,safetyOptions:y,storage:g=null,runner:h=mo,pretokenize:S,estimateBatch:M,runBatch:C,isCancelled:L=()=>!1,isDeviceHealthy:z=()=>!1,clock:G=()=>performance.now(),cacheNow:fe=()=>Date.now()}={}){const me={inFlight:n.inFlight,groupSteps:n.groupSteps},we=t==="automatic",w={protocolRev:We,enabled:e===!0,eligible:!1,source:"default",reason:e===!0?null:"disabled",configuredSchedule:{...me},selectedSchedule:{...me},effectiveSchedule:{...me},workload:null,evidence:null,candidateEvidence:[],observedShape:null,projection:null,deadline:null,screenSubmitShrinks:0,selectedGain:null,screenGain:null,confirmationMinGain:null,sampleCount:0,confirmationCount:0,confirmationPlan:[],completedConfirmationRoles:[],scheduleTuneMs:0,invalidatedReason:null,cache:{status:"not-checked",write:null,verdict:null,persistent:g?.persistent!==!1},amortization:{revision:Et,status:e&&!we?"bypass":"not-checked",reason:null,observationCacheState:"not-checked",observationAgeMs:null,observedProfiledWallMs:null,minimumExpectedSavingMs:null,projectedWorstCaseScreenMs:null,paybackRatio:null,write:null,persistent:g?.persistent!==!1}},V=()=>Lt({selectedSchedule:me,telemetry:w});if(!e)return V();const ge=oi(r);if(w.eligible=ge.eligible,w.reason=ge.reason,!ge.eligible)return V();if(!(Number.isFinite(d)&&d>0))return w.reason="kernel-reference-missing",V();if(typeof a!="function"||typeof h!="function")return w.reason="integration-unavailable",V();if(L())return w.reason="cancelled",V();const Ee=G(),J=()=>{const x=G()-Ee;w.scheduleTuneMs=Number.isFinite(x)&&x>0?x:0};let k,B,_,I,N,T,j,$=[],ee,pe;try{if(k=await a(),!k||!Array.isArray(k.batchCosts)||k.batchCosts.length===0)throw new Error("schedule workload is missing batch costs");const x=k.batchRegions??k.signatureInput?.plannedSourceBuckets??null;ee=ei(k.batchCosts,Gn,x),pe=ni(k.batchCosts,ee,x),B=Ys(k.signatureInput),_=Zs(B);const le={adapterKey:o,modelId:s,weightsId:i,dtype:u,browserMajor:l,kernelTuneId:p,modes:f,signature:B};I=co(le),N=ui(m),we&&(T=li(le),j=di(m))}catch(x){return w.reason="workload-preparation-error",w.error=String(x?.message??x).slice(0,160),J(),V()}w.workload=B;const Me=mi(pn(g,N));$=Me.entries,w.cache.status=Me.status??"miss",Me.status==="corrupt"&&ct(g,N,[]);const oe=fe();let K=$.find(x=>x.identity===I)??null;if(K){const x=pi(K,{now:oe,identity:I,kernelTuneId:p,signatureKey:_});if(x.entry){K={...x.entry,lastUsedAt:oe},$=Cr($,K),ct(g,N,$),w.source="cache",w.reason=K.verdict,w.selectedSchedule={...K.schedule},w.effectiveSchedule={...K.schedule},w.evidence={...K.evidence},w.observedShape=K.observedShape?{...K.observedShape}:null,w.screenSubmitShrinks=K.screenSubmitShrinks,w.selectedGain=K.evidence.wallGain??null,w.screenGain=K.evidence.screenWallGain??null,w.confirmationMinGain=K.evidence.confirmationMinWallGain??null,w.sampleCount=K.evidence.sampleCount??0,w.confirmationCount=K.evidence.confirmationCount??0,w.cache.status="hit",w.cache.verdict=K.verdict,we&&(w.amortization.status="cache-hit",w.amortization.reason=null),J();const le=ue=>{$=hn($,I),ct(g,N,$),K=null,w.invalidatedReason=ue,w.cache.status=ue};return Lt({selectedSchedule:K.schedule,telemetry:w,cacheHit:!0,cachedObservedShape:K.observedShape,driftBatchIndices:ee,invalidate:le})}$=hn($,I),ct(g,N,$),w.cache.status=x.status,K=null}if(L())return w.reason="cancelled",J(),V();if(we){const x=Mr(pn(g,j));let le=x.entries;w.amortization.observationCacheState=x.status??"miss",x.status==="corrupt"&&$t(g,j,[]);let ue=le.find(he=>he.identity===T)??null;if(ue){const he=vi(ue,{now:oe,identity:T,kernelTuneId:p,signatureKey:_});he.entry?(ue={...he.entry,lastUsedAt:oe},le=xr(le,ue),$t(g,j,le),w.amortization.observationCacheState="hit",w.amortization.observationAgeMs=oe-ue.createdAt):(le=le.filter(Ae=>Ae.identity!==T),$t(g,j,le),w.amortization.observationCacheState=he.status,ue=null)}let H=null;if(ue)try{H=si({kernelReferenceMs:d,kernelReferenceCost:v,sampleCosts:ee.map(he=>k.batchCosts[he]),armCount:De.length,confirmationRounds:2,pretokenizeMs:0})}catch{H=null}const xe=Si({observation:ue,projection:H});if(Object.assign(w.amortization,xe),!xe.admit){w.reason=xe.status;let he=!1;const Ae=(X={})=>{if(he)return w.amortization.write="duplicate",!1;he=!0;const Y=q=>q?.inFlight===Le.inFlight&&q?.groupSteps===Le.groupSteps;if(!(X.complete===!0&&X.cancelled===!1&&X.deviceHealthy===!0&&Y(X.configuredSchedule)&&Y(X.effectiveSchedule)&&X.rowCount===r.uncachedRows&&X.batchCount===k.batchCosts.length&&X.submitShrinks===0))return w.amortization.write="rejected",!1;try{const q=fe(),E=bi({identity:T,scopeKey:m,kernelTuneId:p,signatureKey:_,createdAt:q,schedule:Le,profiledWallMs:X.profiledWallMs,profiledDecodeMs:X.profiledDecodeMs,rowCount:X.rowCount,batchCount:X.batchCount,tokenCount:X.tokenCount,submitShrinks:X.submitShrinks}),A=Mr(pn(g,j)),F=xr(A.status===null?A.entries:[],E),O=$t(g,j,F);return w.amortization.write=O?"stored":"unavailable",O}catch{return w.amortization.write="rejected",!1}};return J(),Lt({selectedSchedule:me,telemetry:w,recordBaselineObservation:Ae})}}const P=await h({sampleBatchIndices:ee,confirmationPlan:pe,workloadBatchCosts:[...k.batchCosts],batchRegions:k.batchRegions??k.signatureInput?.plannedSourceBuckets??null,kernelReferenceMs:d,kernelReferenceCost:v,safetyOptions:y,pretokenize:S,estimateBatch:M,runBatch:C,now:G,isCancelled:L,isDeviceHealthy:z});if(J(),L())return w.source="default",w.reason="cancelled",w.cache.write="not-cacheable",V();w.source=P.source,w.reason=P.reason,w.selectedSchedule={...P.schedule},w.effectiveSchedule={...P.schedule},w.evidence=P.evidence?{...P.evidence}:null,w.candidateEvidence=Array.isArray(P.candidateEvidence)?P.candidateEvidence.map(x=>({...x})):[],w.observedShape=P.observedShape?{...P.observedShape}:null,w.projection=P.projection?{...P.projection}:null,w.deadline=P.deadline?{...P.deadline}:null,w.screenSubmitShrinks=P.screenSubmitShrinks??0,w.selectedGain=P.evidence?.wallGain??null,w.screenGain=P.evidence?.screenWallGain??null,w.confirmationMinGain=P.evidence?.confirmationMinWallGain??null,w.sampleCount=P.evidence?.sampleCount??0,w.confirmationCount=P.evidence?.confirmationCount??0,w.confirmationPlan=Array.isArray(P.confirmationPlan)?P.confirmationPlan.map(x=>({...x})):pe.map(x=>({...x})),w.completedConfirmationRoles=Array.isArray(P.completedConfirmationRoles)?[...P.completedConfirmationRoles]:[],w.cache.verdict=P.verdict,P.cache?.cacheable?(K=hi({identity:I,scopeKey:m,kernelTuneId:p,signatureKey:_,createdAt:oe,ttlClass:P.cache.ttlClass,verdict:P.verdict,schedule:P.schedule,observedShape:P.observedShape,screenSubmitShrinks:P.screenSubmitShrinks,evidence:P.cache.evidence}),$=Cr($,K),ct(g,N,$),w.cache.write="stored"):w.cache.write="not-cacheable";const Re=x=>{K&&($=hn($,I),ct(g,N,$),K=null),w.invalidatedReason=x,w.cache.status=x};return Lt({selectedSchedule:P.schedule,telemetry:w,invalidate:Re})}async function rc({model:e=$n(Ln),onPhase:t,onProgress:n,onDeviceLost:r,scheduleAutotuneRunner:a=mo,scheduleCacheStorage:o=null,scheduleDefaultEnabled:s=!1,scheduleDefaultSeedFactory:i=()=>globalThis.crypto?.randomUUID?.()}={}){t?.("gpu");const u=await Jo(),l=u.hasF16?"f16":"f32";let p=null;u.device.lost.then(x=>{x?.reason!=="destroyed"&&(p={reason:x?.reason??"unknown",message:x?.message??""},console.error(`WebGPU device lost (${p.reason}): ${p.message}`),r?.(p))}),t?.("tokenizer");const f=await Qo(e.tokenizerId,e.tokRev),m=new URLSearchParams(location.search);let d=o;const y=["shortlist","directq8","immediates","uniformpool","kvplanner","kvcap","cap","tokenbudget","tm","inplacecompact","submitbudget","encsplit","inflight","groupsteps","scheduletune"].filter(x=>m.get(x)!==null).map(x=>`${x}=${String(m.get(x)).slice(0,24)}`),g=m.has("scheduletune")?Pr(m.get("scheduletune")):null,h=Ts({enabled:s===!0,explicitMode:g,getStorage:()=>d??=zt("local"),createSeed:i}),S=h.mode,M=m.get("shortlist")!=="0",C=m.get("directq8")!=="0",L=m.get("immediates")==="0"?"off":"auto",z=L==="auto"&&u.hasImmediates?"on":"off",G=Ri(z,m.get("uniformpool")),fe=m.get("submitbudget"),me=fe===null?void 0:Number(fe)>0?Number(fe):null,we=Ji(),w=Bi({inFlightParam:m.get("inflight"),groupStepsParam:m.get("groupsteps")}),V=Wi({modelId:e.id,ua:navigator.userAgent??"",maxTouchPoints:navigator.maxTouchPoints??0,plannerParam:m.get("kvplanner"),kvcapParam:m.get("kvcap"),capParam:m.get("cap"),budgetParam:m.get("tokenbudget")}),ge=m.get("encsplit"),Ee=ge===null?zi({ua:navigator.userAgent??""}):ge==="1",J=l==="f16"&&M?Xo(f.idToToken):null;t?.("weights");const k=await Yo(u.device,e.weightsUrl,{targetDtype:l,lmHeadQ8:l==="f16",ffnWT:l==="f16",projWT:l==="f16",directQ8:C,...J?{lmHeadIds:J}:{},onProgress:n});t?.("autotune");let B=null,_=null,I=null,N="default",T=null,j=null,$=null;try{const x=$i(u.adapterInfo,Zo(),l,{subgroupMinSize:u.subgroupMinSize,subgroupMaxSize:u.subgroupMaxSize,immediates:z,uniformPool:G,browserMajor:Hn(navigator.userAgent??"")}),le=localStorage.getItem(x),ue=Oi(le),H=ue.parsed;if(ue.status==="corrupt")try{localStorage.removeItem(x)}catch{}ue.status&&($=ht(ue.status));const xe=await ea({...u,dtype:l});B=xe;let he=!1;const Ae=H?Fi(H,xe):null,X=Gi(H?.tuneId);if(Ae?.status&&($=ht(Ae.status,{priorTuneId:X})),H&&!Ae?.status){const Y=H.timings?.b64?.def?.medianUs;try{const Ne=await ta({...u,dtype:l},k,{immediates:L,uniformPool:G});if(he=_i(Y,Ne.medianUs)==="accepted",he){let q=X,E="accepted";if(!q){q=crypto.randomUUID(),E="legacy-upgraded";try{localStorage.setItem(x,JSON.stringify({...H,tuneId:q}))}catch{}}I=H.tuned,N="cache",_=H.timings??null,T=q,j=Ae.measuredAt,$=ht(E,{priorTuneId:X,cachedUs:Number.isFinite(Y)?Y:null,currentUs:Ne.medianUs})}else $=ht("mismatch",{priorTuneId:X,cachedUs:Number.isFinite(Y)?Y:null,currentUs:Ne.medianUs}),console.info(`autotune cache power-state mismatch (${Y??"missing"}us -> ${Ne.medianUs}us); remeasuring`)}catch(Ne){$=ht("canary-error",{priorTuneId:X,cachedUs:Number.isFinite(Y)?Y:null,error:String(Ne?.message??Ne).slice(0,128)}),console.warn("autotune cache canary failed; remeasuring:",Ne)}}if(!he){const Y=await na({...u,dtype:l},k,{reductionSafety:xe,immediates:L,uniformPool:G,maxB:Br()});if(I=Y.tuned,_=Y.timings??null,T=crypto.randomUUID(),j=Date.now(),N=Y.partial?"partial":"measured",!Y.partial)try{localStorage.setItem(x,JSON.stringify({tuned:I,timings:Y.timings,tuneId:T,date:new Date(j).toISOString()}))}catch{}}}catch(x){if(x?.code==="WEBMT_NO_SAFE_REDUCTION")throw x;console.warn("autotune unavailable, falling back to auto routing:",x)}t?.("ready");const ee=u.adapterInfo,pe=ee.description||[ee.vendor,ee.architecture].filter(Boolean).join(" ")||"GPU",Me=to(),oe=Ms(ee,pe,Me),K=[oe!==pe?pe:null,ee.subgroupMinSize&&ee.subgroupMaxSize?`subgroup ${ee.subgroupMinSize}–${ee.subgroupMaxSize}`:null,navigator.deviceMemory?`RAM ${navigator.deviceMemory>=32?"≥":"~"}${navigator.deviceMemory}GB`:null,navigator.hardwareConcurrency?`~${navigator.hardwareConcurrency} luồng CPU`:null].filter(Boolean).join(" · "),P=l==="f16"?2:4;async function Re(x,{onBatch:le,shouldStop:ue,pack:H=!1,resume:xe=null,tm:he=null,glossary:Ae=null,scheduleTuneMode:X=S,decodeScheduleOverride:Y=null,onScheduleTune:Ne=null}={}){const q=Ii(Y)??{...w},E=performance.now(),A=Dn(x);x=A.text;const F=Yr(x);let O=F.sentences,te=F.paras;if(H){const D=gs(O,te);O=D.rows,te=D.rowParas}if(O.length===0)return{text:"",cancelled:!1,stats:{sentences:0,tokens:0,ms:0,tokPerSec:0}};const Q=Array.isArray(xe)&&xe.length===O.length,W=Q?[...xe]:new Array(O.length).fill(""),be=Q?W.reduce((D,se)=>D+(se?1:0),0):0;let ye=0,Ke=0;if(H&&he?.get){const D=performance.now();try{const se=await he.get(O);for(let ie=0;ieW[se]?null:Ae.protect(D)):null,Ie=ae?ae.filter(Boolean).length:0,tt=[],nt=(H?Ui(O.map(D=>D.length)):O.map((D,se)=>se)).filter(D=>!W[D]),kt=H?V.absCap:Br(),Xt=Math.min(192,kt),zo=H?V.tokenBudget:Vi(),Ct=nt.map(D=>O[D].length),Mt=H?yo(Ct,u,P,Xt,kt,zo,V.policyForS):{ranges:qi(Ct,u,P,Xt,Xt),buckets:[]},{ranges:_e}=Mt,Yt=D=>{const[se,ie]=_e[D],de=nt.slice(se,ie),$e=H?Mt.buckets[D]:null;return{start:se,end:ie,idx:de,plannedS:$e,sources:de.map(Te=>ae?.[Te]?.text??O[Te]),initialKvCapacity:H?V.kvCapacityForS($e):V.forcedCapacity}},Yn=async(D,se,{primeNext:ie=!1,safetyOptions:de=null}={})=>{if(p)throw new Error(`GPU device lost (${p.reason}): ${p.message}`);const $e=Yt(D),Te=de?de.submitBudgetMs:me,U=de?de.encSplitSubmits:Ee;da();const rn=performance.now(),{rows:Rt,metrics:st}=await ia({...u,dtype:l},k,f,$e.sources,{...ca(I,$e.end-$e.start),immediates:L,uniformPool:G,...se,...Te!==void 0?{submitBudgetMs:Te}:{},encSplitSubmits:U,inPlaceCompact:H&&we,kvCapacity:$e.initialKvCapacity,...H?{maxNewTokens:Bn}:{},onPrimed:ie&&D+1<_e.length?()=>{const It=Yt(D+1);It.idx.every(it=>W[it])||hr(f,It.sources).catch(()=>{})}:null}),Bt=performance.now();return{plan:$e,rows:Rt,metrics:st,wallMs:Bt-rn,endedAt:Bt,arenaStats:la()}};let xt=0,At=0,Nt=0,Tt=!1;const Ve={timingMode:"overlapping-gpu-windows",gpuWindowsOverlap:!0,prepMs:0,tmMs:Ke,scheduleTuneMs:0,tokenizeMs:0,encoderMs:0,decodeMs:0,detokMs:0,gapMs:0},rt=[],Zn=performance.now();Ve.prepMs=Zn-E-Ke;const je=Y===null&&H?Pr(X):"off",er=Zi(u.adapterInfo,{subgroupMinSize:u.subgroupMinSize,subgroupMaxSize:u.subgroupMaxSize}),Zt=Gt(k.weightsTag??e.weightsUrl,"dev"),Ho=[er,e.id,Zt,l].join("|").slice(0,512);let en=null;const tr=D=>{if(typeof Ne=="function")try{Ne({active:D,mode:je})}catch{}},Wo=typeof a=="function"?async D=>{tr(!0);try{return await a(D)}finally{tr(!1)}}:null,ne=await nc({enabled:je!=="off",amortizationPolicy:je==="auto"?"automatic":"bypass",configuredSchedule:q,eligibilityInput:{fileMode:H,pack:H,isMobile:V.mobile,uncachedRows:nt.length,plannedBatches:_e.length,kernelTuneSource:N,manualOverrides:{inflight:Y===null?m.get("inflight"):String(q.inFlight),groupsteps:Y===null?m.get("groupsteps"):String(q.groupSteps),submitbudget:m.get("submitbudget"),encsplit:m.get("encsplit")},memorySafe:H&&_e.length>0},buildWorkload:async()=>{const D=Ct.map(ie=>Math.max(1,Math.min(Sn,ie+1)));return en={batchCosts:_e.map(([ie,de],$e)=>{let Te=0;for(let U=ie;Ude-ie),plannedSourceBuckets:[...Mt.buckets],sourceTokenLengths:D,modelId:e.id,weightsId:Zt,dtype:l,policy:{pack:H,kvPlanner:V.policyLabel,tokenBudget:V.tokenBudget,immediates:z,uniformPool:G}}},en},adapterKey:er,modelId:e.id,weightsId:Zt,dtype:l,browserMajor:Pi(navigator.userAgent??""),kernelTuneId:T??"untrusted",modes:{pack:H,kvPlanner:V.policyLabel,kvPolicy:V.policyLabel,tokenBudget:V.tokenBudget,immediates:z,uniformPool:G,inPlaceCompact:H&&we,compact:!0,parameterMode:z},scopeKey:Ho,kernelReferenceMs:Number(_?.b64?.def?.medianUs)/1e3,safetyOptions:{submitBudgetMs:me===void 0?1e3:me,encSplitSubmits:Ee},storage:je!=="off"?d??=zt("local"):d,runner:Wo,pretokenize:async D=>{const se=Yt(D);await hr(f,se.sources)},estimateBatch:async D=>en.batchCosts[D],runBatch:async(D,se,ie)=>{const de=await Yn(D,se,{safetyOptions:ie});return{rows:de.rows,groupStepsStart:de.metrics.groupStepsStart,groupStepsFinal:de.metrics.groupStepsFinal,submitShrinks:de.metrics.submitShrinks,wallMs:de.wallMs,decodeMs:de.metrics.decodeMs,compactions:de.metrics.compactions,cleanupComplete:!0}},isCancelled:()=>ue?.()===!0,isDeviceHealthy:()=>!p,clock:()=>performance.now()});Ve.scheduleTuneMs=ne.telemetry.scheduleTuneMs;const nr={...ne.selectedSchedule},ot=je==="apply"||je==="auto"?{...nr}:{...q};ne.telemetry.mode=je,ne.telemetry.requestedSchedule={...q},ne.telemetry.predictedSchedule={...nr},ne.telemetry.configuredSchedule={...ot};const Ko=je==="auto"&&["admitted","cache-hit"].includes(ne.telemetry.amortization?.status);ne.telemetry.canonicalUsesTunerVerdict=ne.telemetry.eligible&&(je==="apply"||Ko);let Xe={...ot},at=Xe.groupSteps;ne.telemetry.effectiveSchedule={...Xe};const rr=[];let or=0,tn=0;const ar=new Set(ne.driftBatchIndices);let nn=performance.now();for(let D=0;D<_e.length;D++){if(ue?.()){Tt=!0;break}const se=performance.now();Ve.gapMs+=se-nn;const ie={inFlight:Xe.inFlight,groupSteps:Math.min(Xe.groupSteps,at)},de=await Yn(D,ie,{primeNext:!0}),{plan:$e,rows:Te,metrics:U,endedAt:rn,arenaStats:Rt}=de,{idx:st,plannedS:Bt}=$e;Ve.tokenizeMs+=U.tokenizeMs,Ve.encoderMs+=U.encoderMs,Ve.decodeMs+=U.decodeMs,Ve.detokMs+=U.detokMs,U.groupStepsFinal&&(at=Math.min(at,U.groupStepsFinal)),nn=rn;const It=nn-se;rt.push({B:U.B,S:U.S,cap:U.cap,steps:U.steps,submits:U.submits,compactions:U.compactions,compactMode:U.compactMode,inFlight:ie.inFlight,configuredInFlight:ot.inFlight,configuredGroupSteps:ot.groupSteps,groupSteps:U.groupStepsStart,awaitMs:Be(U.awaitMs),cpuEncodeMs:Be(U.cpuEncodeMs),groupStepsFinal:U.groupStepsFinal,submitShrinks:U.submitShrinks,maxGroupAwaitMs:Be(U.maxGroupAwaitMs),plannedS:Bt,initialKvCapacity:U.initialKvCapacity,finalKvCapacity:U.finalKvCapacity,kvGrows:U.kvGrows,kvGrowsWithPending:U.kvGrowsWithPending,kvCapacitySequence:U.kvCapacitySequence,kvGrowBindGroupsPurged:U.kvGrowBindGroupsPurged,sourceTokenArea:U.B*U.S,tokens:U.tokensGenerated,ms:Be(It),encoderMs:Be(U.encoderMs),decodeMs:Be(U.decodeMs),logicalArenaPeakMB:Be(Rt.highWaterBytes/1048576),submittedArenaPeakMB:Be(Rt.submittedHighWaterBytes/1048576)});let it=null;if(ne.telemetry.enabled&&ne.telemetry.eligible&&!ne.telemetry.invalidatedReason&&U.submitShrinks>0)it="submit-shrink";else if(ne.cacheHit&&!ne.telemetry.invalidatedReason&&ne.cachedObservedShape&&ar.has(D)){for(const Oe of Te)rr.push(Math.max(1,(Oe.ids?.length??1)-1));if(U.compactions>0&&or++,tn++,tn===ar.size){const Oe=tc(rr,or,tn);ne.telemetry.canonicalObservedShape=Oe,ho(ne.cachedObservedShape,Oe)&&(it="shape-drift")}}it&&(ne.invalidate(it),Xe={...Le},at=Math.min(at,Le.groupSteps)),ne.telemetry.effectiveSchedule={inFlight:Xe.inFlight,groupSteps:Math.min(Xe.groupSteps,at)};const cr=new Set;if(Te.forEach((Oe,on)=>{const qe=st[on];let an=Oe.text.normalize("NFC");const lr=ae?.[qe];if(lr){const ur=Ae.restore(an,lr.marks);an=ur.text,ur.ok||(tt.push(qe),cr.add(qe))}W[qe]=an,Oe.forcedEos&&At++}),Nt+=Te.length,xt+=U.tokensGenerated,H&&he?.put){const Oe=[];if(Te.forEach((on,qe)=>{!on.forcedEos&&!cr.has(st[qe])&&Oe.push([O[st[qe]],W[st[qe]]])}),Oe.length)try{he.put(Oe)}catch{}}le?.(D+1,_e.length,W)}const Pt=performance.now()-Zn;At>0&&console.warn(`translateText: ${At}/${O.length} rows hit the token cap (tail may be cut)`);const{profiledMs:sr,profiledDecodeMs:ir,sBuckets:Vo}=Xi(rt,Pt),qo=rt.reduce((D,se)=>D+(se.submitShrinks??0),0);return ne.recordBaselineObservation({complete:!Tt&&Nt===nt.length&&rt.length===_e.length,cancelled:Tt,deviceHealthy:!p,configuredSchedule:ot,effectiveSchedule:ne.telemetry.effectiveSchedule,profiledWallMs:sr,profiledDecodeMs:ir,rowCount:Nt,batchCount:rt.length,tokenCount:xt,submitShrinks:qo}),{text:bs(te,W),rowTexts:W,cancelled:Tt,stats:{sentences:O.length,tokens:xt,ms:Pt,forcedEos:At,t2s:A.changed,glossaryRows:Ie,glossaryFailed:tt,batches:_e.length,stages:Ve,resumeHits:be,tmHits:ye,decodedRows:Nt,batchStats:rt,decodeSchedule:{...ot},requestedDecodeSchedule:{...q},effectiveDecodeSchedule:{...ne.telemetry.effectiveSchedule},scheduleAutotune:ne.telemetry,profiledMs:sr,profiledDecodeMs:ir,sBuckets:Vo,tokPerSec:Pt>0?xt/Pt*1e3:0}}}return{info:{gpuName:oe,gpuTitle:K,dtype:l,lmHeadQ8:l==="f16",lmShortN:J?.length??0,directQ8:k.q8Stats.directTensors>0,immediates:z,uniformPool:G?"b64":"off",inPlaceCompact:we?"explicit":"off",decodeSchedule:{...w},scheduleTuneMode:S,scheduleDefault:{source:h.source,reason:h.reason,revision:h.revision,rolloutBps:h.rolloutBps},kvPolicy:V.policyLabel,kvPlannerOverride:m.get("kvplanner"),kvCapacityOverride:m.get("kvcap"),q8Stats:k.q8Stats,tunedFrom:N,modelId:e.id,modelName:e.name,weightsTag:k.weightsTag??"dev",tokRev:e.tokRev??null,bench:{adapterInfo:{...u.adapterInfo},subgroupMinSize:u.subgroupMinSize,subgroupMaxSize:u.subgroupMaxSize,hasF16:u.hasF16,limits:{...u.limits},kernelRev:Kr,safety:B?{...B.verdicts,forceSg:B.forceSg}:null,tuned:I,tunedFrom:N,timings:_,protocolRev:ra,tuneId:T,measuredAt:j,cacheCheck:$,flags:y,gpuName:oe,gpuWebgl:Me?.renderer??null,webglSameGpu:!!(Me&&eo(ee.vendor,Me.vendor,Me.renderer)),adapterLimits:{...u.adapterLimits},features:[...u.features??[]],wgslFeatures:(()=>{try{return[...navigator.gpu?.wgslLanguageFeatures??[]]}catch{return[]}})()}},translateText:Re,isLost:()=>p,destroy:()=>{try{k.buffer.destroy()}catch{}try{u.device.destroy()}catch{}}}}const oc=["auto","utf-8","gb18030","big5","utf-16le","utf-16be"],ac=new Set("的一是不了人我在有他这为之大来以个中上们到说国和地也子时道出而要于就下得可你年生自会那后能对着事其里所去行过家十用发天如然作方成者多日都三小军二无同么经法当起与好看学进种将还分此心前面又定见只主没公从知世什两次使身被高已亲话常活正感明问力理尔点文几本特做外孩相西果走月实向声车全信重机工物气每并别真打太新比才便夫再书部水像眼等体却加电主界门利海受听表德少克代员许先口由死安写性马光白或住难望教命花结乐色更拉东神记处让母父应直字场平报友关放至张认接���入笑内英军候民岁往何度山觉路带万男边风解叫任金快原吃妈变通师立象数四失满战远格士音轻目条呢病始达深完今提求清王化空业思切怎非找片罗钱吗语元喜曾离飞科言干流欢约各即指合反题必该论交终林请医晚制球决传画保读运及则房早院量苦火布品近坐产答星精视五连司巴這為來個們說國時過還進裡著見兩麼開關門問間東車書興學實現點戰處條讓報馬場話認遠飛樂氣師難聽當義務長員島洋歐陽於億敵獨隊淚類燈爾談請諸講謝證識護賽選遺醫錢鐵閒陳陰險陸雙雞離電靈頭頗題顧風餘體高鬥魚鳥龍發夢舊聲應轉醒覺對藥雲會後".split("")).add(",").add("。").add("、"),gn=(e,...t)=>t.every((n,r)=>e[r]===n);function $r(e){let t=0,n=0,r=0;for(const a of e){const o=a.codePointAt(0);if(o===65533){r++;continue}(o>=19968&&o<=40959||o>=12288&&o<=12351||o>=65280&&o<=65374)&&(t++,ac.has(a)&&n++)}return t+r===0?-1:(n-4*r)/(t+r)}function sc(e){if(e.length>=3&&gn(e,239,187,191))return"utf-8";if(e.length>=2&&gn(e,255,254))return"utf-16le";if(e.length>=2&&gn(e,254,255))return"utf-16be";try{return new TextDecoder("utf-8",{fatal:!0}).decode(e),"utf-8"}catch{}const t=e.subarray(0,65536),n=new TextDecoder("gb18030").decode(t),r=new TextDecoder("big5").decode(t),a=$r(n),o=$r(r);return o>a*1.05&&o>0?"big5":"gb18030"}function vo(e,t="auto"){const n=t==="auto"?sc(e):t;return{text:new TextDecoder(n).decode(e),encoding:n}}const ic=["QX7","KX7","RX7","ZX9","ZQ1","VX1"];function cc(e){let t=2166136261;for(let n=0;n>>0).toString(16).padStart(8,"0")}function lc(e){const t=(e??[]).filter(n=>n?.enabled!==!1&&n?.zh&&n?.vi).map(n=>({zh:Dn(n.zh).text,vi:n.vi})).filter((n,r,a)=>a.findIndex(o=>o.zh===n.zh)===r).sort((n,r)=>r.zh.length-n.zh.length);return t.length?{terms:t}:null}function So(e,t){const n=[];for(const r of t.terms){let a=0;for(;(a=e.indexOf(r.zh,a))!==-1;){const o=a+r.zh.length;n.some(s=>as.start)||n.push({start:a,end:o,term:r}),a=o}}return n.sort((r,a)=>r.start-a.start)}function uc(e,t){if(!t)return null;const n=So(e,t);if(!n.length)return null;const r=ic.filter(i=>!e.includes(i)),a=new Map,o=[];for(const i of n){let u=a.get(i.term.zh);if(!u){if(!r.length)continue;u={marker:r.shift(),vi:i.term.vi,count:0},a.set(i.term.zh,u)}u.count++,o.push({start:i.start,end:i.end,marker:u.marker})}if(!o.length)return null;let s=e;for(let i=o.length-1;i>=0;i--){const u=o[i];s=s.slice(0,u.start)+u.marker+s.slice(u.end)}return{text:s,marks:[...a.values()]}}function dc(e,t){let n=!0,r=e;for(const a of t){const o=r.split(a.marker).length-1;o!==a.count&&(n=!1),o&&(r=r.split(a.marker).join(a.vi))}return{text:r,ok:n}}function hc(e,t){if(!t)return null;const n=So(e,t);if(!n.length)return null;const r=[...new Set(n.map(a=>`${a.term.zh}${a.term.vi}`))].sort();return cc(r.join(""))}const Lr="moxhi.glossary",fc="file không đúng định dạng";function Or(e){return e?.version!==1||!Array.isArray(e.terms)?null:e.terms.filter(t=>t&&typeof t.zh=="string"&&typeof t.vi=="string").map(t=>({zh:t.zh.trim(),vi:t.vi.trim(),enabled:t.enabled!==!1})).filter(t=>t.zh&&t.vi)}function mc({storage:e=zt("local")}={}){let t;try{t=Or(JSON.parse(e.getItem(Lr)??"null"))??[]}catch{t=[]}const n=new Set;function r(){e.setItem(Lr,JSON.stringify({version:1,terms:t}));for(const o of n)o()}function a({zh:o,vi:s}){if(o=String(o??"").trim(),s=String(s??"").trim(),!o||!s)return!1;const i=t.find(u=>u.zh===o);return i?(i.vi=s,i.enabled=!0):t.push({zh:o,vi:s,enabled:!0}),r(),!0}return{list:()=>t.map(o=>({...o})),count:()=>t.filter(o=>o.enabled).length,add:a,update(o,s){const i=t.find(u=>u.zh===o);i&&(typeof s?.vi=="string"&&s.vi.trim()&&(i.vi=s.vi.trim()),typeof s?.enabled=="boolean"&&(i.enabled=s.enabled),r())},remove(o){const s=t.length;t=t.filter(i=>i.zh!==o),t.length!==s&&r()},importJson(o){let s;try{s=Or(JSON.parse(o))}catch{s=null}if(!s)throw new Error(fc);let i=0,u=0;for(const l of s){const p=t.find(f=>f.zh===l.zh);p?(p.vi=l.vi,p.enabled=l.enabled,u++):(t.push(l),i++)}return r(),{added:i,updated:u}},exportJson:()=>JSON.stringify({version:1,terms:t},null,2),subscribe(o){return n.add(o),()=>n.delete(o)}}}function pc({assetBase:e="/model-d8",loadEngine:t=()=>In(()=>import("./index-DOgWbOaH.js"),[])}={}){let n=null,r=null;return{id:"lert-small-d8",label:"LERT small D8",downloadMB:28.8,async load({onProgress:a}={}){n||(r??=(async()=>{const{createD8Ner:o}=await t();try{n=await o({assetBase:e,onProgress:a})}catch(s){if(r=null,/shader-f16/i.test(String(s?.message??s))){const i=new Error("GPU này không có shader-f16 — không chạy được mô hình phân tích.");throw i.code="unsupported",i}throw s}})(),await r)},async run(a,{onProgress:o,signal:s}={}){if(!n)throw new Error("provider chưa load()");const i=await n.analyze(a,{signal:s,onProgress:o}),u=[];return i.forEach((l,p)=>{for(const f of l.entities)u.push({text:f.text,type:f.type,row:p,start:f.startCodepoint,end:f.endCodepoint,confidence:f.confidence})}),{entities:u}},release(){try{n?.releaseWorkspaces()}catch{}try{n?.destroy()}catch{}n=null,r=null}}}function gc(e){const t=new Map;for(const n of e){const r=`${n.text}\0${n.type}`,a=t.get(r);a?(a.count+=1,(n.rowr.count-n.count||n.text.localeCompare(r.text,"zh"))}function bc(e){const t={all:e.length,Nh:0,Ns:0,Ni:0};for(const n of e)n.type in t&&(t[n.type]+=1);return t}let Fr=null;function _r(){return Fr??=In(()=>import("./hanviet_data-DivPLpiI.js"),[]).then(e=>e.default),Fr}function Dr(e,t){return Array.from(e??"").map(n=>{const r=t[n];return r?r.charAt(0).toLocaleUpperCase("vi")+r.slice(1):n}).join(" ").replace(/\s+/g," ").trim()}let Gr=null;function Ur(){return Gr??=In(()=>import("./names_data-nngCF4q7.js"),[]).then(e=>e.default),Gr}function jr(e,t){const n=String(e??"");return t.latin[n]??t.latin[Dn(n).text]??null}function yc(e,t){const n=Array.from(String(e??""));return n.length<3?!1:n.every(r=>t.translit.includes(r))}const gt={Nh:"Người",Ns:"Địa danh",Ni:"Tổ chức"},wo={Nh:re.person,Ns:re.pin,Ni:re.flag},Ot=200;function vc(e){const t=document.createElement("span");return t.className="enttypeicon",t.innerHTML=wo[e]??"",t.title=gt[e]??e,t.setAttribute("role","img"),t.setAttribute("aria-label",gt[e]??e),t}function Sc({provider:e,glossaryStore:t,jobs:n,getRows:r,hasText:a,getFp:o=()=>"",onChange:s=()=>{}}={}){let i=null,u=null,l=[],p=null,f=null,m=Ot,d=null,v="",y=null,g=null,h=null,S=null,M=null;const C=k=>`${k.text}\0${k.type}`,L=()=>!!n.current();function z(k){const B=document.createElement("p");return B.className="hint",B.textContent=k,B}function G(k){if(h){if(!k||k.kind!=="analyze"){h.hidden=!0;return}h.hidden=!1,h.firstChild.textContent=k.phase==="tải mô hình"?`Tải mô hình ${(k.done/1048576).toFixed(1)}/${(k.total/1048576).toFixed(1)} MB…`:`Phân tích ${k.done}/${k.total} câu…`}}function fe(){u&&p!==o()&&(u=null,l=[],p=null,d=null,f=null,v="Văn bản đã đổi — bấm Quét tên để cập nhật.")}async function me(){const k=r();if(!k.length)return v="Chưa có văn bản để quét.",J(),"empty";v="";const B=o(),_=Promise.all([_r(),Ur()]).then(([T,j])=>{y=T,g=j}).catch(()=>{}),I=n.run({kind:"analyze",label:"Quét thực thể",total:k.length,exec:async T=>{await e.load({onProgress:$=>{$.stage==="weights"&&T.progress({phase:"tải mô hình",done:$.loaded??0,total:$.total??0})}}),T.progress({phase:"phân tích",done:0,total:k.length});const j=await e.run(k,{signal:T.signal,onProgress:$=>{$.stage==="analysis"&&T.progress({done:$.completedRows,total:$.totalRows})}});u=gc(j.entities),l=k,f=null,m=Ot,d=null}});J();let N="ok";try{await I==="refused"&&(v="Đang bận việc khác — chờ xong rồi quét.",N="refused")}catch(T){T?.name==="AbortError"?(v="Đã hủy quét.",N="cancelled"):(v=T?.code==="unsupported"?T.message:`Quét lỗi: ${T?.message??T}`,N="error")}return N==="ok"&&(p=B),await _,J(),s(),N}function we(){const k=bc(u),B=document.createElement("div");B.className="entfilter";for(const[_,I,N]of[[null,"Tất cả",k.all],["Nh",gt.Nh,k.Nh],["Ns",gt.Ns,k.Ns],["Ni",gt.Ni,k.Ni]]){const T=document.createElement("button");T.type="button",T.className=f===_?"ghost on":"ghost",_&&(T.innerHTML=wo[_]),T.append(`${I} ${N}`),T.addEventListener("click",()=>{f=_,m=Ot,J()}),B.append(T)}return B}function w(k){const B=Array.from(l[k.firstRow]??""),_=document.createElement("p");_.className="entexample";const I=document.createElement("mark");return I.textContent=B.slice(k.firstStart,k.firstEnd).join(""),_.append(B.slice(0,k.firstStart).join(""),I,B.slice(k.firstEnd).join("")),_}function V(k){const B=document.createElement("form");B.className="entadd";const _=document.createElement("input"),I=g?jr(k.text,g):null;_.value=I??(y?Dr(k.text,y):""),_.setAttribute("aria-label","Dịch thành");const N=document.createElement("button");if(N.type="submit",N.className="ghost",N.textContent="Lưu",B.append(_,N),!I&&g&&yc(k.text,g)){const T=document.createElement("p");T.className="hint",T.textContent="Có vẻ là tên phiên âm phương Tây — thường giữ dạng Latin thay vì Hán-Việt.",B.append(T)}return B.addEventListener("submit",T=>{T.preventDefault(),t.add({zh:k.text,vi:_.value})?(v=`đã thêm ${k.text} → ${_.value.trim()}`,d=null):(v="Cần nhập nghĩa tiếng Việt.",J())}),B}function ge(k,B,_){const I=C(k),N=document.createElement("tr"),T=document.createElement("td");T.className="entzh",T.append(vc(k.type),k.text);const j=document.createElement("td");j.className="enthv",j.textContent=y?Dr(k.text,y):"";const $=document.createElement("td");$.className="entvi";const ee=_.get(k.text),pe=!ee&&g?jr(k.text,g):null;ee!=null?($.textContent=ee,$.title="Theo từ điển tên riêng"):pe?($.textContent=pe,$.classList.add("entguess"),$.title="Gợi ý tên Tây/Nhật — bấm Thêm để sửa và lưu"):($.textContent="—",$.classList.add("entnone"),$.title="Chưa thêm — form Thêm sẽ điền sẵn âm Hán-Việt");const Me=document.createElement("td");Me.className="num entn",Me.textContent=`×${k.count}`;const oe=document.createElement("td");if(oe.className="num entact",B)oe.classList.add("entdone"),oe.textContent="✓",oe.title="Đã có trong từ điển — sửa bên panel Từ điển tên riêng";else{const P=document.createElement("button");P.type="button",P.className="ghost",P.textContent="Thêm",P.addEventListener("click",async Re=>{Re.stopPropagation(),[y,g]=await Promise.all([_r(),Ur()]),d={key:I,add:!0},J(),i?.querySelector(".entadd input")?.focus()}),oe.append(P)}N.append(T,j,$,Me,oe),N.addEventListener("click",()=>{d=d?.key===I?null:{key:I,add:!1},J()});const K=[N];if(d?.key===I){const P=document.createElement("tr");P.className="entdetail";const Re=document.createElement("td");Re.colSpan=5,Re.append(w(k)),d.add&&!B&&Re.append(V(k)),P.append(Re),P.addEventListener("click",x=>x.stopPropagation()),K.push(P)}return K}function Ee(k){const B=document.createElement("table");B.className="tmtable enttable";const _=document.createElement("thead"),I=document.createElement("tr");for(const[j,$,ee]of[["Tên",""],["Hán-Việt",""],["Dịch thành",""],["×","num","Số lần xuất hiện"],["","num"]]){const pe=document.createElement("th");pe.className=$,pe.textContent=j,ee&&(pe.title=ee),I.append(pe)}_.append(I);const N=document.createElement("tbody"),T=new Map(t.list().map(j=>[j.zh,j.vi]));return N.append(...k.slice(0,m).flatMap(j=>ge(j,T.has(j.text),T))),B.append(_,N),B}function J(){if(!i)return;const k=[],B=document.createElement("button");if(B.type="button",B.className="ghost",B.textContent=u===null?"Quét văn bản":"Quét lại",B.disabled=L()||!a(),B.addEventListener("click",me),u===null){k.push(z("Tìm tên người, địa danh, tổ chức trong văn bản rồi thêm vào từ điển. Mô hình ~29 MB, tải một lần."));const I=document.createElement("div");I.className="enttools",I.append(B),k.push(I)}else{const I=document.createElement("div");I.className="enthead",I.append(z(`${u.length} tên riêng trong ${l.length} câu.`),B),k.push(I)}h=document.createElement("p"),h.className="entprog",h.append(document.createTextNode(""));const _=document.createElement("button");if(_.type="button",_.className="ghost",_.textContent="Hủy",_.addEventListener("click",()=>n.cancel()),h.append(_),G(n.current()),k.push(h),!a()&&u===null&&k.push(z("Chưa có văn bản — dán hoặc mở file trước.")),u?.length){k.push(we());const I=f?u.filter(N=>N.type===f):u;if(k.push(Ee(I)),I.length>m){const N=document.createElement("button");N.type="button",N.className="ghost entmore",N.textContent=`Hiện thêm (còn ${I.length-m})`,N.addEventListener("click",()=>{m+=Ot,J()}),k.push(N)}}else u&&k.push(z("Không tìm thấy tên riêng nào."));v&&k.push(z(v)),i.replaceChildren(...k)}return{id:"entity",title:"Nhân vật & địa danh",icon:re.pin,prefers:"full",badge:()=>(fe(),u&&u.length||null),scan:me,mount(k){i=k,S=n.subscribe(G),M=t.subscribe(()=>{J(),s()}),fe(),J()},update(){fe(),J()},destroy(){n.current()?.kind==="analyze"&&n.cancel(),S?.(),S=null,M?.(),M=null,e.release(),i=null,h=null}}}const wc=3;function Eo(e){return(e.flags?.length??0)>0?"flags":e.schedule!==void 0&&e.schedule!==null?"schedule-autotune":((e.tmHits??0)+(e.resumeHits??0))/Math.max(1,e.sentences??0)>.05?"tm-reuse":e.decodedRows!==void 0&&e.decodedRows!==null&&e.decodedRows<30?"few-rows":e.mode==="file"||(e.sentences??0)>=30?null:"small"}const Ec={gpuWebgl:512,gpuName:256,model:128,platformVersion:64,cpuArch:32,browserFull:128};[...Object.keys(Ec)];const kc=e=>[...e].map(t=>t.toString(16).padStart(2,"0")).join("");async function Cc(e){if(!e.persistent)return null;let t=e.getItem(fr);return t||(t=kc(crypto.getRandomValues(new Uint8Array(16))),e.setItem(fr,t)),ha(t)}function ko(e=navigator){return e.userAgentData?.platform||e.platform||""}const Fe=(e,t=1)=>typeof e=="number"&&Number.isFinite(e)?Math.round(e*10**t)/10**t:null;function Mc(e){if(!e||typeof e!="object")return null;const t=Array.isArray(e.plannedSourceBucketHistogram)?e.plannedSourceBucketHistogram:[];return{rowCountBand:e.rowCountBand,batchCountBand:e.batchCountBand,sourceBucketHistogram:Object.fromEntries(t),batchSizeQuantiles:[...e.batchSizeQuantiles??[]],sourceTokenQuantiles:[...e.sourceTokenQuantiles??[]]}}function xc(e){return!e||typeof e!="object"?null:{amortizationRev:e.revision,amortizationStatus:e.status,amortizationAdmitted:e.admit??null,observationCacheState:e.observationCacheState,observationAgeMs:Fe(e.observationAgeMs),observationWrite:e.write??null,observedProfiledWallMs:Fe(e.observedProfiledWallMs),minimumExpectedSavingMs:Fe(e.minimumExpectedSavingMs),projectedWorstCaseScreenMs:Fe(e.projectedWorstCaseScreenMs),paybackRatio:Fe(e.paybackRatio,6)}}function Ac(e){const t=e?.scheduleAutotune;if(!t||!["shadow","apply","auto"].includes(t.mode))return null;const n=t.requestedSchedule??e.requestedDecodeSchedule,r=t.predictedSchedule??t.selectedSchedule,a=e.decodeSchedule??t.configuredSchedule,o=e.effectiveDecodeSchedule??t.effectiveSchedule,s=(e.batchStats??[]).reduce((m,d)=>m+(Number.isInteger(d?.submitShrinks)?d.submitShrinks:0),0),i=t.screenSubmitShrinks??0,u=t.invalidatedReason??(i>0?"submit-shrink":null)??(["promoted","selected"].includes(t.reason)?null:t.reason??null),l=xc(t.amortization),p=Fe(t.screenGain,6),f=Fe(t.confirmationMinGain,6);return{mode:t.mode,protocolRev:t.protocolRev,requested:{...n},predicted:{...r},configured:{...a},effective:{...o},source:t.source,cacheState:t.cache?.status??"not-checked",cacheWrite:t.cache?.write??null,scheduleTuneMs:Fe(t.scheduleTuneMs??e.stages?.scheduleTuneMs??0),selectedGain:Fe(t.selectedGain,6),...p!==null?{screenGain:p}:{},...f!==null?{confirmationMinGain:f}:{},sampleCount:t.sampleCount??0,confirmationCount:t.confirmationCount??0,projectedMs:Fe(t.evidence?.projectedMs??t.projection?.postPilot?.projectedMs??t.projection?.preGate?.projectedMs),overrunMs:Fe(t.deadline?.overrunMs??t.evidence?.overrunMs),screenSubmitShrinks:i,canonicalSubmitShrinks:s,fallbackReason:u,...l??{},workload:Mc(t.workload)}}function Co({info:e,stats:t,mode:n,srcChars:r,build:a,pseudo:o,ua:s,platform:i,extras:u=null}){const l=e.bench,p=Ac(t);return{v:wc,id:crypto.randomUUID(),ts:Date.now(),pseudo:o,run:{build:a,model:e.modelId,dtype:e.dtype,t2s:!!t.t2s,mode:n,srcChars:r,sentences:t.sentences,ms:Math.round(t.ms),tokPerSec:Math.round(t.tokPerSec*10)/10,outputTokens:t.tokens??null,decodedRows:t.decodedRows??null,batches:t.batches??null,tmHits:t.tmHits??null,resumeHits:t.resumeHits??null,forcedEos:t.forcedEos??null,stages:t.stages?Object.fromEntries(Object.entries(t.stages).map(([f,m])=>[f,typeof m=="number"?Math.round(m):m])):null,sBuckets:t.sBuckets??null,flags:[...l.flags??[]],weightsTag:e.weightsTag??null,...p?{schedule:p}:{}},device:{...l.adapterInfo,subgroupMin:l.subgroupMinSize,subgroupMax:l.subgroupMaxSize,fp16:l.hasF16,immediates:e.immediates,uniformPool:e.uniformPool,browserMajor:Hn(s),platform:i,limits:{...l.limits},gpuName:l.gpuName??null,gpuWebgl:l.gpuWebgl??null,webglSameGpu:l.webglSameGpu??null,adapterLimits:l.adapterLimits?{...l.adapterLimits}:null,features:l.features?[...l.features]:null,wgslFeatures:l.wgslFeatures?[...l.wgslFeatures]:null,...u??{}},autotune:{kernelRev:l.kernelRev,cacheState:l.tunedFrom,tuned:l.tuned,probeTimings:l.timings,safety:l.safety,protocolRev:l.protocolRev??null,tuneId:l.tuneId??null,measuredAt:l.measuredAt??null,cacheCheck:l.cacheCheck??null}}}function Nc({base:e,reason:t,phase:n,deviceLostReason:r=null,attachedSegment:a=null,comment:o=null,crumb:s=null}){return{...e,reason:t,phase:n,deviceLostReason:r,attachedSegment:a,comment:o,...s?{crumb:s}:{}}}let bn=null;const Pn="moxhi.deviceLost";async function Mo(e=navigator,t=null){if(!bn){let o={};try{o=await e.userAgentData?.getHighEntropyValues?.(["model","platformVersion","architecture","bitness","fullVersionList"])??{}}catch{o={}}const s=(o.fullVersionList??[]).find(i=>!/Not.A.Brand/i.test(i.brand));bn={model:o.model||null,platformVersion:o.platformVersion||null,cpuArch:o.architecture?`${o.architecture}${o.bitness?`-${o.bitness}`:""}`:null,browserFull:s?`${s.brand} ${s.version}`:null,deviceMemory:e.deviceMemory??null,cpuThreads:e.hardwareConcurrency??null}}let n=null,r=null;try{const o=await e.getBattery?.();n=o?.charging??null,r=o?.level??null}catch{}let a=null;if(t){const o=Math.floor(Number(t.getItem(Pn)??0));a=Number.isFinite(o)&&o>=0?o:0}return{...bn,charging:n,batteryLevel:r,deviceLostCount:a}}async function xo(e,t){const n=await fetch(fa()+e,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)});if(!n.ok)throw new Error(`HTTP ${n.status}`);return n.json()}const Tc=20*1024*1024,Pc=600,Rc=900,Ao="moxhi.autotranslate",Kn="moxhi.model",ve=zt("local"),Vn=mc({}),yn={auto:"Tự động","utf-8":"UTF-8",gb18030:"GB18030 / GBK",big5:"Big5","utf-16le":"UTF-16 LE","utf-16be":"UTF-16 BE"},Bc=matchMedia("(prefers-reduced-motion: reduce)").matches,c=Sa(document.querySelector("#app"));qa(c.goBtn);const Ic=new URLSearchParams(location.search).get("profilestats")==="1",b={engine:null,doc:null,stashedTyped:null,srcWindow:0,outWindow:1/0,outRows:[],fileResultText:null,fileProfileText:null,filePartial:null,lastRun:null,pseudo:void 0};let ze=null;async function No(){if(!(ze&&!ze.released))try{ze=await navigator.wakeLock?.request("screen")??null,ze?.addEventListener("release",()=>{ze=null})}catch{ze=null}}function $c(){ze?.release().catch(()=>{}),ze=null}const He=za({onStart:No,onIdle:$c,onError:e=>console.error(e)});let zr=!1;He.subscribe(e=>{const t=!!e;t!==zr&&(zr=t,c.goBtn.classList.toggle("busy",t),c.chipBadge.classList.toggle("busy",t),c.goBtn.disabled=t,c.scanBtn.disabled=t,c.modelSelect.disabled=t)});let vn=!1;He.subscribe(e=>{e?.kind==="analyze"?(vn=!0,R(c.cancelBtn,!0),c.progress.textContent=e.phase==="tải mô hình"?`tải mô hình quét tên ${(e.done/1048576).toFixed(1)}/${(e.total/1048576).toFixed(1)} MB…`:`quét tên ${e.done}/${e.total} câu…`):!e&&vn&&(vn=!1,R(c.cancelBtn,!1),c.progress.textContent="")});document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&He.current()&&!ze&&No()});const R=(e,t=!0)=>{e.hidden=!t},qt=e=>(e/1048576).toFixed(1),Ft=e=>e<950?`${Math.round(e)}ms`:`${(e/1e3).toFixed(1)}s`;function ut(e,t,n=null){c.errMsg.textContent=e,R(c.errBanner),c.retryBtn.onclick=()=>{R(c.errBanner,!1),t()},R(c.reportErrBtn,!!n),c.reportErrBtn.onclick=n?()=>Ro(n):null}function To({title:e,summary:t,payload:n,attach:r=!1,comment:a=!1,send:o}){c.benchModalTitle.textContent=e,c.benchSummary.textContent=t,c.benchPrivacyHint.textContent=r?"Mặc định không gửi nội dung văn bản — chỉ gửi đoạn lỗi nếu bạn tick ô bên dưới.":"Không gửi nội dung văn bản — chỉ các thông số bên dưới.",R(c.benchAttachRow,r),c.benchAttachTgl.checked=!1,R(c.benchComment,a),c.benchComment.value="",c.benchStatus.textContent="",c.benchCancelBtn.textContent="Hủy";const s=()=>{const i=typeof n=="function"?n():n;return c.benchJson.textContent=JSON.stringify(i,null,2),i};s(),c.benchAttachTgl.onchange=s,c.benchSendBtn.disabled=!1,c.benchSendBtn.onclick=async()=>{c.benchSendBtn.disabled=!0,c.benchStatus.textContent="đang gửi…";try{await o(s(),i=>{i instanceof Node?c.benchStatus.replaceChildren(i):c.benchStatus.textContent=i}),c.benchCancelBtn.textContent="Đóng"}catch(i){c.benchStatus.textContent=navigator.onLine===!1?"đang offline — thử lại sau nhé":`gửi lỗi: ${i?.message??i}`,c.benchSendBtn.disabled=!1}},c.benchCancelBtn.onclick=()=>c.benchModal.close(),c.benchModal.showModal()}async function Po(){return b.pseudo===void 0&&(b.pseudo=await Cc(ve)),b.pseudo}function Lc(){const e=Math.floor(Number(ve.getItem(Pn)??0));ve.setItem(Pn,String((Number.isFinite(e)&&e>=0?e:0)+1))}function Oc(e){const t=Eo(e);if(t==="tm-reuse"){const n=(e.tmHits??0)+(e.resumeHits??0);return`Đã ghi nhận — cảm ơn bạn! Run này không xếp hạng: ${Math.round(n/Math.max(1,e.sentences??0)*100)}% câu lấy sẵn từ bộ nhớ dịch (${e.decodedRows??0} hàng dịch mới) nên tốc độ không phản ánh sức GPU.`}return t==="flags"?"Đã ghi nhận! Run chạy với cờ thử nghiệm trên URL nên không xếp hạng — data debug vẫn quý.":t==="schedule-autotune"?"Đã ghi nhận! Run autotune lịch giải mã hiện chỉ dùng để phân tích, chưa xếp hạng cho đến khi board có policy tách cold/warm rõ ràng.":t==="few-rows"||t==="small"?"Đã ghi nhận — cảm ơn bạn! Run nhỏ không xếp hạng (bảng cần ≥30 câu dịch mới), vẫn là data quý.":"Đã ghi nhận — cảm ơn bạn!"}function Fc(e=null){const t="95dca08";if(b.engine){const n=b.lastRun?.stats??{sentences:0,ms:0,tokPerSec:0,t2s:!1};return Co({info:b.engine.info,stats:n,mode:b.lastRun?.mode??"paste",srcChars:b.lastRun?.srcChars??0,build:t,pseudo:b.pseudo??null,ua:navigator.userAgent??"",platform:ko(),extras:e})}return{v:1,id:crypto.randomUUID(),ts:Date.now(),pseudo:b.pseudo??null,run:null,device:null,autotune:null}}async function Ro(e){await Po();const t=Fc(await Mo(navigator,ve));To({title:e.title??"Báo lỗi",summary:e.summary??"",attach:!!e.attach,comment:!0,payload:()=>Nc({base:t,reason:e.reason,phase:e.phase,deviceLostReason:e.deviceLostReason??null,attachedSegment:e.attach&&c.benchAttachTgl.checked?{src:c.src.value.slice(0,1e3),dst:_n(b.outRows).slice(0,1e3)}:null,comment:c.benchComment.value.trim()||null,crumb:e.crumb??null}),send:async(n,r)=>{await xo("/api/report",n),r("Đã ghi nhận — cảm ơn bạn!")}})}const qn="moxhi.lastfile";function _c(e){ve.setItem(qn,JSON.stringify(e))}function Bo(){try{return JSON.parse(ve.getItem(qn)??"null")}catch{return null}}function Dc(){ve.removeItem(qn)}const Jn="moxhi.crumb";function Hr(e){ve.setItem(Jn,JSON.stringify({...e,ts:Date.now(),build:"95dca08"}))}function Qn(){ve.removeItem(Jn)}async function Gc(){let e=null;try{e=JSON.parse(ve.getItem(Jn)??"null")}catch{}if(!e)return;Qn(),console.warn("[moxhi] phiên dịch trước dừng đột ngột (nghi hệ điều hành ngắt vì thiếu bộ nhớ):",e);const t=Bo(),n=!!t&&!t.complete&&(t.done??0)>0&&t.file===e.file;ut(`Phiên dịch file trước dừng đột ngột ở cụm ${e.done??0}/${e.rows??"?"} (batch ${e.batch??0}/${e.batches??"?"}) — thường do thiết bị cạn bộ nhớ.`+(n?' Phần đã dịch vẫn còn: mở lại đúng file đó rồi bấm "Dịch file" để dịch tiếp.':" Hãy dịch lại từ đầu."),()=>{},{reason:"oom",phase:"translate",title:"Báo lỗi văng phiên dịch",crumb:{batch:e.batch,batches:e.batches,done:e.done,rows:e.rows,build:e.build,model:e.model}})}addEventListener("pagehide",Qn);const Uc={gpu:"Gọi linh khí GPU…",weights:"Tải trọng số…",tokenizer:"Nạp từ điển…",autotune:"Đo mạch thiết bị (chỉ lần đầu)…"};async function dt(){R(c.gate,!1),R(c.studio,!1),R(c.loading,!0);const e=$n(ve.getItem(Kn)??Ln);c.modelSelect.value=e.id,c.modelSelect.disabled=!0,c.loadNote.innerHTML=`Lần đầu tải ~${e.downloadMB} MB trọng số (${e.name}) — các lần sau mở nhanh nhờ bộ nhớ đệm của trình duyệt.`;try{b.engine=await rc({model:e,scheduleDefaultEnabled:!0,onPhase:y=>{y!=="ready"&&(c.phaseLabel.textContent=Uc[y]??y,y==="tokenizer"&&(c.brushFill.style.width="100%",c.brushBar.setAttribute("aria-valuenow","100")))},onProgress:(y,g)=>{const h=g?Math.round(y/g*100):0;c.brushFill.style.width=`${h}%`,c.brushBar.setAttribute("aria-valuenow",String(h)),c.phaseLabel.textContent=`Tải trọng số — ${qt(y)} / ${qt(g)} MB (${h}%)`},onDeviceLost:y=>{Lc(),!He.current()&&ut(`GPU bị ngắt kết nối (${y.reason}): ${y.message||"không rõ nguyên nhân"}. Bấm thử lại để khởi động lại bộ dịch.`,dt,{reason:"device-lost",phase:"idle",deviceLostReason:`${y.reason}: ${y.message??""}`})}})}catch(y){console.error(y),c.modelSelect.disabled=!1,R(c.chipBadge,!1),R(c.gpuTip,!1),window.__moxhi=null;const g=String(y?.message??y);/WebGPU unavailable|no adapter/i.test(g)?(R(c.loading,!1),Zc(g),R(c.gate,!0)):ut(`Không khởi động được bộ dịch: ${g}`,dt,{reason:"other",phase:"load"});return}c.modelSelect.disabled=!1;const{gpuName:t,dtype:n,lmHeadQ8:r,lmShortN:a,tunedFrom:o,modelName:s}=b.engine.info,i=o==="cache"?"autotune đệm":o==="measured"?"autotune":o==="partial"?"autotune một phần":"routing mặc định",u="95dca08",l=new URLSearchParams(location.search).get("cap"),p=new URLSearchParams(location.search).get("tokenbudget"),f=new URLSearchParams(location.search).get("kvplanner"),m=new URLSearchParams(location.search).get("inplacecompact"),d=r?`·int8${a?` ${Math.round(a/1e3)}k`:""}`:"",v=ks(t);c.modelLink.textContent=s,e.credit?.url?(c.modelLink.href=e.credit.url,c.modelLink.title=e.credit.label):(c.modelLink.removeAttribute("href"),c.modelLink.removeAttribute("title")),c.statGpu.textContent=` · ${v} · ${n}${d} · ${i} · ${u}`+(l?` · cap=${l}`:"")+(p!==null?` · tokenbudget=${p}`:"")+(f!==null?` · kvplanner=${f}`:"")+(m!==null?` · inplacecompact=${m}`:""),R(c.chipBadge),c.chipBadge.title=[v!==t?t:null,b.engine.info.gpuTitle||null].filter(Boolean).join(" · "),R(c.gpuTip,Cs(t)),R(c.loading,!1),R(c.studio,!0),c.src.focus(),window.__moxhi={engine:b.engine,build:u,translate:y=>b.engine.translateText(y)},document.dispatchEvent(new CustomEvent("moxhi:ready"))}function jc(e){c.dstNote.textContent=e?`${e} ký tự`:""}function Je(e,t={}){b.outRows=e,t.count!==void 0&&(b.outWindow=t.count);const{chars:n,shown:r,total:a}=Ya(c.out,e,{},{...t,count:b.outWindow});jc(n),R(c.outMoreBtn,rHe.cancel());c.src.addEventListener("keydown",e=>{(e.ctrlKey||e.metaKey)&&e.key==="Enter"&&(e.preventDefault(),wt())});c.reportOutBtn.addEventListener("click",()=>Ro({title:"Báo lỗi dịch",reason:"wrong-output",phase:"translate",attach:!0,summary:"Bản dịch sai/lệch nghĩa? Tick ô bên dưới để đính kèm đoạn đang hiển thị."}));c.benchSubmitBtn.addEventListener("click",async()=>{if(!b.engine||!b.lastRun||b.lastRun.submitted)return;const e=await Po();if(!e)return;const t=await Mo(navigator,ve);b.lastRun.payload??=Co({info:b.engine.info,stats:b.lastRun.stats,mode:b.lastRun.mode,srcChars:b.lastRun.srcChars,build:"95dca08",pseudo:e,ua:navigator.userAgent??"",platform:ko(),extras:t});const n=b.lastRun.payload;To({title:"Gửi benchmark",summary:`${pa(e).emoji} ${ga(e)} · ${b.engine.info.gpuName} · ${b.engine.info.modelName} · ${Math.round(n.run.tokPerSec)} tok/s · ${n.run.sentences} câu`+(Eo(n.run)?" · sẽ không xếp hạng":""),payload:n,send:async(r,a)=>{const o=await xo("/api/submit",r);if(b.lastRun.submitted=!0,R(c.benchSubmitBtn,!1),o.rank){const s=document.createDocumentFragment(),i=document.createElement("a");i.href="/board",i.textContent="xem bảng tốc độ",s.append(`Hạng ${o.rank} bảng ${b.engine.info.modelName} — `,i),a(s)}else a(Oc(r.run))}})});let Rn=(ve.getItem(Ao)??"1")==="1";const Hc={autoTranslate:()=>Rn,setAutoTranslate:e=>{Rn=e,ve.setItem(Ao,e?"1":"0")}},$o=matchMedia("(min-width: 1440px)"),Wc=()=>$o.matches,Kc=()=>({doc:b.doc,job:He.current()}),Vc=ts(),Ue=Ca({tabs:c.panelTabs,overlay:{modal:c.panelModal,title:c.panelTitle,body:c.panelBody,closeBtn:c.panelCloseBtn,grip:c.panelGrip},rail:{isOpen:Wc,title:c.railTitle,body:c.railBody,onChange:e=>c.page.classList.toggle("rail-open",e)},getState:Kc}),Lo=Da({getNamespace:()=>b.engine?Vr(b.engine.info):null,enabled:new URLSearchParams(location.search).get("tm")!=="0",onChange:()=>Ue.refresh(),prefs:Hc});On(Lo);On(Ga({store:Vn,onChange:()=>Ue.refresh()}));const Oo=Sc({provider:pc(),glossaryStore:Vn,jobs:He,getRows:()=>{const e=b.doc??_t(c.src.value);return e.text.trim()?Yr(e.text).sentences:[]},hasText:()=>!!(b.doc??_t(c.src.value)).text.trim(),getFp:()=>Vc((b.doc??_t(c.src.value)).text),onChange:()=>Ue.refresh()});On(Oo);c.scanBtn.addEventListener("click",async()=>{const e=await Oo.scan();(e==="ok"||e==="empty"||e==="error")&&Ue.open("entity")});c.settingsBtn.addEventListener("click",()=>Ue.open("memory"));c.helpBtn.addEventListener("click",()=>c.helpModal.showModal());c.helpCloseBtn.addEventListener("click",()=>c.helpModal.close());c.helpModal.addEventListener("click",e=>{e.target===c.helpModal&&c.helpModal.close()});c.railCloseBtn.addEventListener("click",()=>Ue.close());$o.addEventListener("change",()=>Ue.rehost());Ue.refresh();c.modelSelect.replaceChildren(...ma.map(e=>{const t=document.createElement("option");return t.value=e.id,t.textContent=e.name,t}));c.modelSelect.value=$n(ve.getItem(Kn)??Ln).id;c.modelSelect.addEventListener("change",()=>{ve.setItem(Kn,c.modelSelect.value),b.filePartial=null,c.progress.textContent="",b.engine?.destroy?.(),b.engine=null,b.lastRun=null,R(c.benchSubmitBtn,!1),R(c.reportOutBtn,!1),dt()});let Wr=0;c.src.addEventListener("input",()=>{if(c.srcCount.textContent=`${c.src.value.length} ký tự`,b.filePartial=null,Ue.refresh(),clearTimeout(Wr),!(!Rn||!b.engine||b.doc)){if(c.src.value.length>Pc){c.progress.textContent="văn bản dài — bấm Dịch";return}c.progress.textContent="",Wr=setTimeout(wt,Rc)}});c.pasteBtn.addEventListener("click",async()=>{try{c.src.value=await navigator.clipboard.readText(),c.src.dispatchEvent(new Event("input"))}catch{c.src.focus(),c.progress.textContent="trình duyệt chặn đọc clipboard — dán bằng Ctrl+V"}});c.clearBtn.addEventListener("click",()=>{c.src.value="",Je([]),R(c.reportOutBtn,!1),c.src.dispatchEvent(new Event("input")),c.src.focus()});c.copyBtn.addEventListener("click",async()=>{const e=_n(b.outRows);e&&await navigator.clipboard.writeText(e).catch(()=>{})});function Fo(e,t){const n=document.createElement("a");n.href=URL.createObjectURL(new Blob([t],{type:"text/plain;charset=utf-8"})),n.download=e,n.click(),URL.revokeObjectURL(n.href)}c.saveBtn.addEventListener("click",()=>{const e=_n(b.outRows);e&&Fo(os(b.doc),e)});function qc(e){c.encSelect.replaceChildren(...oc.map(t=>{const n=document.createElement("option");return n.value=t,n.textContent=t==="auto"?`${yn.auto} (${yn[e]??e})`:yn[t],n})),c.encSelect.value="auto"}const Jc=2e3,Qc=400;function _o(){const{text:e}=b.doc,t=Math.min(b.srcWindow,e.length);c.srcView.textContent=e.slice(0,t)+(tTc){ut(`File ${qt(e.size)} MB vượt giới hạn 20 MB.`,()=>{});return}const t=new Uint8Array(await e.arrayBuffer()),{text:n,encoding:r}=vo(t,"auto");b.fileResultText=null,b.fileProfileText=null,b.filePartial=null,qc(r),Xn(Xr({name:e.name,bytes:t,text:n,encoding:r})),Je([]),R(c.profileBtn,!1),R(c.reportOutBtn,!1),c.progress.textContent="";const a=Bo(),o=Do();Na(a,o)?c.progress.textContent=`phiên trước dừng ở ${a.done}/${a.rows} cụm — "Dịch file" sẽ dịch tiếp từ bộ nhớ dịch`:a&&!a.complete&&(a.done??0)>0&&a.file===o.file&&a.model===o.model&&(c.progress.textContent="file đã thay đổi so phiên dịch dở trước — phần trùng sẽ lấy lại từ bộ nhớ dịch")}c.openBtn.addEventListener("click",()=>c.fileInput.click());c.fileInput.addEventListener("change",()=>Go(c.fileInput.files[0]));c.srcMoreBtn.addEventListener("click",()=>{b.srcWindow*=4,_o()});let mt=0;const Uo=e=>{mt=e?mt+1:Math.max(0,mt-1),R(c.dropveil,mt>0)};c.panes.addEventListener("dragenter",e=>{e.preventDefault(),Uo(!0)});c.panes.addEventListener("dragover",e=>{e.preventDefault()});c.panes.addEventListener("dragleave",e=>{e.preventDefault(),Uo(!1)});c.panes.addEventListener("drop",e=>{e.preventDefault(),mt=0,R(c.dropveil,!1),Go(e.dataTransfer.files[0])});c.encSelect.addEventListener("change",()=>{const e=c.encSelect.value,{text:t,encoding:n}=vo(b.doc.bytes,e);b.doc.text=t,b.doc.encoding=n,b.filePartial=null,b.fileProfileText=null,R(c.profileBtn,!1),c.progress.textContent="",Xn(Xr({...b.doc,text:t,encoding:n}))});c.docCloseBtn.addEventListener("click",()=>{b.fileResultText=null,b.fileProfileText=null,b.filePartial=null,c.fileInput.value="",R(c.profileBtn,!1),Xn(null)});async function Xc(e){const t=b.doc??_t(c.src.value),n=t.origin==="file",r=rs(t);if(!n&&!t.text.trim()){Io();return}R(c.benchSubmitBtn,!1),R(c.cancelBtn,!0),R(c.profileBtn,!1),b.fileProfileText=null,r||(c.progress.textContent="đang dịch…"),n&&Hr({file:t.name,batch:0,model:b.engine?.info.modelId??""});const a=n?Do():null,o=Vr(b.engine.info),s=lc(Vn.list()),i=s?{protect:d=>uc(d,s),restore:(d,v)=>dc(d,v)}:null,u=s?d=>{const v=hc(d,s);return v?d+"\0"+v:d}:d=>d,l=r&&new URLSearchParams(location.search).get("tm")!=="0",p=d=>l?{get:async v=>{c.progress.textContent="tra bộ nhớ dịch…";const y=await Pa(o,v.map(d)),g=y.filter(Boolean).length;return c.progress.textContent=g?`khôi phục ${g}/${v.length} cụm từ bộ nhớ dịch`:"",y},put:v=>Ra(o,v.map(([y,g])=>[d(y),g]))}:null,f=performance.now(),m=({glossary:d,resume:v,tm:y})=>b.engine.translateText(t.text,{pack:r,glossary:d,scheduleTuneMode:r?b.engine.info.scheduleTuneMode:void 0,onScheduleTune:r?({active:g})=>{g?c.progress.textContent="đang tối ưu GPU…":c.progress.textContent==="đang tối ưu GPU…"&&(c.progress.textContent="")}:null,resume:v,tm:y,shouldStop:()=>e.signal.aborted,onBatch:r?(g,h,S)=>{b.filePartial=S;const M=S.filter(Boolean).length;n&&(Hr({file:t.name,batch:g,batches:h,done:M,rows:S.length,model:b.engine?.info.modelId??""}),_c({...a,done:M,rows:S.length}));const C=Math.round(g/h*100),L=(performance.now()-f)/1e3,z=g>0?Math.max(0,L/g*(h-g)):0;c.progress.textContent=`${M}/${S.length} cụm câu · ${C}% · còn ~${Math.ceil(z)}s`}:(g,h,S)=>{const M=S.filter(Boolean).length;c.progress.textContent=`câu ${M}/${S.length}`,h>1&&Je(sn(S.filter(Boolean).join(" ")))}});try{let d=await m({glossary:i,resume:r?b.filePartial:null,tm:p(u)});if(i&&d.stats.glossaryFailed?.length&&!d.cancelled){const y=d.stats,g=[...d.rowTexts];for(const S of y.glossaryFailed)g[S]="";const h=await m({glossary:null,resume:g,tm:p(S=>S)});d={...h,stats:{...y,glossaryFailed:y.glossaryFailed}},h.cancelled&&(d.cancelled=!0)}const v=(d.stats.glossaryFailed??[]).length;if(!r){d.cancelled?c.progress.textContent="đã hủy":(Je(sn(d.text),{ink:!0,reduced:Bc}),c.progress.textContent="",c.statPerf.textContent=`${Math.round(d.stats.tokPerSec)} tok/s · ${Ft(d.stats.ms)} · ${d.stats.sentences} câu`+(d.stats.t2s?" · phồn→giản":"")+(v?` · ⚠ ${v} câu lỗi term`:""),b.lastRun={stats:d.stats,mode:"paste",srcChars:t.text.length,submitted:!1},ve.persistent&&R(c.benchSubmitBtn,!0),R(c.reportOutBtn,!0));return}if(d.cancelled||(b.filePartial=null,n&&Dc(),Ba()),b.fileResultText=d.text+(d.cancelled?`
+
+[— bản dịch dở dang —]`:""),c.progress.textContent=d.cancelled?"đã hủy — phần dịch dở vẫn tải được":`xong — ${Ft(d.stats.ms)} · ${Math.round(d.stats.tokPerSec)} tok/s`+(d.stats.tmHits?` · ${d.stats.tmHits} cụm từ bộ nhớ dịch`:"")+(d.stats.forcedEos?` · ⚠ ${d.stats.forcedEos} cụm chạm trần token`:"")+(v?` · ⚠ ${v} cụm lỗi term`:""),Je(sn(b.fileResultText),{count:Qc}),Ic){const y=new URLSearchParams(location.search);let g=null;try{g=await Qi(b.fileResultText)}catch(M){console.warn("[moxhi profile] output SHA-256 unavailable:",M)}const h=d.stats.scheduleAutotune??{},S={build:"95dca08",capturedAt:new Date().toISOString(),file:{name:t.name,bytes:t.bytes?.length??null,encoding:t.encoding},engine:{modelId:b.engine.info.modelId,modelName:b.engine.info.modelName,gpuName:b.engine.info.gpuName,dtype:b.engine.info.dtype,immediates:b.engine.info.immediates,uniformPool:b.engine.info.uniformPool,inPlaceCompact:b.engine.info.inPlaceCompact,scheduleTuneMode:b.engine.info.scheduleTuneMode,scheduleDefault:{...b.engine.info.scheduleDefault},kvPolicy:b.engine.info.kvPolicy,kvPlannerOverride:b.engine.info.kvPlannerOverride,kvCapacityOverride:b.engine.info.kvCapacityOverride},policy:{cap:y.get("cap"),tokenbudget:y.get("tokenbudget"),kvplanner:y.get("kvplanner"),kvcap:y.get("kvcap"),inplacecompact:y.get("inplacecompact"),scheduletune:y.get("scheduletune"),tm:y.get("tm")},totals:{cancelled:d.cancelled,sentences:d.stats.sentences,tokens:d.stats.tokens,ms:Math.round(d.stats.ms*10)/10,tokPerSec:Math.round(d.stats.tokPerSec*10)/10,forcedEos:d.stats.forcedEos,batches:d.stats.batches,resumeHits:d.stats.resumeHits,tmHits:d.stats.tmHits,decodedRows:d.stats.decodedRows,profiledMs:d.stats.profiledMs,profiledDecodeMs:d.stats.profiledDecodeMs,stages:d.stats.stages,outputSha256:g},schedule:{featureMode:h.mode??"off",requested:d.stats.requestedDecodeSchedule??null,predicted:h.predictedSchedule??null,configured:d.stats.decodeSchedule??null,effective:d.stats.effectiveDecodeSchedule??null,canonicalUsesTunerVerdict:h.canonicalUsesTunerVerdict??!1,source:h.source??"default",protocolRev:h.protocolRev??null,reason:h.reason??null,fallbackReason:h.invalidatedReason??(h.source==="default"?h.reason??null:null),invalidatedReason:h.invalidatedReason??null,cache:h.cache??null,workload:h.workload??null,evidence:h.evidence??null,candidateEvidence:h.candidateEvidence??[],projection:h.projection??null,deadline:h.deadline??null,screenSubmitShrinks:h.screenSubmitShrinks??0,selectedGain:h.selectedGain??null,sampleCount:h.sampleCount??0,confirmationCount:h.confirmationCount??0,scheduleTuneMs:h.scheduleTuneMs??0},sBuckets:d.stats.sBuckets,batchStats:d.stats.batchStats};b.fileProfileText=JSON.stringify(S,null,2),globalThis.__moxhiLastProfile=S,console.log("[moxhi profile]",S),R(c.profileBtn,!0)}if(c.statPerf.textContent=`${Math.round(d.stats.tokPerSec)} tok/s · ${Ft(d.stats.ms)} · ${d.stats.sentences} cụm câu`+(d.stats.t2s?" · phồn→giản":""),d.cancelled||(b.lastRun={stats:d.stats,mode:n?"file":"paste",srcChars:t.text.length,submitted:!1},ve.persistent&&R(c.benchSubmitBtn,!0),n||R(c.reportOutBtn,!0)),d.stats.stages){const y=d.stats.stages,g=h=>`${(h/1e3).toFixed(1)}s ${Math.round(h/d.stats.ms*100)}%`;console.log(`[moxhi] ${d.stats.batches} batch · ${Ft(d.stats.ms)} — tokenize ${g(y.tokenizeMs)} · encoder ${g(y.encoderMs)} · decode ${g(y.decodeMs)} · detok ${g(y.detokMs)} · gap ${g(y.gapMs)} · encoder/decode là cửa sổ chồng lấn (không cộng)`+(y.tmMs?` · tm ${(y.tmMs/1e3).toFixed(1)}s (ngoài wall)`:""))}}catch(d){console.error(d);const v=b.filePartial?b.filePartial.filter(Boolean).length:0;if(b.engine?.isLost?.()){const{reason:y,message:g}=b.engine.isLost();c.progress.textContent=v?`đã dịch ${v} cụm — sẽ tiếp tục từ đó`:"",ut(`GPU bị ngắt kết nối (${y}): ${g||"không rõ nguyên nhân"}. Thử lại sẽ khởi động lại bộ dịch${v?" và dịch tiếp từ chỗ dừng":""}.`,async()=>{await dt(),wt()},{reason:"device-lost",phase:"translate",deviceLostReason:`${y}: ${g??""}`})}else c.progress.textContent="",ut(`${n?"Dịch file lỗi":"Dịch lỗi"}: ${d?.message??d}`,wt,{reason:"other",phase:"translate"})}finally{n&&Qn(),R(c.cancelBtn,!1),r&&Lo.update()}}c.outMoreBtn.addEventListener("click",()=>{Je(b.outRows,{count:b.outWindow*4})});c.profileBtn.addEventListener("click",async()=>{if(b.fileProfileText)try{await navigator.clipboard.writeText(b.fileProfileText),c.profileBtn.title="Đã chép profile"}catch{const e=b.doc?.name?.replace(/\.txt$/i,"")||"moxhi";Fo(`${e}.profile.json`,b.fileProfileText)}});function jo(e){const t=document.createElement("div");t.className="gate-address";const n=document.createElement("code");n.textContent=e;const r=document.createElement("button");return r.type="button",r.className="ghost gate-copy",r.dataset.copyAddress=e,r.textContent="Sao chép",r.setAttribute("aria-label",`Sao chép địa chỉ ${e}`),t.append(n,r),t}function Yc(e){const t=document.createElement("li"),n=document.createElement("span");return n.className="gate-step-text",n.textContent=e.text,t.append(n),e.address&&t.append(jo(e.address)),t}function Zc(e){const t=navigator.userAgentData,n=hs({userAgent:navigator.userAgent,platform:t?.platform??navigator.platform,mobile:t?.mobile,maxTouchPoints:navigator.maxTouchPoints,message:e});if(c.gateSummary.textContent=n.summary,c.gateSteps.replaceChildren(...n.steps.map(Yc)),c.gateCopyStatus.textContent="",c.gateAdvanced.open=!1,c.gateAdvancedBody.replaceChildren(),R(c.gateAdvanced,!!n.advanced),n.advanced){const r=document.createElement("p");r.textContent=n.advanced.text,c.gateAdvancedBody.append(r),n.advanced.address&&c.gateAdvancedBody.append(jo(n.advanced.address))}c.gateErr.textContent=`Chi tiết kỹ thuật: ${e}`}c.gate.addEventListener("click",async e=>{const t=e.target.closest?.("[data-copy-address]");if(!t||!c.gate.contains(t))return;const n=t.dataset.copyAddress;try{if(!navigator.clipboard?.writeText)throw new Error("clipboard unavailable");await navigator.clipboard.writeText(n),c.gateCopyStatus.textContent=`Đã sao chép ${n}`}catch{c.gateCopyStatus.textContent="Trình duyệt chặn sao chép tự động — hãy chọn địa chỉ rồi sao chép thủ công."}});c.gateRetryBtn.addEventListener("click",dt);Gc();dt();"serviceWorker"in navigator&&window.addEventListener("load",()=>{navigator.serviceWorker.register("/sw.js").catch(()=>{})});