tokentracker-cli 0.86.1 → 0.87.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/dashboard/dist/assets/{AchievementBadge-BHWjTRZh.js → AchievementBadge-CU9m5POo.js} +1 -1
  2. package/dashboard/dist/assets/{AchievementsPage-X6Z6fiAx.js → AchievementsPage-ESzayVR5.js} +2 -2
  3. package/dashboard/dist/assets/{AchievementsSection-DL2CccQ8.js → AchievementsSection-DUVRqw19.js} +1 -1
  4. package/dashboard/dist/assets/{BadgeDetailModal-DKn88JDX.js → BadgeDetailModal-CxNQcN6_.js} +1 -1
  5. package/dashboard/dist/assets/{Card-B_gKsFZR.js → Card-DXIoSOtO.js} +1 -1
  6. package/dashboard/dist/assets/{ClawdAnimated-vEB5WCNu.js → ClawdAnimated-BsuxMkNd.js} +1 -1
  7. package/dashboard/dist/assets/{CommandPalette-BoxeCsUF.js → CommandPalette-C-amBp21.js} +1 -1
  8. package/dashboard/dist/assets/{CommunityStatsModal-BwELjQld.js → CommunityStatsModal-ByFOQube.js} +1 -1
  9. package/dashboard/dist/assets/{ConfirmModal-j8yHWm2k.js → ConfirmModal-BnUyidbn.js} +1 -1
  10. package/dashboard/dist/assets/{DashboardPage-CkvAOuBF.js → DashboardPage-GyXkKYW0.js} +1 -1
  11. package/dashboard/dist/assets/{DevicePage-k4Lr11LG.js → DevicePage-B_o-jhku.js} +1 -1
  12. package/dashboard/dist/assets/{DialogClose-C-ZhX9eY.js → DialogClose-BSd7Jiag.js} +1 -1
  13. package/dashboard/dist/assets/DialogDescription-BFBVGbUT.js +1 -0
  14. package/dashboard/dist/assets/{DialogTitle-XCGSHZDz.js → DialogTitle-XBpneDtQ.js} +1 -1
  15. package/dashboard/dist/assets/{FadeIn-ljP_7vPC.js → FadeIn-Dg0v4V9p.js} +1 -1
  16. package/dashboard/dist/assets/{HeaderGithubStar-D4QupeSb.js → HeaderGithubStar-BIsQD1OK.js} +1 -1
  17. package/dashboard/dist/assets/{HoverTooltip-Dkpz8RmH.js → HoverTooltip-CtmRa8ne.js} +1 -1
  18. package/dashboard/dist/assets/{IpCheckPage-WkZK9Tr3.js → IpCheckPage-BUoLz5sL.js} +1 -1
  19. package/dashboard/dist/assets/{LandingPage-Dp3m0uJg.js → LandingPage-BheA-lw8.js} +2 -2
  20. package/dashboard/dist/assets/{LeaderboardAvatar-DleP6bK7.js → LeaderboardAvatar-DAy9SOdL.js} +1 -1
  21. package/dashboard/dist/assets/{LeaderboardPage-DTwMMaF2.js → LeaderboardPage-CwLqtEUN.js} +2 -2
  22. package/dashboard/dist/assets/{LeaderboardProfileModal-xdDlcRDd.js → LeaderboardProfileModal-BZ9yGyjB.js} +3 -3
  23. package/dashboard/dist/assets/{LeaderboardProfilePage-Ckytgq9h.js → LeaderboardProfilePage-Cs-LTfvS.js} +1 -1
  24. package/dashboard/dist/assets/{LimitsPage-D_2cV3S4.js → LimitsPage-BQle8e8N.js} +1 -1
  25. package/dashboard/dist/assets/{LocalOnlyNotice-DpCb8VIO.js → LocalOnlyNotice-Bp4CqObQ.js} +1 -1
  26. package/dashboard/dist/assets/{LoginCard-BeAb35_3.js → LoginCard-BIXfWkR2.js} +1 -1
  27. package/dashboard/dist/assets/{LoginModal-DNdAgKeE.js → LoginModal-B-ubPXdr.js} +1 -1
  28. package/dashboard/dist/assets/{LoginPage-nuWkBuqy.js → LoginPage-9arjWT-s.js} +1 -1
  29. package/dashboard/dist/assets/{PetPage-CCLFROsF.js → PetPage-BzAVsvh6.js} +1 -1
  30. package/dashboard/dist/assets/{PopoverPopup-BCaeRKf4.js → PopoverPopup-DMg7XE1h.js} +1 -1
  31. package/dashboard/dist/assets/{ProviderIcon-C_Fpc2jL.js → ProviderIcon-BG3oqeST.js} +1 -1
  32. package/dashboard/dist/assets/{ResetPasswordPage-lLDxtpC9.js → ResetPasswordPage-LQ9rfcRE.js} +1 -1
  33. package/dashboard/dist/assets/{SegmentedControl-Bnfv5lDS.js → SegmentedControl-GY2tRk1u.js} +1 -1
  34. package/dashboard/dist/assets/{Select-CvY_Y0WS.js → Select-CCngFwmz.js} +1 -1
  35. package/dashboard/dist/assets/{SelectItemText-DX4QYfBW.js → SelectItemText-B9Zm8WTR.js} +1 -1
  36. package/dashboard/dist/assets/{ServiceStatusPage-DcUrtacl.js → ServiceStatusPage-BxPvk1-W.js} +1 -1
  37. package/dashboard/dist/assets/{SessionsPage-CJXyaHQA.js → SessionsPage-DGo6yAwP.js} +1 -1
  38. package/dashboard/dist/assets/SettingsPage-ConPEiwO.js +1 -0
  39. package/dashboard/dist/assets/{SkillsPage-BGvK3HZ0.js → SkillsPage-D0PB3WR5.js} +1 -1
  40. package/dashboard/dist/assets/{TokenGalaxy-D9_H79bK.js → TokenGalaxy-Chh_fPIv.js} +1 -1
  41. package/dashboard/dist/assets/{ToolbarRootContext-BsM_3QBs.js → ToolbarRootContext-BXacVvrF.js} +1 -1
  42. package/dashboard/dist/assets/{TrendMonitor-D2QSVlSi.js → TrendMonitor-CjiCwNmO.js} +1 -1
  43. package/dashboard/dist/assets/{WidgetsPage-BpWOr7-c.js → WidgetsPage-CBw9uBCO.js} +1 -1
  44. package/dashboard/dist/assets/{WrappedPage-DliB3OZk.js → WrappedPage-CEpBAMZR.js} +1 -1
  45. package/dashboard/dist/assets/{__vite-browser-external-CzDhMv0q.js → __vite-browser-external-Dyag-P6u.js} +19 -13
  46. package/dashboard/dist/assets/{agent-logos-Q7rTqkGv.js → agent-logos-CLQGE0AM.js} +1 -1
  47. package/dashboard/dist/assets/{arrow-up-right-DwqQgMsR.js → arrow-up-right-CU2HDjoG.js} +1 -1
  48. package/dashboard/dist/assets/{check-Cypjnyke.js → check-CucGM5lh.js} +1 -1
  49. package/dashboard/dist/assets/{chevron-right-LZRe0crm.js → chevron-right-DYzUvcID.js} +1 -1
  50. package/dashboard/dist/assets/{copy-BUe15mXV.js → copy-BFeQ31Tr.js} +1 -1
  51. package/dashboard/dist/assets/{download-BhjaQuUD.js → download-Coq_llCX.js} +1 -1
  52. package/dashboard/dist/assets/{external-link-BHU7m_Df.js → external-link-BJiDBW3d.js} +1 -1
  53. package/dashboard/dist/assets/{flame-BPQ7FpRu.js → flame-5stsnhc0.js} +1 -1
  54. package/dashboard/dist/assets/{format-tokens-C0XEJ96L.js → format-tokens-CpTJbo-2.js} +1 -1
  55. package/dashboard/dist/assets/{icons-De5Qo1lp.js → icons-jsuvmnnO.js} +1 -1
  56. package/dashboard/dist/assets/{index-Cl8hqOBU.js → index-BU6GsTbx.js} +1 -1
  57. package/dashboard/dist/assets/{index-lmWJH5W9.js → index-Bs97feNM.js} +1 -1
  58. package/dashboard/dist/assets/{index-UfiJKvuV.js → index-DSD3RLQ4.js} +1 -1
  59. package/dashboard/dist/assets/{info-CCPDu6hQ.js → info-DNNUzeV_.js} +1 -1
  60. package/dashboard/dist/assets/{limits-providers-B2Qjydn9.js → limits-providers-DKTqNO55.js} +1 -1
  61. package/dashboard/dist/assets/{link-2-Dl1DAfTL.js → link-2-DC1hnQcE.js} +1 -1
  62. package/dashboard/dist/assets/{loader-circle-C-mC8s6j.js → loader-circle-DtInM4Io.js} +1 -1
  63. package/dashboard/dist/assets/{maximize-2-C9YpCcsr.js → maximize-2-DxpsaYXp.js} +1 -1
  64. package/dashboard/dist/assets/{provider-display-DNXQkneb.js → provider-display-hkyvfEJF.js} +1 -1
  65. package/dashboard/dist/assets/{react-LsYzFOQW.js → react-TbJoDSP4.js} +1 -1
  66. package/dashboard/dist/assets/{search-D5SGjOTl.js → search-C7bnqB9b.js} +1 -1
  67. package/dashboard/dist/assets/{skills-api-CGRg1lZw.js → skills-api-D7glOWg7.js} +1 -1
  68. package/dashboard/dist/assets/{store-BMdm145i.js → store-CCVlzuqv.js} +1 -1
  69. package/dashboard/dist/assets/{terminal-HhtP7nqJ.js → terminal-uQlsmzGi.js} +1 -1
  70. package/dashboard/dist/assets/{trash-2-CeEoITVO.js → trash-2-B1yuX-oD.js} +1 -1
  71. package/dashboard/dist/assets/{use-community-stats-BTZHzzWd.js → use-community-stats-0Fs5nY1G.js} +1 -1
  72. package/dashboard/dist/assets/{use-limits-display-prefs-DPNlMKcg.js → use-limits-display-prefs-CrftAn62.js} +1 -1
  73. package/dashboard/dist/assets/{use-native-settings-DFF0ouY5.js → use-native-settings-CVqB9eoO.js} +1 -1
  74. package/dashboard/dist/assets/{use-ordered-list-CCLtmxXg.js → use-ordered-list-DAdPjLb5.js} +1 -1
  75. package/dashboard/dist/assets/use-reduced-motion-DVGYs3-k.js +1 -0
  76. package/dashboard/dist/assets/{use-session-efficiency-pref-CrvLKyhz.js → use-session-efficiency-pref-Cc52HiK0.js} +1 -1
  77. package/dashboard/dist/assets/{use-transform-BnJ0PftW.js → use-transform-D76wHhX0.js} +1 -1
  78. package/dashboard/dist/assets/{use-usage-limits-BY3ZXlDo.js → use-usage-limits-B7Prb8rk.js} +1 -1
  79. package/dashboard/dist/assets/{useCurrency-BiFDQKMu.js → useCurrency-DWoM_A3s.js} +1 -1
  80. package/dashboard/dist/assets/{useScrollLock-BXUoxe5p.js → useScrollLock-Bp6ddiQo.js} +1 -1
  81. package/dashboard/dist/assets/{useTokenFormat-C6DBFS-R.js → useTokenFormat-DZOYz5HT.js} +1 -1
  82. package/dashboard/dist/assets/{zap-9H5t1Kye.js → zap-DyeAeO8l.js} +1 -1
  83. package/dashboard/dist/index.html +1 -1
  84. package/dashboard/dist/ip-check.html +1 -1
  85. package/dashboard/dist/leaderboard.html +1 -1
  86. package/dashboard/dist/share.html +1 -1
  87. package/package.json +1 -1
  88. package/src/commands/sync.js +8 -9
  89. package/src/lib/codex-rollout-parser.js +8 -52
  90. package/src/lib/jsonl-lines.js +104 -0
  91. package/src/lib/pricing/seed-snapshot.json +1 -1
  92. package/src/lib/rollout.js +69 -11
  93. package/dashboard/dist/assets/DialogDescription-BRiqm-uZ.js +0 -1
  94. package/dashboard/dist/assets/SettingsPage-BkgPxhGn.js +0 -1
  95. package/dashboard/dist/assets/use-reduced-motion-DUtjZjIj.js +0 -1
