@ipv9/tokentracker-cli 0.39.38 → 0.39.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -9
- package/dashboard/dist/assets/{Card-DD4s0V6T.js → Card-BbRYRVXf.js} +1 -1
- package/dashboard/dist/assets/DashboardPage-DYKHv0m3.js +60 -0
- package/dashboard/dist/assets/{FadeIn-CUSBK0jm.js → FadeIn-CjAacJ5t.js} +1 -1
- package/dashboard/dist/assets/{IpCheckPage-PHF4lPax.js → IpCheckPage-BGALK8Vy.js} +1 -1
- package/dashboard/dist/assets/{LimitsPage-dS9C9Vdt.js → LimitsPage-LkZGPYvg.js} +2 -2
- package/dashboard/dist/assets/{LocalOnlyNotice-DCmtS_j5.js → LocalOnlyNotice-Dxo2vFMQ.js} +1 -1
- package/dashboard/dist/assets/PopoverPopup-DP9fwdtl.js +1 -0
- package/dashboard/dist/assets/Select-DPE53NmM.js +1 -0
- package/dashboard/dist/assets/SelectItemText-D69v77is.js +12 -0
- package/dashboard/dist/assets/SettingsPage-Dxzqpi02.js +1 -0
- package/dashboard/dist/assets/SkillsPage-Bo7e39AB.js +1 -0
- package/dashboard/dist/assets/WidgetsPage-HHcIr_Eq.js +1 -0
- package/dashboard/dist/assets/WrappedPage-C-_jLXXU.js +1 -0
- package/dashboard/dist/assets/{arrow-up-right-CjaBQnwI.js → arrow-up-right-BJvJHUGj.js} +1 -1
- package/dashboard/dist/assets/{download-DLBqkSwp.js → download-CnzY_EgN.js} +1 -1
- package/dashboard/dist/assets/format-1w-q5n2f.js +1 -0
- package/dashboard/dist/assets/main-1kxAVM3m.css +1 -0
- package/dashboard/dist/assets/main-3gBEI6Jl.js +694 -0
- package/dashboard/dist/assets/mock-data-CJOMGcL9.js +1 -0
- package/dashboard/dist/assets/use-limits-display-prefs-D1nT9-mr.js +1 -0
- package/dashboard/dist/assets/use-native-settings-Dh6NzqjY.js +1 -0
- package/dashboard/dist/assets/use-usage-limits-BXR6lzGf.js +1 -0
- package/dashboard/dist/assets/useCurrency-Hhs5jbWw.js +1 -0
- package/dashboard/dist/index.html +15 -27
- package/dashboard/dist/llms.txt +0 -2
- package/dashboard/dist/sitemap.xml +0 -12
- package/package.json +7 -4
- package/src/cli.js +4 -13
- package/src/commands/doctor.js +1 -3
- package/src/commands/init.js +63 -53
- package/src/commands/serve.js +2 -50
- package/src/commands/status.js +1 -55
- package/src/commands/sync.js +134 -227
- package/src/lib/{browser-auth.js → browser-open.js} +3 -149
- package/src/lib/claude-categorizer.js +204 -32
- package/src/lib/codex-context-breakdown.js +83 -7
- package/src/lib/codex-rollout-parser.js +52 -10
- package/src/lib/diagnostics.js +1 -49
- package/src/lib/doctor.js +12 -87
- package/src/lib/file-identity.js +69 -0
- package/src/lib/init-flow.js +6 -3
- package/src/lib/local-api.js +6 -364
- package/src/lib/pricing/curated-overrides.json +1 -1
- package/src/lib/pricing/seed-snapshot.json +1 -1
- package/src/lib/rollout.js +392 -144
- package/src/lib/runtime-config.js +0 -32
- package/src/lib/sqlite-reader.js +83 -8
- package/dashboard/dist/assets/ActivityHeatmap-BrehqUIb.js +0 -42
- package/dashboard/dist/assets/DashboardPage-CyUShBRJ.js +0 -19
- package/dashboard/dist/assets/DevicePage-BA74Su1l.js +0 -1
- package/dashboard/dist/assets/DialogTitle-DoKsz5wi.js +0 -1
- package/dashboard/dist/assets/InsforgeUserHeaderControls-Bk_U2dHr.js +0 -1
- package/dashboard/dist/assets/LandingPage-Bbeu84Iu.js +0 -4356
- package/dashboard/dist/assets/LeaderboardAvatar-ByqeB6bM.js +0 -1
- package/dashboard/dist/assets/LeaderboardPage-BeWXF00S.js +0 -6
- package/dashboard/dist/assets/LeaderboardProfileModal-C4yvbZd_.js +0 -72
- package/dashboard/dist/assets/LeaderboardProfilePage-D3cbSh5o.js +0 -1
- package/dashboard/dist/assets/LoginPage-Ch3UQoWj.js +0 -1
- package/dashboard/dist/assets/PopoverPopup-DjG0gjlA.js +0 -1
- package/dashboard/dist/assets/Select-HzIjWJpE.js +0 -1
- package/dashboard/dist/assets/SelectItemText-f0tCwtvZ.js +0 -1
- package/dashboard/dist/assets/SettingsPage-DJOZAlZy.js +0 -1
- package/dashboard/dist/assets/SkillsPage-BQcyJIdx.js +0 -1
- package/dashboard/dist/assets/WidgetsPage-B_vxuV09.js +0 -1
- package/dashboard/dist/assets/WrappedPage-CZN9Y3Vz.js +0 -1
- package/dashboard/dist/assets/index-BeoRn2gJ.js +0 -2
- package/dashboard/dist/assets/info-BAIxlHIB.js +0 -1
- package/dashboard/dist/assets/main-DAcSUW2t.css +0 -1
- package/dashboard/dist/assets/main-pi07CfeC.js +0 -1004
- package/dashboard/dist/assets/use-limits-display-prefs-CMfASZsh.js +0 -1
- package/dashboard/dist/assets/use-native-settings-CfPik-Ao.js +0 -1
- package/dashboard/dist/assets/use-spring-wsmJQRqb.js +0 -1
- package/dashboard/dist/assets/use-usage-limits-Bt0Dp6kx.js +0 -1
- package/dashboard/dist/assets/useCurrency-CsaAMc3j.js +0 -1
- package/dashboard/dist/assets/useOpenInteractionType-CPzi5Z8M.js +0 -12
- package/dashboard/dist/share.html +0 -140
- package/src/commands/device-login.js +0 -161
- package/src/lib/upload-throttle.js +0 -148
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as o,aQ as I,aR as h,aS as C,aT as R}from"./main-pi07CfeC.js";const d=["claude","codex","cursor","gemini","kimi","zai","kiro","copilot","antigravity"],Y={claude:"Claude",codex:"Codex",cursor:"Cursor",gemini:"Gemini",kimi:"Kimi",zai:"Z.AI",kiro:"Kiro",copilot:"GitHub Copilot",antigravity:"Antigravity"},P={claude:"/brand-logos/claude-code.svg",codex:"/brand-logos/codex.svg",cursor:"/brand-logos/cursor.svg",gemini:"/brand-logos/gemini.svg",kimi:"/brand-logos/kimi.svg",zai:null,kiro:"/brand-logos/kiro.svg",copilot:"/brand-logos/copilot.svg",antigravity:"/brand-logos/antigravity.svg"},w="tt.limits.providerOrder",m="tt.limits.providerVisibility",S="tt.limits.displayMode",p="limitsDisplayMode",f=Object.freeze({USED:"used",REMAINING:"remaining"}),E=new Set(Object.values(f));function O(){if(typeof window>"u")return[...d];try{const n=window.localStorage.getItem(w);if(!n)return[...d];const a=JSON.parse(n);if(!Array.isArray(a))return[...d];const r=a.filter(c=>d.includes(c));for(const c of d)r.includes(c)||r.push(c);return r}catch{return[...d]}}function D(){const n=Object.fromEntries(d.map(a=>[a,!0]));if(typeof window>"u")return n;try{const a=window.localStorage.getItem(m);if(!a)return n;const r=JSON.parse(a);if(!r||typeof r!="object")return n;const c={...n};for(const u of d)typeof r[u]=="boolean"&&(c[u]=r[u]);return c}catch{return n}}function v(){if(typeof window>"u")return f.USED;try{const n=window.localStorage.getItem(S);return E.has(n)?n:f.USED}catch{return f.USED}}function T(){const[n,a]=o.useState(O),[r,c]=o.useState(D),[u,l]=o.useState(v),g=o.useCallback(t=>{E.has(t)&&(l(t),I()&&h(p,t))},[]);o.useEffect(()=>{if(!(typeof window>"u"))try{window.localStorage.setItem(w,JSON.stringify(n))}catch{}},[n]),o.useEffect(()=>{if(!(typeof window>"u"))try{window.localStorage.setItem(m,JSON.stringify(r))}catch{}},[r]),o.useEffect(()=>{if(!(typeof window>"u"))try{window.localStorage.setItem(S,u)}catch{}},[u]),o.useEffect(()=>{if(!I())return;const t=C(e=>{const i=e?.[p];E.has(i)&&l(i)});return R(),t},[]),o.useEffect(()=>{if(typeof window>"u")return;const t=e=>{e.key===w&&a(O()),e.key===m&&c(D()),e.key===S&&l(v())};return window.addEventListener("storage",t),()=>window.removeEventListener("storage",t)},[]);const k=o.useCallback(t=>{c(e=>({...e,[t]:!e[t]}))},[]),x=o.useCallback(t=>{a(e=>{const i=e.indexOf(t);if(i<=0)return e;const s=[...e];return[s[i-1],s[i]]=[s[i],s[i-1]],s})},[]),M=o.useCallback(t=>{a(e=>{const i=e.indexOf(t);if(i<0||i>=e.length-1)return e;const s=[...e];return[s[i],s[i+1]]=[s[i+1],s[i]],s})},[]),_=o.useCallback((t,e)=>{t!==e&&a(i=>{const s=i.indexOf(t),b=i.indexOf(e);if(s<0||b<0)return i;const y=[...i],[N]=y.splice(s,1);return y.splice(b,0,N),y})},[]),L=o.useCallback(()=>{a([...d]),c(Object.fromEntries(d.map(t=>[t,!0]))),g(f.USED)},[g]),A=o.useMemo(()=>n.filter(t=>r[t]!==!1),[n,r]);return{order:n,visibility:r,displayMode:u,setDisplayMode:g,visibleOrdered:A,toggle:k,moveUp:x,moveDown:M,moveToward:_,reset:L}}export{f as L,P as a,Y as b,T as u};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{j as a,O as x,r as n,ay as g,bP as m,aS as b,aT as u,aR as f,bO as h}from"./main-pi07CfeC.js";import{C as y}from"./Card-DD4s0V6T.js";function k({checked:s,onChange:t,disabled:e,ariaLabel:i}){return a.jsx("button",{type:"button",role:"switch","aria-checked":s,"aria-label":i,onClick:t,disabled:e,className:x("relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-oai-brand-500 disabled:opacity-50 disabled:cursor-not-allowed",s?"bg-oai-brand-500":"bg-oai-gray-300 dark:bg-oai-gray-700"),children:a.jsx("span",{className:x("inline-block h-3.5 w-3.5 rounded-full bg-white transition-transform",s?"translate-x-[18px]":"translate-x-[3px]")})})}function p({label:s,hint:t,control:e}){return a.jsxs("div",{className:"flex items-center justify-between gap-4 py-3",children:[a.jsxs("div",{className:"min-w-0 flex-1",children:[a.jsx("div",{className:"text-sm text-oai-gray-900 dark:text-oai-gray-200",children:s}),t?a.jsx("div",{className:"mt-0.5 text-xs text-oai-gray-500 dark:text-oai-gray-400",children:t}):null]}),a.jsx("div",{className:"shrink-0",children:e})]})}function N({title:s,subtitle:t,action:e,children:i}){return a.jsxs(y,{children:[a.jsxs("div",{className:"mb-3 flex items-start justify-between gap-4",children:[a.jsxs("div",{className:"min-w-0 flex-1",children:[a.jsx("h2",{className:"text-sm font-medium text-oai-gray-500 dark:text-oai-gray-300 uppercase tracking-wide",children:s}),t?a.jsx("p",{className:"mt-1 truncate text-xs text-oai-gray-500 dark:text-oai-gray-400",children:t}):null]}),e?a.jsx("div",{className:"shrink-0",children:e}):null]}),a.jsx("div",{className:"-mb-3 divide-y divide-oai-gray-200/60 dark:divide-oai-gray-800/60",children:i})]})}function w({options:s,value:t,onChange:e}){return a.jsx("div",{className:"inline-flex items-center rounded-lg border border-oai-gray-200 bg-oai-gray-50 p-0.5 dark:border-oai-gray-800 dark:bg-oai-gray-900",children:s.map(({value:i,label:d,Icon:l})=>{const r=t===i;return a.jsxs("button",{type:"button",onClick:()=>e(i),"aria-pressed":r,className:x("inline-flex items-center gap-1.5 rounded-md px-3 py-1.5 text-xs font-medium transition-colors",r?"bg-white text-oai-black shadow-sm dark:bg-oai-gray-800 dark:text-white":"text-oai-gray-500 hover:text-oai-black dark:text-oai-gray-400 dark:hover:text-white"),children:[l?a.jsx(l,{className:"h-3.5 w-3.5","aria-hidden":!0}):null,a.jsx("span",{children:d})]},i)})})}function S(){const[s,t]=n.useState(null),e=g()&&m();n.useEffect(()=>{if(!e)return;const r=b(o=>t(o));return u(),r},[e]);const i=n.useCallback((r,o)=>{e&&(t(c=>c&&{...c,[r]:o}),f(r,o))},[e]),d=n.useCallback(r=>{e&&h(r)},[e]),l=n.useCallback(()=>{e&&u()},[e]);return{available:e,settings:s,setSetting:i,runAction:d,refresh:l}}export{N as S,k as T,p as a,w as b,S as u};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{aa as I,ab as S,ac as C,ad as j,ae as y,af as w,r as m,ag as k,ah as L,ai as N,aj as p}from"./main-pi07CfeC.js";function D(...t){const e=!Array.isArray(t[0]),n=e?0:-1,s=t[0+n],o=t[1+n],a=t[2+n],r=t[3+n],i=I(o,a,r);return e?i(s):i}function J(t,e,n={}){const s=t.get();let o=null,a=s,r;const i=typeof s=="string"?s.replace(/[\d.-]/g,""):void 0,c=()=>{o&&(o.stop(),o=null),t.animation=void 0},d=()=>{const u=h(t.get()),f=h(a);if(u===f){c();return}const l=o?o.getGeneratorVelocity():t.getVelocity();c(),o=new j({keyframes:[u,f],velocity:l,type:"spring",restDelta:.001,restSpeed:.01,...n,onUpdate:r})},F=()=>{d(),t.animation=o??void 0,t.events.animationStart?.notify(),o?.then(()=>{t.animation=void 0,t.events.animationComplete?.notify()})};if(t.attach((u,f)=>{a=u,r=l=>f(A(l,i)),S.postRender(F)},c),C(e)){let u=n.skipInitialAnimation===!0;const f=e.on("change",V=>{u?(u=!1,t.jump(A(V,i),!1)):t.set(A(V,i))}),l=t.on("destroy",f);return()=>{f(),l()}}return c}function A(t,e){return e?t+e:t}function h(t){return typeof t=="number"?t:parseFloat(t)}function b(t){const e=y(()=>w(t)),{isStatic:n}=m.useContext(k);if(n){const[,s]=m.useState(t);m.useEffect(()=>e.on("change",s),[])}return e}function x(t,e){const n=b(e()),s=()=>n.set(e());return s(),L(()=>{const o=()=>S.preRender(s,!1,!0),a=t.map(r=>r.on("change",o));return()=>{a.forEach(r=>r()),N(s)}}),n}function M(t){p.current=[],t();const e=x(p.current,t);return p.current=void 0,e}function E(t,e,n,s){if(typeof t=="function")return M(t);if(n!==void 0&&!Array.isArray(n)&&typeof e!="function")return U(t,e,n,s);const r=typeof e=="function"?e:D(e,n,s),i=Array.isArray(t)?g(t,r):g([t],([d])=>r(d)),c=Array.isArray(t)?void 0:t.accelerate;return c&&!c.isTransformed&&typeof e!="function"&&Array.isArray(n)&&s?.clamp!==!1&&(i.accelerate={...c,times:e,keyframes:n,isTransformed:!0}),i}function g(t,e){const n=y(()=>[]);return x(t,()=>{n.length=0;const s=t.length;for(let o=0;o<s;o++)n[o]=t[o].get();return e(n)})}function U(t,e,n,s){const o=y(()=>Object.keys(n)),a=y(()=>({}));for(const r of o)a[r]=E(t,e,n[r],s);return a}function G(t,e={}){const{isStatic:n}=m.useContext(k),s=()=>C(t)?t.get():t;if(n)return E(s);const o=b(s());return m.useInsertionEffect(()=>J(o,t,e),[o,JSON.stringify(e)]),o}function z(t,e={}){return G(t,{type:"spring",...e})}export{z as a,E as b,b as u};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as a,a4 as m,aB as f}from"./main-pi07CfeC.js";function p(s){const r=!!s?.initialState,[h,c]=a.useState(()=>r?s?.initialState?.data??null:null),[S,l]=a.useState(()=>r?s?.initialState?.error??null:null),[g,b]=a.useState(!r),i=!!s?.initialRefresh,o=!!s?.publishToPreloadCache,n=a.useCallback((e,t)=>{!o||!e||typeof e!="object"||m(e,{source:t})},[o]),d=a.useCallback(async()=>{try{const e=await f({refresh:!0}),t=e&&typeof e=="object"?e:null;c(t),l(null),n(t,"manual-refresh")}catch(e){l(e?.message||String(e))}},[n]);return a.useEffect(()=>{if(r&&!i)return;let e=!1;return(async()=>{try{const t=await f(i?{refresh:!0}:{});if(e)return;const u=t&&typeof t=="object"?t:null;c(u),l(null),n(u,"page-load")}catch(t){if(e)return;l(t?.message||String(t))}finally{e||b(!1)}})(),()=>{e=!0}},[r,i,n]),{data:h,error:S,isLoading:g,refresh:d}}export{p as u};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as e,bM as t,bN as r,E as c}from"./main-pi07CfeC.js";const s=Object.freeze({currency:c,rate:1,symbol:"$",rates:{...r},rateSource:"default",rateFetchedAt:null,setCurrency:()=>{}});function a(){return e.useContext(t)??s}export{a as u};
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import{c as en,cn as Je,co as tn,by as Ot,aW as q,j as be,c9 as kt,r as p,bp as U,c6 as It,aV as F,cb as ot,cp as nn,aY as ct,bl as De,bU as rn,ca as it,cq as Mt,cr as tt,bL as he,bm as Ze,cs as ne,cc as we,bs as V,b0 as sn,bo as on,cg as Lt,bC as ut,bE as at,bG as cn,ct as un,bq as Z,b as me,bx as an,cu as Ft,bY as We,bB as ln,cv as fn,b_ as Pt,br as pe,c2 as Ge,c1 as dn,cw as pn,cx as z,bW as Ke,bt as Qe,bu as lt,bv as hn,b$ as mn,b1 as bn,aU as gn,cy as At,cz as En,aX as Dt,cA as ce,cB as yn,cC as Nt,cD as Wt,cE as ft,cf as Ce,cF as Vt,c7 as jt,ck as vn}from"./main-pi07CfeC.js";const Sn=[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]],Or=en("check",Sn);function ge(e,n,t=!0){return e.filter(s=>s.parentId===n&&(!t||s.context?.open)).flatMap(s=>[s,...ge(e,s.id,t)])}function dt(e,n){let t=[],r=e.find(s=>s.id===n)?.parentId;for(;r;){const s=e.find(c=>c.id===r);r=s?.parentId,s&&(t=t.concat(s))}return t}function Rn(e){e.preventDefault(),e.stopPropagation()}function wn(e){return"nativeEvent"in e}function Tn(e){return e.mozInputSource===0&&e.isTrusted?!0:Je&&e.pointerType?e.type==="click"&&e.buttons===1:e.detail===0&&!e.pointerType}function xn(e){return tn?!1:!Je&&e.width===0&&e.height===0||Je&&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 kr(e,n){const t=["mouse","pen"];return n||t.push("",void 0),t.includes(e)}function Cn(e){const n=e.type;return n==="click"||n==="mousedown"||n==="keydown"||n==="keyup"}function Me(e){const n=Ot(On,e).current;return n.next=e,q(n.effect),n}function On(e){const n={current:e,next:e,effect:()=>{n.current=n.next}};return n}function _t(){const e=new Map;return{emit(n,t){e.get(n)?.forEach(r=>r(t))},on(n,t){e.has(n)||e.set(n,new Set),e.get(n).add(t)},off(n,t){e.get(n)?.delete(t)}}}class kn{nodesRef={current:[]};events=_t();addNode(n){this.nodesRef.current.push(n)}removeNode(n){const t=this.nodesRef.current.findIndex(r=>r===n);t!==-1&&this.nodesRef.current.splice(t,1)}}const Yt=p.createContext(null),Gt=p.createContext(null),Kt=()=>p.useContext(Yt)?.id||null,nt=e=>{const n=p.useContext(Gt);return e??n};function Ir(e){const n=kt(),t=nt(e),r=Kt();return q(()=>{if(!n)return;const s={id:n,parentId:r};return t?.addNode(s),()=>{t?.removeNode(s)}},[t,n,r]),n}function Mr(e){const{children:n,id:t}=e,r=Kt();return be.jsx(Yt.Provider,{value:p.useMemo(()=>({id:t,parentId:r}),[t,r]),children:n})}function Lr(e){const{children:n,externalTree:t}=e,r=Ot(()=>t??new kn).current;return be.jsx(Gt.Provider,{value:r,children:n})}let pt=0;function qe(e,n={}){const{preventScroll:t=!1,cancelPrevious:r=!0,sync:s=!1}=n;r&&cancelAnimationFrame(pt);const c=()=>e?.focus({preventScroll:t});s?c():pt=requestAnimationFrame(c)}const Ee={inert:new WeakMap,"aria-hidden":new WeakMap,none:new WeakMap};function ht(e){return e==="inert"?Ee.inert:e==="aria-hidden"?Ee["aria-hidden"]:Ee.none}let Le=new WeakSet,Fe={},Be=0;const qt=e=>e&&(e.host||qt(e.parentNode)),In=(e,n)=>n.map(t=>{if(e.contains(t))return t;const r=qt(t);return e.contains(r)?r:null}).filter(t=>t!=null);function Mn(e,n,t,r){const s="data-base-ui-inert",c=r?"inert":t?"aria-hidden":null,i=In(n,e),u=new Set,d=new Set(i),l=[];Fe[s]||(Fe[s]=new WeakMap);const b=Fe[s];i.forEach(y),v(n),u.clear();function y(f){!f||u.has(f)||(u.add(f),f.parentNode&&y(f.parentNode))}function v(f){!f||d.has(f)||[].forEach.call(f.children,g=>{if(It(g)!=="script")if(u.has(g))v(g);else{const C=c?g.getAttribute(c):null,k=C!==null&&C!=="false",M=ht(c),w=(M.get(g)||0)+1,x=(b.get(g)||0)+1;M.set(g,w),b.set(g,x),l.push(g),w===1&&k&&Le.add(g),x===1&&g.setAttribute(s,""),!k&&c&&g.setAttribute(c,c==="inert"?"":"true")}})}return Be+=1,()=>{l.forEach(f=>{const g=ht(c),k=(g.get(f)||0)-1,M=(b.get(f)||0)-1;g.set(f,k),b.set(f,M),k||(!Le.has(f)&&c&&f.removeAttribute(c),Le.delete(f)),M||f.removeAttribute(s)}),Be-=1,Be||(Ee.inert=new WeakMap,Ee["aria-hidden"]=new WeakMap,Ee.none=new WeakMap,Le=new WeakSet,Fe={})}}function Ln(e,n=!1,t=!1){const r=U(e[0]).body;return Mn(e.concat(Array.from(r.querySelectorAll("[aria-live]"))),r,n,t)}function Fn(e,n){const t=We(e.target);return e instanceof t.KeyboardEvent?"keyboard":e instanceof t.FocusEvent?n||"keyboard":"pointerType"in e?e.pointerType||"keyboard":"touches"in e?"touch":e instanceof t.MouseEvent?n||(e.detail===0?"keyboard":"mouse"):""}const mt=20;let re=[];function rt(){re=re.filter(e=>e.isConnected)}function Pn(e){rt(),e&&It(e)!=="body"&&(re.push(e),re.length>mt&&(re=re.slice(-mt)))}function He(){return rt(),re[re.length-1]}function An(e){if(!e)return null;const n=tt();return Ft(e,n)?e:Mt(e,n)[0]||e}function Dn(e){return!e||!e.isConnected?!1:typeof e.checkVisibility=="function"?e.checkVisibility():Pt(e).display!=="none"}function bt(e,n){if(!n.current.includes("floating")&&!e.getAttribute("role")?.includes("dialog"))return;const t=tt(),s=fn(e,t).filter(i=>{const u=i.getAttribute("data-tabindex")||"";return Ft(i,t)||i.hasAttribute("data-tabindex")&&!u.startsWith("-")}),c=e.getAttribute("tabindex");n.current.includes("floating")||s.length===0?c!=="0"&&e.setAttribute("tabindex","0"):(c!=="-1"||e.hasAttribute("data-tabindex")&&e.getAttribute("data-tabindex")!=="-1")&&(e.setAttribute("tabindex","-1"),e.setAttribute("data-tabindex","-1"))}function Fr(e){const{context:n,children:t,disabled:r=!1,order:s=["content"],initialFocus:c=!0,returnFocus:i=!0,restoreFocus:u=!1,modal:d=!0,closeOnFocusOut:l=!0,openInteractionType:b="",getInsideElements:y=()=>[],nextFocusableElement:v,previousFocusableElement:f,beforeContentFocusGuardRef:g,externalTree:C}=e,k="rootStore"in n?n.rootStore:n,M=k.useState("open"),w=k.useState("domReferenceElement"),x=k.useState("floatingElement"),{events:N,dataRef:D}=k.context,L=F(()=>D.current.floatingContext?.nodeId),_=F(y),P=c===!1,j=ot(w)&&P,X=Me(s),Q=Me(c),te=Me(i),ye=Me(b),G=nt(C),O=nn(),ee=p.useRef(null),Ve=p.useRef(null),W=p.useRef(!1),J=p.useRef(!1),ie=p.useRef(!1),Oe=p.useRef(-1),ue=p.useRef(""),$=p.useRef(""),ve=p.useRef(null),se=p.useRef(null),je=ct(ve,g,O?.beforeInsideRef),Se=ct(se,O?.afterInsideRef),ae=De(),oe=De(),le=rn(),fe=O!=null,o=it(x),R=F((a=o)=>a?Mt(a,tt()):[]),h=F(a=>{const E=R(a);return X.current.map(()=>E).filter(Boolean).flat()});p.useEffect(()=>{if(r||!d)return;function a(T){T.key==="Tab"&&V(o,we(U(o)))&&R().length===0&&!j&&Rn(T)}const E=U(o);return E.addEventListener("keydown",a),()=>{E.removeEventListener("keydown",a)}},[r,w,o,d,X,j,R,h]),p.useEffect(()=>{if(r||!x)return;function a(E){const T=Z(E),A=R().indexOf(T);A!==-1&&(Oe.current=A)}return x.addEventListener("focusin",a),()=>{x.removeEventListener("focusin",a)}},[r,x,R]),p.useEffect(()=>{if(r||!M)return;const a=U(o);function E(){ie.current=!1}function T(A){const S=Z(A),m=V(x,S)||V(w,S)||V(O?.portalNode,S);ie.current=!m,$.current=A.pointerType||"keyboard"}function I(){$.current="keyboard"}return a.addEventListener("pointerdown",T,!0),a.addEventListener("pointerup",E,!0),a.addEventListener("pointercancel",E,!0),a.addEventListener("keydown",I,!0),()=>{a.removeEventListener("pointerdown",T,!0),a.removeEventListener("pointerup",E,!0),a.removeEventListener("pointercancel",E,!0),a.removeEventListener("keydown",I,!0)}},[r,x,w,o,M,O]),p.useEffect(()=>{if(r||!l)return;function a(){J.current=!0,oe.start(0,()=>{J.current=!1})}function E(S){const m=S.relatedTarget,B=S.currentTarget,K=Z(S);queueMicrotask(()=>{const de=L(),ke=k.context.triggerElements,_e=m?.hasAttribute(Ze("focus-guard"))&&[ve.current,se.current,O?.beforeInsideRef.current,O?.afterInsideRef.current,O?.beforeOutsideRef.current,O?.afterOutsideRef.current,ne(f),ne(v)].includes(m),Ye=!(V(w,m)||V(x,m)||V(m,x)||V(O?.portalNode,m)||m!=null&&ke.hasElement(m)||ke.hasMatchingElement(H=>V(H,m))||_e||G&&(ge(G.nodesRef.current,de).find(H=>V(H.context?.elements.floating,m)||V(H.context?.elements.domReference,m))||dt(G.nodesRef.current,de).find(H=>[H.context?.elements.floating,it(H.context?.elements.floating)].includes(m)||H.context?.elements.domReference===m)));if(B===w&&o&&bt(o,X),u&&B!==w&&!Dn(K)&&we(U(o))===U(o).body){if(he(o)&&(o.focus(),u==="popup")){le.request(()=>{o.focus()});return}const H=Oe.current,Re=R(),Ie=Re[H]||Re[Re.length-1]||o;he(Ie)&&Ie.focus()}if(D.current.insideReactTree){D.current.insideReactTree=!1;return}(j||!d)&&m&&Ye&&!J.current&&(j||m!==He())&&(W.current=!0,k.setOpen(!1,me(an,S)))})}function T(){ie.current||(D.current.insideReactTree=!0,ae.start(0,()=>{D.current.insideReactTree=!1}))}const I=he(w)?w:null,A=[];if(!(!x&&!I))return I&&(I.addEventListener("focusout",E),I.addEventListener("pointerdown",a),A.push(()=>{I.removeEventListener("focusout",E),I.removeEventListener("pointerdown",a)})),x&&(x.addEventListener("focusout",E),O&&(x.addEventListener("focusout",T,!0),A.push(()=>{x.removeEventListener("focusout",T,!0)})),A.push(()=>{x.removeEventListener("focusout",E)})),()=>{A.forEach(S=>{S()})}},[r,w,x,o,d,G,O,k,l,u,R,j,L,X,D,ae,oe,le,v,f]),p.useEffect(()=>{if(r||!x||!M)return;const a=Array.from(O?.portalNode?.querySelectorAll(`[${Ze("portal")}]`)||[]),T=(G?dt(G.nodesRef.current,L()):[]).find(S=>ot(S.context?.elements.domReference||null))?.context?.elements.domReference,I=[x,T,...a,..._(),ee.current,Ve.current,ve.current,se.current,O?.beforeOutsideRef.current,O?.afterOutsideRef.current,ne(f),ne(v),j?w:null].filter(S=>S!=null),A=Ln(I,d||j);return()=>{A()}},[M,r,w,x,d,X,O,j,G,L,_,v,f]),q(()=>{if(!M||r||!he(o))return;const a=U(o),E=we(a);queueMicrotask(()=>{const T=h(o),I=Q.current,A=typeof I=="function"?I(ye.current||""):I;if(A===void 0||A===!1)return;let S;A===!0||A===null?S=T[0]||o:S=ne(A),S=S||T[0]||o,!V(o,E)&&qe(S,{preventScroll:S===o})})},[r,M,o,P,h,Q,ye]),q(()=>{if(r||!o)return;const a=U(o),E=we(a);Pn(E);function T(S){if(S.open||(ue.current=Fn(S.nativeEvent,$.current)),S.reason===on&&S.nativeEvent.type==="mouseleave"&&(W.current=!0),S.reason===Lt)if(S.nested)W.current=!1;else if(Tn(S.nativeEvent)||xn(S.nativeEvent))W.current=!1;else{let m=!1;document.createElement("div").focus({get preventScroll(){return m=!0,!1}}),m?W.current=!1:W.current=!0}}N.on("openchange",T);const I=a.createElement("span");I.setAttribute("tabindex","-1"),I.setAttribute("aria-hidden","true"),Object.assign(I.style,sn),fe&&w&&w.insertAdjacentElement("afterend",I);function A(){const S=te.current;let m=typeof S=="function"?S(ue.current):S;if(m===void 0||m===!1)return null;if(m===null&&(m=!0),typeof m=="boolean"){const K=w||He();return K&&K.isConnected?K:I}const B=w||He()||I;return ne(m)||B}return()=>{N.off("openchange",T);const S=we(a),m=V(x,S)||G&&ge(G.nodesRef.current,L(),!1).some(K=>V(K.context?.elements.floating,S)),B=A();queueMicrotask(()=>{const K=An(B),de=typeof te.current!="boolean";te.current&&!W.current&&he(K)&&(!(!de&&K!==S&&S!==a.body)||m)&&K.focus({preventScroll:!0}),I.remove()})}},[r,x,o,te,D,N,G,fe,w,L]),p.useEffect(()=>{queueMicrotask(()=>{W.current=!1})},[r]),p.useEffect(()=>{if(r||!M)return;function a(T){Z(T)?.closest(`[${ln}]`)&&(J.current=!0)}const E=U(o);return E.addEventListener("pointerdown",a,!0),()=>{E.removeEventListener("pointerdown",a,!0)}},[r,M,o]),q(()=>{if(!r&&O)return O.setFocusManagerState({modal:d,closeOnFocusOut:l,open:M,onOpenChange:k.setOpen,domReference:w}),()=>{O.setFocusManagerState(null)}},[r,O,d,M,k,l,w]),q(()=>{if(!(r||!o))return bt(o,X),()=>{queueMicrotask(rt)}},[r,o,X]);const Y=!r&&(d?!j:!0)&&(fe||d);return be.jsxs(p.Fragment,{children:[Y&&be.jsx(ut,{"data-type":"inside",ref:je,onFocus:a=>{if(d){const E=h();qe(E[E.length-1])}else O?.portalNode&&(W.current=!1,at(a,O.portalNode)?cn(w)?.focus():ne(f??O.beforeOutsideRef)?.focus())}}),t,Y&&be.jsx(ut,{"data-type":"inside",ref:Se,onFocus:a=>{d?qe(h()[0]):O?.portalNode&&(l&&(W.current=!0),at(a,O.portalNode)?un(w)?.focus():ne(v??O.afterOutsideRef)?.focus())}})]})}const Nn={intentional:"onClick",sloppy:"onPointerDown"};function Wn(e){return{escapeKey:typeof e=="boolean"?e:e?.escapeKey??!1,outsidePress:typeof e=="boolean"?e:e?.outsidePress??!0}}function Pr(e,n={}){const t="rootStore"in e?e.rootStore:e,r=t.useState("open"),s=t.useState("floatingElement"),c=t.useState("referenceElement"),i=t.useState("domReferenceElement"),{onOpenChange:u,dataRef:d}=t.context,{enabled:l=!0,escapeKey:b=!0,outsidePress:y=!0,outsidePressEvent:v="sloppy",referencePress:f=!1,referencePressEvent:g="sloppy",ancestorScroll:C=!1,bubbles:k,externalTree:M}=n,w=nt(M),x=F(typeof y=="function"?y:()=>!1),N=typeof y=="function"?x:y,D=p.useRef(!1),{escapeKey:L,outsidePress:_}=Wn(k),P=p.useRef(null),j=De(),X=De(),Q=F(()=>{X.clear(),d.current.insideReactTree=!1}),te=p.useRef(!1),ye=p.useRef(""),G=F(o=>{ye.current=o.pointerType}),O=F(()=>{const o=ye.current,R=o==="pen"||!o?"mouse":o,h=typeof v=="function"?v():v;return typeof h=="string"?h:h[R]}),ee=F(o=>{if(!r||!l||!b||o.key!=="Escape"||te.current)return;const R=d.current.floatingContext?.nodeId,h=w?ge(w.nodesRef.current,R):[];if(!L&&h.length>0){let E=!0;if(h.forEach(T=>{T.context?.open&&!T.context.dataRef.current.__escapeKeyBubbles&&(E=!1)}),!E)return}const Y=wn(o)?o.nativeEvent:o,a=me(hn,Y);t.setOpen(!1,a),!L&&!a.isPropagationAllowed&&o.stopPropagation()}),Ve=F(o=>{const R=O();return R==="intentional"&&o.type!=="click"||R==="sloppy"&&o.type==="click"}),W=F(()=>{d.current.insideReactTree=!0,X.start(0,Q)}),J=F((o,R=!1)=>{if(Ve(o)){Q();return}if(d.current.insideReactTree){Q();return}if(O()==="intentional"&&R||typeof N=="function"&&!N(o))return;const h=Z(o),Y=`[${Ze("inert")}]`,a=U(t.select("floatingElement")).querySelectorAll(Y),E=t.context.triggerElements;if(h&&(E.hasElement(h)||E.hasMatchingElement(m=>V(m,h))))return;let T=pe(h)?h:null;for(;T&&!Ge(T);){const m=dn(T);if(Ge(m)||!pe(m))break;T=m}if(a.length&&pe(h)&&!pn(h)&&!V(h,t.select("floatingElement"))&&Array.from(a).every(m=>!V(T,m)))return;if(he(h)&&!("touches"in o)){const m=Ge(h),B=Pt(h),K=/auto|scroll/,de=m||K.test(B.overflowX),ke=m||K.test(B.overflowY),_e=de&&h.clientWidth>0&&h.scrollWidth>h.clientWidth,Ye=ke&&h.clientHeight>0&&h.scrollHeight>h.clientHeight,H=B.direction==="rtl",Re=Ye&&(H?o.offsetX<=h.offsetWidth-h.clientWidth:o.offsetX>h.clientWidth),Ie=_e&&o.offsetY>h.clientHeight;if(Re||Ie)return}const I=d.current.floatingContext?.nodeId,A=w&&ge(w.nodesRef.current,I).some(m=>z(o,m.context?.elements.floating));if(z(o,t.select("floatingElement"))||z(o,t.select("domReferenceElement"))||A)return;const S=w?ge(w.nodesRef.current,I):[];if(S.length>0){let m=!0;if(S.forEach(B=>{B.context?.open&&!B.context.dataRef.current.__outsidePressBubbles&&(m=!1)}),!m)return}t.setOpen(!1,me(Lt,o)),Q()}),ie=F(o=>{O()!=="sloppy"||o.pointerType==="touch"||!t.select("open")||!l||z(o,t.select("floatingElement"))||z(o,t.select("domReferenceElement"))||J(o)}),Oe=F(o=>{if(O()!=="sloppy"||!t.select("open")||!l||z(o,t.select("floatingElement"))||z(o,t.select("domReferenceElement")))return;const R=o.touches[0];R&&(P.current={startTime:Date.now(),startX:R.clientX,startY:R.clientY,dismissOnTouchEnd:!1,dismissOnMouseDown:!0},j.start(1e3,()=>{P.current&&(P.current.dismissOnTouchEnd=!1,P.current.dismissOnMouseDown=!1)}))}),ue=F(o=>{const R=Z(o);function h(){Oe(o),R?.removeEventListener(o.type,h)}R?.addEventListener(o.type,h)}),$=F(o=>{const R=D.current;if(D.current=!1,j.clear(),o.type==="mousedown"&&P.current&&!P.current.dismissOnMouseDown)return;const h=Z(o);function Y(){o.type==="pointerdown"?ie(o):J(o,R),h?.removeEventListener(o.type,Y)}h?.addEventListener(o.type,Y)}),ve=F(o=>{if(O()!=="sloppy"||!P.current||z(o,t.select("floatingElement"))||z(o,t.select("domReferenceElement")))return;const R=o.touches[0];if(!R)return;const h=Math.abs(R.clientX-P.current.startX),Y=Math.abs(R.clientY-P.current.startY),a=Math.sqrt(h*h+Y*Y);a>5&&(P.current.dismissOnTouchEnd=!0),a>10&&(J(o),j.clear(),P.current=null)}),se=F(o=>{const R=Z(o);function h(){ve(o),R?.removeEventListener(o.type,h)}R?.addEventListener(o.type,h)}),je=F(o=>{O()!=="sloppy"||!P.current||z(o,t.select("floatingElement"))||z(o,t.select("domReferenceElement"))||(P.current.dismissOnTouchEnd&&J(o),j.clear(),P.current=null)}),Se=F(o=>{const R=Z(o);function h(){je(o),R?.removeEventListener(o.type,h)}R?.addEventListener(o.type,h)});p.useEffect(()=>{if(!r||!l)return;d.current.__escapeKeyBubbles=L,d.current.__outsidePressBubbles=_;const o=new Qe;function R(T){t.setOpen(!1,me(bn,T))}function h(){o.clear(),te.current=!0}function Y(){o.start(mn()?5:0,()=>{te.current=!1})}const a=U(s);a.addEventListener("pointerdown",G,!0),b&&(a.addEventListener("keydown",ee),a.addEventListener("compositionstart",h),a.addEventListener("compositionend",Y)),N&&(a.addEventListener("click",$,!0),a.addEventListener("pointerdown",$,!0),a.addEventListener("touchstart",ue,!0),a.addEventListener("touchmove",se,!0),a.addEventListener("touchend",Se,!0),a.addEventListener("mousedown",$,!0));let E=[];return C&&(pe(i)&&(E=Ke(i)),pe(s)&&(E=E.concat(Ke(s))),!pe(c)&&c&&c.contextElement&&(E=E.concat(Ke(c.contextElement)))),E=E.filter(T=>T!==a.defaultView?.visualViewport),E.forEach(T=>{T.addEventListener("scroll",R,{passive:!0})}),()=>{a.removeEventListener("pointerdown",G,!0),b&&(a.removeEventListener("keydown",ee),a.removeEventListener("compositionstart",h),a.removeEventListener("compositionend",Y)),N&&(a.removeEventListener("click",$,!0),a.removeEventListener("pointerdown",$,!0),a.removeEventListener("touchstart",ue,!0),a.removeEventListener("touchmove",se,!0),a.removeEventListener("touchend",Se,!0),a.removeEventListener("mousedown",$,!0)),E.forEach(T=>{T.removeEventListener("scroll",R)}),o.clear(),D.current=!1}},[d,s,c,i,b,N,r,u,C,l,L,_,ee,J,$,ie,ue,se,Se,G,t]),p.useEffect(Q,[N,Q]);const ae=p.useMemo(()=>({onKeyDown:ee,...f&&{[Nn[g]]:o=>{t.setOpen(!1,me(lt,o.nativeEvent))},...g!=="intentional"&&{onClick(o){t.setOpen(!1,me(lt,o.nativeEvent))}}}}),[ee,t,f,g]),oe=F(o=>{const R=Z(o.nativeEvent);!V(t.select("floatingElement"),R)||o.button!==0||(D.current=!0)}),le=F(o=>{!r||!l||o.button!==0||(D.current=!0)}),fe=p.useMemo(()=>({onKeyDown:ee,onPointerDown:oe,onMouseDown:oe,onMouseUp:oe,onClickCapture:W,onMouseDownCapture(o){W(),le(o)},onPointerDownCapture(o){W(),le(o)},onMouseUpCapture:W,onTouchEndCapture:W,onTouchMoveCapture:W}),[ee,oe,W,le]);return p.useMemo(()=>l?{reference:ae,floating:fe,trigger:ae}:{},[l,ae,fe])}var Ne=Symbol("NOT_FOUND");function Vn(e,n=`expected a function, instead received ${typeof e}`){if(typeof e!="function")throw new TypeError(n)}function jn(e,n=`expected an object, instead received ${typeof e}`){if(typeof e!="object")throw new TypeError(n)}function _n(e,n="expected all items to be functions, instead received the following types: "){if(!e.every(t=>typeof t=="function")){const t=e.map(r=>typeof r=="function"?`function ${r.name||"unnamed"}()`:typeof r).join(", ");throw new TypeError(`${n}[${t}]`)}}var gt=e=>Array.isArray(e)?e:[e];function Yn(e){const n=Array.isArray(e[0])?e[0]:e;return _n(n,"createSelector expects all input-selectors to be functions, but received the following types: "),n}function Gn(e,n){const t=[],{length:r}=e;for(let s=0;s<r;s++)t.push(e[s].apply(null,n));return t}function Kn(e){let n;return{get(t){return n&&e(n.key,t)?n.value:Ne},put(t,r){n={key:t,value:r}},getEntries(){return n?[n]:[]},clear(){n=void 0}}}function qn(e,n){let t=[];function r(u){const d=t.findIndex(l=>n(u,l.key));if(d>-1){const l=t[d];return d>0&&(t.splice(d,1),t.unshift(l)),l.value}return Ne}function s(u,d){r(u)===Ne&&(t.unshift({key:u,value:d}),t.length>e&&t.pop())}function c(){return t}function i(){t=[]}return{get:r,put:s,getEntries:c,clear:i}}var Bn=(e,n)=>e===n;function Hn(e){return function(t,r){if(t===null||r===null||t.length!==r.length)return!1;const{length:s}=t;for(let c=0;c<s;c++)if(!e(t[c],r[c]))return!1;return!0}}function $n(e,n){const t=typeof n=="object"?n:{equalityCheck:n},{equalityCheck:r=Bn,maxSize:s=1,resultEqualityCheck:c}=t,i=Hn(r);let u=0;const d=s<=1?Kn(i):qn(s,i);function l(){let b=d.get(arguments);if(b===Ne){if(b=e.apply(null,arguments),u++,c){const v=d.getEntries().find(f=>c(f.value,b));v&&(b=v.value,u!==0&&u--)}d.put(arguments,b)}return b}return l.clearCache=()=>{d.clear(),l.resetResultsCount()},l.resultsCount=()=>u,l.resetResultsCount=()=>{u=0},l}var zn=class{constructor(e){this.value=e}deref(){return this.value}},Un=typeof WeakRef<"u"?WeakRef:zn,Xn=0,Et=1;function Pe(){return{s:Xn,v:void 0,o:null,p:null}}function Bt(e,n={}){let t=Pe();const{resultEqualityCheck:r}=n;let s,c=0;function i(){let u=t;const{length:d}=arguments;for(let y=0,v=d;y<v;y++){const f=arguments[y];if(typeof f=="function"||typeof f=="object"&&f!==null){let g=u.o;g===null&&(u.o=g=new WeakMap);const C=g.get(f);C===void 0?(u=Pe(),g.set(f,u)):u=C}else{let g=u.p;g===null&&(u.p=g=new Map);const C=g.get(f);C===void 0?(u=Pe(),g.set(f,u)):u=C}}const l=u;let b;if(u.s===Et)b=u.v;else if(b=e.apply(null,arguments),c++,r){const y=s?.deref?.()??s;y!=null&&r(y,b)&&(b=y,c!==0&&c--),s=typeof b=="object"&&b!==null||typeof b=="function"?new Un(b):b}return l.s=Et,l.v=b,b}return i.clearCache=()=>{t=Pe(),i.resetResultsCount()},i.resultsCount=()=>c,i.resetResultsCount=()=>{c=0},i}function Ht(e,...n){const t=typeof e=="function"?{memoize:e,memoizeOptions:n}:e,r=(...s)=>{let c=0,i=0,u,d={},l=s.pop();typeof l=="object"&&(d=l,l=s.pop()),Vn(l,`createSelector expects an output function after the inputs, but received: [${typeof l}]`);const b={...t,...d},{memoize:y,memoizeOptions:v=[],argsMemoize:f=Bt,argsMemoizeOptions:g=[]}=b,C=gt(v),k=gt(g),M=Yn(s),w=y(function(){return c++,l.apply(null,arguments)},...C),x=f(function(){i++;const D=Gn(M,arguments);return u=w.apply(null,D),u},...k);return Object.assign(x,{resultFunc:l,memoizedResultFunc:w,dependencies:M,dependencyRecomputations:()=>i,resetDependencyRecomputations:()=>{i=0},lastResult:()=>u,recomputations:()=>c,resetRecomputations:()=>{c=0},memoize:y,argsMemoize:f})};return Object.assign(r,{withTypes:()=>r}),r}var Jn=Ht(Bt),Zn=Object.assign((e,n=Jn)=>{jn(e,`createStructuredSelector expects first argument to be an object where each property is a selector, instead received a ${typeof e}`);const t=Object.keys(e),r=t.map(c=>e[c]);return n(r,(...c)=>c.reduce((i,u,d)=>(i[t[d]]=u,i),{}))},{withTypes:()=>Zn});Ht({memoize:$n,memoizeOptions:{maxSize:1,equalityCheck:Object.is}});const Te=(e,n,t,r,s,c,...i)=>{if(i.length>0)throw new Error(gn(1));let u;if(e)u=e;else throw new Error("Missing arguments");return u};var $e={exports:{}},ze={};var yt;function Qn(){if(yt)return ze;yt=1;var e=At();function n(y,v){return y===v&&(y!==0||1/y===1/v)||y!==y&&v!==v}var t=typeof Object.is=="function"?Object.is:n,r=e.useState,s=e.useEffect,c=e.useLayoutEffect,i=e.useDebugValue;function u(y,v){var f=v(),g=r({inst:{value:f,getSnapshot:v}}),C=g[0].inst,k=g[1];return c(function(){C.value=f,C.getSnapshot=v,d(C)&&k({inst:C})},[y,f,v]),s(function(){return d(C)&&k({inst:C}),y(function(){d(C)&&k({inst:C})})},[y]),i(f),f}function d(y){var v=y.getSnapshot;y=y.value;try{var f=v();return!t(y,f)}catch{return!0}}function l(y,v){return v()}var b=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?l:u;return ze.useSyncExternalStore=e.useSyncExternalStore!==void 0?e.useSyncExternalStore:b,ze}var vt;function $t(){return vt||(vt=1,$e.exports=Qn()),$e.exports}var er=$t(),Ue={exports:{}},Xe={};var St;function tr(){if(St)return Xe;St=1;var e=At(),n=$t();function t(l,b){return l===b&&(l!==0||1/l===1/b)||l!==l&&b!==b}var r=typeof Object.is=="function"?Object.is:t,s=n.useSyncExternalStore,c=e.useRef,i=e.useEffect,u=e.useMemo,d=e.useDebugValue;return Xe.useSyncExternalStoreWithSelector=function(l,b,y,v,f){var g=c(null);if(g.current===null){var C={hasValue:!1,value:null};g.current=C}else C=g.current;g=u(function(){function M(L){if(!w){if(w=!0,x=L,L=v(L),f!==void 0&&C.hasValue){var _=C.value;if(f(_,L))return N=_}return N=L}if(_=N,r(x,L))return _;var P=v(L);return f!==void 0&&f(_,P)?(x=L,_):(x=L,N=P)}var w=!1,x,N,D=y===void 0?null:y;return[function(){return M(b())},D===null?void 0:function(){return M(D())}]},[b,y,v,f]);var k=s(l,g[0],g[1]);return i(function(){C.hasValue=!0,C.value=k},[k]),d(k),k},Xe}var Rt;function nr(){return Rt||(Rt=1,Ue.exports=tr()),Ue.exports}var rr=nr();const sr=En(19),or=sr?ir:ur;function cr(e,n,t,r,s){return or(e,n,t,r,s)}function ir(e,n,t,r,s){const c=p.useCallback(()=>n(e.getSnapshot(),t,r,s),[e,n,t,r,s]);return er.useSyncExternalStore(e.subscribe,c,c)}function ur(e,n,t,r,s){return rr.useSyncExternalStoreWithSelector(e.subscribe,e.getSnapshot,e.getSnapshot,c=>n(c,t,r,s))}class xe{constructor(n){this.state=n,this.listeners=new Set,this.updateTick=0}subscribe=n=>(this.listeners.add(n),()=>{this.listeners.delete(n)});getSnapshot=()=>this.state;setState(n){if(this.state===n)return;this.state=n,this.updateTick+=1;const t=this.updateTick;for(const r of this.listeners){if(t!==this.updateTick)return;r(n)}}update(n){for(const t in n)if(!Object.is(this.state[t],n[t])){xe.prototype.setState.call(this,{...this.state,...n});return}}set(n,t){Object.is(this.state[n],t)||xe.prototype.setState.call(this,{...this.state,[n]:t})}notifyAll(){const n={...this.state};xe.prototype.setState.call(this,n)}}class ar extends xe{constructor(n,t={},r){super(n),this.context=t,this.selectors=r}controlledValues=new Map;useSyncedValue(n,t){p.useDebugValue(n),q(()=>{this.state[n]!==t&&this.set(n,t)},[n,t])}useSyncedValueWithCleanup(n,t){const r=this;q(()=>(r.state[n]!==t&&r.set(n,t),()=>{r.set(n,void 0)}),[r,n,t])}useSyncedValues(n){const t=this,r=Object.values(n);q(()=>{t.update(n)},[t,...r])}useControlledProp(n,t,r){p.useDebugValue(n);const s=this,c=t!==void 0;this.controlledValues.has(n)||(this.controlledValues.set(n,c),!c&&!Object.is(this.state[n],r)&&super.setState({...this.state,[n]:r})),q(()=>{c&&!Object.is(s.state[n],t)&&super.setState({...s.state,[n]:t})},[s,n,t,r,c])}set(n,t){this.controlledValues.get(n)!==!0&&super.set(n,t)}update(n){const t={...n};for(const r in t)if(Object.hasOwn(t,r)&&this.controlledValues.get(r)===!0){delete t[r];continue}super.update(t)}setState(n){const t={...n};for(const r in t)if(Object.hasOwn(t,r)&&this.controlledValues.get(r)===!0){delete t[r];continue}super.setState({...this.state,...t})}select=(n,t,r,s)=>{const c=this.selectors[n];return c(this.state,t,r,s)};useState=(n,t,r,s)=>{p.useDebugValue(n);const c=this.selectors[n];return cr(this,c,t,r,s)};useContextCallback(n,t){p.useDebugValue(n);const r=F(t??Dt);this.context[n]=r}useStateSetter(n){const t=p.useRef(void 0);return t.current===void 0&&(t.current=r=>{this.set(n,r)}),t.current}observe(n,t){let r;typeof n=="function"?r=n:r=this.selectors[n];let s=r(this.state);return t(s,s,this),this.subscribe(c=>{const i=r(c);if(!Object.is(s,i)){const u=s;s=i,t(i,u,this)}})}}const lr={open:Te(e=>e.open),domReferenceElement:Te(e=>e.domReferenceElement),referenceElement:Te(e=>e.positionReference??e.referenceElement),floatingElement:Te(e=>e.floatingElement),floatingId:Te(e=>e.floatingId)};class Ar extends ar{constructor(n){const{nested:t,noEmit:r,onOpenChange:s,triggerElements:c,...i}=n;super({...i,positionReference:i.referenceElement,domReferenceElement:i.referenceElement},{onOpenChange:s,dataRef:{current:{}},events:_t(),nested:t,noEmit:r,triggerElements:c},lr)}setOpen=(n,t)=>{if((!n||!this.state.open||Cn(t.event))&&(this.context.dataRef.current.openEvent=n?t.event:void 0),!this.context.noEmit){const r={open:n,reason:t.reason,nativeEvent:t.event,nested:this.context.nested,triggerElement:t.trigger};this.context.events.emit("openchange",r)}this.context.onOpenChange?.(n,t)}}function Dr(e,n=!1,t=!1){const[r,s]=p.useState(e&&n?"idle":void 0),[c,i]=p.useState(e);return e&&!c&&(i(!0),s("starting")),!e&&c&&r!=="ending"&&!t&&s("ending"),!e&&!c&&r==="ending"&&s(void 0),q(()=>{if(!e&&c&&r!=="ending"&&t){const u=ce.request(()=>{s("ending")});return()=>{ce.cancel(u)}}},[e,c,r,t]),q(()=>{if(!e||n)return;const u=ce.request(()=>{s(void 0)});return()=>{ce.cancel(u)}},[n,e]),q(()=>{if(!e||!n)return;e&&c&&r!=="idle"&&s("starting");const u=ce.request(()=>{s("idle")});return()=>{ce.cancel(u)}},[n,e,c,s,r]),p.useMemo(()=>({mounted:c,setMounted:i,transitionStatus:r}),[c,r])}class Nr{constructor(){this.elements=new Set,this.idMap=new Map}add(n,t){const r=this.idMap.get(n);r!==t&&(r!==void 0&&this.elements.delete(r),this.elements.add(t),this.idMap.set(n,t))}delete(n){const t=this.idMap.get(n);t&&(this.elements.delete(t),this.idMap.delete(n))}hasElement(n){return this.elements.has(n)}hasMatchingElement(n){for(const t of this.elements)if(n(t))return!0;return!1}getById(n){return this.idMap.get(n)}entries(){return this.idMap.entries()}get size(){return this.idMap.size}}function Wr(e=[]){const n=e.map(l=>l?.reference),t=e.map(l=>l?.floating),r=e.map(l=>l?.item),s=e.map(l=>l?.trigger),c=p.useCallback(l=>Ae(l,e,"reference"),n),i=p.useCallback(l=>Ae(l,e,"floating"),t),u=p.useCallback(l=>Ae(l,e,"item"),r),d=p.useCallback(l=>Ae(l,e,"trigger"),s);return p.useMemo(()=>({getReferenceProps:c,getFloatingProps:i,getItemProps:u,getTriggerProps:d}),[c,i,u,d])}function Ae(e,n,t){const r=new Map,s=t==="item",c={};t==="floating"&&(c.tabIndex=-1,c[yn]="");for(const i in e)s&&e&&(i===Nt||i===Wt)||(c[i]=e[i]);for(let i=0;i<n.length;i+=1){let u;const d=n[i]?.[t];typeof d=="function"?u=e?d(e):null:u=d,u&&wt(c,u,s,r)}return wt(c,e,s,r),c}function wt(e,n,t,r){for(const s in n){const c=n[s];t&&(s===Nt||s===Wt)||(s.startsWith("on")?(r.has(s)||r.set(s,[]),typeof c=="function"&&(r.get(s)?.push(c),e[s]=(...i)=>r.get(s)?.map(u=>u(...i)).find(u=>u!==void 0))):e[s]=c)}}let st=(function(e){return e.open="data-open",e.closed="data-closed",e[e.startingStyle=ft.startingStyle]="startingStyle",e[e.endingStyle=ft.endingStyle]="endingStyle",e.anchorHidden="data-anchor-hidden",e})({}),et=(function(e){return e.popupOpen="data-popup-open",e.pressed="data-pressed",e})({});const fr={[et.popupOpen]:""},dr={[et.popupOpen]:"",[et.pressed]:""},pr={[st.open]:""},hr={[st.closed]:""},mr={[st.anchorHidden]:""},Vr={open(e){return e?fr:null}},jr={open(e){return e?dr:null}},_r={open(e){return e?pr:hr},anchorHidden(e){return e?mr:null}};function Yr(e){return kt(e,"base-ui")}const zt="ArrowUp",Ut="ArrowDown",Xt="ArrowLeft",Jt="ArrowRight",Zt="Home",Qt="End",br=new Set([Xt,Jt]),gr=new Set([zt,Ut]),Er=new Set([...br,...gr]);[...Er];const Gr=new Set([zt,Ut,Xt,Jt,Zt,Qt]),Kr=p.forwardRef(function(n,t){const{cutout:r,...s}=n;let c;if(r){const i=r?.getBoundingClientRect();c=`polygon(
|
|
2
|
-
0% 0%,
|
|
3
|
-
100% 0%,
|
|
4
|
-
100% 100%,
|
|
5
|
-
0% 100%,
|
|
6
|
-
0% 0%,
|
|
7
|
-
${i.left}px ${i.top}px,
|
|
8
|
-
${i.left}px ${i.bottom}px,
|
|
9
|
-
${i.right}px ${i.bottom}px,
|
|
10
|
-
${i.right}px ${i.top}px,
|
|
11
|
-
${i.left}px ${i.top}px
|
|
12
|
-
)`}return be.jsx("div",{ref:t,role:"presentation","data-base-ui-inert":"",...s,style:{position:"fixed",inset:0,userSelect:"none",WebkitUserSelect:"none",clipPath:c}})});let Tt={},xt={},Ct="";function yr(e){if(typeof document>"u")return!1;const n=Ce(e);return We(n).innerWidth-n.documentElement.clientWidth>0}function vr(e){if(!(typeof CSS<"u"&&CSS.supports&&CSS.supports("scrollbar-gutter","stable"))||typeof document>"u")return!1;const r=Ce(e).documentElement,s={scrollbarGutter:r.style.scrollbarGutter,overflowY:r.style.overflowY};r.style.scrollbarGutter="stable",r.style.overflowY="scroll";const c=r.offsetWidth;r.style.overflowY="hidden";const i=r.offsetWidth;return Object.assign(r.style,s),c===i}function Sr(e){const n=Ce(e),t=n.documentElement,r=n.body,s=jt(t)?t:r,c=s.style.overflow;return s.style.overflow="hidden",()=>{s.style.overflow=c}}function Rr(e){const n=Ce(e),t=n.documentElement,r=n.body,s=We(t);let c=0,i=0,u=!1;const d=ce.create();if(vn&&(s.visualViewport?.scale??1)!==1)return()=>{};function l(){const v=s.getComputedStyle(t),f=s.getComputedStyle(r),k=(v.scrollbarGutter||"").includes("both-edges")?"stable both-edges":"stable";c=t.scrollTop,i=t.scrollLeft,Tt={scrollbarGutter:t.style.scrollbarGutter,overflowY:t.style.overflowY,overflowX:t.style.overflowX},Ct=t.style.scrollBehavior,xt={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 M=t.scrollHeight>t.clientHeight,w=t.scrollWidth>t.clientWidth,x=v.overflowY==="scroll"||f.overflowY==="scroll",N=v.overflowX==="scroll"||f.overflowX==="scroll",D=Math.max(0,s.innerWidth-r.clientWidth),L=Math.max(0,s.innerHeight-r.clientHeight),_=parseFloat(f.marginTop)+parseFloat(f.marginBottom),P=parseFloat(f.marginLeft)+parseFloat(f.marginRight),j=jt(t)?t:r;if(u=vr(e),u){t.style.scrollbarGutter=k,j.style.overflowY="hidden",j.style.overflowX="hidden";return}Object.assign(t.style,{scrollbarGutter:k,overflowY:"hidden",overflowX:"hidden"}),(M||x)&&(t.style.overflowY="scroll"),(w||N)&&(t.style.overflowX="scroll"),Object.assign(r.style,{position:"relative",height:_||L?`calc(100dvh - ${_+L}px)`:"100dvh",width:P||D?`calc(100vw - ${P+D}px)`:"100vw",boxSizing:"border-box",overflow:"hidden",scrollBehavior:"unset"}),r.scrollTop=c,r.scrollLeft=i,t.setAttribute("data-base-ui-scroll-locked",""),t.style.scrollBehavior="unset"}function b(){Object.assign(t.style,Tt),Object.assign(r.style,xt),u||(t.scrollTop=c,t.scrollLeft=i,t.removeAttribute("data-base-ui-scroll-locked"),t.style.scrollBehavior=Ct)}function y(){b(),d.request(l)}return l(),s.addEventListener("resize",y),()=>{d.cancel(),b(),typeof s.removeEventListener=="function"&&s.removeEventListener("resize",y)}}class wr{lockCount=0;restore=null;timeoutLock=Qe.create();timeoutUnlock=Qe.create();acquire(n){return this.lockCount+=1,this.lockCount===1&&this.restore===null&&this.timeoutLock.start(0,()=>this.lock(n)),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(n){if(this.lockCount===0||this.restore!==null)return;const r=Ce(n).documentElement,s=We(r).getComputedStyle(r).overflowY;if(s==="hidden"||s==="clip"){this.restore=Dt;return}const c=Vt||!yr(n);this.restore=c?Sr(n):Rr(n)}}const Tr=new wr;function qr(e=!0,n=null){q(()=>{if(e)return Tr.acquire(n)},[e,n])}function xr(e){const n=p.useRef(""),t=p.useCallback(s=>{s.defaultPrevented||(n.current=s.pointerType,e(s,s.pointerType))},[e]);return{onClick:p.useCallback(s=>{if(s.detail===0){e(s,"keyboard");return}"pointerType"in s&&e(s,s.pointerType),e(s,n.current),n.current=""},[e]),onPointerDown:t}}function Br(e){const[n,t]=p.useState(null),r=F((u,d)=>{e||t(d||(Vt?"touch":""))}),s=p.useCallback(()=>{t(null)},[]),{onClick:c,onPointerDown:i}=xr(r);return p.useMemo(()=>({openMethod:n,reset:s,triggerProps:{onClick:c,onPointerDown:i}}),[n,s,c,i])}export{st as A,Or as C,Lr as F,Kr as I,Nr as P,ar as R,xe as S,cr as a,Dr as b,nt as c,Kt as d,Me as e,Te as f,ge as g,Br as h,kr as i,qr as j,Pr as k,Wr as l,Ir as m,Mr as n,_r as o,jr as p,Fr as q,Gr as r,Rn as s,Vr as t,Yr as u,Cn as v,Ar as w,qe as x,Tn as y,xn as z};
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>Token Tracker Share</title>
|
|
7
|
-
<meta name="description" content="Share a Token Tracker dashboard snapshot with token usage insights across models, projects, and time windows." />
|
|
8
|
-
<meta property="og:site_name" content="Token Tracker" />
|
|
9
|
-
<meta property="og:title" content="Token Tracker Share" />
|
|
10
|
-
<meta property="og:description" content="Share a Token Tracker dashboard snapshot with token usage insights across models, projects, and time windows." />
|
|
11
|
-
<meta property="og:image" content="https://www.tokentracker.cc/dashboard-dark.png" />
|
|
12
|
-
<meta property="og:type" content="website" />
|
|
13
|
-
<meta property="og:url" content="https://www.tokentracker.cc/share" />
|
|
14
|
-
<meta name="twitter:card" content="summary_large_image" />
|
|
15
|
-
<meta name="twitter:title" content="Token Tracker Share" />
|
|
16
|
-
<meta name="twitter:description" content="Share a Token Tracker dashboard snapshot with token usage insights across models, projects, and time windows." />
|
|
17
|
-
<meta name="twitter:image" content="https://www.tokentracker.cc/dashboard-dark.png" />
|
|
18
|
-
<link rel="canonical" href="https://www.tokentracker.cc/share" />
|
|
19
|
-
<link rel="icon" href="/icon.svg" type="image/svg+xml" />
|
|
20
|
-
<link rel="icon" href="/favicon.ico" sizes="any" />
|
|
21
|
-
<link rel="icon" href="/favicon-32.png" sizes="32x32" type="image/png" />
|
|
22
|
-
<link rel="icon" href="/favicon-16.png" sizes="16x16" type="image/png" />
|
|
23
|
-
<link rel="apple-touch-icon" href="/apple-touch-icon.png" sizes="180x180" />
|
|
24
|
-
<meta name="theme-color" content="#000000" />
|
|
25
|
-
<script>
|
|
26
|
-
// ES2022 built-in polyfills for WebKit < 15.4 (macOS 12.0 Monterey ships Safari 15.0).
|
|
27
|
-
// Base UI uses Object.hasOwn and Array.prototype.at lands in Safari 15.4; esbuild
|
|
28
|
-
// down-levels syntax but never polyfills built-ins. Run before the bundle.
|
|
29
|
-
(function () {
|
|
30
|
-
try {
|
|
31
|
-
if (typeof Object.hasOwn !== "function") {
|
|
32
|
-
Object.defineProperty(Object, "hasOwn", {
|
|
33
|
-
value: function (o, k) { return Object.prototype.hasOwnProperty.call(o, k); },
|
|
34
|
-
configurable: true, writable: true,
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
function at(n) {
|
|
38
|
-
n = Math.trunc(n) || 0;
|
|
39
|
-
if (n < 0) n += this.length;
|
|
40
|
-
return n < 0 || n >= this.length ? undefined : this[n];
|
|
41
|
-
}
|
|
42
|
-
if (typeof Array.prototype.at !== "function") {
|
|
43
|
-
Object.defineProperty(Array.prototype, "at", { value: at, configurable: true, writable: true });
|
|
44
|
-
}
|
|
45
|
-
if (typeof String.prototype.at !== "function") {
|
|
46
|
-
Object.defineProperty(String.prototype, "at", { value: at, configurable: true, writable: true });
|
|
47
|
-
}
|
|
48
|
-
} catch (e) {}
|
|
49
|
-
})();
|
|
50
|
-
document.documentElement.classList.add("js");
|
|
51
|
-
</script>
|
|
52
|
-
<style>
|
|
53
|
-
.js .aeo-seed-content {
|
|
54
|
-
display: none;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
.aeo-seed-content {
|
|
58
|
-
margin: 0;
|
|
59
|
-
padding: 1.5rem;
|
|
60
|
-
font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
61
|
-
line-height: 1.55;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
.aeo-seed-content h1,
|
|
65
|
-
.aeo-seed-content h2 {
|
|
66
|
-
margin: 0.75rem 0;
|
|
67
|
-
}
|
|
68
|
-
</style>
|
|
69
|
-
<script type="application/ld+json">
|
|
70
|
-
{
|
|
71
|
-
"@context": "https://schema.org",
|
|
72
|
-
"@type": "WebPage",
|
|
73
|
-
"name": "Token Tracker Share Dashboard",
|
|
74
|
-
"url": "https://www.tokentracker.cc/share",
|
|
75
|
-
"description": "Shareable Token Tracker dashboard snapshot."
|
|
76
|
-
}
|
|
77
|
-
</script>
|
|
78
|
-
<script type="module" crossorigin src="/assets/main-pi07CfeC.js"></script>
|
|
79
|
-
<link rel="stylesheet" crossorigin href="/assets/main-DAcSUW2t.css">
|
|
80
|
-
</head>
|
|
81
|
-
<body>
|
|
82
|
-
<main class="aeo-seed-content" aria-label="Token Tracker share page summary">
|
|
83
|
-
<h1>Token Tracker Share Dashboard</h1>
|
|
84
|
-
<p>
|
|
85
|
-
This page renders a shareable dashboard snapshot for Token Tracker token tracking data, including model
|
|
86
|
-
usage trends and project-level summaries. It is designed for quick sharing with teammates,
|
|
87
|
-
collaborators, or stakeholders who need clear usage context.
|
|
88
|
-
</p>
|
|
89
|
-
<p>
|
|
90
|
-
The shared view keeps the same core signal style as the main dashboard: concise metrics, readable
|
|
91
|
-
trend framing, and lightweight navigation. Use it when you want to communicate usage outcomes without
|
|
92
|
-
requiring the recipient to open the full private workspace.
|
|
93
|
-
</p>
|
|
94
|
-
<p>
|
|
95
|
-
In practice, teams use this page during sprint reviews, weekly engineering updates, and cost-analysis
|
|
96
|
-
discussions. Instead of manually summarizing logs, you can share one URL that highlights model usage,
|
|
97
|
-
project activity, and trend direction in a format that is easy to scan.
|
|
98
|
-
</p>
|
|
99
|
-
|
|
100
|
-
<h2>What this share page includes</h2>
|
|
101
|
-
<ul>
|
|
102
|
-
<li>Snapshot-oriented presentation for token usage highlights.</li>
|
|
103
|
-
<li>Model and project usage context suitable for async reporting.</li>
|
|
104
|
-
<li>Fast navigation back to primary Token Tracker pages.</li>
|
|
105
|
-
</ul>
|
|
106
|
-
<p>
|
|
107
|
-
If you are reviewing usage impact after adopting a new coding workflow, this page helps you present
|
|
108
|
-
changes clearly: which models were used, where token volume concentrated, and whether the trend is
|
|
109
|
-
rising or stabilizing. It is optimized for communication and fast interpretation.
|
|
110
|
-
</p>
|
|
111
|
-
<p>
|
|
112
|
-
For deeper analysis and operational actions, recipients can jump back to the main dashboard from the
|
|
113
|
-
links below, then inspect richer views such as leaderboard ranking, project-level usage, and historical
|
|
114
|
-
trends over custom time ranges.
|
|
115
|
-
</p>
|
|
116
|
-
<p>
|
|
117
|
-
Example use cases include comparing token efficiency before and after a model swap, validating budget
|
|
118
|
-
controls for a weekly sprint, and checking if newly introduced automation scripts are causing
|
|
119
|
-
unexpected model spikes. Teams often use this page when they want a concise status snapshot before
|
|
120
|
-
a planning meeting, because it keeps language and focus simple while still preserving key operational
|
|
121
|
-
context.
|
|
122
|
-
</p>
|
|
123
|
-
<p>
|
|
124
|
-
You can also reference this page as supporting material in PRs or postmortems: it helps answer
|
|
125
|
-
questions like “Did we improve or increase cost this cycle?”, “Which projects drove the largest increase?”,
|
|
126
|
-
and “What follow-up guardrails should we add next?”.
|
|
127
|
-
</p>
|
|
128
|
-
|
|
129
|
-
<h2>Quick links</h2>
|
|
130
|
-
<ul>
|
|
131
|
-
<li><a href="https://www.tokentracker.cc/">Token Tracker homepage</a></li>
|
|
132
|
-
<li><a href="https://www.tokentracker.cc/leaderboard">Public leaderboard</a></li>
|
|
133
|
-
<li><a href="https://github.com/mm7894215/TokenTracker">GitHub: mm7894215/TokenTracker</a></li>
|
|
134
|
-
<li><a href="https://www.npmjs.com/package/tokentracker-cli">npm: tokentracker-cli</a></li>
|
|
135
|
-
</ul>
|
|
136
|
-
</main>
|
|
137
|
-
|
|
138
|
-
<div id="root"></div>
|
|
139
|
-
</body>
|
|
140
|
-
</html>
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
const os = require("node:os");
|
|
4
|
-
const path = require("node:path");
|
|
5
|
-
const fs = require("node:fs/promises");
|
|
6
|
-
|
|
7
|
-
const { readJson, writeJson } = require("../lib/fs");
|
|
8
|
-
const { resolveTrackerPaths } = require("../lib/tracker-paths");
|
|
9
|
-
|
|
10
|
-
const DEFAULT_BASE_URL = "https://srctyff5.us-east.insforge.app";
|
|
11
|
-
const POLL_INTERVAL_MS = 5_000;
|
|
12
|
-
const ABSOLUTE_TIMEOUT_MS = 16 * 60 * 1000; // matches the 15-min server window with a small buffer
|
|
13
|
-
|
|
14
|
-
function readBaseUrl(config) {
|
|
15
|
-
return (
|
|
16
|
-
process.env.TOKENTRACKER_BASE_URL ||
|
|
17
|
-
process.env.TOKENTRACKER_API_URL ||
|
|
18
|
-
config?.baseUrl ||
|
|
19
|
-
DEFAULT_BASE_URL
|
|
20
|
-
);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
async function authorize({ baseUrl, clientInfo }) {
|
|
24
|
-
const res = await fetch(`${baseUrl}/functions/tokentracker-device-flow-authorize`, {
|
|
25
|
-
method: "POST",
|
|
26
|
-
headers: { "Content-Type": "application/json" },
|
|
27
|
-
body: JSON.stringify({ client_info: clientInfo }),
|
|
28
|
-
});
|
|
29
|
-
if (!res.ok) {
|
|
30
|
-
const text = await res.text();
|
|
31
|
-
throw new Error(`authorize failed (HTTP ${res.status}): ${text.slice(0, 200)}`);
|
|
32
|
-
}
|
|
33
|
-
return res.json();
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
async function pollOnce({ baseUrl, deviceCode }) {
|
|
37
|
-
const res = await fetch(`${baseUrl}/functions/tokentracker-device-flow-poll`, {
|
|
38
|
-
method: "POST",
|
|
39
|
-
headers: { "Content-Type": "application/json" },
|
|
40
|
-
body: JSON.stringify({ device_code: deviceCode }),
|
|
41
|
-
});
|
|
42
|
-
const data = await res.json().catch(() => ({}));
|
|
43
|
-
// 404 = unknown, 410 = expired, 200 = {status, user_id?, device_token?}.
|
|
44
|
-
// Anything else (502 from a misconfigured edge, 5xx during deploy, …) must
|
|
45
|
-
// bubble up as a network-style error — masking it as "unknown" would tell
|
|
46
|
-
// the user their device_code was evicted when it wasn't.
|
|
47
|
-
if (!res.ok && res.status !== 404 && res.status !== 410) {
|
|
48
|
-
throw new Error(`poll HTTP ${res.status}: ${(data?.error ?? "").toString().slice(0, 200)}`);
|
|
49
|
-
}
|
|
50
|
-
return {
|
|
51
|
-
status: data.status ?? "unknown",
|
|
52
|
-
user_id: data.user_id ?? null,
|
|
53
|
-
deviceToken: data.device_token ?? data.deviceToken ?? null,
|
|
54
|
-
deviceId: data.device_id ?? data.deviceId ?? null,
|
|
55
|
-
httpStatus: res.status,
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function sleep(ms) {
|
|
60
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
async function cmdDeviceLogin(argv = [], options = {}) {
|
|
64
|
-
const opts = parseArgs(argv);
|
|
65
|
-
const home = options.home || os.homedir();
|
|
66
|
-
const sleepFn = options.sleep || sleep;
|
|
67
|
-
const { trackerDir } = await resolveTrackerPaths({ home });
|
|
68
|
-
const configPath = path.join(trackerDir, "config.json");
|
|
69
|
-
const config = (await readJson(configPath)) || {};
|
|
70
|
-
const baseUrl = opts.baseUrl || readBaseUrl(config);
|
|
71
|
-
|
|
72
|
-
const clientInfo = `${os.platform()}-${os.arch()} ${os.hostname()}`;
|
|
73
|
-
process.stdout.write(`Requesting device code from ${baseUrl}...\n`);
|
|
74
|
-
const authResp = await authorize({ baseUrl, clientInfo });
|
|
75
|
-
|
|
76
|
-
if (opts.json) {
|
|
77
|
-
process.stdout.write(JSON.stringify(authResp, null, 2) + "\n");
|
|
78
|
-
} else {
|
|
79
|
-
process.stdout.write(
|
|
80
|
-
[
|
|
81
|
-
"",
|
|
82
|
-
" Sign in from a browser:",
|
|
83
|
-
` ${authResp.verification_uri_complete || authResp.verification_uri}`,
|
|
84
|
-
"",
|
|
85
|
-
` Or visit ${authResp.verification_uri} and enter the code:`,
|
|
86
|
-
"",
|
|
87
|
-
` ${authResp.user_code}`,
|
|
88
|
-
"",
|
|
89
|
-
` This code expires in ${Math.round(authResp.expires_in / 60)} minutes.`,
|
|
90
|
-
" Polling every 5 seconds until you approve…",
|
|
91
|
-
"",
|
|
92
|
-
].join("\n"),
|
|
93
|
-
);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const startedAt = Date.now();
|
|
97
|
-
let consecutiveErrors = 0;
|
|
98
|
-
const MAX_BACKOFF_MS = 30_000;
|
|
99
|
-
while (Date.now() - startedAt < ABSOLUTE_TIMEOUT_MS) {
|
|
100
|
-
// Exponential backoff on consecutive network failures (capped at 30s) so
|
|
101
|
-
// a flaky network doesn't hammer the server at the full 5s cadence for
|
|
102
|
-
// the entire 15-minute window. ±20% jitter on retries prevents
|
|
103
|
-
// thundering-herd reconnects when many CLIs lose connectivity at once.
|
|
104
|
-
let wait =
|
|
105
|
-
consecutiveErrors === 0
|
|
106
|
-
? POLL_INTERVAL_MS
|
|
107
|
-
: Math.min(POLL_INTERVAL_MS * Math.pow(2, consecutiveErrors - 1), MAX_BACKOFF_MS);
|
|
108
|
-
if (consecutiveErrors > 0) {
|
|
109
|
-
const jitter = wait * 0.2 * (Math.random() * 2 - 1);
|
|
110
|
-
wait = Math.max(POLL_INTERVAL_MS, wait + jitter);
|
|
111
|
-
}
|
|
112
|
-
await sleepFn(wait);
|
|
113
|
-
let result;
|
|
114
|
-
try {
|
|
115
|
-
result = await pollOnce({ baseUrl, deviceCode: authResp.device_code });
|
|
116
|
-
consecutiveErrors = 0;
|
|
117
|
-
} catch (e) {
|
|
118
|
-
consecutiveErrors++;
|
|
119
|
-
process.stderr.write(`poll error (retry ${consecutiveErrors}): ${e?.message || e}\n`);
|
|
120
|
-
continue;
|
|
121
|
-
}
|
|
122
|
-
if (result.status === "approved" && result.user_id) {
|
|
123
|
-
if (!result.deviceToken) {
|
|
124
|
-
throw new Error("device login approved but server did not return a device token");
|
|
125
|
-
}
|
|
126
|
-
const next = {
|
|
127
|
-
...config,
|
|
128
|
-
baseUrl,
|
|
129
|
-
user_id: result.user_id,
|
|
130
|
-
deviceToken: result.deviceToken,
|
|
131
|
-
deviceId: result.deviceId || config.deviceId,
|
|
132
|
-
device_login_at: new Date().toISOString(),
|
|
133
|
-
};
|
|
134
|
-
await writeJson(configPath, next);
|
|
135
|
-
process.stdout.write(`\n✓ Approved. device token written to ${configPath}\n`);
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
if (result.status === "expired") {
|
|
139
|
-
throw new Error("device_code expired — re-run `tracker device-login`");
|
|
140
|
-
}
|
|
141
|
-
if (result.status === "unknown") {
|
|
142
|
-
throw new Error("device_code is unknown — server may have evicted it");
|
|
143
|
-
}
|
|
144
|
-
// status === "pending" → just keep polling silently
|
|
145
|
-
}
|
|
146
|
-
throw new Error("device-login timed out without approval");
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
function parseArgs(argv) {
|
|
150
|
-
const out = { json: false, baseUrl: null };
|
|
151
|
-
for (let i = 0; i < argv.length; i++) {
|
|
152
|
-
const a = argv[i];
|
|
153
|
-
if (a === "--json") out.json = true;
|
|
154
|
-
else if (a === "--base-url") {
|
|
155
|
-
out.baseUrl = argv[++i] || null;
|
|
156
|
-
} else throw new Error(`Unknown option: ${a}`);
|
|
157
|
-
}
|
|
158
|
-
return out;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
module.exports = { cmdDeviceLogin, authorize, pollOnce };
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
const DEFAULTS = {
|
|
2
|
-
intervalMs: 30 * 60_000,
|
|
3
|
-
jitterMsMax: 60_000,
|
|
4
|
-
backlogBytes: 1_000_000,
|
|
5
|
-
batchSize: 300,
|
|
6
|
-
maxBatchesSmall: 2,
|
|
7
|
-
maxBatchesLarge: 4,
|
|
8
|
-
backoffInitialMs: 60_000,
|
|
9
|
-
backoffMaxMs: 30 * 60_000,
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
function normalizeState(raw) {
|
|
13
|
-
const s = raw && typeof raw === "object" ? raw : {};
|
|
14
|
-
return {
|
|
15
|
-
version: 1,
|
|
16
|
-
lastSuccessMs: toSafeInt(s.lastSuccessMs),
|
|
17
|
-
nextAllowedAtMs: toSafeInt(s.nextAllowedAtMs),
|
|
18
|
-
backoffUntilMs: toSafeInt(s.backoffUntilMs),
|
|
19
|
-
backoffStep: toSafeInt(s.backoffStep),
|
|
20
|
-
lastErrorAt: typeof s.lastErrorAt === "string" ? s.lastErrorAt : null,
|
|
21
|
-
lastError: typeof s.lastError === "string" ? s.lastError : null,
|
|
22
|
-
updatedAt: typeof s.updatedAt === "string" ? s.updatedAt : null,
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function decideAutoUpload({ nowMs, pendingBytes, state, config }) {
|
|
27
|
-
const cfg = { ...DEFAULTS, ...(config || {}) };
|
|
28
|
-
const s = normalizeState(state);
|
|
29
|
-
const pending = Number(pendingBytes || 0);
|
|
30
|
-
|
|
31
|
-
if (pending <= 0) {
|
|
32
|
-
return {
|
|
33
|
-
allowed: false,
|
|
34
|
-
reason: "no-pending",
|
|
35
|
-
maxBatches: 0,
|
|
36
|
-
batchSize: cfg.batchSize,
|
|
37
|
-
blockedUntilMs: 0,
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const blockedUntilMs = Math.max(s.nextAllowedAtMs || 0, s.backoffUntilMs || 0);
|
|
42
|
-
if (blockedUntilMs > 0 && nowMs < blockedUntilMs) {
|
|
43
|
-
return {
|
|
44
|
-
allowed: false,
|
|
45
|
-
reason: "throttled",
|
|
46
|
-
maxBatches: 0,
|
|
47
|
-
batchSize: cfg.batchSize,
|
|
48
|
-
blockedUntilMs,
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const maxBatches = pending >= cfg.backlogBytes ? cfg.maxBatchesLarge : cfg.maxBatchesSmall;
|
|
53
|
-
return {
|
|
54
|
-
allowed: true,
|
|
55
|
-
reason: "allowed",
|
|
56
|
-
maxBatches,
|
|
57
|
-
batchSize: cfg.batchSize,
|
|
58
|
-
blockedUntilMs: 0,
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function recordUploadSuccess({ nowMs, state, config, randInt }) {
|
|
63
|
-
const cfg = { ...DEFAULTS, ...(config || {}) };
|
|
64
|
-
const s = normalizeState(state);
|
|
65
|
-
const jitter =
|
|
66
|
-
typeof randInt === "function" ? randInt(0, cfg.jitterMsMax) : randomInt(0, cfg.jitterMsMax);
|
|
67
|
-
const nextAllowedAtMs = nowMs + cfg.intervalMs + jitter;
|
|
68
|
-
|
|
69
|
-
return {
|
|
70
|
-
...s,
|
|
71
|
-
lastSuccessMs: nowMs,
|
|
72
|
-
nextAllowedAtMs,
|
|
73
|
-
backoffUntilMs: 0,
|
|
74
|
-
backoffStep: 0,
|
|
75
|
-
lastErrorAt: null,
|
|
76
|
-
lastError: null,
|
|
77
|
-
updatedAt: new Date(nowMs).toISOString(),
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
function recordUploadFailure({ nowMs, state, error, config }) {
|
|
82
|
-
const cfg = { ...DEFAULTS, ...(config || {}) };
|
|
83
|
-
const s = normalizeState(state);
|
|
84
|
-
|
|
85
|
-
const retryAfterMs = toSafeInt(error?.retryAfterMs);
|
|
86
|
-
const status = toSafeInt(error?.status);
|
|
87
|
-
|
|
88
|
-
let backoffMs = 0;
|
|
89
|
-
if (retryAfterMs > 0) {
|
|
90
|
-
backoffMs = Math.min(cfg.backoffMaxMs, Math.max(cfg.backoffInitialMs, retryAfterMs));
|
|
91
|
-
} else {
|
|
92
|
-
const step = Math.min(10, Math.max(0, s.backoffStep || 0));
|
|
93
|
-
backoffMs = Math.min(cfg.backoffMaxMs, cfg.backoffInitialMs * Math.pow(2, step));
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const backoffUntilMs = nowMs + backoffMs;
|
|
97
|
-
const nextAllowedAtMs = Math.max(s.nextAllowedAtMs || 0, backoffUntilMs);
|
|
98
|
-
|
|
99
|
-
return {
|
|
100
|
-
...s,
|
|
101
|
-
nextAllowedAtMs,
|
|
102
|
-
backoffUntilMs,
|
|
103
|
-
backoffStep: Math.min(20, (s.backoffStep || 0) + 1),
|
|
104
|
-
lastErrorAt: new Date(nowMs).toISOString(),
|
|
105
|
-
lastError: truncate(String(error?.message || "upload failed"), 200),
|
|
106
|
-
updatedAt: new Date(nowMs).toISOString(),
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
function parseRetryAfterMs(headerValue, nowMs = Date.now()) {
|
|
111
|
-
if (typeof headerValue !== "string" || headerValue.trim().length === 0) return null;
|
|
112
|
-
const v = headerValue.trim();
|
|
113
|
-
const seconds = Number(v);
|
|
114
|
-
if (Number.isFinite(seconds) && seconds >= 0) return Math.floor(seconds * 1000);
|
|
115
|
-
const d = new Date(v);
|
|
116
|
-
if (Number.isNaN(d.getTime())) return null;
|
|
117
|
-
const delta = d.getTime() - nowMs;
|
|
118
|
-
return delta > 0 ? delta : 0;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function randomInt(min, maxInclusive) {
|
|
122
|
-
const lo = Math.floor(min);
|
|
123
|
-
const hi = Math.floor(maxInclusive);
|
|
124
|
-
if (hi <= lo) return lo;
|
|
125
|
-
return lo + Math.floor(Math.random() * (hi - lo + 1));
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function toSafeInt(v) {
|
|
129
|
-
const n = Number(v);
|
|
130
|
-
if (!Number.isFinite(n)) return 0;
|
|
131
|
-
if (n <= 0) return 0;
|
|
132
|
-
return Math.floor(n);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
function truncate(s, maxLen) {
|
|
136
|
-
if (typeof s !== "string") return "";
|
|
137
|
-
if (s.length <= maxLen) return s;
|
|
138
|
-
return s.slice(0, maxLen - 1) + "…";
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
module.exports = {
|
|
142
|
-
DEFAULTS,
|
|
143
|
-
normalizeState,
|
|
144
|
-
decideAutoUpload,
|
|
145
|
-
recordUploadSuccess,
|
|
146
|
-
recordUploadFailure,
|
|
147
|
-
parseRetryAfterMs,
|
|
148
|
-
};
|