tokentracker-cli 0.63.1 → 0.64.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dashboard/dist/assets/{ActivityHeatmap-3rWViAnK.js → ActivityHeatmap-WJZDXbwS.js} +1 -1
- package/dashboard/dist/assets/{Card-CjtoUN-V.js → Card-BLMSo0Yk.js} +1 -1
- package/dashboard/dist/assets/DashboardPage-B6riL6Zc.js +19 -0
- package/dashboard/dist/assets/{DevicePage-DWgc0ITo.js → DevicePage-DB89vSmn.js} +1 -1
- package/dashboard/dist/assets/{DialogTitle-BOWoDnVq.js → DialogTitle-B1RHm8WW.js} +1 -1
- package/dashboard/dist/assets/{FadeIn-CK1EopuS.js → FadeIn-7JSzFnw8.js} +1 -1
- package/dashboard/dist/assets/{HeaderGithubStar-C1CldHWg.js → HeaderGithubStar-BLtS5CM-.js} +1 -1
- package/dashboard/dist/assets/{IpCheckPage-DKiEo4LO.js → IpCheckPage-Bd-0YOCq.js} +1 -1
- package/dashboard/dist/assets/{LandingPage-BCzXJP9I.js → LandingPage-2EhY8k2J.js} +1 -1
- package/dashboard/dist/assets/{LeaderboardAvatar-Dw-KfosP.js → LeaderboardAvatar-CsPY9Amf.js} +1 -1
- package/dashboard/dist/assets/{LeaderboardPage-XQBrmlgA.js → LeaderboardPage-DC76VQpf.js} +3 -3
- package/dashboard/dist/assets/{LeaderboardProfileModal-8xPG0MRj.js → LeaderboardProfileModal-C6fllhU2.js} +1 -1
- package/dashboard/dist/assets/{LeaderboardProfilePage-DHa73U-g.js → LeaderboardProfilePage-C42UiGkG.js} +3 -3
- package/dashboard/dist/assets/{LimitsPage-BTF8cZ-P.js → LimitsPage-CwxWe18U.js} +1 -1
- package/dashboard/dist/assets/{LocalOnlyNotice-BqLH4XMA.js → LocalOnlyNotice-CWBhqZ0X.js} +1 -1
- package/dashboard/dist/assets/{LoginPage-OZf1-OnV.js → LoginPage-Dw0rFhaO.js} +1 -1
- package/dashboard/dist/assets/{PopoverPopup-BQ03eBHT.js → PopoverPopup-D5d98dJF.js} +1 -1
- package/dashboard/dist/assets/{ResetPasswordPage-CqSU4VnK.js → ResetPasswordPage-Ca1vYCmL.js} +1 -1
- package/dashboard/dist/assets/{Select-C2miulxl.js → Select-TG8sTI5Z.js} +1 -1
- package/dashboard/dist/assets/{SelectItemText-CvU6qFNt.js → SelectItemText-ChAwxrlu.js} +1 -1
- package/dashboard/dist/assets/SettingsPage-CHO9pTCC.js +1 -0
- package/dashboard/dist/assets/{SkillsPage-DKHdur0w.js → SkillsPage-D4gqRDz5.js} +1 -1
- package/dashboard/dist/assets/{WidgetsPage-Dh_FKo1H.js → WidgetsPage-B4hDqpOL.js} +1 -1
- package/dashboard/dist/assets/{WrappedPage-BIdXJTOA.js → WrappedPage-_5A_J24M.js} +1 -1
- package/dashboard/dist/assets/{agent-logos-CWBw3t4a.js → agent-logos-BxXu3XPn.js} +1 -1
- package/dashboard/dist/assets/{arrow-up-right-D1Qv9-hJ.js → arrow-up-right-B1VUIoVh.js} +1 -1
- package/dashboard/dist/assets/{download-9hc1LZwP.js → download-D6ma9Qrl.js} +1 -1
- package/dashboard/dist/assets/{info-Bw9sw3vW.js → info-K9Ps997U.js} +1 -1
- package/dashboard/dist/assets/{main-BN1NzjX3.js → main-CnThe5nE.js} +30 -13
- package/dashboard/dist/assets/main-DEU_X1Ba.css +1 -0
- package/dashboard/dist/assets/{use-limits-display-prefs-CpHg_a82.js → use-limits-display-prefs-lH7AACmv.js} +1 -1
- package/dashboard/dist/assets/{use-native-settings-BCMRmnLD.js → use-native-settings-C43_rEQP.js} +1 -1
- package/dashboard/dist/assets/use-quality-per-dollar-pref-DsVwHWvg.js +1 -0
- package/dashboard/dist/assets/{use-usage-limits-CVu3Jff0.js → use-usage-limits-D6QquT0m.js} +1 -1
- package/dashboard/dist/assets/{useCurrency-3hjYtt-n.js → useCurrency-CCGK2Rdz.js} +1 -1
- package/dashboard/dist/assets/{useScrollLock-BNfQujzc.js → useScrollLock-BtA-ptIe.js} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/dashboard/dist/share.html +2 -2
- package/package.json +4 -2
- package/src/lib/local-api.js +25 -0
- package/src/lib/opencode-go-limits.js +253 -20
- package/src/lib/outcomes-engine.js +230 -0
- package/src/lib/pricing/curated-overrides.json +4 -0
- package/src/lib/pricing/seed-snapshot.json +1 -1
- package/src/lib/sqlite-reader.js +59 -0
- package/src/lib/usage-limits.js +4 -4
- package/dashboard/dist/assets/DashboardPage-C8Zm5caR.js +0 -19
- package/dashboard/dist/assets/SettingsPage-DYiO30s5.js +0 -1
- package/dashboard/dist/assets/main-iuBgdxqX.css +0 -1
- package/dashboard/dist/assets/pencil-C8mN_ljR.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as _t,cM as Xe,cG as Dt,b7 as Ot,b5 as H,b8 as wt,bE as U,cN as Ct,ch as je,j as Se,cm as ze,r as g,bC as V,co as ot,cO as Gt,b9 as it,bB as Le,c6 as Kt,cn as ct,cP as xt,bG as x,bF as ke,c1 as he,cQ as Ve,cR as le,cs as ae,bK as C,bL as Ut,cF as It,cJ as Je,c7 as Xt,bY as ut,bT as lt,bV as Vt,cS as qt,bH as be,bX as $t,cA as jt,b as Pe,bQ as zt,cT as Qe,bc as Ye,cU as Jt,cV as He,bN as Qt,bA as We,bO as Zt,bD as Ie,cd as _e,cc as en,cW as tn,ca as nn,bM as rn,bR as Te,cX as me,bf as sn,bg as on,bb as De,cY as cn,cZ as at,cD as un,ci as Ze}from"./main-BN1NzjX3.js";const ln=[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]],zn=_t("check",ln);function Fe(e,t,n=!0){return e.filter(s=>s.parentId===t).flatMap(s=>[...!n||s.context?.open?[s]:[],...Fe(e,s.id,n)])}function ft(e,t){let n=[],r=e.find(s=>s.id===t)?.parentId;for(;r;){const s=e.find(o=>o.id===r);r=s?.parentId,s&&(n=n.concat(s))}return n}function an(e){e.preventDefault(),e.stopPropagation()}function fn(e){return"nativeEvent"in e}function dn(e){return e.pointerType===""&&e.isTrusted?!0:Xe&&e.pointerType?e.type==="click"&&e.buttons===1:e.detail===0&&!e.pointerType}function pn(e){return Dt?!1:!Xe&&e.width===0&&e.height===0||Xe&&e.width===1&&e.height===1&&e.pressure===0&&e.detail===0&&e.pointerType==="mouse"||e.width<1&&e.height<1&&e.pressure===0&&e.detail===0&&e.pointerType==="touch"}function Jn(e,t){const n=["mouse","pen"];return t||n.push("",void 0),n.includes(e)}function gn(e){const t=e.type;return t==="click"||t==="mousedown"||t==="keydown"||t==="keyup"}function Ae(e){const t=Ot(hn,e).current;return t.next=e,H(t.effect),t}function hn(e){const t={current:e,next:e,effect:()=>{t.current=t.next}};return t}let Ne=0;function Ge(e,t={}){const{preventScroll:n=!1,sync:r=!1,shouldFocus:s}=t;cancelAnimationFrame(Ne);function o(){s&&!s()||e?.focus({preventScroll:n})}if(r)return o(),wt;const i=requestAnimationFrame(o);return Ne=i,()=>{Ne===i&&(cancelAnimationFrame(i),Ne=0)}}const Ke={inert:new WeakMap,"aria-hidden":new WeakMap},dt="data-base-ui-inert",qe={inert:new WeakSet,"aria-hidden":new WeakSet};let xe=new WeakMap,Ue=0;function mn(e){return qe[e]}function kt(e){return e?Ct(e)?e.host:kt(e.parentNode):null}const pt=(e,t)=>t.map(n=>{if(e.contains(n))return n;const r=kt(n);return e.contains(r)?r:null}).filter(n=>n!=null),gt=e=>{const t=new Set;return e.forEach(n=>{let r=n;for(;r&&!t.has(r);)t.add(r),r=r.parentNode}),t},ht=(e,t,n)=>{const r=[],s=o=>{!o||n.has(o)||Array.from(o.children).forEach(i=>{je(i)!=="script"&&(t.has(i)?s(i):r.push(i))})};return s(e),r};function bn(e,t,n,r,{mark:s=!0}){let o=null;r?o="inert":n&&(o="aria-hidden");let i=null,u=null;const h=pt(t,e),f=s?ht(t,gt(h),new Set(h)):[],k=[],W=[];if(o){const b=Ke[o],T=mn(o);u=T,i=b;const A=pt(t,Array.from(t.querySelectorAll("[aria-live]"))),P=h.concat(A);ht(t,gt(P),new Set(P)).forEach(y=>{const E=y.getAttribute(o),Q=E!==null&&E!=="false",B=(b.get(y)||0)+1;b.set(y,B),k.push(y),B===1&&Q&&T.add(y),Q||y.setAttribute(o,o==="inert"?"":"true")})}return s&&f.forEach(b=>{const T=(xe.get(b)||0)+1;xe.set(b,T),W.push(b),T===1&&b.setAttribute(dt,"")}),Ue+=1,()=>{i&&k.forEach(b=>{const A=(i.get(b)||0)-1;i.set(b,A),A||(!u?.has(b)&&o&&b.removeAttribute(o),u?.delete(b))}),s&&W.forEach(b=>{const T=(xe.get(b)||0)-1;xe.set(b,T),T||b.removeAttribute(dt)}),Ue-=1,Ue||(Ke.inert=new WeakMap,Ke["aria-hidden"]=new WeakMap,qe.inert=new WeakSet,qe["aria-hidden"]=new WeakSet,xe=new WeakMap)}}function mt(e,t={}){const{ariaHidden:n=!1,inert:r=!1,mark:s=!0}=t,o=U(e[0]).body;return bn(e,o,n,r,{mark:s})}function Pt(){const e=new Map;return{emit(t,n){e.get(t)?.forEach(r=>r(n))},on(t,n){e.has(t)||e.set(t,new Set),e.get(t).add(n)},off(t,n){e.get(t)?.delete(n)}}}class En{nodesRef={current:[]};events=Pt();addNode(t){this.nodesRef.current.push(t)}removeNode(t){const n=this.nodesRef.current.findIndex(r=>r===t);n!==-1&&this.nodesRef.current.splice(n,1)}}const Ft=g.createContext(null),Mt=g.createContext(null),et=()=>g.useContext(Ft)?.id||null,tt=e=>{const t=g.useContext(Mt);return e??t};function Qn(e){const t=ze(),n=tt(e),r=et();return H(()=>{if(!t)return;const s={id:t,parentId:r};return n?.addNode(s),()=>{n?.removeNode(s)}},[n,t,r]),t}function Zn(e){const{children:t,id:n}=e,r=et();return Se.jsx(Ft.Provider,{value:g.useMemo(()=>({id:n,parentId:r}),[n,r]),children:t})}function er(e){const{children:t,externalTree:n}=e,r=Ot(()=>n??new En).current;return Se.jsx(Mt.Provider,{value:r,children:t})}function yn(e,t){const n=Ye(be(e));return e instanceof n.KeyboardEvent?"keyboard":e instanceof n.FocusEvent?t||"keyboard":"pointerType"in e?e.pointerType||"keyboard":"touches"in e?"touch":e instanceof n.MouseEvent?t||(e.detail===0?"keyboard":"mouse"):""}const bt=20;let fe=[];function nt(){fe=fe.filter(e=>e.deref()?.isConnected)}function Et(e){nt(),e&&je(e)!=="body"&&(fe.push(new WeakRef(e)),fe.length>bt&&(fe=fe.slice(-bt)))}function yt(){return nt(),fe[fe.length-1]?.deref()}function Rn(e){return e?Qe(e)?e:xt(e)[0]||e:null}function Rt(e){if(e.hasAttribute("tabindex")&&!e.hasAttribute("data-tabindex")||!e.getAttribute("role")?.includes("dialog"))return;const n=Jt(e).filter(s=>{const o=s.getAttribute("data-tabindex")||"";return Qe(s)||s.hasAttribute("data-tabindex")&&!o.startsWith("-")}),r=e.getAttribute("tabindex");n.length===0?r!=="0"&&(e.setAttribute("tabindex","0"),e.setAttribute("data-tabindex","0")):(r!=="-1"||e.hasAttribute("data-tabindex")&&e.getAttribute("data-tabindex")!=="-1")&&(e.setAttribute("tabindex","-1"),e.setAttribute("data-tabindex","-1"))}function tr(e){const{context:t,children:n,disabled:r=!1,initialFocus:s=!0,returnFocus:o=!0,restoreFocus:i=!1,modal:u=!0,closeOnFocusOut:h=!0,openInteractionType:f="",nextFocusableElement:k,previousFocusableElement:W,beforeContentFocusGuardRef:b,externalTree:T,getInsideElements:A}=e,P="rootStore"in t?t.rootStore:t,_=P.useState("open"),y=P.useState("domReferenceElement"),E=P.useState("floatingElement"),{events:Q,dataRef:B}=P.context,q=V(()=>B.current.floatingContext?.nodeId),J=s===!1,D=ot(y)&&J,se=Ae(s),F=Ae(o),$=Ae(f),ve=Ae(_),N=tt(T),R=Gt(),Y=g.useRef(!1),oe=g.useRef(!1),ee=g.useRef(!1),te=g.useRef(null),Ee=g.useRef(""),de=g.useRef(""),pe=g.useRef(null),ye=g.useRef(null),S=it(pe,b,R?.beforeInsideRef),j=it(ye,R?.afterInsideRef),ie=Le(),ce=Le(),Oe=Kt(),Me=R!=null,p=ct(E),ne=V((m=p)=>m?xt(m):[]),Z=V(()=>A?.().filter(m=>m!=null)??[]);g.useEffect(()=>{if(r||!u)return;function m(L){L.key==="Tab"&&C(p,ae(U(p)))&&ne().length===0&&!D&&an(L)}const I=U(p);return x(I,"keydown",m)},[r,p,u,D,ne]),g.useEffect(()=>{if(r||!_)return;const m=U(p);function I(){ee.current=!1}function L(z){const a=be(z),O=Z(),d=C(E,a)||C(y,a)||C(R?.portalNode,a)||O.some(M=>M===a||C(M,a));ee.current=!d,de.current=z.pointerType||"keyboard",a?.closest(`[${$t}]`)&&(oe.current=!0,ce.start(0,()=>{oe.current=!1}))}function G(){de.current="keyboard"}return ke(x(m,"pointerdown",L,!0),x(m,"pointerup",I,!0),x(m,"pointercancel",I,!0),x(m,"keydown",G,!0),I)},[r,E,y,p,_,R,ce,Z]),g.useEffect(()=>{if(r||!h)return;const m=U(p);function I(){oe.current=!0,ce.start(0,()=>{oe.current=!1})}function L(O){const d=be(O);Qe(d)&&(te.current=d)}function G(O){const d=O.relatedTarget,M=O.currentTarget,K=be(O);u&&d==null&&K!=null&&C(E,K)&&Et(K),queueMicrotask(()=>{const w=q(),Re=P.context.triggerElements,c=Z(),l=d?.hasAttribute(Ve("focus-guard"))&&[pe.current,ye.current,R?.beforeInsideRef.current,R?.afterInsideRef.current,R?.beforeOutsideRef.current,R?.afterOutsideRef.current,le(W),le(k)].includes(d),X=!(C(y,d)||C(E,d)||C(d,E)||C(R?.portalNode,d)||c.some(v=>v===d||C(v,d))||d!=null&&Re.hasElement(d)||Re.hasMatchingElement(v=>C(v,d))||l||N&&(Fe(N.nodesRef.current,w).find(v=>C(v.context?.elements.floating,d)||C(v.context?.elements.domReference,d))||ft(N.nodesRef.current,w).find(v=>[v.context?.elements.floating,ct(v.context?.elements.floating)].includes(d)||v.context?.elements.domReference===d)));if(M===y&&p&&Rt(p),i&&M!==y&&!jt(K)&&ae(m)===m.body){if(he(p)&&(p.focus(),i==="popup")){Oe.request(()=>{p.focus()});return}const v=ne(),ue=te.current,we=(ue&&v.includes(ue)?ue:null)||v[v.length-1]||p;he(we)&&we.focus()}if(B.current.insideReactTree){B.current.insideReactTree=!1;return}(D||!u)&&d&&X&&!oe.current&&(D||d!==yt())&&(Y.current=!0,P.setOpen(!1,Pe(zt,O)))})}function z(){ee.current||(B.current.insideReactTree=!0,ie.start(0,()=>{B.current.insideReactTree=!1}))}const a=he(y)?y:null;if(!(!E&&!a))return ke(a&&x(a,"focusout",G),a&&x(a,"pointerdown",I),E&&x(E,"focusin",L),E&&x(E,"focusout",G),E&&R&&x(E,"focusout",z,!0))},[r,y,E,p,u,N,R,P,h,i,ne,D,q,B,ie,ce,Oe,k,W,Z]),g.useEffect(()=>{if(r||!E||!_)return;const m=Array.from(R?.portalNode?.querySelectorAll(`[${Ve("portal")}]`)||[]),L=(N?ft(N.nodesRef.current,q()):[]).find(M=>ot(M.context?.elements.domReference||null))?.context?.elements.domReference,z=[...[E,...m,pe.current,ye.current,R?.beforeOutsideRef.current,R?.afterOutsideRef.current,...Z()],L,le(W),le(k),D?y:null].filter(M=>M!=null),a=mt(z,{ariaHidden:u||D,mark:!1}),O=[E,...m].filter(M=>M!=null),d=mt(O);return()=>{d(),a()}},[_,r,y,E,u,R,D,N,q,k,W,Z]),H(()=>{if(!_||r||!he(p))return;const m=U(p),I=ae(m);queueMicrotask(()=>{const L=se.current,G=typeof L=="function"?L($.current||""):L;if(G===void 0||G===!1||C(p,I))return;let a=null;const O=()=>(a==null&&(a=ne(p)),a[0]||p);let d;G===!0||G===null?d=O():d=le(G),d=d||O();const M=C(p,ae(m));Ge(d,{preventScroll:d===p,shouldFocus(){if(!ve.current)return!1;if(M)return!0;const K=ae(m);return!(K!==d&&C(p,K))}})})},[r,_,p,ne,se,$,ve]),H(()=>{if(r||!p)return;const m=U(p),I=ae(m),L=$.current==null;Et(I);function G(a){if(a.open||(Ee.current=yn(a.nativeEvent,de.current)),a.reason===Ut&&a.nativeEvent.type==="mouseleave"&&(Y.current=!0),a.reason===It)if(a.nested)Y.current=!1;else if(dn(a.nativeEvent)||pn(a.nativeEvent))Y.current=!1;else{let O=!1;U(p).createElement("div").focus({get preventScroll(){return O=!0,!1}}),O?Y.current=!1:Y.current=!0}}Q.on("openchange",G);function z(){const a=F.current;let O=typeof a=="function"?a(Ee.current):a;if(O===void 0||O===!1)return null;O===null&&(O=!0);const d=y?.isConnected?y:null,M=I?.isConnected&&je(I)!=="body"?I:null;let K=L?M||d:d||M;return K||(K=yt()||null),typeof O=="boolean"?K:le(O)||K||null}return()=>{Q.off("openchange",G);const a=ae(m),O=Z(),d=C(E,a)||O.some(w=>w===a||C(w,a))||N&&Fe(N.nodesRef.current,q(),!1).some(w=>C(w.context?.elements.floating,a)),M=F.current,K=z();queueMicrotask(()=>{const w=Rn(K),Re=typeof M!="boolean";M&&!Y.current&&he(w)&&(!(!Re&&w!==a&&a!==m.body)||d)&&w.focus({preventScroll:!0}),Y.current=!1})}},[r,E,p,F,$,Q,N,y,q,Z]),H(()=>{if(!Je||_||!E)return;const m=ae(U(E));!he(m)||!Xt(m)||C(E,m)&&m.blur()},[_,E]),H(()=>{if(!(r||!R))return R.setFocusManagerState({modal:u,closeOnFocusOut:h,open:_,onOpenChange:P.setOpen,domReference:y}),()=>{R.setFocusManagerState(null)}},[r,R,u,_,P,h,y]),H(()=>{if(!(r||!p))return Rt(p),()=>{queueMicrotask(nt)}},[r,p]);const ge=!r&&(u?!D:!0)&&(Me||u);return Se.jsxs(g.Fragment,{children:[ge&&Se.jsx(ut,{"data-type":"inside",ref:S,onFocus:m=>{if(u){const I=ne();Ge(I[I.length-1])}else R?.portalNode&&(Y.current=!1,lt(m,R.portalNode)?Vt(y)?.focus():le(W??R.beforeOutsideRef)?.focus())}}),n,ge&&Se.jsx(ut,{"data-type":"inside",ref:j,onFocus:m=>{u?Ge(ne()[0]):R?.portalNode&&(h&&(Y.current=!0),lt(m,R.portalNode)?qt(y)?.focus():le(k??R.afterOutsideRef)?.focus())}})]})}function Tn(){return!1}function Sn(e){return{escapeKey:typeof e=="boolean"?e:e?.escapeKey??!1,outsidePress:typeof e=="boolean"?e:e?.outsidePress??!0}}function nr(e,t={}){const{enabled:n=!0,escapeKey:r=!0,outsidePress:s=!0,outsidePressEvent:o="sloppy",referencePress:i=Tn,bubbles:u,externalTree:h}=t,f="rootStore"in e?e.rootStore:e,k=f.useState("open"),W=f.useState("floatingElement"),{dataRef:b}=f.context,T=tt(h),A=V(typeof s=="function"?s:()=>!1),P=typeof s=="function"?A:s,_=P!==!1,y=V(()=>o),{escapeKey:E,outsidePress:Q}=Sn(u),B=g.useRef(!1),q=g.useRef(!1),J=g.useRef(!1),D=g.useRef(!1),se=g.useRef(""),F=g.useRef(null),$=Le(),ve=Le(),N=V(()=>{ve.clear(),b.current.insideReactTree=!1}),R=V(S=>{const j=b.current.floatingContext?.nodeId;return(T?Fe(T.nodesRef.current,j):[]).some(ce=>ce.context?.open&&!ce.context.dataRef.current[S])}),Y=V(S=>He(S,f.select("floatingElement"))||He(S,f.select("domReferenceElement"))),oe=V(S=>{i()&&f.setOpen(!1,Pe(Qt,S.nativeEvent))}),ee=V(S=>{if(!k||!n||!r||S.key!=="Escape"||D.current||!E&&R("__escapeKeyBubbles"))return;const j=fn(S)?S.nativeEvent:S,ie=Pe(Zt,j);f.setOpen(!1,ie),ie.isCanceled||S.preventDefault(),!E&&!ie.isPropagationAllowed&&S.stopPropagation()}),te=V(()=>{b.current.insideReactTree=!0,ve.start(0,N)}),Ee=V(S=>{if(!k||!n||S.button!==0)return;const j=be(S.nativeEvent);C(f.select("floatingElement"),j)&&(B.current||(B.current=!0,q.current=!1))}),de=V(S=>{!k||!n||(S.defaultPrevented||S.nativeEvent.defaultPrevented)&&B.current&&(q.current=!0)});g.useEffect(()=>{if(!k||!n)return;b.current.__escapeKeyBubbles=E,b.current.__outsidePressBubbles=Q;const S=new We,j=new We;function ie(){S.clear(),D.current=!0}function ce(){S.start(Je?5:0,()=>{D.current=!1})}function Oe(){J.current=!0,j.start(0,()=>{J.current=!1})}function Me(){B.current=!1,q.current=!1}function p(){const c=se.current,l=c==="pen"||!c?"mouse":c,X=y(),v=typeof X=="function"?X():X;return typeof v=="string"?v:v[l]}function ne(c){const l=p();return l==="intentional"&&c.type!=="click"||l==="sloppy"&&c.type==="click"}function Z(c){const l=b.current.floatingContext?.nodeId,X=T&&Fe(T.nodesRef.current,l).some(v=>He(c,v.context?.elements.floating));return Y(c)||X}function ge(c){if(ne(c)){c.type!=="click"&&!Y(c)&&(j.clear(),J.current=!1),N();return}if(b.current.insideReactTree){N();return}const l=be(c),X=`[${Ve("inert")}]`,v=Ie(l)?l.getRootNode():null,ue=Array.from((Ct(v)?v:U(f.select("floatingElement"))).querySelectorAll(X)),we=f.context.triggerElements;if(l&&(we.hasElement(l)||we.hasMatchingElement(re=>C(re,l))))return;let Ce=Ie(l)?l:null;for(;Ce&&!_e(Ce);){const re=en(Ce);if(_e(re)||!Ie(re))break;Ce=re}if(!(ue.length&&Ie(l)&&!tn(l)&&!C(l,f.select("floatingElement"))&&ue.every(re=>!C(Ce,re)))){if(he(l)&&!("touches"in c)){const re=_e(l),Be=nn(l),st=/auto|scroll/,At=re||st.test(Be.overflowX),Nt=re||st.test(Be.overflowY),Lt=At&&l.clientWidth>0&&l.scrollWidth>l.clientWidth,Wt=Nt&&l.clientHeight>0&&l.scrollHeight>l.clientHeight,Yt=Be.direction==="rtl",Bt=Wt&&(Yt?c.offsetX<=l.offsetWidth-l.clientWidth:c.offsetX>l.clientWidth),Ht=Lt&&c.offsetY>l.clientHeight;if(Bt||Ht)return}if(!Z(c)){if(p()==="intentional"&&J.current){j.clear(),J.current=!1;return}typeof P=="function"&&!P(c)||R("__outsidePressBubbles")||(f.setOpen(!1,Pe(It,c)),N())}}}function m(c){p()!=="sloppy"||c.pointerType==="touch"||!f.select("open")||!n||Y(c)||ge(c)}function I(c){if(p()!=="sloppy"||!f.select("open")||!n||Y(c))return;const l=c.touches[0];l&&(F.current={startTime:Date.now(),startX:l.clientX,startY:l.clientY,dismissOnTouchEnd:!1,dismissOnMouseDown:!0},$.start(1e3,()=>{F.current&&(F.current.dismissOnTouchEnd=!1,F.current.dismissOnMouseDown=!1)}))}function L(c,l){const X=be(c);if(!X)return;const v=x(X,c.type,()=>{l(c),v()})}function G(c){se.current="touch",L(c,I)}function z(c){$.clear(),c.type==="pointerdown"&&(se.current=c.pointerType),!(c.type==="mousedown"&&F.current&&!F.current.dismissOnMouseDown)&&L(c,l=>{l.type==="pointerdown"?m(l):ge(l)})}function a(c){if(!B.current)return;const l=q.current;if(Me(),p()==="intentional"){if(c.type==="pointercancel"){l&&Oe();return}if(!Z(c)){if(l){Oe();return}typeof P=="function"&&!P(c)||(j.clear(),J.current=!0,N())}}}function O(c){if(p()!=="sloppy"||!F.current||Y(c))return;const l=c.touches[0];if(!l)return;const X=Math.abs(l.clientX-F.current.startX),v=Math.abs(l.clientY-F.current.startY),ue=Math.sqrt(X*X+v*v);ue>5&&(F.current.dismissOnTouchEnd=!0),ue>10&&(ge(c),$.clear(),F.current=null)}function d(c){L(c,O)}function M(c){p()!=="sloppy"||!F.current||Y(c)||(F.current.dismissOnTouchEnd&&ge(c),$.clear(),F.current=null)}function K(c){L(c,M)}const w=U(W),Re=ke(r&&ke(x(w,"keydown",ee),x(w,"compositionstart",ie),x(w,"compositionend",ce)),_&&ke(x(w,"click",z,!0),x(w,"pointerdown",z,!0),x(w,"pointerup",a,!0),x(w,"pointercancel",a,!0),x(w,"mousedown",z,!0),x(w,"mouseup",a,!0),x(w,"touchstart",G,!0),x(w,"touchmove",d,!0),x(w,"touchend",K,!0)));return()=>{Re(),S.clear(),j.clear(),Me(),J.current=!1}},[b,W,r,_,P,k,n,E,Q,ee,N,y,R,Y,T,f,$]),g.useEffect(N,[P,N]);const pe=g.useMemo(()=>({onKeyDown:ee,onPointerDown:oe,onClick:oe}),[ee,oe]),ye=g.useMemo(()=>({onKeyDown:ee,onPointerDown:de,onMouseDown:de,onClickCapture:te,onMouseDownCapture(S){te(),Ee(S)},onPointerDownCapture(S){te(),Ee(S)},onMouseUpCapture:te,onTouchEndCapture:te,onTouchMoveCapture:te}),[ee,te,Ee,de]);return g.useMemo(()=>n?{reference:pe,floating:ye,trigger:pe}:{},[n,pe,ye])}function vn(e){const t=g.useRef(!0);t.current&&(t.current=!1,e())}const On={open:Te(e=>e.open),transitionStatus:Te(e=>e.transitionStatus),domReferenceElement:Te(e=>e.domReferenceElement),referenceElement:Te(e=>e.positionReference??e.referenceElement),floatingElement:Te(e=>e.floatingElement),floatingId:Te(e=>e.floatingId)};class wn extends rn{constructor(t){const{syncOnly:n,nested:r,onOpenChange:s,triggerElements:o,...i}=t;super({...i,positionReference:i.referenceElement,domReferenceElement:i.referenceElement},{onOpenChange:s,dataRef:{current:{}},events:Pt(),nested:r,triggerElements:o},On),this.syncOnly=n}syncOpenEvent=(t,n)=>{(!t||!this.state.open||n!=null&&gn(n))&&(this.context.dataRef.current.openEvent=t?n:void 0)};dispatchOpenChange=(t,n)=>{this.syncOpenEvent(t,n.event);const r={open:t,reason:n.reason,nativeEvent:n.event,nested:this.context.nested,triggerElement:n.trigger};this.context.events.emit("openchange",r)};setOpen=(t,n)=>{if(this.syncOnly){this.context.onOpenChange?.(t,n);return}this.dispatchOpenChange(t,n),this.context.onOpenChange?.(t,n)}}function Cn(e){const{popupStore:t,treatPopupAsFloatingElement:n=!1,floatingRootContext:r,floatingId:s,nested:o,onOpenChange:i}=e,u=t.useState("open"),h=t.useState("activeTriggerElement"),f=t.useState(n?"popupElement":"positionerElement"),k=t.context.triggerElements,W=i,b=g.useRef(null);r===void 0&&b.current===null&&(b.current=new wn({open:u,transitionStatus:void 0,referenceElement:h,floatingElement:f,triggerElements:k,onOpenChange:W,floatingId:s,syncOnly:!0,nested:o}));const T=r??b.current;return t.useSyncedValue("floatingId",s),H(()=>{const A={open:u,floatingId:s,referenceElement:h,floatingElement:f};Ie(h)&&(A.domReferenceElement=h),T.state.positionReference===T.state.referenceElement&&(A.positionReference=h),T.update(A)},[u,s,h,f,T]),T.context.onOpenChange=W,T.context.nested=o,T}function xn(e,t=!1,n=!1){const[r,s]=g.useState(e&&t?"idle":void 0),[o,i]=g.useState(e);return e&&!o&&(i(!0),s("starting")),!e&&o&&r!=="ending"&&!n&&s("ending"),!e&&!o&&r==="ending"&&s(void 0),H(()=>{if(!e&&o&&r!=="ending"&&n){const u=me.request(()=>{s("ending")});return()=>{me.cancel(u)}}},[e,o,r,n]),H(()=>{if(!e||t)return;const u=me.request(()=>{s(void 0)});return()=>{me.cancel(u)}},[t,e]),H(()=>{if(!e||!t)return;e&&o&&r!=="idle"&&s("starting");const u=me.request(()=>{s("idle")});return()=>{me.cancel(u)}},[t,e,o,r]),{mounted:o,setMounted:i,transitionStatus:r}}const rr={tabIndex:-1,[cn]:""};function sr(e){return t=>t==="touch"?e.current:!0}function or(e,t,n=!1){const r=ze(),s=et()!=null,o=g.useRef(null);e===void 0&&o.current===null&&(o.current=t(r,s));const i=e??o.current;return Cn({popupStore:i,treatPopupAsFloatingElement:n,floatingRootContext:i.state.floatingRootContext,floatingId:r,nested:s,onOpenChange:i.setOpen}),{store:i,internalStore:o.current}}function In(e,t){const n=g.useRef(null),r=g.useRef(null);return g.useCallback(s=>{if(e===void 0)return;let o=!1;if(n.current!==null){const i=n.current,u=r.current,h=t.context.triggerElements.getById(i);u&&h===u&&(t.context.triggerElements.delete(i),o=!0),n.current=null,r.current=null}if(s!==null&&(n.current=e,r.current=s,t.context.triggerElements.add(e,s),o=!0),o){const i=t.context.triggerElements.size;t.select("open")&&t.state.triggerCount!==i&&t.set("triggerCount",i)}},[t,e])}function ir(e,t,n,r=!1){t?e.preventUnmountingOnClose=!1:r&&(e.preventUnmountingOnClose=!0);const s=n?.id??null;(s||t)&&(e.activeTriggerId=s,e.activeTriggerElement=n??null)}function cr(e){let t=!1;return e.preventUnmountOnClose=()=>{t=!0},()=>t}function ur(e,t,n,r){vn(()=>{t===void 0&&e.state.open===!1&&n&&(e.state={...e.state,open:!0,activeTriggerId:r,preventUnmountingOnClose:!1})})}function lr(e,t,n,r){const s=n.useState("isMountedByTrigger",e),o=In(e,n),i=V(u=>{if(o(u),!u)return;const h=n.select("open"),f=n.select("activeTriggerId");if(f===e){n.update({activeTriggerElement:u,...h?r:null});return}f==null&&h&&n.update({activeTriggerId:e,activeTriggerElement:u,...r})});return H(()=>{s&&n.update({activeTriggerElement:t.current,...r})},[s,n,t,...Object.values(r)]),{registerTrigger:i,isMountedByThisTrigger:s}}function ar(e,t={}){const{closeOnActiveTriggerUnmount:n=!1}=t,r=e.useState("open"),s=e.useState("triggerCount");H(()=>{if(!r){e.state.triggerCount!==0&&e.set("triggerCount",0);return}const o=e.context.triggerElements.size,i={};e.state.triggerCount!==o&&(i.triggerCount=o);const u=e.select("activeTriggerId");let h=null;if(u){const f=e.context.triggerElements.getById(u);f?f!==e.state.activeTriggerElement&&(i.activeTriggerElement=f):h=u}if(!h&&!u&&o===1){const f=e.context.triggerElements.entries().next();if(!f.done){const[k,W]=f.value;i.activeTriggerId=k,i.activeTriggerElement=W}}(i.triggerCount!==void 0||i.activeTriggerId!==void 0||i.activeTriggerElement!==void 0)&&e.update(i),h&&n&&queueMicrotask(()=>{if(e.select("open")&&e.select("activeTriggerId")===h&&!e.context.triggerElements.getById(h)){const f=Pe(sn);e.setOpen(!1,f),f.isCanceled||e.update({activeTriggerId:null,activeTriggerElement:null})}})},[r,e,s,n])}function fr(e,t,n){const{mounted:r,setMounted:s,transitionStatus:o}=xn(e),i=t.useState("preventUnmountingOnClose"),u=e?!1:i;t.useSyncedValues({mounted:r,transitionStatus:o,preventUnmountingOnClose:u});const h=V(()=>{s(!1),t.update({activeTriggerId:null,activeTriggerElement:null,mounted:!1,preventUnmountingOnClose:!1}),n?.(),t.context.onOpenChangeComplete?.(!1)});return on({enabled:r&&!e&&!u,open:e,ref:t.context.popupRef,onComplete(){e||h()}}),{forceUnmount:h,transitionStatus:o}}function dr(e,t){e.useSyncedValues(t),H(()=>()=>{e.update({activeTriggerProps:De,inactiveTriggerProps:De,popupProps:De})},[e])}function pr(e,t){H(()=>{!t&&e.state.openMethod!==null&&e.set("openMethod",null)},[t,e]),H(()=>()=>{e.state.openMethod!==null&&e.set("openMethod",null)},[e])}class gr{constructor(){this.elementsSet=new Set,this.idMap=new Map}add(t,n){const r=this.idMap.get(t);r!==n&&(r!==void 0&&this.elementsSet.delete(r),this.elementsSet.add(n),this.idMap.set(t,n))}delete(t){const n=this.idMap.get(t);n&&(this.elementsSet.delete(n),this.idMap.delete(t))}hasElement(t){return this.elementsSet.has(t)}hasMatchingElement(t){for(const n of this.elementsSet)if(t(n))return!0;return!1}getById(t){return this.idMap.get(t)}entries(){return this.idMap.entries()}elements(){return this.elementsSet.values()}get size(){return this.idMap.size}}let rt=(function(e){return e.open="data-open",e.closed="data-closed",e[e.startingStyle=at.startingStyle]="startingStyle",e[e.endingStyle=at.endingStyle]="endingStyle",e.anchorHidden="data-anchor-hidden",e.side="data-side",e.align="data-align",e})({}),$e=(function(e){return e.popupOpen="data-popup-open",e.pressed="data-pressed",e})({});const kn={[$e.popupOpen]:""},Pn={[$e.popupOpen]:"",[$e.pressed]:""},Fn={[rt.open]:""},Mn={[rt.closed]:""},An={[rt.anchorHidden]:""},hr={open(e){return e?kn:null}},mr={open(e){return e?Pn:null}},br={open(e){return e?Fn:Mn},anchorHidden(e){return e?An:null}};function Er(e){return ze(e,"base-ui")}const Nn="ArrowUp",Ln="ArrowDown",Wn="ArrowLeft",Yn="ArrowRight",Bn="Home",Hn="End",_n=new Set([Wn,Yn]),Dn=new Set([Nn,Ln]),Gn=new Set([..._n,...Dn]),yr=new Set([...Gn,Bn,Hn]),Rr=g.forwardRef(function(t,n){const{cutout:r,...s}=t;let o;if(r){const i=r.getBoundingClientRect();o=`polygon(0% 0%,100% 0%,100% 100%,0% 100%,0% 0%,${i.left}px ${i.top}px,${i.left}px ${i.bottom}px,${i.right}px ${i.bottom}px,${i.right}px ${i.top}px,${i.left}px ${i.top}px)`}return Se.jsx("div",{ref:n,role:"presentation","data-base-ui-inert":"",...s,style:{position:"fixed",inset:0,userSelect:"none",WebkitUserSelect:"none",clipPath:o}})});let Tt={},St={},vt="";function Kn(e){if(typeof document>"u")return!1;const t=U(e);return Ye(t).innerWidth-t.documentElement.clientWidth>0}function Un(e){if(!(typeof CSS<"u"&&CSS.supports&&CSS.supports("scrollbar-gutter","stable"))||typeof document>"u")return!1;const n=U(e),r=n.documentElement,s=n.body,o=Ze(r)?r:s,i=o.style.overflowY,u=r.style.scrollbarGutter;r.style.scrollbarGutter="stable",o.style.overflowY="scroll";const h=o.offsetWidth;o.style.overflowY="hidden";const f=o.offsetWidth;return o.style.overflowY=i,r.style.scrollbarGutter=u,h===f}function Xn(e){const t=U(e),n=t.documentElement,r=t.body,s=Ze(n)?n:r,o={overflowY:s.style.overflowY,overflowX:s.style.overflowX};return Object.assign(s.style,{overflowY:"hidden",overflowX:"hidden"}),()=>{Object.assign(s.style,o)}}function Vn(e){const t=U(e),n=t.documentElement,r=t.body,s=Ye(n);let o=0,i=0,u=!1;const h=me.create();if(Je&&(s.visualViewport?.scale??1)!==1)return()=>{};function f(){const T=s.getComputedStyle(n),A=s.getComputedStyle(r),y=(T.scrollbarGutter||"").includes("both-edges")?"stable both-edges":"stable";o=n.scrollTop,i=n.scrollLeft,Tt={scrollbarGutter:n.style.scrollbarGutter,overflowY:n.style.overflowY,overflowX:n.style.overflowX},vt=n.style.scrollBehavior,St={position:r.style.position,height:r.style.height,width:r.style.width,boxSizing:r.style.boxSizing,overflowY:r.style.overflowY,overflowX:r.style.overflowX,scrollBehavior:r.style.scrollBehavior};const E=n.scrollHeight>n.clientHeight,Q=n.scrollWidth>n.clientWidth,B=T.overflowY==="scroll"||A.overflowY==="scroll",q=T.overflowX==="scroll"||A.overflowX==="scroll",J=Math.max(0,s.innerWidth-r.clientWidth),D=Math.max(0,s.innerHeight-r.clientHeight),se=parseFloat(A.marginTop)+parseFloat(A.marginBottom),F=parseFloat(A.marginLeft)+parseFloat(A.marginRight),$=Ze(n)?n:r;if(u=Un(e),u){n.style.scrollbarGutter=y,$.style.overflowY="hidden",$.style.overflowX="hidden";return}Object.assign(n.style,{scrollbarGutter:y,overflowY:"hidden",overflowX:"hidden"}),(E||B)&&(n.style.overflowY="scroll"),(Q||q)&&(n.style.overflowX="scroll"),Object.assign(r.style,{position:"relative",height:se||D?`calc(100dvh - ${se+D}px)`:"100dvh",width:F||J?`calc(100vw - ${F+J}px)`:"100vw",boxSizing:"border-box",overflow:"hidden",scrollBehavior:"unset"}),r.scrollTop=o,r.scrollLeft=i,n.setAttribute("data-base-ui-scroll-locked",""),n.style.scrollBehavior="unset"}function k(){Object.assign(n.style,Tt),Object.assign(r.style,St),u||(n.scrollTop=o,n.scrollLeft=i,n.removeAttribute("data-base-ui-scroll-locked"),n.style.scrollBehavior=vt)}function W(){k(),h.request(f)}f();const b=x(s,"resize",W);return()=>{h.cancel(),k(),typeof s.removeEventListener=="function"&&b()}}class qn{lockCount=0;restore=null;timeoutLock=We.create();timeoutUnlock=We.create();acquire(t){return this.lockCount+=1,this.lockCount===1&&this.restore===null&&this.timeoutLock.start(0,()=>this.lock(t)),this.release}release=()=>{this.lockCount-=1,this.lockCount===0&&this.restore&&this.timeoutUnlock.start(0,this.unlock)};unlock=()=>{this.lockCount===0&&this.restore&&(this.restore?.(),this.restore=null)};lock(t){if(this.lockCount===0||this.restore!==null)return;const r=U(t).documentElement,s=Ye(r).getComputedStyle(r).overflowY;if(s==="hidden"||s==="clip"){this.restore=wt;return}const o=un||!Kn(t);this.restore=o?Xn(t):Vn(t)}}const $n=new qn;function Tr(e=!0,t=null){H(()=>{if(e)return $n.acquire(t)},[e,t])}export{wn as A,Ge as B,zn as C,an as D,dn as E,er as F,pn as G,vn as H,Rr as I,Tr as J,rt as K,gr as P,xn as a,tt as b,et as c,Ae as d,cr as e,or as f,Fe as g,ur as h,Jn as i,pr as j,ar as k,fr as l,nr as m,rr as n,dr as o,lr as p,mr as q,Qn as r,ir as s,hr as t,Er as u,Zn as v,sr as w,tr as x,yr as y,br as z};
|
|
1
|
+
import{c as _t,cN as Xe,cH as Gt,b8 as Ot,b6 as H,b9 as wt,bF as K,cO as Ct,ci as $e,j as Se,cn as ze,r as g,bD as V,cp as ot,cP as Dt,ba as it,bC as We,c7 as Ut,co as ct,cQ as xt,bH as x,bG as ke,c2 as he,cR as Ve,cS as le,ct as ae,bL as C,bM as Kt,cG as It,cK as Ze,c8 as Xt,bZ as ut,bU as lt,bW as Vt,cT as qt,bI as be,bY as jt,cB as $t,b as Pe,bR as zt,cU as Je,bd as Be,cV as Zt,cW as He,bO as Jt,bB as Le,bP as Qt,bE as Ie,ce as _e,cd as en,cX as tn,cb as nn,bN as rn,bS as Te,cY as me,bg as sn,bh as on,bc as Ge,cZ as cn,c_ as at,cE as un,cj as Qe}from"./main-CnThe5nE.js";const ln=[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]],zn=_t("check",ln);function Fe(e,t,n=!0){return e.filter(s=>s.parentId===t).flatMap(s=>[...!n||s.context?.open?[s]:[],...Fe(e,s.id,n)])}function ft(e,t){let n=[],r=e.find(s=>s.id===t)?.parentId;for(;r;){const s=e.find(o=>o.id===r);r=s?.parentId,s&&(n=n.concat(s))}return n}function an(e){e.preventDefault(),e.stopPropagation()}function fn(e){return"nativeEvent"in e}function dn(e){return e.pointerType===""&&e.isTrusted?!0:Xe&&e.pointerType?e.type==="click"&&e.buttons===1:e.detail===0&&!e.pointerType}function pn(e){return Gt?!1:!Xe&&e.width===0&&e.height===0||Xe&&e.width===1&&e.height===1&&e.pressure===0&&e.detail===0&&e.pointerType==="mouse"||e.width<1&&e.height<1&&e.pressure===0&&e.detail===0&&e.pointerType==="touch"}function Zn(e,t){const n=["mouse","pen"];return t||n.push("",void 0),n.includes(e)}function gn(e){const t=e.type;return t==="click"||t==="mousedown"||t==="keydown"||t==="keyup"}function Ae(e){const t=Ot(hn,e).current;return t.next=e,H(t.effect),t}function hn(e){const t={current:e,next:e,effect:()=>{t.current=t.next}};return t}let Ne=0;function De(e,t={}){const{preventScroll:n=!1,sync:r=!1,shouldFocus:s}=t;cancelAnimationFrame(Ne);function o(){s&&!s()||e?.focus({preventScroll:n})}if(r)return o(),wt;const i=requestAnimationFrame(o);return Ne=i,()=>{Ne===i&&(cancelAnimationFrame(i),Ne=0)}}const Ue={inert:new WeakMap,"aria-hidden":new WeakMap},dt="data-base-ui-inert",qe={inert:new WeakSet,"aria-hidden":new WeakSet};let xe=new WeakMap,Ke=0;function mn(e){return qe[e]}function kt(e){return e?Ct(e)?e.host:kt(e.parentNode):null}const pt=(e,t)=>t.map(n=>{if(e.contains(n))return n;const r=kt(n);return e.contains(r)?r:null}).filter(n=>n!=null),gt=e=>{const t=new Set;return e.forEach(n=>{let r=n;for(;r&&!t.has(r);)t.add(r),r=r.parentNode}),t},ht=(e,t,n)=>{const r=[],s=o=>{!o||n.has(o)||Array.from(o.children).forEach(i=>{$e(i)!=="script"&&(t.has(i)?s(i):r.push(i))})};return s(e),r};function bn(e,t,n,r,{mark:s=!0}){let o=null;r?o="inert":n&&(o="aria-hidden");let i=null,u=null;const h=pt(t,e),f=s?ht(t,gt(h),new Set(h)):[],k=[],L=[];if(o){const b=Ue[o],T=mn(o);u=T,i=b;const A=pt(t,Array.from(t.querySelectorAll("[aria-live]"))),P=h.concat(A);ht(t,gt(P),new Set(P)).forEach(y=>{const E=y.getAttribute(o),J=E!==null&&E!=="false",Y=(b.get(y)||0)+1;b.set(y,Y),k.push(y),Y===1&&J&&T.add(y),J||y.setAttribute(o,o==="inert"?"":"true")})}return s&&f.forEach(b=>{const T=(xe.get(b)||0)+1;xe.set(b,T),L.push(b),T===1&&b.setAttribute(dt,"")}),Ke+=1,()=>{i&&k.forEach(b=>{const A=(i.get(b)||0)-1;i.set(b,A),A||(!u?.has(b)&&o&&b.removeAttribute(o),u?.delete(b))}),s&&L.forEach(b=>{const T=(xe.get(b)||0)-1;xe.set(b,T),T||b.removeAttribute(dt)}),Ke-=1,Ke||(Ue.inert=new WeakMap,Ue["aria-hidden"]=new WeakMap,qe.inert=new WeakSet,qe["aria-hidden"]=new WeakSet,xe=new WeakMap)}}function mt(e,t={}){const{ariaHidden:n=!1,inert:r=!1,mark:s=!0}=t,o=K(e[0]).body;return bn(e,o,n,r,{mark:s})}function Pt(){const e=new Map;return{emit(t,n){e.get(t)?.forEach(r=>r(n))},on(t,n){e.has(t)||e.set(t,new Set),e.get(t).add(n)},off(t,n){e.get(t)?.delete(n)}}}class En{nodesRef={current:[]};events=Pt();addNode(t){this.nodesRef.current.push(t)}removeNode(t){const n=this.nodesRef.current.findIndex(r=>r===t);n!==-1&&this.nodesRef.current.splice(n,1)}}const Ft=g.createContext(null),Mt=g.createContext(null),et=()=>g.useContext(Ft)?.id||null,tt=e=>{const t=g.useContext(Mt);return e??t};function Jn(e){const t=ze(),n=tt(e),r=et();return H(()=>{if(!t)return;const s={id:t,parentId:r};return n?.addNode(s),()=>{n?.removeNode(s)}},[n,t,r]),t}function Qn(e){const{children:t,id:n}=e,r=et();return Se.jsx(Ft.Provider,{value:g.useMemo(()=>({id:n,parentId:r}),[n,r]),children:t})}function er(e){const{children:t,externalTree:n}=e,r=Ot(()=>n??new En).current;return Se.jsx(Mt.Provider,{value:r,children:t})}function yn(e,t){const n=Be(be(e));return e instanceof n.KeyboardEvent?"keyboard":e instanceof n.FocusEvent?t||"keyboard":"pointerType"in e?e.pointerType||"keyboard":"touches"in e?"touch":e instanceof n.MouseEvent?t||(e.detail===0?"keyboard":"mouse"):""}const bt=20;let fe=[];function nt(){fe=fe.filter(e=>e.deref()?.isConnected)}function Et(e){nt(),e&&$e(e)!=="body"&&(fe.push(new WeakRef(e)),fe.length>bt&&(fe=fe.slice(-bt)))}function yt(){return nt(),fe[fe.length-1]?.deref()}function Rn(e){return e?Je(e)?e:xt(e)[0]||e:null}function Rt(e){if(e.hasAttribute("tabindex")&&!e.hasAttribute("data-tabindex")||!e.getAttribute("role")?.includes("dialog"))return;const n=Zt(e).filter(s=>{const o=s.getAttribute("data-tabindex")||"";return Je(s)||s.hasAttribute("data-tabindex")&&!o.startsWith("-")}),r=e.getAttribute("tabindex");n.length===0?r!=="0"&&(e.setAttribute("tabindex","0"),e.setAttribute("data-tabindex","0")):(r!=="-1"||e.hasAttribute("data-tabindex")&&e.getAttribute("data-tabindex")!=="-1")&&(e.setAttribute("tabindex","-1"),e.setAttribute("data-tabindex","-1"))}function tr(e){const{context:t,children:n,disabled:r=!1,initialFocus:s=!0,returnFocus:o=!0,restoreFocus:i=!1,modal:u=!0,closeOnFocusOut:h=!0,openInteractionType:f="",nextFocusableElement:k,previousFocusableElement:L,beforeContentFocusGuardRef:b,externalTree:T,getInsideElements:A}=e,P="rootStore"in t?t.rootStore:t,_=P.useState("open"),y=P.useState("domReferenceElement"),E=P.useState("floatingElement"),{events:J,dataRef:Y}=P.context,q=V(()=>Y.current.floatingContext?.nodeId),Z=s===!1,G=ot(y)&&Z,se=Ae(s),F=Ae(o),j=Ae(f),ve=Ae(_),N=tt(T),R=Dt(),B=g.useRef(!1),oe=g.useRef(!1),ee=g.useRef(!1),te=g.useRef(null),Ee=g.useRef(""),de=g.useRef(""),pe=g.useRef(null),ye=g.useRef(null),S=it(pe,b,R?.beforeInsideRef),$=it(ye,R?.afterInsideRef),ie=We(),ce=We(),Oe=Ut(),Me=R!=null,p=ct(E),ne=V((m=p)=>m?xt(m):[]),Q=V(()=>A?.().filter(m=>m!=null)??[]);g.useEffect(()=>{if(r||!u)return;function m(W){W.key==="Tab"&&C(p,ae(K(p)))&&ne().length===0&&!G&&an(W)}const I=K(p);return x(I,"keydown",m)},[r,p,u,G,ne]),g.useEffect(()=>{if(r||!_)return;const m=K(p);function I(){ee.current=!1}function W(z){const a=be(z),O=Q(),d=C(E,a)||C(y,a)||C(R?.portalNode,a)||O.some(M=>M===a||C(M,a));ee.current=!d,de.current=z.pointerType||"keyboard",a?.closest(`[${jt}]`)&&(oe.current=!0,ce.start(0,()=>{oe.current=!1}))}function D(){de.current="keyboard"}return ke(x(m,"pointerdown",W,!0),x(m,"pointerup",I,!0),x(m,"pointercancel",I,!0),x(m,"keydown",D,!0),I)},[r,E,y,p,_,R,ce,Q]),g.useEffect(()=>{if(r||!h)return;const m=K(p);function I(){oe.current=!0,ce.start(0,()=>{oe.current=!1})}function W(O){const d=be(O);Je(d)&&(te.current=d)}function D(O){const d=O.relatedTarget,M=O.currentTarget,U=be(O);u&&d==null&&U!=null&&C(E,U)&&Et(U),queueMicrotask(()=>{const w=q(),Re=P.context.triggerElements,c=Q(),l=d?.hasAttribute(Ve("focus-guard"))&&[pe.current,ye.current,R?.beforeInsideRef.current,R?.afterInsideRef.current,R?.beforeOutsideRef.current,R?.afterOutsideRef.current,le(L),le(k)].includes(d),X=!(C(y,d)||C(E,d)||C(d,E)||C(R?.portalNode,d)||c.some(v=>v===d||C(v,d))||d!=null&&Re.hasElement(d)||Re.hasMatchingElement(v=>C(v,d))||l||N&&(Fe(N.nodesRef.current,w).find(v=>C(v.context?.elements.floating,d)||C(v.context?.elements.domReference,d))||ft(N.nodesRef.current,w).find(v=>[v.context?.elements.floating,ct(v.context?.elements.floating)].includes(d)||v.context?.elements.domReference===d)));if(M===y&&p&&Rt(p),i&&M!==y&&!$t(U)&&ae(m)===m.body){if(he(p)&&(p.focus(),i==="popup")){Oe.request(()=>{p.focus()});return}const v=ne(),ue=te.current,we=(ue&&v.includes(ue)?ue:null)||v[v.length-1]||p;he(we)&&we.focus()}if(Y.current.insideReactTree){Y.current.insideReactTree=!1;return}(G||!u)&&d&&X&&!oe.current&&(G||d!==yt())&&(B.current=!0,P.setOpen(!1,Pe(zt,O)))})}function z(){ee.current||(Y.current.insideReactTree=!0,ie.start(0,()=>{Y.current.insideReactTree=!1}))}const a=he(y)?y:null;if(!(!E&&!a))return ke(a&&x(a,"focusout",D),a&&x(a,"pointerdown",I),E&&x(E,"focusin",W),E&&x(E,"focusout",D),E&&R&&x(E,"focusout",z,!0))},[r,y,E,p,u,N,R,P,h,i,ne,G,q,Y,ie,ce,Oe,k,L,Q]),g.useEffect(()=>{if(r||!E||!_)return;const m=Array.from(R?.portalNode?.querySelectorAll(`[${Ve("portal")}]`)||[]),W=(N?ft(N.nodesRef.current,q()):[]).find(M=>ot(M.context?.elements.domReference||null))?.context?.elements.domReference,z=[...[E,...m,pe.current,ye.current,R?.beforeOutsideRef.current,R?.afterOutsideRef.current,...Q()],W,le(L),le(k),G?y:null].filter(M=>M!=null),a=mt(z,{ariaHidden:u||G,mark:!1}),O=[E,...m].filter(M=>M!=null),d=mt(O);return()=>{d(),a()}},[_,r,y,E,u,R,G,N,q,k,L,Q]),H(()=>{if(!_||r||!he(p))return;const m=K(p),I=ae(m);queueMicrotask(()=>{const W=se.current,D=typeof W=="function"?W(j.current||""):W;if(D===void 0||D===!1||C(p,I))return;let a=null;const O=()=>(a==null&&(a=ne(p)),a[0]||p);let d;D===!0||D===null?d=O():d=le(D),d=d||O();const M=C(p,ae(m));De(d,{preventScroll:d===p,shouldFocus(){if(!ve.current)return!1;if(M)return!0;const U=ae(m);return!(U!==d&&C(p,U))}})})},[r,_,p,ne,se,j,ve]),H(()=>{if(r||!p)return;const m=K(p),I=ae(m),W=j.current==null;Et(I);function D(a){if(a.open||(Ee.current=yn(a.nativeEvent,de.current)),a.reason===Kt&&a.nativeEvent.type==="mouseleave"&&(B.current=!0),a.reason===It)if(a.nested)B.current=!1;else if(dn(a.nativeEvent)||pn(a.nativeEvent))B.current=!1;else{let O=!1;K(p).createElement("div").focus({get preventScroll(){return O=!0,!1}}),O?B.current=!1:B.current=!0}}J.on("openchange",D);function z(){const a=F.current;let O=typeof a=="function"?a(Ee.current):a;if(O===void 0||O===!1)return null;O===null&&(O=!0);const d=y?.isConnected?y:null,M=I?.isConnected&&$e(I)!=="body"?I:null;let U=W?M||d:d||M;return U||(U=yt()||null),typeof O=="boolean"?U:le(O)||U||null}return()=>{J.off("openchange",D);const a=ae(m),O=Q(),d=C(E,a)||O.some(w=>w===a||C(w,a))||N&&Fe(N.nodesRef.current,q(),!1).some(w=>C(w.context?.elements.floating,a)),M=F.current,U=z();queueMicrotask(()=>{const w=Rn(U),Re=typeof M!="boolean";M&&!B.current&&he(w)&&(!(!Re&&w!==a&&a!==m.body)||d)&&w.focus({preventScroll:!0}),B.current=!1})}},[r,E,p,F,j,J,N,y,q,Q]),H(()=>{if(!Ze||_||!E)return;const m=ae(K(E));!he(m)||!Xt(m)||C(E,m)&&m.blur()},[_,E]),H(()=>{if(!(r||!R))return R.setFocusManagerState({modal:u,closeOnFocusOut:h,open:_,onOpenChange:P.setOpen,domReference:y}),()=>{R.setFocusManagerState(null)}},[r,R,u,_,P,h,y]),H(()=>{if(!(r||!p))return Rt(p),()=>{queueMicrotask(nt)}},[r,p]);const ge=!r&&(u?!G:!0)&&(Me||u);return Se.jsxs(g.Fragment,{children:[ge&&Se.jsx(ut,{"data-type":"inside",ref:S,onFocus:m=>{if(u){const I=ne();De(I[I.length-1])}else R?.portalNode&&(B.current=!1,lt(m,R.portalNode)?Vt(y)?.focus():le(L??R.beforeOutsideRef)?.focus())}}),n,ge&&Se.jsx(ut,{"data-type":"inside",ref:$,onFocus:m=>{u?De(ne()[0]):R?.portalNode&&(h&&(B.current=!0),lt(m,R.portalNode)?qt(y)?.focus():le(k??R.afterOutsideRef)?.focus())}})]})}function Tn(){return!1}function Sn(e){return{escapeKey:typeof e=="boolean"?e:e?.escapeKey??!1,outsidePress:typeof e=="boolean"?e:e?.outsidePress??!0}}function nr(e,t={}){const{enabled:n=!0,escapeKey:r=!0,outsidePress:s=!0,outsidePressEvent:o="sloppy",referencePress:i=Tn,bubbles:u,externalTree:h}=t,f="rootStore"in e?e.rootStore:e,k=f.useState("open"),L=f.useState("floatingElement"),{dataRef:b}=f.context,T=tt(h),A=V(typeof s=="function"?s:()=>!1),P=typeof s=="function"?A:s,_=P!==!1,y=V(()=>o),{escapeKey:E,outsidePress:J}=Sn(u),Y=g.useRef(!1),q=g.useRef(!1),Z=g.useRef(!1),G=g.useRef(!1),se=g.useRef(""),F=g.useRef(null),j=We(),ve=We(),N=V(()=>{ve.clear(),b.current.insideReactTree=!1}),R=V(S=>{const $=b.current.floatingContext?.nodeId;return(T?Fe(T.nodesRef.current,$):[]).some(ce=>ce.context?.open&&!ce.context.dataRef.current[S])}),B=V(S=>He(S,f.select("floatingElement"))||He(S,f.select("domReferenceElement"))),oe=V(S=>{i()&&f.setOpen(!1,Pe(Jt,S.nativeEvent))}),ee=V(S=>{if(!k||!n||!r||S.key!=="Escape"||G.current||!E&&R("__escapeKeyBubbles"))return;const $=fn(S)?S.nativeEvent:S,ie=Pe(Qt,$);f.setOpen(!1,ie),ie.isCanceled||S.preventDefault(),!E&&!ie.isPropagationAllowed&&S.stopPropagation()}),te=V(()=>{b.current.insideReactTree=!0,ve.start(0,N)}),Ee=V(S=>{if(!k||!n||S.button!==0)return;const $=be(S.nativeEvent);C(f.select("floatingElement"),$)&&(Y.current||(Y.current=!0,q.current=!1))}),de=V(S=>{!k||!n||(S.defaultPrevented||S.nativeEvent.defaultPrevented)&&Y.current&&(q.current=!0)});g.useEffect(()=>{if(!k||!n)return;b.current.__escapeKeyBubbles=E,b.current.__outsidePressBubbles=J;const S=new Le,$=new Le;function ie(){S.clear(),G.current=!0}function ce(){S.start(Ze?5:0,()=>{G.current=!1})}function Oe(){Z.current=!0,$.start(0,()=>{Z.current=!1})}function Me(){Y.current=!1,q.current=!1}function p(){const c=se.current,l=c==="pen"||!c?"mouse":c,X=y(),v=typeof X=="function"?X():X;return typeof v=="string"?v:v[l]}function ne(c){const l=p();return l==="intentional"&&c.type!=="click"||l==="sloppy"&&c.type==="click"}function Q(c){const l=b.current.floatingContext?.nodeId,X=T&&Fe(T.nodesRef.current,l).some(v=>He(c,v.context?.elements.floating));return B(c)||X}function ge(c){if(ne(c)){c.type!=="click"&&!B(c)&&($.clear(),Z.current=!1),N();return}if(b.current.insideReactTree){N();return}const l=be(c),X=`[${Ve("inert")}]`,v=Ie(l)?l.getRootNode():null,ue=Array.from((Ct(v)?v:K(f.select("floatingElement"))).querySelectorAll(X)),we=f.context.triggerElements;if(l&&(we.hasElement(l)||we.hasMatchingElement(re=>C(re,l))))return;let Ce=Ie(l)?l:null;for(;Ce&&!_e(Ce);){const re=en(Ce);if(_e(re)||!Ie(re))break;Ce=re}if(!(ue.length&&Ie(l)&&!tn(l)&&!C(l,f.select("floatingElement"))&&ue.every(re=>!C(Ce,re)))){if(he(l)&&!("touches"in c)){const re=_e(l),Ye=nn(l),st=/auto|scroll/,At=re||st.test(Ye.overflowX),Nt=re||st.test(Ye.overflowY),Wt=At&&l.clientWidth>0&&l.scrollWidth>l.clientWidth,Lt=Nt&&l.clientHeight>0&&l.scrollHeight>l.clientHeight,Bt=Ye.direction==="rtl",Yt=Lt&&(Bt?c.offsetX<=l.offsetWidth-l.clientWidth:c.offsetX>l.clientWidth),Ht=Wt&&c.offsetY>l.clientHeight;if(Yt||Ht)return}if(!Q(c)){if(p()==="intentional"&&Z.current){$.clear(),Z.current=!1;return}typeof P=="function"&&!P(c)||R("__outsidePressBubbles")||(f.setOpen(!1,Pe(It,c)),N())}}}function m(c){p()!=="sloppy"||c.pointerType==="touch"||!f.select("open")||!n||B(c)||ge(c)}function I(c){if(p()!=="sloppy"||!f.select("open")||!n||B(c))return;const l=c.touches[0];l&&(F.current={startTime:Date.now(),startX:l.clientX,startY:l.clientY,dismissOnTouchEnd:!1,dismissOnMouseDown:!0},j.start(1e3,()=>{F.current&&(F.current.dismissOnTouchEnd=!1,F.current.dismissOnMouseDown=!1)}))}function W(c,l){const X=be(c);if(!X)return;const v=x(X,c.type,()=>{l(c),v()})}function D(c){se.current="touch",W(c,I)}function z(c){j.clear(),c.type==="pointerdown"&&(se.current=c.pointerType),!(c.type==="mousedown"&&F.current&&!F.current.dismissOnMouseDown)&&W(c,l=>{l.type==="pointerdown"?m(l):ge(l)})}function a(c){if(!Y.current)return;const l=q.current;if(Me(),p()==="intentional"){if(c.type==="pointercancel"){l&&Oe();return}if(!Q(c)){if(l){Oe();return}typeof P=="function"&&!P(c)||($.clear(),Z.current=!0,N())}}}function O(c){if(p()!=="sloppy"||!F.current||B(c))return;const l=c.touches[0];if(!l)return;const X=Math.abs(l.clientX-F.current.startX),v=Math.abs(l.clientY-F.current.startY),ue=Math.sqrt(X*X+v*v);ue>5&&(F.current.dismissOnTouchEnd=!0),ue>10&&(ge(c),j.clear(),F.current=null)}function d(c){W(c,O)}function M(c){p()!=="sloppy"||!F.current||B(c)||(F.current.dismissOnTouchEnd&&ge(c),j.clear(),F.current=null)}function U(c){W(c,M)}const w=K(L),Re=ke(r&&ke(x(w,"keydown",ee),x(w,"compositionstart",ie),x(w,"compositionend",ce)),_&&ke(x(w,"click",z,!0),x(w,"pointerdown",z,!0),x(w,"pointerup",a,!0),x(w,"pointercancel",a,!0),x(w,"mousedown",z,!0),x(w,"mouseup",a,!0),x(w,"touchstart",D,!0),x(w,"touchmove",d,!0),x(w,"touchend",U,!0)));return()=>{Re(),S.clear(),$.clear(),Me(),Z.current=!1}},[b,L,r,_,P,k,n,E,J,ee,N,y,R,B,T,f,j]),g.useEffect(N,[P,N]);const pe=g.useMemo(()=>({onKeyDown:ee,onPointerDown:oe,onClick:oe}),[ee,oe]),ye=g.useMemo(()=>({onKeyDown:ee,onPointerDown:de,onMouseDown:de,onClickCapture:te,onMouseDownCapture(S){te(),Ee(S)},onPointerDownCapture(S){te(),Ee(S)},onMouseUpCapture:te,onTouchEndCapture:te,onTouchMoveCapture:te}),[ee,te,Ee,de]);return g.useMemo(()=>n?{reference:pe,floating:ye,trigger:pe}:{},[n,pe,ye])}function vn(e){const t=g.useRef(!0);t.current&&(t.current=!1,e())}const On={open:Te(e=>e.open),transitionStatus:Te(e=>e.transitionStatus),domReferenceElement:Te(e=>e.domReferenceElement),referenceElement:Te(e=>e.positionReference??e.referenceElement),floatingElement:Te(e=>e.floatingElement),floatingId:Te(e=>e.floatingId)};class wn extends rn{constructor(t){const{syncOnly:n,nested:r,onOpenChange:s,triggerElements:o,...i}=t;super({...i,positionReference:i.referenceElement,domReferenceElement:i.referenceElement},{onOpenChange:s,dataRef:{current:{}},events:Pt(),nested:r,triggerElements:o},On),this.syncOnly=n}syncOpenEvent=(t,n)=>{(!t||!this.state.open||n!=null&&gn(n))&&(this.context.dataRef.current.openEvent=t?n:void 0)};dispatchOpenChange=(t,n)=>{this.syncOpenEvent(t,n.event);const r={open:t,reason:n.reason,nativeEvent:n.event,nested:this.context.nested,triggerElement:n.trigger};this.context.events.emit("openchange",r)};setOpen=(t,n)=>{if(this.syncOnly){this.context.onOpenChange?.(t,n);return}this.dispatchOpenChange(t,n),this.context.onOpenChange?.(t,n)}}function Cn(e){const{popupStore:t,treatPopupAsFloatingElement:n=!1,floatingRootContext:r,floatingId:s,nested:o,onOpenChange:i}=e,u=t.useState("open"),h=t.useState("activeTriggerElement"),f=t.useState(n?"popupElement":"positionerElement"),k=t.context.triggerElements,L=i,b=g.useRef(null);r===void 0&&b.current===null&&(b.current=new wn({open:u,transitionStatus:void 0,referenceElement:h,floatingElement:f,triggerElements:k,onOpenChange:L,floatingId:s,syncOnly:!0,nested:o}));const T=r??b.current;return t.useSyncedValue("floatingId",s),H(()=>{const A={open:u,floatingId:s,referenceElement:h,floatingElement:f};Ie(h)&&(A.domReferenceElement=h),T.state.positionReference===T.state.referenceElement&&(A.positionReference=h),T.update(A)},[u,s,h,f,T]),T.context.onOpenChange=L,T.context.nested=o,T}function xn(e,t=!1,n=!1){const[r,s]=g.useState(e&&t?"idle":void 0),[o,i]=g.useState(e);return e&&!o&&(i(!0),s("starting")),!e&&o&&r!=="ending"&&!n&&s("ending"),!e&&!o&&r==="ending"&&s(void 0),H(()=>{if(!e&&o&&r!=="ending"&&n){const u=me.request(()=>{s("ending")});return()=>{me.cancel(u)}}},[e,o,r,n]),H(()=>{if(!e||t)return;const u=me.request(()=>{s(void 0)});return()=>{me.cancel(u)}},[t,e]),H(()=>{if(!e||!t)return;e&&o&&r!=="idle"&&s("starting");const u=me.request(()=>{s("idle")});return()=>{me.cancel(u)}},[t,e,o,r]),{mounted:o,setMounted:i,transitionStatus:r}}const rr={tabIndex:-1,[cn]:""};function sr(e){return t=>t==="touch"?e.current:!0}function or(e,t,n=!1){const r=ze(),s=et()!=null,o=g.useRef(null);e===void 0&&o.current===null&&(o.current=t(r,s));const i=e??o.current;return Cn({popupStore:i,treatPopupAsFloatingElement:n,floatingRootContext:i.state.floatingRootContext,floatingId:r,nested:s,onOpenChange:i.setOpen}),{store:i,internalStore:o.current}}function In(e,t){const n=g.useRef(null),r=g.useRef(null);return g.useCallback(s=>{if(e===void 0)return;let o=!1;if(n.current!==null){const i=n.current,u=r.current,h=t.context.triggerElements.getById(i);u&&h===u&&(t.context.triggerElements.delete(i),o=!0),n.current=null,r.current=null}if(s!==null&&(n.current=e,r.current=s,t.context.triggerElements.add(e,s),o=!0),o){const i=t.context.triggerElements.size;t.select("open")&&t.state.triggerCount!==i&&t.set("triggerCount",i)}},[t,e])}function ir(e,t,n,r=!1){t?e.preventUnmountingOnClose=!1:r&&(e.preventUnmountingOnClose=!0);const s=n?.id??null;(s||t)&&(e.activeTriggerId=s,e.activeTriggerElement=n??null)}function cr(e){let t=!1;return e.preventUnmountOnClose=()=>{t=!0},()=>t}function ur(e,t,n,r){vn(()=>{t===void 0&&e.state.open===!1&&n&&(e.state={...e.state,open:!0,activeTriggerId:r,preventUnmountingOnClose:!1})})}function lr(e,t,n,r){const s=n.useState("isMountedByTrigger",e),o=In(e,n),i=V(u=>{if(o(u),!u)return;const h=n.select("open"),f=n.select("activeTriggerId");if(f===e){n.update({activeTriggerElement:u,...h?r:null});return}f==null&&h&&n.update({activeTriggerId:e,activeTriggerElement:u,...r})});return H(()=>{s&&n.update({activeTriggerElement:t.current,...r})},[s,n,t,...Object.values(r)]),{registerTrigger:i,isMountedByThisTrigger:s}}function ar(e,t={}){const{closeOnActiveTriggerUnmount:n=!1}=t,r=e.useState("open"),s=e.useState("triggerCount");H(()=>{if(!r){e.state.triggerCount!==0&&e.set("triggerCount",0);return}const o=e.context.triggerElements.size,i={};e.state.triggerCount!==o&&(i.triggerCount=o);const u=e.select("activeTriggerId");let h=null;if(u){const f=e.context.triggerElements.getById(u);f?f!==e.state.activeTriggerElement&&(i.activeTriggerElement=f):h=u}if(!h&&!u&&o===1){const f=e.context.triggerElements.entries().next();if(!f.done){const[k,L]=f.value;i.activeTriggerId=k,i.activeTriggerElement=L}}(i.triggerCount!==void 0||i.activeTriggerId!==void 0||i.activeTriggerElement!==void 0)&&e.update(i),h&&n&&queueMicrotask(()=>{if(e.select("open")&&e.select("activeTriggerId")===h&&!e.context.triggerElements.getById(h)){const f=Pe(sn);e.setOpen(!1,f),f.isCanceled||e.update({activeTriggerId:null,activeTriggerElement:null})}})},[r,e,s,n])}function fr(e,t,n){const{mounted:r,setMounted:s,transitionStatus:o}=xn(e),i=t.useState("preventUnmountingOnClose"),u=e?!1:i;t.useSyncedValues({mounted:r,transitionStatus:o,preventUnmountingOnClose:u});const h=V(()=>{s(!1),t.update({activeTriggerId:null,activeTriggerElement:null,mounted:!1,preventUnmountingOnClose:!1}),n?.(),t.context.onOpenChangeComplete?.(!1)});return on({enabled:r&&!e&&!u,open:e,ref:t.context.popupRef,onComplete(){e||h()}}),{forceUnmount:h,transitionStatus:o}}function dr(e,t){e.useSyncedValues(t),H(()=>()=>{e.update({activeTriggerProps:Ge,inactiveTriggerProps:Ge,popupProps:Ge})},[e])}function pr(e,t){H(()=>{!t&&e.state.openMethod!==null&&e.set("openMethod",null)},[t,e]),H(()=>()=>{e.state.openMethod!==null&&e.set("openMethod",null)},[e])}class gr{constructor(){this.elementsSet=new Set,this.idMap=new Map}add(t,n){const r=this.idMap.get(t);r!==n&&(r!==void 0&&this.elementsSet.delete(r),this.elementsSet.add(n),this.idMap.set(t,n))}delete(t){const n=this.idMap.get(t);n&&(this.elementsSet.delete(n),this.idMap.delete(t))}hasElement(t){return this.elementsSet.has(t)}hasMatchingElement(t){for(const n of this.elementsSet)if(t(n))return!0;return!1}getById(t){return this.idMap.get(t)}entries(){return this.idMap.entries()}elements(){return this.elementsSet.values()}get size(){return this.idMap.size}}let rt=(function(e){return e.open="data-open",e.closed="data-closed",e[e.startingStyle=at.startingStyle]="startingStyle",e[e.endingStyle=at.endingStyle]="endingStyle",e.anchorHidden="data-anchor-hidden",e.side="data-side",e.align="data-align",e})({}),je=(function(e){return e.popupOpen="data-popup-open",e.pressed="data-pressed",e})({});const kn={[je.popupOpen]:""},Pn={[je.popupOpen]:"",[je.pressed]:""},Fn={[rt.open]:""},Mn={[rt.closed]:""},An={[rt.anchorHidden]:""},hr={open(e){return e?kn:null}},mr={open(e){return e?Pn:null}},br={open(e){return e?Fn:Mn},anchorHidden(e){return e?An:null}};function Er(e){return ze(e,"base-ui")}const Nn="ArrowUp",Wn="ArrowDown",Ln="ArrowLeft",Bn="ArrowRight",Yn="Home",Hn="End",_n=new Set([Ln,Bn]),Gn=new Set([Nn,Wn]),Dn=new Set([..._n,...Gn]),yr=new Set([...Dn,Yn,Hn]),Rr=g.forwardRef(function(t,n){const{cutout:r,...s}=t;let o;if(r){const i=r.getBoundingClientRect();o=`polygon(0% 0%,100% 0%,100% 100%,0% 100%,0% 0%,${i.left}px ${i.top}px,${i.left}px ${i.bottom}px,${i.right}px ${i.bottom}px,${i.right}px ${i.top}px,${i.left}px ${i.top}px)`}return Se.jsx("div",{ref:n,role:"presentation","data-base-ui-inert":"",...s,style:{position:"fixed",inset:0,userSelect:"none",WebkitUserSelect:"none",clipPath:o}})});let Tt={},St={},vt="";function Un(e){if(typeof document>"u")return!1;const t=K(e);return Be(t).innerWidth-t.documentElement.clientWidth>0}function Kn(e){if(!(typeof CSS<"u"&&CSS.supports&&CSS.supports("scrollbar-gutter","stable"))||typeof document>"u")return!1;const n=K(e),r=n.documentElement,s=n.body,o=Qe(r)?r:s,i=o.style.overflowY,u=r.style.scrollbarGutter;r.style.scrollbarGutter="stable",o.style.overflowY="scroll";const h=o.offsetWidth;o.style.overflowY="hidden";const f=o.offsetWidth;return o.style.overflowY=i,r.style.scrollbarGutter=u,h===f}function Xn(e){const t=K(e),n=t.documentElement,r=t.body,s=Qe(n)?n:r,o={overflowY:s.style.overflowY,overflowX:s.style.overflowX};return Object.assign(s.style,{overflowY:"hidden",overflowX:"hidden"}),()=>{Object.assign(s.style,o)}}function Vn(e){const t=K(e),n=t.documentElement,r=t.body,s=Be(n);let o=0,i=0,u=!1;const h=me.create();if(Ze&&(s.visualViewport?.scale??1)!==1)return()=>{};function f(){const T=s.getComputedStyle(n),A=s.getComputedStyle(r),y=(T.scrollbarGutter||"").includes("both-edges")?"stable both-edges":"stable";o=n.scrollTop,i=n.scrollLeft,Tt={scrollbarGutter:n.style.scrollbarGutter,overflowY:n.style.overflowY,overflowX:n.style.overflowX},vt=n.style.scrollBehavior,St={position:r.style.position,height:r.style.height,width:r.style.width,boxSizing:r.style.boxSizing,overflowY:r.style.overflowY,overflowX:r.style.overflowX,scrollBehavior:r.style.scrollBehavior};const E=n.scrollHeight>n.clientHeight,J=n.scrollWidth>n.clientWidth,Y=T.overflowY==="scroll"||A.overflowY==="scroll",q=T.overflowX==="scroll"||A.overflowX==="scroll",Z=Math.max(0,s.innerWidth-r.clientWidth),G=Math.max(0,s.innerHeight-r.clientHeight),se=parseFloat(A.marginTop)+parseFloat(A.marginBottom),F=parseFloat(A.marginLeft)+parseFloat(A.marginRight),j=Qe(n)?n:r;if(u=Kn(e),u){n.style.scrollbarGutter=y,j.style.overflowY="hidden",j.style.overflowX="hidden";return}Object.assign(n.style,{scrollbarGutter:y,overflowY:"hidden",overflowX:"hidden"}),(E||Y)&&(n.style.overflowY="scroll"),(J||q)&&(n.style.overflowX="scroll"),Object.assign(r.style,{position:"relative",height:se||G?`calc(100dvh - ${se+G}px)`:"100dvh",width:F||Z?`calc(100vw - ${F+Z}px)`:"100vw",boxSizing:"border-box",overflow:"hidden",scrollBehavior:"unset"}),r.scrollTop=o,r.scrollLeft=i,n.setAttribute("data-base-ui-scroll-locked",""),n.style.scrollBehavior="unset"}function k(){Object.assign(n.style,Tt),Object.assign(r.style,St),u||(n.scrollTop=o,n.scrollLeft=i,n.removeAttribute("data-base-ui-scroll-locked"),n.style.scrollBehavior=vt)}function L(){k(),h.request(f)}f();const b=x(s,"resize",L);return()=>{h.cancel(),k(),typeof s.removeEventListener=="function"&&b()}}class qn{lockCount=0;restore=null;timeoutLock=Le.create();timeoutUnlock=Le.create();acquire(t){return this.lockCount+=1,this.lockCount===1&&this.restore===null&&this.timeoutLock.start(0,()=>this.lock(t)),this.release}release=()=>{this.lockCount-=1,this.lockCount===0&&this.restore&&this.timeoutUnlock.start(0,this.unlock)};unlock=()=>{this.lockCount===0&&this.restore&&(this.restore?.(),this.restore=null)};lock(t){if(this.lockCount===0||this.restore!==null)return;const r=K(t).documentElement,s=Be(r).getComputedStyle(r).overflowY;if(s==="hidden"||s==="clip"){this.restore=wt;return}const o=un||!Un(t);this.restore=o?Xn(t):Vn(t)}}const jn=new qn;function Tr(e=!0,t=null){H(()=>{if(e)return jn.acquire(t)},[e,t])}export{wn as A,De as B,zn as C,an as D,dn as E,er as F,pn as G,vn as H,Rr as I,Tr as J,rt as K,gr as P,xn as a,tt as b,et as c,Ae as d,cr as e,or as f,Fe as g,ur as h,Zn as i,pr as j,ar as k,fr as l,nr as m,rr as n,dr as o,lr as p,mr as q,Jn as r,ir as s,hr as t,Er as u,Qn as v,sr as w,tr as x,yr as y,br as z};
|
|
@@ -235,8 +235,8 @@
|
|
|
235
235
|
]
|
|
236
236
|
}
|
|
237
237
|
</script>
|
|
238
|
-
<script type="module" crossorigin src="/assets/main-
|
|
239
|
-
<link rel="stylesheet" crossorigin href="/assets/main-
|
|
238
|
+
<script type="module" crossorigin src="/assets/main-CnThe5nE.js"></script>
|
|
239
|
+
<link rel="stylesheet" crossorigin href="/assets/main-DEU_X1Ba.css">
|
|
240
240
|
</head>
|
|
241
241
|
<body>
|
|
242
242
|
<main class="aeo-seed-content" aria-label="Token Tracker AI-readable summary">
|
|
@@ -75,8 +75,8 @@
|
|
|
75
75
|
"description": "Shareable Token Tracker dashboard snapshot."
|
|
76
76
|
}
|
|
77
77
|
</script>
|
|
78
|
-
<script type="module" crossorigin src="/assets/main-
|
|
79
|
-
<link rel="stylesheet" crossorigin href="/assets/main-
|
|
78
|
+
<script type="module" crossorigin src="/assets/main-CnThe5nE.js"></script>
|
|
79
|
+
<link rel="stylesheet" crossorigin href="/assets/main-DEU_X1Ba.css">
|
|
80
80
|
</head>
|
|
81
81
|
<body>
|
|
82
82
|
<main class="aeo-seed-content" aria-label="Token Tracker share page summary">
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tokentracker-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.64.1",
|
|
4
4
|
"description": "Token usage tracker for AI agent CLIs (Claude Code, Codex, Cursor, Gemini, Antigravity, Kiro, OpenCode, OpenClaw, Every Code, Hermes, GitHub Copilot, Kimi Code, CodeBuddy, WorkBuddy, Grok Build, oh-my-pi, pi, Craft Agents, Kilo CLI, Kilo Code, Roo Code, Zed Agent, Goose, Mimo, ZCode)",
|
|
5
5
|
"main": "src/cli.js",
|
|
6
6
|
"bin": {
|
|
@@ -38,7 +38,9 @@
|
|
|
38
38
|
"validate:copy": "node scripts/validate-copy-registry.cjs",
|
|
39
39
|
"validate:guardrails": "node scripts/validate-architecture-guardrails.cjs",
|
|
40
40
|
"validate:retros": "node scripts/validate-retros.cjs",
|
|
41
|
-
"validate:ui-hardcode": "node scripts/ops/validate-ui-hardcode.cjs"
|
|
41
|
+
"validate:ui-hardcode": "node scripts/ops/validate-ui-hardcode.cjs",
|
|
42
|
+
"sync-versions": "node scripts/sync-versions.cjs",
|
|
43
|
+
"version": "node scripts/sync-versions.cjs && git add TokenTrackerBar/project.yml TokenTrackerWin/TokenTrackerWin.csproj"
|
|
42
44
|
},
|
|
43
45
|
"dependencies": {
|
|
44
46
|
"@mongodb-js/zstd": "^2.0.1",
|
package/src/lib/local-api.js
CHANGED
|
@@ -1595,6 +1595,31 @@ function createLocalApiHandler({ queuePath }) {
|
|
|
1595
1595
|
return true;
|
|
1596
1596
|
}
|
|
1597
1597
|
|
|
1598
|
+
// --- outcomes (opt-in quality-per-dollar / Effective Tokens; sidecar) ---
|
|
1599
|
+
// Reads the optional ~/.tokentracker/tracker/outcomes.jsonl sidecar and
|
|
1600
|
+
// joins it to the existing token/$ rows at READ time. Returns
|
|
1601
|
+
// available:false with empty arrays when the user hasn't opted in, so the
|
|
1602
|
+
// dashboard renders exactly as before. This path NEVER reads or writes
|
|
1603
|
+
// queue.jsonl's schema or the sync path (see GitHub #229).
|
|
1604
|
+
if (p === "/functions/tokentracker-outcomes") {
|
|
1605
|
+
const from = url.searchParams.get("from") || "";
|
|
1606
|
+
const to = url.searchParams.get("to") || "";
|
|
1607
|
+
const {
|
|
1608
|
+
readOutcomesData,
|
|
1609
|
+
resolveOutcomesPath,
|
|
1610
|
+
computeQualityPerDollar,
|
|
1611
|
+
} = require("./outcomes-engine");
|
|
1612
|
+
const outcomes = readOutcomesData(resolveOutcomesPath());
|
|
1613
|
+
if (!outcomes.length) {
|
|
1614
|
+
json(res, { available: false, from, to, by_model: [], by_tool: [], totals: null });
|
|
1615
|
+
return true;
|
|
1616
|
+
}
|
|
1617
|
+
const { rows, scope, excludedSources } = scopedQueueRows(qp, url);
|
|
1618
|
+
const result = computeQualityPerDollar(rows, outcomes, { from, to });
|
|
1619
|
+
json(res, { from, to, scope, excluded_sources: excludedSources, ...result });
|
|
1620
|
+
return true;
|
|
1621
|
+
}
|
|
1622
|
+
|
|
1598
1623
|
// --- usage-heatmap ---
|
|
1599
1624
|
if (p === "/functions/tokentracker-usage-heatmap") {
|
|
1600
1625
|
const weeks = parseInt(url.searchParams.get("weeks") || "52", 10);
|
|
@@ -1,20 +1,36 @@
|
|
|
1
1
|
const crypto = require("node:crypto");
|
|
2
|
+
const fssync = require("node:fs");
|
|
3
|
+
const path = require("node:path");
|
|
4
|
+
const { readSqliteJsonRowsAsync } = require("./sqlite-reader");
|
|
2
5
|
|
|
3
6
|
// OpenCode Go usage limits.
|
|
4
7
|
//
|
|
5
|
-
//
|
|
6
|
-
// (https://opencode.ai/workspace/<id>/go) for rolling (5h) / weekly / monthly
|
|
7
|
-
// usage. The opencode web console has no public REST API for quota today
|
|
8
|
-
// (tracked at anomalyco/opencode#16017, anomalyco/opencode#16513), so we
|
|
9
|
-
// read the same data the React app uses by parsing the SSR hydration output
|
|
10
|
-
// (SolidStart `queryLiteSubscription` serializes the result as
|
|
11
|
-
// `rollingUsage:$R[N]={...usagePercent:N...resetInSec:N...}`) with a
|
|
12
|
-
// `data-slot="usage-item"` HTML fallback.
|
|
8
|
+
// Two data sources, in priority order:
|
|
13
9
|
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
10
|
+
// 1. Local opencode.db (auth-free, the default / zero-config path). The
|
|
11
|
+
// `opencode` CLI records every Go turn's USD `cost` in its SQLite
|
|
12
|
+
// `message` table. OpenCode Go's limits are themselves dollar caps
|
|
13
|
+
// ($12/5h, $30/week, $60/month — https://opencode.ai/docs/go), so summing
|
|
14
|
+
// local cost per window ÷ the dollar cap is dimensionally exact, not a
|
|
15
|
+
// heuristic. Its only blind spot is usage that did NOT go through the
|
|
16
|
+
// local CLI (e.g. the web console, or another machine). This is what
|
|
17
|
+
// token-monitor (Javis603/token-monitor) falls back to, and the only
|
|
18
|
+
// source that survives opencode's OAuth changes (see #225).
|
|
19
|
+
//
|
|
20
|
+
// 2. Web scrape of the workspace dashboard
|
|
21
|
+
// (https://opencode.ai/workspace/<id>/go) for the server's EXACT
|
|
22
|
+
// rolling (5h) / weekly / monthly usagePercent. Used only when a cookie
|
|
23
|
+
// is configured AND the scrape succeeds — it carries the precise
|
|
24
|
+
// server-side number but is fragile: opencode moved auth to OAuth
|
|
25
|
+
// (auth.opencode.ai), so a bare `auth` cookie now often 302s to the login
|
|
26
|
+
// page (the #225 saga). The cookie is sent verbatim as
|
|
27
|
+
// `Cookie: auth=<OPENCODE_GO_AUTH_COOKIE>` per slkiser/opencode-quota#41.
|
|
28
|
+
//
|
|
29
|
+
// The opencode web console has no public REST API for quota
|
|
30
|
+
// (anomalyco/opencode#16017, #16513) and the CLI's `sk-` API key authenticates
|
|
31
|
+
// only the inference gateway (/zen/go/v1), not the usage windows — so the local
|
|
32
|
+
// DB is the only accurate auth-free option. The returned shape is identical for
|
|
33
|
+
// both sources; `source` is `'local'` or `'web'`.
|
|
18
34
|
|
|
19
35
|
const SCRAPED_NUMBER_PATTERN = "([0-9]+(?:\\.[0-9]+)?)";
|
|
20
36
|
|
|
@@ -271,15 +287,195 @@ function looksSignedOut(text) {
|
|
|
271
287
|
|| l.includes("not associated with an account") || l.includes('actor of type "public"');
|
|
272
288
|
}
|
|
273
289
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
290
|
+
// --- Local opencode.db cost aggregation (auth-free source) ------------------
|
|
291
|
+
|
|
292
|
+
const SESSION_MS = 5 * 60 * 60 * 1000;
|
|
293
|
+
const WEEK_MS = 7 * 24 * 60 * 60 * 1000;
|
|
294
|
+
// OpenCode Go's official dollar caps — https://opencode.ai/docs/go
|
|
295
|
+
// ($12 per 5h, $30 per week, $60 per month). The limits are not stored in the
|
|
296
|
+
// local DB, so they are hardcoded; env-overridable in case opencode changes
|
|
297
|
+
// them (TOKENTRACKER_OPENCODE_GO_LIMITS="12,30,60").
|
|
298
|
+
const DEFAULT_GO_LIMITS = { session: 12, weekly: 30, monthly: 60 };
|
|
299
|
+
|
|
300
|
+
function goDollarLimits(env = process.env) {
|
|
301
|
+
const raw = String((env && env.TOKENTRACKER_OPENCODE_GO_LIMITS) || "").trim();
|
|
302
|
+
if (!raw) return { ...DEFAULT_GO_LIMITS };
|
|
303
|
+
const parts = raw.split(",").map((s) => Number(s.trim()));
|
|
304
|
+
if (parts.length === 3 && parts.every((n) => Number.isFinite(n) && n > 0)) {
|
|
305
|
+
return { session: parts[0], weekly: parts[1], monthly: parts[2] };
|
|
306
|
+
}
|
|
307
|
+
return { ...DEFAULT_GO_LIMITS };
|
|
308
|
+
}
|
|
282
309
|
|
|
310
|
+
// Mirror sync.js's opencode home resolution (OPENCODE_HOME / XDG_DATA_HOME /
|
|
311
|
+
// <home>/.local/share/opencode) so we read the SAME DB the parser reads. The
|
|
312
|
+
// user home comes from the `home` arg getUsageLimits already threads to every
|
|
313
|
+
// other home-based provider (cf. resolveZcodeHome). NOTE: we deliberately do
|
|
314
|
+
// NOT fall back to os.homedir() — only an explicit `home`/env HOME — so a
|
|
315
|
+
// synthetic test env (no home, no HOME) discovers nothing and the web-scrape
|
|
316
|
+
// tests stay isolated from the developer's real opencode.db.
|
|
317
|
+
function resolveOpencodeDataDir({ home, env = process.env } = {}) {
|
|
318
|
+
if (env.OPENCODE_HOME) return env.OPENCODE_HOME;
|
|
319
|
+
if (env.XDG_DATA_HOME) return path.join(env.XDG_DATA_HOME, "opencode");
|
|
320
|
+
const base = home || env.HOME || env.USERPROFILE;
|
|
321
|
+
if (!base) return null;
|
|
322
|
+
return path.join(base, ".local", "share", "opencode");
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Matches `opencode.db` or `opencode-<channel>.db`; excludes WAL/SHM side-files.
|
|
326
|
+
function isOpencodeDbFilename(name) {
|
|
327
|
+
if (!name.endsWith(".db")) return false;
|
|
328
|
+
const stem = name.slice(0, -3);
|
|
329
|
+
if (stem === "opencode") return true;
|
|
330
|
+
if (!stem.startsWith("opencode-")) return false;
|
|
331
|
+
const channel = stem.slice("opencode-".length);
|
|
332
|
+
return channel.length > 0 && /^[A-Za-z0-9._-]+$/.test(channel);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
function discoverOpencodeDbPaths({ home, env = process.env } = {}) {
|
|
336
|
+
const override = String((env && env.OPENCODE_DB) || "").trim();
|
|
337
|
+
if (override) {
|
|
338
|
+
try {
|
|
339
|
+
if (fssync.statSync(override).isFile()) return [override];
|
|
340
|
+
} catch (_e) {
|
|
341
|
+
/* fall through to directory scan */
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
const dir = resolveOpencodeDataDir({ home, env });
|
|
345
|
+
if (!dir) return [];
|
|
346
|
+
let entries;
|
|
347
|
+
try {
|
|
348
|
+
entries = fssync.readdirSync(dir);
|
|
349
|
+
} catch (_e) {
|
|
350
|
+
return [];
|
|
351
|
+
}
|
|
352
|
+
return entries.filter(isOpencodeDbFilename).sort().map((n) => path.join(dir, n));
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
function weekStartMs(nowMs) {
|
|
356
|
+
const d = new Date(nowMs);
|
|
357
|
+
const day = d.getUTCDay(); // 0=Sun..6=Sat
|
|
358
|
+
const sinceMonday = day === 0 ? 6 : day - 1;
|
|
359
|
+
return Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate() - sinceMonday);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Calendar-month bounds (UTC). OpenCode Go's true monthly reset is the
|
|
363
|
+
// subscription anniversary, which the local DB does not record; the calendar
|
|
364
|
+
// month is a stable, defensible approximation for the auth-free estimate.
|
|
365
|
+
function monthBoundsMs(nowMs) {
|
|
366
|
+
const now = new Date(nowMs);
|
|
367
|
+
return {
|
|
368
|
+
startMs: Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1),
|
|
369
|
+
endMs: Date.UTC(now.getUTCFullYear(), now.getUTCMonth() + 1, 1),
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// Percentage clamp for the local estimate. Unlike clampPercent() (which scales
|
|
374
|
+
// a 0–1 fraction from the web payload), this treats its input as an already-
|
|
375
|
+
// computed percentage and must NOT rescale values below 1 (e.g. 0.5%).
|
|
376
|
+
function clampLocalPercent(n) {
|
|
377
|
+
if (!Number.isFinite(n)) return null;
|
|
378
|
+
if (n <= 0) return 0;
|
|
379
|
+
if (n >= 100) return 100;
|
|
380
|
+
return n;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
function buildLocalWindow({ used, limit, resetMs }) {
|
|
384
|
+
if (!(limit > 0)) return null;
|
|
385
|
+
const pct = clampLocalPercent((Number(used) / limit) * 100);
|
|
386
|
+
if (pct === null) return null;
|
|
387
|
+
return { used_percent: pct, reset_at: new Date(resetMs).toISOString() };
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// One full-table aggregate (the message table has no index on the JSON fields,
|
|
391
|
+
// so we sum in SQLite and return a single row rather than streaming every
|
|
392
|
+
// opencode-go turn into JS — keeps the limits poll cheap, cf. the spawnSync
|
|
393
|
+
// freeze lesson).
|
|
394
|
+
function buildGoAggregateSql({ sessionStart, weekStart, weekEnd, monthStart, monthEnd }) {
|
|
395
|
+
return (
|
|
396
|
+
"SELECT " +
|
|
397
|
+
`COALESCE(SUM(CASE WHEN createdMs >= ${sessionStart} THEN cost ELSE 0 END), 0) AS sessionCost, ` +
|
|
398
|
+
`MIN(CASE WHEN createdMs >= ${sessionStart} THEN createdMs END) AS sessionOldest, ` +
|
|
399
|
+
`COALESCE(SUM(CASE WHEN createdMs >= ${weekStart} AND createdMs < ${weekEnd} THEN cost ELSE 0 END), 0) AS weeklyCost, ` +
|
|
400
|
+
`COALESCE(SUM(CASE WHEN createdMs >= ${monthStart} AND createdMs < ${monthEnd} THEN cost ELSE 0 END), 0) AS monthlyCost, ` +
|
|
401
|
+
"COUNT(*) AS rowCount " +
|
|
402
|
+
"FROM (" +
|
|
403
|
+
"SELECT CAST(COALESCE(json_extract(data,'$.time.created'), time_created) AS INTEGER) AS createdMs, " +
|
|
404
|
+
"CAST(json_extract(data,'$.cost') AS REAL) AS cost " +
|
|
405
|
+
"FROM message " +
|
|
406
|
+
"WHERE json_valid(data) " +
|
|
407
|
+
"AND json_extract(data,'$.providerID') = 'opencode-go' " +
|
|
408
|
+
"AND json_extract(data,'$.role') = 'assistant' " +
|
|
409
|
+
"AND json_type(data,'$.cost') IN ('integer','real')" +
|
|
410
|
+
")"
|
|
411
|
+
);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// Returns { source:'local', primary/secondary/tertiary_window } or null when no
|
|
415
|
+
// opencode.db / no opencode-go rows are found.
|
|
416
|
+
async function collectOpencodeGoLocal({ home, env = process.env, nowMs = Date.now(), sqliteOptions = {} } = {}) {
|
|
417
|
+
const paths = discoverOpencodeDbPaths({ home, env });
|
|
418
|
+
if (paths.length === 0) return null;
|
|
419
|
+
|
|
420
|
+
const sessionStart = Math.floor(nowMs - SESSION_MS);
|
|
421
|
+
const weekStart = weekStartMs(nowMs);
|
|
422
|
+
const weekEnd = weekStart + WEEK_MS;
|
|
423
|
+
const { startMs: monthStart, endMs: monthEnd } = monthBoundsMs(nowMs);
|
|
424
|
+
const sql = buildGoAggregateSql({ sessionStart, weekStart, weekEnd, monthStart, monthEnd });
|
|
425
|
+
|
|
426
|
+
let agg = null;
|
|
427
|
+
for (const dbPath of paths) {
|
|
428
|
+
let rows;
|
|
429
|
+
try {
|
|
430
|
+
rows = await readSqliteJsonRowsAsync(dbPath, sql, {
|
|
431
|
+
label: "OpenCode Go",
|
|
432
|
+
timeout: 5_000,
|
|
433
|
+
...sqliteOptions,
|
|
434
|
+
});
|
|
435
|
+
} catch (_e) {
|
|
436
|
+
continue;
|
|
437
|
+
}
|
|
438
|
+
const row = rows && rows[0];
|
|
439
|
+
if (!row) continue;
|
|
440
|
+
const rowCount = Number(row.rowCount) || 0;
|
|
441
|
+
if (rowCount <= 0) continue;
|
|
442
|
+
if (!agg) agg = { sessionCost: 0, weeklyCost: 0, monthlyCost: 0, sessionOldest: null, rowCount: 0 };
|
|
443
|
+
agg.sessionCost += Number(row.sessionCost) || 0;
|
|
444
|
+
agg.weeklyCost += Number(row.weeklyCost) || 0;
|
|
445
|
+
agg.monthlyCost += Number(row.monthlyCost) || 0;
|
|
446
|
+
agg.rowCount += rowCount;
|
|
447
|
+
const oldest = row.sessionOldest == null ? null : Number(row.sessionOldest);
|
|
448
|
+
if (oldest != null && Number.isFinite(oldest)) {
|
|
449
|
+
agg.sessionOldest = agg.sessionOldest == null ? oldest : Math.min(agg.sessionOldest, oldest);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
if (!agg || agg.rowCount <= 0) return null;
|
|
453
|
+
|
|
454
|
+
const limits = goDollarLimits(env);
|
|
455
|
+
const sessionReset = (agg.sessionOldest != null ? agg.sessionOldest : nowMs) + SESSION_MS;
|
|
456
|
+
return {
|
|
457
|
+
source: "local",
|
|
458
|
+
primary_window: buildLocalWindow({ used: agg.sessionCost, limit: limits.session, resetMs: sessionReset }),
|
|
459
|
+
secondary_window: buildLocalWindow({ used: agg.weeklyCost, limit: limits.weekly, resetMs: weekEnd }),
|
|
460
|
+
tertiary_window: buildLocalWindow({ used: agg.monthlyCost, limit: limits.monthly, resetMs: monthEnd }),
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
function localGoResult(local) {
|
|
465
|
+
return {
|
|
466
|
+
configured: true,
|
|
467
|
+
error: null,
|
|
468
|
+
source: "local",
|
|
469
|
+
// No `plan_label` — the brand name "OpenCode Go" is the row title.
|
|
470
|
+
primary_window: local.primary_window || null,
|
|
471
|
+
secondary_window: local.secondary_window || null,
|
|
472
|
+
tertiary_window: local.tertiary_window || null,
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// --- Web scrape (exact server-side usage, cookie-gated) ---------------------
|
|
477
|
+
|
|
478
|
+
async function scrapeOpencodeGoWeb({ cfg, fetchImpl, nowMs, timeoutMs }) {
|
|
283
479
|
let workspaceId = cfg.workspaceId;
|
|
284
480
|
if (!workspaceId) {
|
|
285
481
|
try {
|
|
@@ -349,6 +545,34 @@ async function fetchOpencodeGoLimits({
|
|
|
349
545
|
};
|
|
350
546
|
}
|
|
351
547
|
|
|
548
|
+
async function fetchOpencodeGoLimits({
|
|
549
|
+
home,
|
|
550
|
+
env = process.env,
|
|
551
|
+
fetchImpl = fetch,
|
|
552
|
+
nowMs = Date.now(),
|
|
553
|
+
timeoutMs = DEFAULT_SCRAPE_TIMEOUT_MS,
|
|
554
|
+
sqliteOptions = {},
|
|
555
|
+
} = {}) {
|
|
556
|
+
const cfg = readConfig(env);
|
|
557
|
+
|
|
558
|
+
// Cookie configured → prefer the exact server-side scrape; fall back to the
|
|
559
|
+
// local DB estimate when the scrape can't authenticate/parse (the #225 case).
|
|
560
|
+
if (cfg) {
|
|
561
|
+
const web = await scrapeOpencodeGoWeb({ cfg, fetchImpl, nowMs, timeoutMs });
|
|
562
|
+
if (web && !web.error && (web.primary_window || web.secondary_window || web.tertiary_window)) {
|
|
563
|
+
return { ...web, source: "web" };
|
|
564
|
+
}
|
|
565
|
+
const local = await collectOpencodeGoLocal({ home, env, nowMs, sqliteOptions });
|
|
566
|
+
if (local) return localGoResult(local);
|
|
567
|
+
return web || { configured: true, error: "OpenCode Go unavailable" };
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
// No cookie → the local opencode.db is the zero-config source.
|
|
571
|
+
const local = await collectOpencodeGoLocal({ home, env, nowMs, sqliteOptions });
|
|
572
|
+
if (local) return localGoResult(local);
|
|
573
|
+
return { configured: false };
|
|
574
|
+
}
|
|
575
|
+
|
|
352
576
|
module.exports = {
|
|
353
577
|
fetchOpencodeGoLimits,
|
|
354
578
|
readConfig,
|
|
@@ -360,4 +584,13 @@ module.exports = {
|
|
|
360
584
|
resolveWorkspaceId,
|
|
361
585
|
parseWorkspaceIds,
|
|
362
586
|
looksSignedOut,
|
|
587
|
+
// Local opencode.db cost-based estimate (auth-free source).
|
|
588
|
+
collectOpencodeGoLocal,
|
|
589
|
+
discoverOpencodeDbPaths,
|
|
590
|
+
resolveOpencodeDataDir,
|
|
591
|
+
isOpencodeDbFilename,
|
|
592
|
+
goDollarLimits,
|
|
593
|
+
weekStartMs,
|
|
594
|
+
monthBoundsMs,
|
|
595
|
+
buildLocalWindow,
|
|
363
596
|
};
|