@@ -6,6 +6,7 @@ const readline = require("node:readline");
6
6
 
7
7
  const crypto = require("node:crypto");
8
8
  const { ensureDir, writeJson, chmod600IfPossible } = require("./fs");
9
+ const { physicalJsonlRecords } = require("./jsonl-lines");
9
10
  const { readSqliteJsonRows, readSqliteJsonRowsAsync } = require("./sqlite-reader");
10
11
  const wsl = require("./wsl-probe");
11
12
  const { resolveInstallPaths } = require("./install-resolver");
@@ -180,7 +181,11 @@ async function parseRolloutIncremental({
180
181
  source,
181
182
  publicRepoResolver,
182
183
  diagnostics,
184
+ invalidRecordPolicy = "skip",
183
185
  }) {
186
+ if (invalidRecordPolicy !== "skip" && invalidRecordPolicy !== "throw") {
187
+ throw new TypeError(`unsupported invalidRecordPolicy: ${invalidRecordPolicy}`);
188
+ }
184
189
  await ensureDir(path.dirname(queuePath));
185
190
  let filesProcessed = 0;
186
191
  let eventsAggregated = 0;
@@ -446,6 +451,7 @@ async function parseRolloutIncremental({
446
451
  publicRepoCache,
447
452
  publicRepoResolver,
448
453
  projectContext,
454
+ invalidRecordPolicy,
449
455
  })
450
456
  : await parseRolloutFile({
451
457
  filePath,
@@ -467,6 +473,7 @@ async function parseRolloutIncremental({
467
473
  projectContext,
468
474
  seenCodexEvents: codexEventTracker,
469
475
  sessionId: codexSessionIdFromPath(filePath),
476
+ invalidRecordPolicy,
470
477
  });
471
478
 
472
479
  const nextCursor = {
@@ -1952,6 +1959,7 @@ async function parseRolloutFile({
1952
1959
  projectContext,
1953
1960
  seenCodexEvents,
1954
1961
  sessionId,
1962
+ invalidRecordPolicy,
1955
1963
  }) {
1956
1964
  const st = fileStat || (await fs.stat(filePath));
1957
1965
  const endOffset = st.size;
@@ -1968,8 +1976,10 @@ async function parseRolloutFile({
1968
1976
  };
1969
1977
  }
1970
1978
 
1971
- const stream = fssync.createReadStream(filePath, { encoding: "utf8", start: startOffset });
1972
- const rl = readline.createInterface({ input: stream, crlfDelay: Infinity });
1979
+ const stream = fssync.createReadStream(filePath, {
1980
+ start: startOffset,
1981
+ end: endOffset - 1,
1982
+ });
1973
1983
 
1974
1984
  let model = typeof lastModel === "string" ? lastModel : null;
1975
1985
  const usageDeltaState = createUsageDeltaState({
@@ -1994,8 +2004,19 @@ async function parseRolloutFile({
1994
2004
  let currentProjectRef = projectRef || null;
1995
2005
  let currentProjectKey = projectKey || null;
1996
2006
  let eventsAggregated = 0;
2007
+ let scannedEndOffset = startOffset;
2008
+ let committedEndOffset = startOffset;
2009
+
2010
+ const invalidUtf8 = invalidRecordPolicy === "throw" ? "throw" : "record";
2011
+ for await (const record of physicalJsonlRecords(stream, { invalidUtf8 })) {
2012
+ scannedEndOffset += record.physicalBytes;
2013
+ if (record.terminated) committedEndOffset = scannedEndOffset;
2014
+ if (!record.utf8Valid) {
2015
+ if (!record.terminated) break;
2016
+ continue;
2017
+ }
1997
2018
 
1998
- for await (const line of rl) {
2019
+ const { line } = record;
1999
2020
  if (!line) continue;
2000
2021
  const maybeTokenCount = line.includes('"token_count"');
2001
2022
  const maybeTurnContext =
@@ -2005,14 +2026,28 @@ async function parseRolloutFile({
2005
2026
  line.includes('"cwd"') ||
2006
2027
  line.includes('"current_date"') ||
2007
2028
  line.includes('"forked_from_id"'));
2008
- if (!maybeTokenCount && !maybeTurnContext) continue;
2029
+ if (!maybeTokenCount && !maybeTurnContext) {
2030
+ if (invalidRecordPolicy === "throw" || !record.terminated) {
2031
+ try {
2032
+ JSON.parse(line);
2033
+ committedEndOffset = scannedEndOffset;
2034
+ } catch (error) {
2035
+ if (invalidRecordPolicy === "throw") throw error;
2036
+ break;
2037
+ }
2038
+ }
2039
+ continue;
2040
+ }
2009
2041
 
2010
2042
  let obj;
2011
2043
  try {
2012
2044
  obj = JSON.parse(line);
2013
- } catch (_e) {
2045
+ } catch (error) {
2046
+ if (invalidRecordPolicy === "throw") throw error;
2047
+ if (!record.terminated) break;
2014
2048
  continue;
2015
2049
  }
2050
+ if (!record.terminated) committedEndOffset = scannedEndOffset;
2016
2051
 
2017
2052
  if (
2018
2053
  (obj?.type === "turn_context" || obj?.type === "session_meta") &&
@@ -2156,7 +2191,7 @@ async function parseRolloutFile({
2156
2191
  }
2157
2192
 
2158
2193
  return {
2159
- endOffset,
2194
+ endOffset: committedEndOffset,
2160
2195
  lastTotal: latestTotal,
2161
2196
  tokenUsageBaselines: snapshotUsageBaselines(usageDeltaState),
2162
2197
  lastModel: model,
@@ -2176,6 +2211,7 @@ async function scanRolloutProjectFileContexts({
2176
2211
  publicRepoCache,
2177
2212
  publicRepoResolver,
2178
2213
  projectContext,
2214
+ invalidRecordPolicy,
2179
2215
  }) {
2180
2216
  const st = fileStat || (await fs.stat(filePath));
2181
2217
  const endOffset = st.size;
@@ -2192,11 +2228,21 @@ async function scanRolloutProjectFileContexts({
2192
2228
  };
2193
2229
  }
2194
2230
 
2195
- const stream = fssync.createReadStream(filePath, { encoding: "utf8", start: 0 });
2196
- const rl = readline.createInterface({ input: stream, crlfDelay: Infinity });
2231
+ const stream = fssync.createReadStream(filePath, { start: 0, end: endOffset - 1 });
2197
2232
  let currentCwd = null;
2233
+ let scannedEndOffset = 0;
2234
+ let committedEndOffset = 0;
2235
+
2236
+ const invalidUtf8 = invalidRecordPolicy === "throw" ? "throw" : "record";
2237
+ for await (const record of physicalJsonlRecords(stream, { invalidUtf8 })) {
2238
+ scannedEndOffset += record.physicalBytes;
2239
+ if (record.terminated) committedEndOffset = scannedEndOffset;
2240
+ if (!record.utf8Valid) {
2241
+ if (!record.terminated) break;
2242
+ continue;
2243
+ }
2198
2244
 
2199
- for await (const line of rl) {
2245
+ const { line } = record;
2200
2246
  if (
2201
2247
  !line ||
2202
2248
  !(
@@ -2205,15 +2251,27 @@ async function scanRolloutProjectFileContexts({
2205
2251
  ) ||
2206
2252
  !line.includes('"cwd"')
2207
2253
  ) {
2254
+ if (line && (invalidRecordPolicy === "throw" || !record.terminated)) {
2255
+ try {
2256
+ JSON.parse(line);
2257
+ committedEndOffset = scannedEndOffset;
2258
+ } catch (error) {
2259
+ if (invalidRecordPolicy === "throw") throw error;
2260
+ break;
2261
+ }
2262
+ }
2208
2263
  continue;
2209
2264
  }
2210
2265
 
2211
2266
  let obj;
2212
2267
  try {
2213
2268
  obj = JSON.parse(line);
2214
- } catch (_e) {
2269
+ } catch (error) {
2270
+ if (invalidRecordPolicy === "throw") throw error;
2271
+ if (!record.terminated) break;
2215
2272
  continue;
2216
2273
  }
2274
+ if (!record.terminated) committedEndOffset = scannedEndOffset;
2217
2275
  if (
2218
2276
  (obj?.type !== "turn_context" && obj?.type !== "session_meta") ||
2219
2277
  !obj?.payload ||
@@ -2237,7 +2295,7 @@ async function scanRolloutProjectFileContexts({
2237
2295
  }
2238
2296
 
2239
2297
  return {
2240
- endOffset,
2298
+ endOffset: committedEndOffset,
2241
2299
  lastTotal,
2242
2300
  tokenUsageBaselines,
2243
2301
  lastModel,
@@ -1 +0,0 @@
1
- import{r as n,A as a}from"./__vite-browser-external-CzDhMv0q.js";import{u as p}from"./DialogTitle-XCGSHZDz.js";import{u as c}from"./useScrollLock-BXUoxe5p.js";const x=n.forwardRef(function(e,r){const{render:l,className:u,style:m,id:s,...t}=e,{store:i}=p(),o=c(s);return i.useSyncedValueWithCleanup("descriptionElementId",o),a("p",e,{ref:r,props:[{id:o},t]})});export{x as D};
@@ -1 +0,0 @@
1
- import{m as C,r as u,j as t,e as N,c as a,a as ie,aq as oe,bd as re,aw as le,ax as ce,a7 as F,be as ue,bf as de,u as ge,d as L,Z as me,a1 as H,n as I,bg as he,bh as pe,O as $,bi as be,y as fe,bj as xe,bk as ye,bl as ve,bm as ke,bn as je,bo as Ne,bp as Se,L as Ce,R as we,bq as Le,br as Ae,a4 as _,h as Oe,bs as Ee}from"./__vite-browser-external-CzDhMv0q.js";import{b as Pe,g as Ie,L as G,m as V}from"./react-LsYzFOQW.js";import{u as _e,L as T}from"./use-limits-display-prefs-DPNlMKcg.js";import{P as Ge}from"./ProviderIcon-C_Fpc2jL.js";import{a as D,l as R}from"./limits-providers-B2Qjydn9.js";import{a as S,T as k,b as f,S as A,u as O}from"./use-native-settings-DFF0ouY5.js";import{P as Te,u as De,a as Re}from"./use-session-efficiency-pref-CrvLKyhz.js";import{C as Me}from"./check-Cypjnyke.js";import{C as Ue}from"./copy-BUe15mXV.js";import{A as Fe}from"./index-Cl8hqOBU.js";import{u as He}from"./useCurrency-BiFDQKMu.js";import{u as $e}from"./useTokenFormat-C6DBFS-R.js";import{S as B}from"./Select-CvY_Y0WS.js";import{I as Ve}from"./info-CCPDu6hQ.js";import{C as Be}from"./ConfirmModal-j8yHWm2k.js";import{A as qe}from"./arrow-up-right-DwqQgMsR.js";import{D as ze}from"./download-BhjaQuUD.js";import"./Card-B_gKsFZR.js";import"./ToolbarRootContext-BsM_3QBs.js";import"./useScrollLock-BXUoxe5p.js";import"./SelectItemText-DX4QYfBW.js";import"./DialogTitle-XCGSHZDz.js";import"./store-BMdm145i.js";import"./DialogDescription-BRiqm-uZ.js";const Ke=[["path",{d:"M14 2v6a2 2 0 0 0 .245.96l5.51 10.08A2 2 0 0 1 18 22H6a2 2 0 0 1-1.755-2.96l5.51-10.08A2 2 0 0 0 10 8V2",key:"18mbvz"}],["path",{d:"M6.453 15h11.094",key:"3shlmq"}],["path",{d:"M8.5 2h7",key:"csnxdl"}]],Ze=C("flask-conical",Ke);const We=[["circle",{cx:"9",cy:"12",r:"1",key:"1vctgf"}],["circle",{cx:"9",cy:"5",r:"1",key:"hp0tcf"}],["circle",{cx:"9",cy:"19",r:"1",key:"fkjjf6"}],["circle",{cx:"15",cy:"12",r:"1",key:"1tmaij"}],["circle",{cx:"15",cy:"5",r:"1",key:"19l28e"}],["circle",{cx:"15",cy:"19",r:"1",key:"f4zoj3"}]],Ye=C("grip-vertical",We);const Qe=[["path",{d:"m5 8 6 6",key:"1wu5hv"}],["path",{d:"m4 14 6-6 2-3",key:"1k1g8d"}],["path",{d:"M2 5h12",key:"or177f"}],["path",{d:"M7 2h1",key:"1t2jsx"}],["path",{d:"m22 22-5-10-5 10",key:"don7ne"}],["path",{d:"M14 18h6",key:"1m8k6r"}]],Je=C("languages",Qe);const Xe=[["path",{d:"m16 17 5-5-5-5",key:"1bji2h"}],["path",{d:"M21 12H9",key:"dn1m92"}],["path",{d:"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4",key:"1uf3rs"}]],et=C("log-out",Xe);const tt=[["path",{d:"M12 22a1 1 0 0 1 0-20 10 9 0 0 1 10 9 5 5 0 0 1-5 5h-2.25a1.75 1.75 0 0 0-1.4 2.8l.3.4a1.75 1.75 0 0 1-1.4 2.8z",key:"e79jfc"}],["circle",{cx:"13.5",cy:"6.5",r:".5",fill:"currentColor",key:"1okk4w"}],["circle",{cx:"17.5",cy:"10.5",r:".5",fill:"currentColor",key:"f64h9f"}],["circle",{cx:"6.5",cy:"12.5",r:".5",fill:"currentColor",key:"qy21gx"}],["circle",{cx:"8.5",cy:"7.5",r:".5",fill:"currentColor",key:"fotxhn"}]],nt=C("palette",tt);const at=[["circle",{cx:"12",cy:"8",r:"5",key:"1hypcn"}],["path",{d:"M20 21a8 8 0 0 0-16 0",key:"rfgkzh"}]],st=C("user-round",at),it=e=>!e.isLayoutDirty&&e.willUpdate(!1);function M(){const e=new Set,n=new WeakMap,s=()=>e.forEach(it);return{add:i=>{e.add(i),n.set(i,i.addEventListener("willUpdate",s))},remove:i=>{e.delete(i);const o=n.get(i);o&&(o(),n.delete(i)),s()},dirty:s}}const ot=u.createContext(null);function rt(){const e=u.useRef(!1);return Pe(()=>(e.current=!0,()=>{e.current=!1}),[]),e}function lt(){const e=rt(),[n,s]=u.useState(0),i=u.useCallback(()=>{e.current&&s(n+1)},[n]);return[u.useCallback(()=>Ie.postRender(i),[i]),n]}const q=e=>e===!0,ct=e=>q(e===!0)||e==="id",ut=({children:e,id:n,inherit:s=!0})=>{const i=u.useContext(G),o=u.useContext(ot),[r,l]=lt(),d=u.useRef(null),g=i.id||o;d.current===null&&(ct(s)&&g&&(n=n?g+"-"+n:g),d.current={id:n,group:q(s)&&i.group||M()});const p=u.useMemo(()=>({...d.current,forceRender:r}),[l]);return t.jsx(G.Provider,{value:p,children:e})},dt="shrink-0 text-oai-gray-900 dark:text-oai-gray-200";function gt({checked:e,onChange:n,ariaLabel:s}){return t.jsx("button",{type:"button",role:"switch","aria-checked":e,"aria-label":s,onClick:n,className:N("relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-oai-brand-500",e?"bg-oai-brand-500":"bg-oai-gray-300 dark:bg-oai-gray-700"),children:t.jsx("span",{className:N("inline-block h-3.5 w-3.5 rounded-full bg-white transition-transform",e?"translate-x-[18px]":"translate-x-[3px]")})})}function mt({prefs:e}){const{order:n,visibility:s,toggle:i,moveToward:o}=e,[r,l]=u.useState(null),[d,g]=u.useState(null),p=c=>h=>{l(c),h.dataTransfer.effectAllowed="move",h.dataTransfer.setData("text/plain",c)},m=c=>h=>{h.preventDefault(),h.dataTransfer.dropEffect="move",r&&r!==c&&d!==c&&(g(c),o(r,c))},x=()=>{l(null),g(null)},y=c=>{c.preventDefault(),l(null),g(null)};return t.jsx(ut,{children:t.jsx("div",{className:"flex flex-col",children:n.map(c=>{const h=s[c]!==!1,b=r===c;return t.jsxs(V.div,{layout:!0,transition:{duration:.28,ease:[.22,1,.36,1]},draggable:!0,onDragStart:p(c),onDragOver:m(c),onDragEnd:x,onDrop:y,className:N("flex items-center gap-3 py-2 rounded-md","hover:bg-oai-gray-100/60 dark:hover:bg-oai-gray-800/60",b&&"opacity-40"),style:{cursor:b?"grabbing":"grab"},children:[t.jsx(Ye,{className:"h-4 w-4 shrink-0 text-oai-gray-400 dark:text-oai-gray-500",strokeWidth:1.75,"aria-hidden":!0}),D(c)?t.jsx(Ge,{provider:D(c),size:18,className:N("pointer-events-none",dt)}):null,t.jsx("span",{className:"flex-1 text-sm text-oai-gray-900 dark:text-oai-gray-200 select-none",children:R(c)}),t.jsx("div",{onMouseDown:v=>v.stopPropagation(),draggable:!1,children:t.jsx(gt,{checked:h,onChange:()=>i(c),ariaLabel:`${a("limits.settings.toggle_visible")}: ${R(c)}`})})]},c)})})})}function ht(e){if(!e||typeof e!="object")return"";const n=e.user_metadata&&typeof e.user_metadata=="object"?e.user_metadata:{},s=e.profile&&typeof e.profile=="object"?e.profile:{},i=n.full_name||n.name||s.name||n.user_name||n.preferred_username;return typeof i=="string"&&i.trim()?i.trim():typeof e.email=="string"&&e.email.includes("@")?e.email.split("@")[0].trim()||e.email.trim():typeof e.email=="string"?e.email.trim():""}function pt(e){return!e||typeof e!="object"?"":typeof e.email=="string"?e.email.trim():""}function bt(e){const n=typeof e=="string"?e.trim():"";if(!n)return null;const s=n.match(/^@?([A-Za-z0-9][A-Za-z0-9-]{0,38})$/),i=n.match(/^https:\/\/github\.com\/([A-Za-z0-9][A-Za-z0-9-]{0,38})\/?$/i),o=s?.[1]||i?.[1];return o?`https://github.com/${o}`:null}function E(e,n){console.warn(`[tokentracker] settings ${e}:`,n)}function ft(e,n,s){const[i,o]=u.useState(()=>oe()),r=n&&s&&re(),l=u.useCallback(async()=>{const d=!i;if(le(d),o(d),!!d)try{await ce(()=>e())}catch(g){E("cloud sync",g)}},[i,e]);return{cloudSyncOn:i,handleCloudSyncToggle:l,showLocalCloudSync:r}}function xt(e){const[n,s]=u.useState(!1),[i,o]=u.useState(!1),[r,l]=u.useState(!1),[d,g]=u.useState(!1),[p,m]=u.useState(null),[x,y]=u.useState(!1),[c,h]=u.useState(""),[b,v]=u.useState(!1),[w,P]=u.useState(""),[W,Y]=u.useState(""),[Q,J]=u.useState(!1),[X,ee]=u.useState(null),te=u.useMemo(()=>ht(e),[e]),ne=u.useMemo(()=>pt(e),[e]),ae=u.useMemo(()=>typeof e?.id=="string"?e.id.trim():"",[e]),se=u.useMemo(()=>({setAnonymousOn:o,setCustomDisplayName:m,setGithubUrl:P,setProfileLoading:l,setPublicProfileOn:s,setShowGithubOn:v}),[]);return{anonymousOn:i,customDisplayName:p,displayName:te,editingGithub:Q,editingName:x,email:ne,githubError:X,githubInput:W,githubUrl:w,loadSetters:se,nameInput:c,profileLoading:r,profileSaving:d,publicProfileOn:n,setAnonymousOn:o,setCustomDisplayName:m,setEditingGithub:J,setEditingName:y,setGithubError:ee,setGithubInput:Y,setGithubUrl:P,setNameInput:h,setProfileLoading:l,setProfileSaving:g,setPublicProfileOn:s,setShowGithubOn:v,showGithubOn:b,userId:ae}}function yt(e,n,s){u.useEffect(()=>{if(!n)return;let i=!0;return s.setProfileLoading(!0),(async()=>{try{const o=await F({getAccessToken:e});if(!i||!o)return;const r=await ue({accessToken:o});if(!i)return;s.setPublicProfileOn(!!r?.enabled),s.setAnonymousOn(!!r?.anonymous),r?.display_name&&s.setCustomDisplayName(r.display_name),s.setShowGithubOn(!!r?.show_github_url),s.setGithubUrl(r?.github_url||"")}catch(o){E("load public profile",o)}finally{i&&s.setProfileLoading(!1)}})(),()=>{i=!1}},[e,n,s])}function vt(e,n){return u.useCallback(async(s,{label:i,onError:o,onSuccess:r}={})=>{if(n.profileSaving)return!1;n.setProfileSaving(!0);try{const l=await F({getAccessToken:e});if(!l)return!1;const d=await de({accessToken:l,...s});return r?.(d),!0}catch(l){return o?o(l):E(i||"mutate profile",l),!1}finally{n.setProfileSaving(!1)}},[e,n])}function kt(e,n){return{anonymousOn:e.anonymousOn,customDisplayName:e.customDisplayName,displayName:e.displayName,editingName:e.editingName,handleAnonymousToggle:n.handleAnonymousToggle,handleSaveName:n.handleSaveName,nameInput:e.nameInput,profileLoading:e.profileLoading,profileSaving:e.profileSaving,setEditingName:e.setEditingName,setNameInput:e.setNameInput,startEditingName:n.startEditingName}}function jt(e,n){return{editingGithub:e.editingGithub,githubError:e.githubError,githubInput:e.githubInput,githubUrl:e.githubUrl,handleSaveGithub:n.handleSaveGithub,handleShowGithubToggle:n.handleShowGithubToggle,profileLoading:e.profileLoading,profileSaving:e.profileSaving,setEditingGithub:e.setEditingGithub,setGithubError:e.setGithubError,setGithubInput:e.setGithubInput,showGithubOn:e.showGithubOn,startEditingGithub:n.startEditingGithub}}function Nt(e,n){const s=u.useCallback(async()=>{const o=!e.publicProfileOn;await n({enabled:o},{label:"toggle public profile",onSuccess:()=>e.setPublicProfileOn(o)})},[n,e]);return{handleAnonymousToggle:u.useCallback(async()=>{const o=!e.anonymousOn;await n({anonymous:o},{label:"toggle anonymous",onSuccess:()=>e.setAnonymousOn(o)})},[n,e]),handlePublicProfileToggle:s}}function St(e,n,s){const i=u.useCallback(async()=>{const r=e.nameInput.trim().slice(0,50);r&&await n({display_name:r},{label:"save display name",onSuccess:()=>{e.setCustomDisplayName(r),e.setEditingName(!1),s?.()}})},[n,e,s]),o=u.useCallback(()=>{e.setNameInput(e.customDisplayName||e.displayName),e.setEditingName(!0)},[e]);return{handleSaveName:i,startEditingName:o}}function Ct(e,n){const s=u.useCallback(async()=>{if(!e.showGithubOn&&!e.githubUrl){e.setEditingGithub(!0),e.setGithubInput(""),e.setGithubError(null);return}const r=!e.showGithubOn;await n({show_github_url:r},{label:"toggle GitHub profile",onSuccess:()=>e.setShowGithubOn(r)})},[n,e]),i=u.useCallback(async()=>{const r=bt(e.githubInput);if(e.githubInput.trim()&&!r){e.setGithubError(a("settings.account.githubUrlInvalid"));return}e.setGithubError(null),await n({github_url:r,show_github_url:!!r},{label:"save GitHub profile",onError:l=>e.setGithubError(l?.message||a("settings.account.githubUrlInvalid")),onSuccess:l=>{e.setGithubUrl(l?.github_url||r||""),e.setShowGithubOn(!!r),e.setEditingGithub(!1)}})},[n,e]),o=u.useCallback(()=>{e.setGithubInput(e.githubUrl),e.setGithubError(null),e.setEditingGithub(!0)},[e]);return{handleSaveGithub:i,handleShowGithubToggle:s,startEditingGithub:o}}function wt(){const e=ie(),n=xt(e.user),s=ft(e.getAccessToken,e.enabled,e.signedIn);yt(e.getAccessToken,e.signedIn,n.loadSetters);const i=vt(e.getAccessToken,n),o=Nt(n,i),r=St(n,i,e.refreshDisplayName),l=Ct(n,i);return{...e,...s,email:n.email,handlePublicProfileToggle:o.handlePublicProfileToggle,userId:n.userId,name:kt(n,{...o,...r}),github:jt(n,l),profileLoading:n.profileLoading,profileSaving:n.profileSaving,publicProfileOn:n.publicProfileOn}}function z({disabled:e,onCancel:n,onSave:s,saveLabel:i=a("settings.account.save")}){return t.jsxs(t.Fragment,{children:[t.jsx("button",{type:"button",onClick:s,disabled:e,className:"rounded-md bg-oai-brand-500 px-3 py-1.5 text-xs font-medium text-white transition-colors hover:bg-oai-brand-600 disabled:opacity-50",children:i}),t.jsx("button",{type:"button",onClick:n,className:"rounded-md px-2 py-1.5 text-xs text-oai-gray-500 transition-colors hover:text-oai-gray-700 dark:hover:text-oai-gray-300",children:a("settings.account.cancel")})]})}function Lt({nameInput:e,setEditingName:n,setNameInput:s,profileSaving:i,handleSaveName:o}){return t.jsxs("div",{className:"mt-2 flex items-center gap-2",children:[t.jsx("input",{type:"text",value:e,onChange:r=>s(r.target.value),onKeyDown:r=>{r.key==="Enter"&&o(),r.key==="Escape"&&n(!1)},maxLength:50,autoFocus:!0,className:"flex-1 rounded-md border border-oai-gray-300 bg-transparent px-2.5 py-1.5 text-sm text-oai-black outline-none focus:border-oai-brand-500 focus:ring-1 focus:ring-inset focus:ring-oai-brand-500 dark:border-oai-gray-700 dark:text-white",placeholder:a("settings.account.displayName")}),t.jsx(z,{disabled:i||!e.trim(),onCancel:()=>n(!1),onSave:o,saveLabel:i?a("settings.account.saving"):void 0})]})}function At({githubError:e,githubInput:n,handleSaveGithub:s,profileSaving:i,setEditingGithub:o,setGithubError:r,setGithubInput:l}){return t.jsxs("div",{className:"mt-2",children:[t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx("input",{type:"text",value:n,onChange:d=>{l(d.target.value),e&&r(null)},onKeyDown:d=>{d.key==="Enter"&&s(),d.key==="Escape"&&(o(!1),r(null))},maxLength:100,autoFocus:!0,className:"flex-1 rounded-md border border-oai-gray-300 bg-transparent px-2.5 py-1.5 text-sm text-oai-black outline-none focus:border-oai-brand-500 focus:ring-1 focus:ring-inset focus:ring-oai-brand-500 dark:border-oai-gray-700 dark:text-white",placeholder:a("settings.account.githubUrlPlaceholder")}),t.jsx(z,{disabled:i,onCancel:()=>{o(!1),r(null)},onSave:s,saveLabel:i?a("settings.account.saving"):void 0})]}),e?t.jsx("div",{className:"mt-1.5 text-xs text-red-600 dark:text-red-400",children:e}):null]})}function K({disabled:e=!1,label:n,onClick:s,title:i}){return t.jsxs("button",{type:"button",onClick:s,disabled:e,title:i,className:"inline-flex h-8 shrink-0 items-center gap-1.5 rounded-md border border-oai-gray-200 px-3 text-xs font-medium text-oai-gray-700 transition-colors hover:bg-oai-gray-100 disabled:cursor-not-allowed disabled:opacity-40 dark:border-oai-gray-800 dark:text-oai-gray-300 dark:hover:bg-oai-gray-800",children:[t.jsx(Te,{className:"h-3.5 w-3.5","aria-hidden":!0}),n]})}function Z({actions:e,editing:n,editor:s,hint:i,label:o}){return t.jsx("div",{className:"py-3",children:t.jsxs("div",{className:"flex items-start justify-between gap-4",children:[t.jsxs("div",{className:"min-w-0 flex-1",children:[t.jsx("div",{className:"text-sm text-oai-gray-900 dark:text-oai-gray-200",children:o}),n?s:t.jsx("div",{className:"mt-0.5 truncate text-xs text-oai-gray-500 dark:text-oai-gray-400",children:i})]}),n?null:e]})})}function Ot({name:e}){const n=e.anonymousOn?a("settings.account.displayNameDisabledWhileAnon"):void 0;return t.jsxs("div",{className:"flex shrink-0 items-center gap-2",children:[t.jsx(K,{disabled:e.anonymousOn,label:a("settings.account.edit"),onClick:e.startEditingName,title:n}),t.jsx(k,{checked:!e.anonymousOn,onChange:e.handleAnonymousToggle,disabled:e.profileLoading||e.profileSaving,ariaLabel:a("settings.account.displayName")})]})}function Et({name:e}){const{anonymousOn:n,customDisplayName:s,displayName:i,editingName:o,handleAnonymousToggle:r,handleSaveName:l,nameInput:d,profileLoading:g,profileSaving:p,setEditingName:m,setNameInput:x,startEditingName:y}=e,c=n?a("settings.account.displayNameAnonymousHint"):s||i;return t.jsx(Z,{label:a("settings.account.displayName"),editing:o,hint:c,editor:t.jsx(Lt,{nameInput:d,setEditingName:m,setNameInput:x,profileSaving:p,handleSaveName:l}),actions:t.jsx(Ot,{name:e})})}function Pt({github:e}){const{editingGithub:n,githubError:s,githubInput:i,githubUrl:o,handleSaveGithub:r,handleShowGithubToggle:l,profileLoading:d,profileSaving:g,setEditingGithub:p,setGithubError:m,setGithubInput:x,showGithubOn:y,startEditingGithub:c}=e;return t.jsx(t.Fragment,{children:t.jsx(Z,{label:a("settings.account.githubUrl"),editing:n,hint:o||a("settings.account.githubUrlHint"),editor:t.jsx(At,{githubError:s,githubInput:i,handleSaveGithub:r,profileSaving:g,setEditingGithub:p,setGithubError:m,setGithubInput:x}),actions:t.jsxs("div",{className:"flex shrink-0 items-center gap-2",children:[t.jsx(K,{label:a("settings.account.edit"),onClick:c}),t.jsx(k,{checked:y,onChange:l,disabled:d||g,ariaLabel:a("settings.account.githubUrl")})]})})})}function It(){const{openLoginModal:e}=ge();return t.jsx(S,{title:a("settings.section.account"),children:t.jsxs("div",{className:"flex items-center justify-between gap-4 py-3",children:[t.jsx("p",{className:"text-sm text-oai-gray-500 dark:text-oai-gray-400",children:a("settings.account.signedOutHint")}),t.jsx("button",{type:"button",onClick:e,className:"inline-flex h-8 shrink-0 items-center justify-center rounded-md bg-oai-gray-900 px-4 text-xs font-medium text-white transition-colors hover:bg-oai-gray-800 dark:bg-white dark:text-oai-gray-900 dark:hover:bg-oai-gray-100",children:a("settings.account.signIn")})]})})}function _t({name:e,github:n}){return t.jsxs(t.Fragment,{children:[t.jsx(Et,{name:e}),t.jsx(Pt,{github:n})]})}function Gt(){const e=wt();return e.enabled?e.signedIn?t.jsxs(S,{title:a("settings.section.account"),subtitle:e.email||e.name.customDisplayName||e.name.displayName,action:t.jsx(Dt,{onSignOut:e.signOut}),children:[t.jsx(Tt,{userId:e.userId}),t.jsx(Rt,{settings:e}),t.jsx(Mt,{checked:e.publicProfileOn,disabled:e.profileLoading||e.profileSaving,onChange:e.handlePublicProfileToggle}),t.jsx(Ut,{visible:e.publicProfileOn,name:e.name,github:e.github})]}):t.jsx(It,{}):null}function Tt({userId:e}){const[n,s]=L.useState(!1);if(!e)return null;const i=async()=>{try{if(typeof navigator>"u"||!navigator.clipboard?.writeText)return;await navigator.clipboard.writeText(e),s(!0),globalThis.setTimeout(()=>s(!1),1200)}catch{s(!1)}};return t.jsxs("div",{className:"flex items-center justify-between gap-4 py-3",children:[t.jsxs("div",{className:"min-w-0 flex-1",children:[t.jsx("div",{className:"text-sm text-oai-gray-900 dark:text-oai-gray-200",children:a("settings.account.userId")}),t.jsx("div",{className:"mt-0.5 truncate font-mono text-xs text-oai-gray-500 dark:text-oai-gray-400",children:e})]}),t.jsxs("button",{type:"button",onClick:i,className:"inline-flex h-8 shrink-0 items-center gap-1.5 rounded-md border border-oai-gray-200 px-3 text-xs font-medium text-oai-gray-700 transition-colors hover:bg-oai-gray-100 dark:border-oai-gray-800 dark:text-oai-gray-300 dark:hover:bg-oai-gray-800","aria-label":a("settings.account.copyUserId"),children:[n?t.jsx(Me,{className:"h-3.5 w-3.5","aria-hidden":!0}):t.jsx(Ue,{className:"h-3.5 w-3.5","aria-hidden":!0}),n?a("settings.account.copied"):a("settings.account.copy")]})]})}function Dt({onSignOut:e}){return t.jsxs("button",{type:"button",onClick:()=>e(),className:"inline-flex h-7 items-center gap-1.5 text-xs font-medium text-oai-gray-500 transition-colors hover:text-oai-gray-700 dark:hover:text-oai-gray-300",children:[t.jsx(et,{className:"h-3.5 w-3.5","aria-hidden":!0}),a("settings.account.signOut")]})}function Rt({settings:e}){return e.showLocalCloudSync?t.jsx(f,{label:a("settings.account.cloudSync"),hint:a("settings.account.cloudSyncHint"),control:t.jsx(k,{checked:e.cloudSyncOn,onChange:e.handleCloudSyncToggle,ariaLabel:a("settings.account.cloudSync")})}):null}function Mt({checked:e,disabled:n,onChange:s}){return t.jsx(f,{label:a("settings.account.publicProfile"),hint:a("settings.account.publicProfileHint"),control:t.jsx(k,{checked:e,onChange:s,disabled:n,ariaLabel:a("settings.account.publicProfile")})})}function Ut({visible:e,name:n,github:s}){return t.jsx(Fe,{initial:!1,children:e?t.jsx(V.div,{initial:{height:0,opacity:0},animate:{height:"auto",opacity:1},exit:{height:0,opacity:0},transition:{height:{duration:.28,ease:[.22,1,.36,1]},opacity:{duration:.2,ease:[.22,1,.36,1]}},style:{overflow:"hidden"},className:"divide-y divide-oai-gray-200/60 dark:divide-oai-gray-800/60",children:t.jsx(_t,{name:n,github:s})},"public-profile-fields"):null})}function Ft(){return[{value:"light",label:a("settings.appearance.theme.light"),Icon:he},{value:"dark",label:a("settings.appearance.theme.dark"),Icon:pe},{value:"system",label:a("settings.appearance.theme.system"),Icon:$}]}function Ht(){return[{value:xe,label:a("settings.appearance.language.system")},{value:ye,label:a("settings.appearance.language.english")},{value:ve,label:a("settings.appearance.language.chinese")},{value:ke,label:a("settings.appearance.language.traditional_chinese")},{value:je,label:a("settings.appearance.language.japanese")},{value:Ne,label:a("settings.appearance.language.korean")},{value:Se,label:a("settings.appearance.language.german")}]}function $t(e){if(!e)return null;try{const n=new Date(e);return Number.isNaN(n.getTime())?null:n.toLocaleString()}catch{return null}}function Vt(e,n){const s=a(`settings.appearance.currency.rate_source.${e}`),i=$t(n),o=i?a("settings.appearance.currency.rate_updated",{when:i}):a("settings.appearance.currency.rate_never");return`${s} · ${o}`}function Bt({locale:e,setLocale:n}){const s=Ht();return t.jsx(B,{value:e,onValueChange:n,options:s,ariaLabel:a("settings.appearance.language.label"),className:"px-2.5 py-1.5 text-xs font-medium",leadingIcon:t.jsx(Je,{className:"h-3.5 w-3.5 text-oai-gray-500 dark:text-oai-gray-400","aria-hidden":!0})})}function qt({currency:e,setCurrency:n}){const s=be().map(i=>({value:i.code,label:a(i.labelKey)}));return t.jsx(B,{value:e,onValueChange:n,options:s,ariaLabel:a("settings.appearance.currency.label"),className:"px-3 py-1.5 text-xs font-medium"})}function zt({currency:e,rate:n,rateSource:s,rateFetchedAt:i}){if(e===fe)return t.jsx(t.Fragment,{children:a("settings.appearance.currency.hint")});const o=Vt(s,i);return t.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[t.jsx("span",{children:`1 USD = ${n.toFixed(4)} ${e}`}),t.jsx("span",{role:"img","aria-label":o,title:o,className:"inline-flex h-4 w-4 cursor-help items-center justify-center text-oai-gray-400 hover:text-oai-gray-600 dark:text-oai-gray-500 dark:hover:text-oai-gray-300",children:t.jsx(Ve,{className:"h-3.5 w-3.5","aria-hidden":!0})})]})}function Kt(){const{theme:e,setTheme:n}=me(),{locale:s,setLocale:i}=H(),{currency:o,rate:r,rateSource:l,rateFetchedAt:d,setCurrency:g}=He(),{mode:p,setMode:m}=$e();return t.jsxs(S,{title:a("settings.section.appearance"),children:[t.jsx(f,{label:a("settings.appearance.theme.label"),hint:a("settings.appearance.theme.hint"),control:t.jsx(A,{options:Ft(),value:e,onChange:n})}),t.jsx(f,{label:a("settings.appearance.language.label"),hint:a("settings.appearance.language.hint"),control:t.jsx(Bt,{locale:s,setLocale:i})}),t.jsx(f,{label:a("settings.appearance.currency.label"),hint:t.jsx(zt,{currency:o,rate:r,rateSource:l,rateFetchedAt:d}),control:t.jsx(qt,{currency:o,setCurrency:g})}),t.jsx(f,{label:a("settings.appearance.token_format.label"),hint:a("settings.appearance.token_format.hint"),control:t.jsx(A,{options:[{value:I.COMPACT,label:a("settings.appearance.token_format.compact")},{value:I.FULL,label:a("settings.appearance.token_format.full")}],value:p,onChange:m})})]})}function U({labelKey:e}){return t.jsxs("div",{className:"flex items-center gap-1.5",children:[t.jsx("span",{children:a(e)}),t.jsx("span",{className:"px-1.5 py-0.5 text-[8px] font-semibold tracking-wider text-oai-gray-500 bg-oai-gray-100 dark:text-oai-gray-400 dark:bg-oai-gray-800/80 rounded uppercase scale-90 origin-left",children:a("qpd.card.badge")})]})}function Zt(){const{enabled:e,toggle:n}=De(),{enabled:s,toggle:i}=Re();return t.jsxs(S,{title:a("settings.section.labs"),children:[t.jsx(f,{label:t.jsx(U,{labelKey:"settings.labs.qpd.label"}),hint:a("settings.labs.qpd.hint"),control:t.jsx(k,{checked:e,onChange:n,ariaLabel:a("settings.labs.qpd.aria")})}),t.jsx(f,{label:t.jsx(U,{labelKey:"settings.labs.sessions.label"}),hint:a("settings.labs.sessions.hint"),control:t.jsx(k,{checked:s,onChange:i,ariaLabel:a("settings.labs.sessions.aria")})})]})}function Wt(){const{available:e,settings:n,setSetting:s,runAction:i}=O();if(!e)return null;const o=!!n?.launchAtLogin,r=n?.toastOnReset!==!1,l=n?.confettiOnReset!==!1,d=n?.launchAtLoginSupported!==!1,g=n?.updateStatus||null,p=!!n?.updateBusy,m=!!n?.isSyncing;return t.jsxs(S,{title:a("settings.section.menubar"),children:[t.jsx(f,{label:a("settings.menubar.appearance"),hint:a("settings.menubar.appearanceHint"),control:t.jsxs(Ce,{to:"/widgets",className:"inline-flex h-8 items-center gap-1.5 rounded-md border border-oai-gray-200 px-3 text-xs font-medium text-oai-gray-700 no-underline transition-colors hover:bg-oai-gray-100 dark:border-oai-gray-800 dark:text-oai-gray-300 dark:hover:bg-oai-gray-800",children:[a("settings.menubar.appearanceLink"),t.jsx(qe,{className:"h-3.5 w-3.5","aria-hidden":!0})]})}),t.jsx(f,{label:a("settings.menubar.toastOnReset"),hint:a("settings.menubar.toastOnResetHint"),control:t.jsx(k,{checked:r,onChange:()=>s("toastOnReset",!r),ariaLabel:a("settings.menubar.toastOnReset")})}),t.jsx(f,{label:a("settings.menubar.confettiOnReset"),hint:a("settings.menubar.confettiOnResetHint"),control:t.jsx(k,{checked:l,onChange:()=>s("confettiOnReset",!l),ariaLabel:a("settings.menubar.confettiOnReset")})}),d?t.jsx(f,{label:a("settings.menubar.launchAtLogin"),hint:a("settings.menubar.launchAtLoginHint"),control:t.jsx(k,{checked:o,onChange:()=>s("launchAtLogin",!o),ariaLabel:a("settings.menubar.launchAtLogin")})}):null,t.jsx(f,{label:a("settings.menubar.syncNow"),hint:a("settings.menubar.syncNowHint"),control:t.jsxs("button",{type:"button",onClick:()=>i("syncNow"),disabled:m,className:"inline-flex h-8 items-center gap-1.5 rounded-md border border-oai-gray-200 px-3 text-xs font-medium text-oai-gray-700 transition-colors hover:bg-oai-gray-100 disabled:cursor-not-allowed disabled:opacity-50 dark:border-oai-gray-800 dark:text-oai-gray-300 dark:hover:bg-oai-gray-800",children:[t.jsx(we,{className:N("h-3.5 w-3.5",m&&"animate-spin"),"aria-hidden":!0}),m?a("settings.menubar.syncing"):a("settings.menubar.syncNow")]})}),t.jsx(f,{label:a("settings.menubar.updates"),hint:g||void 0,control:t.jsxs("button",{type:"button",onClick:()=>i("checkForUpdates"),disabled:p,className:"inline-flex h-8 items-center gap-1.5 rounded-md border border-oai-gray-200 px-3 text-xs font-medium text-oai-gray-700 transition-colors hover:bg-oai-gray-100 disabled:cursor-not-allowed disabled:opacity-50 dark:border-oai-gray-800 dark:text-oai-gray-300 dark:hover:bg-oai-gray-800",children:[t.jsx(ze,{className:"h-3.5 w-3.5","aria-hidden":!0}),a("settings.menubar.checkUpdates")]})})]})}function Yt(e,n){function s(r){return r.replace(/^v/,"").split(".").map(Number)}const i=s(e),o=s(n);for(let r=0;r<Math.max(i.length,o.length);r++){const l=i[r]||0,d=o[r]||0;if(l<d)return!0;if(l>d)return!1}return!1}function Qt(){const{available:e,settings:n,runAction:s}=O(),i=e&&n?.version,[o,r]=L.useState(!1),[l,d]=L.useState({open:!1,latestVersion:"",htmlUrl:""}),{resolvedLocale:g}=H(),p="0.86.1",m=async()=>{r(!0);try{const b=await fetch("https://api.github.com/repos/mm7894215/TokenTracker/releases/latest");if(!b.ok)throw new Error("Failed to fetch");const v=await b.json(),w=v.tag_name;Yt(p,w)?d({open:!0,latestVersion:w,htmlUrl:v.html_url}):_({title:a("settings.menubar.updates.upToDate")})}catch(b){console.error("Check updates failed:",b),_({title:a("settings.menubar.updates.failed")})}finally{r(!1)}},x=a("settings.menubar.updates.modalTitle"),y=a("settings.menubar.updates.modalDescription",{version:l.latestVersion}),c=a("settings.menubar.updates.modalConfirm"),h=a("settings.menubar.updates.modalCancel");return t.jsxs("div",{className:"mt-6 flex flex-col items-center justify-center gap-4 text-xs text-oai-gray-500 dark:text-oai-gray-500",children:[t.jsxs("div",{className:"flex flex-wrap items-center justify-center gap-2",children:[i?t.jsxs(t.Fragment,{children:[t.jsx("span",{children:a("settings.menubar.updates.footerCombined",{barVersion:n.version,coreVersion:p})}),t.jsx("span",{"aria-hidden":!0,children:"·"}),t.jsx("button",{type:"button",onClick:()=>s("openAbout"),className:"underline-offset-2 transition-colors hover:text-oai-gray-700 hover:underline dark:hover:text-oai-gray-300",children:"GitHub"}),t.jsx("span",{"aria-hidden":!0,children:"·"})]}):t.jsxs(t.Fragment,{children:[t.jsx("span",{children:a("settings.menubar.updates.footerCore",{version:p})}),t.jsx("span",{"aria-hidden":!0,children:"·"}),t.jsx("button",{type:"button",onClick:m,disabled:o,className:"underline-offset-2 transition-colors hover:text-oai-gray-700 hover:underline dark:hover:text-oai-gray-300 disabled:opacity-50",children:o?a("settings.menubar.updates.checking"):a("settings.menubar.checkUpdates")}),t.jsx("span",{"aria-hidden":!0,children:"·"})]}),t.jsxs("a",{href:Le,target:"_blank",rel:"noopener noreferrer",className:"inline-flex items-center gap-1.5 underline-offset-2 transition-colors hover:text-oai-gray-700 hover:underline dark:hover:text-oai-gray-300",children:[t.jsx(Ae,{className:"h-3.5 w-3.5","aria-hidden":!0}),a("settings.footer.statusPage")]})]}),t.jsx(Be,{open:l.open,title:x,description:y,confirmLabel:c,cancelLabel:h,onConfirm:()=>{window.open(l.htmlUrl,"_blank"),d(b=>({...b,open:!1}))},onCancel:()=>d(b=>({...b,open:!1}))})]})}const j={APPEARANCE:"appearance",NATIVE_APP:"native-app",ACCOUNT:"account",LIMITS:"limits",LABS:"labs"};function Jt({prefs:e}){return t.jsx(A,{options:[{value:T.USED,label:a("limits.settings.display_mode_used")},{value:T.REMAINING,label:a("limits.settings.display_mode_remaining")}],value:e.displayMode,onChange:e.setDisplayMode})}function Sn(){const e=_e(),{available:n,settings:s,setSetting:i}=O(),o=s?.toastOnReset!==!1,r=s?.confettiOnReset!==!1,[l,d]=Oe(),g=l.get("section"),m=Object.values(j).includes(g)&&(g!==j.NATIVE_APP||n)?g:j.APPEARANCE,x=c=>{const h=new URLSearchParams(l);c===j.APPEARANCE?h.delete("section"):h.set("section",c),d(h,{replace:!0})},y=[{id:j.APPEARANCE,label:a("settings.section.appearance"),Icon:nt,content:t.jsx(Kt,{})},...n?[{id:j.NATIVE_APP,label:a("settings.section.menubar"),Icon:$,content:t.jsx(Wt,{})}]:[],{id:j.ACCOUNT,label:a("settings.section.account"),Icon:st,content:t.jsx(Gt,{})},{id:j.LIMITS,label:a("settings.section.limits"),Icon:Ee,content:t.jsxs("div",{className:"space-y-4",children:[t.jsxs(S,{title:a("settings.section.limits"),children:[t.jsx(f,{label:a("limits.settings.display_mode_label"),control:t.jsx(Jt,{prefs:e})}),t.jsx(f,{label:a("settings.menubar.toastOnReset"),hint:a("settings.menubar.toastOnResetHint"),control:t.jsx(k,{checked:o,disabled:!n,onChange:()=>i("toastOnReset",!o),ariaLabel:a("settings.menubar.toastOnReset")})}),t.jsx(f,{label:a("settings.menubar.confettiOnReset"),hint:a("settings.menubar.confettiOnResetHint"),control:t.jsx(k,{checked:r,disabled:!n,onChange:()=>i("confettiOnReset",!r),ariaLabel:a("settings.menubar.confettiOnReset")})})]}),t.jsx(S,{title:a("settings.limits.providers"),children:t.jsx(mt,{prefs:e})})]})},{id:j.LABS,label:a("settings.section.labs"),Icon:Ze,content:t.jsx(Zt,{})}];return t.jsx("div",{className:"flex flex-1 flex-col font-oai text-oai-black antialiased dark:text-oai-white",children:t.jsx("main",{className:"flex-1 pb-12 pt-8 sm:pb-16 sm:pt-10",children:t.jsxs("div",{className:"mx-auto w-full max-w-5xl px-4 sm:px-6",children:[t.jsx("div",{className:"mb-7",children:t.jsx("h1",{className:"text-3xl font-semibold tracking-tight text-oai-black dark:text-white sm:text-4xl",children:a("settings.page.title")})}),t.jsxs("div",{className:"grid min-w-0 gap-6 md:grid-cols-[12rem_minmax(0,1fr)] md:gap-8 lg:grid-cols-[13.5rem_minmax(0,1fr)]",children:[t.jsx("aside",{className:"min-w-0 border-b border-oai-gray-200 pb-3 dark:border-oai-gray-800 md:border-b-0 md:border-r md:pb-0 md:pr-5",children:t.jsx("nav",{"aria-label":a("settings.page.title"),className:"flex gap-0 overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden md:sticky md:top-6 md:flex-col md:gap-1 md:overflow-visible",children:y.map(({id:c,label:h,Icon:b})=>{const v=m===c;return t.jsxs("button",{id:`settings-nav-${c}`,type:"button","aria-current":v?"page":void 0,"aria-controls":`settings-panel-${c}`,onClick:()=>x(c),className:N("inline-flex min-h-10 min-w-max shrink-0 items-center gap-1.5 rounded-md px-2 py-2 text-left text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-oai-brand-500 md:w-full md:min-w-0 md:gap-2 md:px-3",v?"bg-oai-gray-100 text-oai-black dark:bg-oai-gray-800 dark:text-white":"text-oai-gray-500 hover:bg-oai-gray-50 hover:text-oai-gray-900 dark:text-oai-gray-400 dark:hover:bg-oai-gray-900 dark:hover:text-oai-gray-200"),children:[t.jsx(b,{className:N("h-4 w-4 shrink-0",v?"text-oai-black dark:text-white":"text-oai-gray-400 dark:text-oai-gray-500"),"aria-hidden":!0}),t.jsx("span",{className:"truncate",children:h})]},c)})})}),t.jsxs("div",{className:"min-w-0",children:[y.map(({id:c,label:h,content:b})=>t.jsx("section",{id:`settings-panel-${c}`,"aria-labelledby":`settings-nav-${c}`,"aria-label":h,"data-settings-panel":c,hidden:m!==c,children:b},c)),t.jsx(Qt,{})]})]})]})})})}export{Sn as SettingsPage};
@@ -1 +0,0 @@
1
- import{r as o}from"./__vite-browser-external-CzDhMv0q.js";import{h as r,i as t,p as s}from"./react-LsYzFOQW.js";function i(){!r.current&&t();const[e]=o.useState(s.current);return e}export{i as u};