@cassius0924/dsh-usage-dashboard 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js CHANGED
@@ -27,23 +27,76 @@ __export(index_exports, {
27
27
  });
28
28
  module.exports = __toCommonJS(index_exports);
29
29
 
30
+ // src/client/boundary.tsx
31
+ var import_react = require("react");
32
+ var import_jsx_runtime = require("react/jsx-runtime");
33
+ var PREFIX = "dsh-usage-dashboard:";
34
+ function clearPluginStorage() {
35
+ if (typeof localStorage === "undefined") return;
36
+ try {
37
+ for (const key of Object.keys(localStorage)) {
38
+ if (key.startsWith(PREFIX)) localStorage.removeItem(key);
39
+ }
40
+ } catch {
41
+ }
42
+ }
43
+ var ErrorBoundary = class extends import_react.Component {
44
+ state = { message: null };
45
+ static getDerivedStateFromError(error) {
46
+ return { message: error?.message ?? String(error) };
47
+ }
48
+ componentDidCatch(error, info) {
49
+ console.error("[dsh-usage-dashboard] render failed", error, info.componentStack);
50
+ }
51
+ reset = () => {
52
+ clearPluginStorage();
53
+ location.reload();
54
+ };
55
+ render() {
56
+ const { message } = this.state;
57
+ if (message === null) return this.props.children;
58
+ if (this.props.silent === true) return null;
59
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dq-balance", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dq-card", children: [
60
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dq-card-title", children: "\u989D\u5EA6\u9762\u677F\u51FA\u9519\u4E86" }),
61
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dq-empty", children: "\u6E32\u67D3\u65F6\u629B\u4E86\u5F02\u5E38\uFF0C\u901A\u5E38\u662F\u6D4F\u89C8\u5668\u91CC\u5B58\u7740\u65E7\u7248\u672C\u7684\u7F13\u5B58\u6570\u636E\u3002\u6E05\u6389\u672C\u63D2\u4EF6\u7684\u672C\u5730\u6570\u636E\u518D\u91CD\u65B0\u52A0\u8F7D\u5C31\u80FD\u6062\u590D\u3002" }),
62
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("pre", { className: "dq-crash", children: message }),
63
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "dq-refresh-btn", onClick: this.reset, children: "\u6E05\u9664\u672C\u5730\u6570\u636E\u5E76\u91CD\u65B0\u52A0\u8F7D" })
64
+ ] }) });
65
+ }
66
+ };
67
+
30
68
  // src/client/dashboard.tsx
31
- var import_react2 = require("react");
69
+ var import_react3 = require("react");
32
70
 
33
71
  // src/client/cache.ts
34
- var LS_VERSION = 1;
35
- function loadPersisted(storageKey) {
72
+ var LS_VERSION = 2;
73
+ function loadPersisted(storageKey, isUsable) {
36
74
  if (typeof localStorage === "undefined") return null;
75
+ const key = `${storageKey}:v${LS_VERSION}`;
37
76
  try {
38
- const raw = localStorage.getItem(`${storageKey}:v${LS_VERSION}`);
77
+ const raw = localStorage.getItem(key);
39
78
  if (raw === null) return null;
40
79
  const parsed = JSON.parse(raw);
41
80
  if (parsed.data === void 0 || typeof parsed.at !== "number") return null;
81
+ if (isUsable !== void 0 && !isUsable(parsed.data)) {
82
+ localStorage.removeItem(key);
83
+ return null;
84
+ }
42
85
  return { data: parsed.data, at: parsed.at };
43
86
  } catch {
44
87
  return null;
45
88
  }
46
89
  }
90
+ function pruneOldVersions(storageKey) {
91
+ if (typeof localStorage === "undefined") return;
92
+ try {
93
+ const current = `${storageKey}:v${LS_VERSION}`;
94
+ for (const key of Object.keys(localStorage)) {
95
+ if (key.startsWith(`${storageKey}:v`) && key !== current) localStorage.removeItem(key);
96
+ }
97
+ } catch {
98
+ }
99
+ }
47
100
  function persist(storageKey, hit) {
48
101
  if (typeof localStorage === "undefined") return;
49
102
  try {
@@ -51,8 +104,9 @@ function persist(storageKey, hit) {
51
104
  } catch {
52
105
  }
53
106
  }
54
- function createCache(ttlMs, storageKey) {
55
- let hit = storageKey === void 0 ? null : loadPersisted(storageKey);
107
+ function createCache(ttlMs, storageKey, isUsable) {
108
+ if (storageKey !== void 0) pruneOldVersions(storageKey);
109
+ let hit = storageKey === void 0 ? null : loadPersisted(storageKey, isUsable);
56
110
  return {
57
111
  get: () => hit,
58
112
  getFresh: () => hit !== null && Date.now() - hit.at < ttlMs ? hit.data : null,
@@ -73,8 +127,14 @@ async function getJson(path, cache) {
73
127
  }
74
128
  return res.json();
75
129
  }
76
- var balanceCache = createCache(BALANCE_TTL_MS, "dsh-usage-dashboard:balance");
77
- var usageCache = createCache(USAGE_TTL_MS, "dsh-usage-dashboard:usage");
130
+ var usageIsUsable = (res) => {
131
+ if (res.ok !== true) return false;
132
+ const data = res.data;
133
+ return data !== void 0 && Array.isArray(data.daily) && Array.isArray(data.hourly) && Array.isArray(data.heatmap) && Array.isArray(data.models) && Array.isArray(data.sessions) && typeof data.sessionCount === "number" && data.totals !== void 0 && typeof data.totals.cacheSavings === "number" && data.summary?.today !== void 0 && Array.isArray(data.pricing?.tiers) && data.peakSplit?.peak !== void 0;
134
+ };
135
+ var balanceIsUsable = (res) => res.ok === true && Array.isArray(res.data?.balances);
136
+ var balanceCache = createCache(BALANCE_TTL_MS, "dsh-usage-dashboard:balance", balanceIsUsable);
137
+ var usageCache = createCache(USAGE_TTL_MS, "dsh-usage-dashboard:usage", usageIsUsable);
78
138
  var getCachedBalance = () => balanceCache.get()?.data ?? null;
79
139
  var getCachedUsage = () => usageCache.get()?.data ?? null;
80
140
  var getCachedUsageAt = () => usageCache.get()?.at ?? null;
@@ -110,11 +170,11 @@ async function fetchUsage(force = false) {
110
170
  }
111
171
 
112
172
  // src/client/charts.tsx
113
- var import_react = require("react");
114
- var import_jsx_runtime = require("react/jsx-runtime");
173
+ var import_react2 = require("react");
174
+ var import_jsx_runtime2 = require("react/jsx-runtime");
115
175
  function useChartTip() {
116
- const wrapRef = (0, import_react.useRef)(null);
117
- const [tip, setTip] = (0, import_react.useState)(null);
176
+ const wrapRef = (0, import_react2.useRef)(null);
177
+ const [tip, setTip] = (0, import_react2.useState)(null);
118
178
  const show = (e, text) => {
119
179
  const wrap = wrapRef.current;
120
180
  if (text === void 0 || text === "" || wrap === null) return;
@@ -128,9 +188,9 @@ function ChartTip(props) {
128
188
  const { tip } = props;
129
189
  if (tip === null) return null;
130
190
  const [head, ...rows] = tip.lines;
131
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dq-tip", style: { left: `${tip.x}px`, top: `${tip.y}px` }, role: "tooltip", children: [
132
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dq-tip-head", children: head }),
133
- rows.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dq-tip-row", children: row }, i))
191
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-tip", style: { left: `${tip.x}px`, top: `${tip.y}px` }, role: "tooltip", children: [
192
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-tip-head", children: head }),
193
+ rows.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-tip-row", children: row }, i))
134
194
  ] });
135
195
  }
136
196
  var MODEL_COLORS = ["#4176e6", "#2da44e", "#e16f24", "#8250df", "#bf8700", "#cf222e", "#1f883d", "#0969da"];
@@ -140,25 +200,25 @@ function Bars(props) {
140
200
  let max = 0;
141
201
  for (const datum of data) if (datum.value > max) max = datum.value;
142
202
  const scale = max > 0 ? max : 1;
143
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dq-chart-wrap", ref: wrapRef, onPointerLeave: hide, children: [
144
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dq-bars", style: { height: `${height + 18}px` }, children: data.map((datum, i) => {
203
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-chart-wrap", ref: wrapRef, onPointerLeave: hide, children: [
204
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-bars", style: { height: `${height + 18}px` }, children: data.map((datum, i) => {
145
205
  const h = Math.max(1, Math.round(datum.value / scale * height));
146
206
  const text = datum.title ?? `${datum.label}: ${datum.value.toLocaleString()}`;
147
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
207
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
148
208
  "div",
149
209
  {
150
210
  className: "dq-bar-col",
151
211
  "aria-label": text,
152
212
  onPointerMove: (e) => show(e, text),
153
213
  children: [
154
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dq-bar", style: { height: `${h}px` } }),
155
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dq-bar-label", style: { visibility: i % labelEvery === 0 ? "visible" : "hidden" }, children: datum.label })
214
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-bar", style: { height: `${h}px` } }),
215
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-bar-label", style: { visibility: i % labelEvery === 0 ? "visible" : "hidden" }, children: datum.label })
156
216
  ]
157
217
  },
158
218
  i
159
219
  );
160
220
  }) }),
161
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChartTip, { tip })
221
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartTip, { tip })
162
222
  ] });
163
223
  }
164
224
  function GroupedBars(props) {
@@ -168,13 +228,13 @@ function GroupedBars(props) {
168
228
  let max = 0;
169
229
  for (const s of series) for (const datum of s.bars) if (datum.value > max) max = datum.value;
170
230
  const scale = max > 0 ? max : 1;
171
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dq-chart-wrap", ref: wrapRef, onPointerLeave: hide, children: [
172
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dq-bars", style: { height: `${height + 18}px` }, children: Array.from({ length: count }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dq-bar-col", children: [
173
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dq-bar-group", children: series.map((s) => {
231
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-chart-wrap", ref: wrapRef, onPointerLeave: hide, children: [
232
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-bars", style: { height: `${height + 18}px` }, children: Array.from({ length: count }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-bar-col", children: [
233
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-bar-group", children: series.map((s) => {
174
234
  const datum = s.bars[i];
175
235
  const h = Math.max(1, Math.round(datum.value / scale * height));
176
236
  const text = datum.title ?? `${s.key}: ${datum.value.toLocaleString()}`;
177
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
237
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
178
238
  "div",
179
239
  {
180
240
  className: "dq-bar",
@@ -185,9 +245,9 @@ function GroupedBars(props) {
185
245
  s.key
186
246
  );
187
247
  }) }),
188
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dq-bar-label", style: { visibility: i % labelEvery === 0 ? "visible" : "hidden" }, children: series[0].bars[i].label })
248
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-bar-label", style: { visibility: i % labelEvery === 0 ? "visible" : "hidden" }, children: series[0].bars[i].label })
189
249
  ] }, i)) }),
190
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChartTip, { tip })
250
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartTip, { tip })
191
251
  ] });
192
252
  }
193
253
  function heatColor(level) {
@@ -228,15 +288,15 @@ function Heatmap(props) {
228
288
  const r = max > 0 ? total / max : 0;
229
289
  return r < 0.25 ? 1 : r < 0.5 ? 2 : r < 0.75 ? 3 : 4;
230
290
  };
231
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dq-heat dq-chart-wrap", ref: wrapRef, onPointerLeave: hide, children: [
232
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dq-heat-grid", children: [
233
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dq-heat-dows", "aria-hidden": "true", children: DOW_LABELS.map((label, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dq-heat-dow", children: label }, i)) }),
234
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dq-heat-cols", children: [
235
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dq-heat-months", "aria-hidden": "true", children: monthLabels.map((label, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dq-heat-month", children: label }, i)) }),
236
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dq-heatmap", children: weeks.map((week, w) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dq-heat-week", children: week.map((datum, d) => {
237
- if (datum === null) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dq-heat-cell dq-heat-cell--pad" }, d);
291
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-heat dq-chart-wrap", ref: wrapRef, onPointerLeave: hide, children: [
292
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-heat-grid", children: [
293
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-heat-dows", "aria-hidden": "true", children: DOW_LABELS.map((label, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-heat-dow", children: label }, i)) }),
294
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-heat-cols", children: [
295
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-heat-months", "aria-hidden": "true", children: monthLabels.map((label, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-heat-month", children: label }, i)) }),
296
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-heatmap", children: weeks.map((week, w) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-heat-week", children: week.map((datum, d) => {
297
+ if (datum === null) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-heat-cell dq-heat-cell--pad" }, d);
238
298
  const text = `${datum.date} \xB7 ${datum.total.toLocaleString()} tokens \xB7 \xA5${datum.cost.toFixed(2)} \xB7 ${datum.calls} \u6B21\u8C03\u7528`;
239
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
299
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
240
300
  "div",
241
301
  {
242
302
  className: "dq-heat-cell",
@@ -249,11 +309,11 @@ function Heatmap(props) {
249
309
  }) }, w)) })
250
310
  ] })
251
311
  ] }),
252
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChartTip, { tip }),
253
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dq-heat-scale", children: [
254
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "\u5C11" }),
255
- [0, 1, 2, 3, 4].map((level) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dq-heat-key", style: { background: heatColor(level) } }, level)),
256
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "\u591A" })
312
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartTip, { tip }),
313
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-heat-scale", children: [
314
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "\u5C11" }),
315
+ [0, 1, 2, 3, 4].map((level) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dq-heat-key", style: { background: heatColor(level) } }, level)),
316
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "\u591A" })
257
317
  ] })
258
318
  ] });
259
319
  }
@@ -271,9 +331,9 @@ var fmtCompact = (v) => {
271
331
  };
272
332
 
273
333
  // src/client/prefs.ts
274
- var PREFIX = "dsh-usage-dashboard:pref:";
334
+ var PREFIX2 = "dsh-usage-dashboard:pref:";
275
335
  var VERSION = 1;
276
- var keyOf = (key) => `${PREFIX}${key}:v${VERSION}`;
336
+ var keyOf = (key) => `${PREFIX2}${key}:v${VERSION}`;
277
337
  function loadPref(key, isValid, fallback) {
278
338
  if (typeof localStorage === "undefined") return fallback;
279
339
  try {
@@ -318,61 +378,61 @@ var widgetVisibleStore = createStore("widget.visible", isBoolean, true);
318
378
  var lowBalanceStore = createStore("alert.lowBalance", isThreshold, 10);
319
379
 
320
380
  // src/client/dashboard.tsx
321
- var import_jsx_runtime2 = require("react/jsx-runtime");
381
+ var import_jsx_runtime3 = require("react/jsx-runtime");
322
382
  function Skel(props) {
323
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-skel", style: { width: `${props.w}px`, height: `${props.h}px` } });
383
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-skel", style: { width: `${props.w}px`, height: `${props.h}px` } });
324
384
  }
325
385
  function BalanceSkeleton() {
326
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-balance-grid", children: [
327
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-stat", children: [
328
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Skel, { w: 56, h: 11 }),
329
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Skel, { w: 150, h: 22 })
386
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-balance-grid", children: [
387
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-stat", children: [
388
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Skel, { w: 56, h: 11 }),
389
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Skel, { w: 150, h: 22 })
330
390
  ] }),
331
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-stat", children: [
332
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Skel, { w: 28, h: 11 }),
333
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Skel, { w: 48, h: 22 })
391
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-stat", children: [
392
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Skel, { w: 28, h: 11 }),
393
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Skel, { w: 48, h: 22 })
334
394
  ] })
335
395
  ] });
336
396
  }
337
397
  function UsageSkeleton() {
338
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
339
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-usage-totals", children: [44, 44, 62, 62].map((w, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-stat", children: [
340
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Skel, { w, h: 11 }),
341
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Skel, { w: w > 70 ? 84 : 56, h: 20 })
398
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
399
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-usage-totals", children: [44, 44, 62, 62].map((w, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-stat", children: [
400
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Skel, { w, h: 11 }),
401
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Skel, { w: w > 70 ? 84 : 56, h: 20 })
342
402
  ] }, i)) }),
343
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Skel, { w: 140, h: 12 }),
344
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-skel-bars", children: Array.from({ length: 30 }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-skel dq-skel-bar", style: { height: `${18 + i * 37 % 82}px` } }, i)) })
403
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Skel, { w: 140, h: 12 }),
404
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-skel-bars", children: Array.from({ length: 30 }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-skel dq-skel-bar", style: { height: `${18 + i * 37 % 82}px` } }, i)) })
345
405
  ] });
346
406
  }
347
407
  function Delta(props) {
348
408
  const { current, previous, label } = props;
349
409
  if (previous <= 0) {
350
410
  if (current <= 0) return null;
351
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dq-delta dq-delta--new", title: `${label}\u6CA1\u6709\u7528\u91CF\uFF0C\u65E0\u4ECE\u5BF9\u6BD4`, children: "\u65E0\u5BF9\u6BD4" });
411
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dq-delta dq-delta--new", title: `${label}\u6CA1\u6709\u7528\u91CF\uFF0C\u65E0\u4ECE\u5BF9\u6BD4`, children: "\u65E0\u5BF9\u6BD4" });
352
412
  }
353
413
  const percent = Math.round((current - previous) / previous * 100);
354
414
  const title = `${label} \xA5${fmt(previous)}`;
355
- if (percent === 0) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dq-delta dq-delta--flat", title, children: "\u6301\u5E73" });
415
+ if (percent === 0) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dq-delta dq-delta--flat", title, children: "\u6301\u5E73" });
356
416
  const up = percent > 0;
357
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: `dq-delta ${up ? "dq-delta--up" : "dq-delta--down"}`, title, children: [
417
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: `dq-delta ${up ? "dq-delta--up" : "dq-delta--down"}`, title, children: [
358
418
  up ? "\u2191" : "\u2193",
359
419
  Math.abs(percent),
360
420
  "% ",
361
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dq-delta-label", children: label })
421
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dq-delta-label", children: label })
362
422
  ] });
363
423
  }
364
424
  function Period(props) {
365
425
  const { period, previous, compare } = props;
366
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-period", children: [
367
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-period-head", children: [
368
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dq-period-label", children: props.label }),
369
- previous !== void 0 && compare !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Delta, { current: period.cost, previous: previous.cost, label: compare })
426
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-period", children: [
427
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-period-head", children: [
428
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dq-period-label", children: props.label }),
429
+ previous !== void 0 && compare !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Delta, { current: period.cost, previous: previous.cost, label: compare })
370
430
  ] }),
371
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-period-cost", children: [
431
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-period-cost", children: [
372
432
  "\xA5 ",
373
433
  fmt(period.cost)
374
434
  ] }),
375
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-period-sub", children: [
435
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-period-sub", children: [
376
436
  fmtCompact(period.total),
377
437
  " tokens \xB7 ",
378
438
  fmtInt(period.calls),
@@ -384,40 +444,40 @@ var rate = (value) => `\xA5${value.toLocaleString(void 0, { maximumFractionDigit
384
444
  function PricingNote(props) {
385
445
  const { pricing } = props;
386
446
  const split = pricing.splitActive;
387
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("details", { className: "dq-pricing", children: [
388
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("summary", { className: "dq-pricing-summary", children: [
447
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("details", { className: "dq-pricing", children: [
448
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("summary", { className: "dq-pricing-summary", children: [
389
449
  "\u8BA1\u4EF7\u8BF4\u660E",
390
- split && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: `dq-pricing-now${pricing.inPeakNow ? " dq-pricing-now--peak" : ""}`, children: [
450
+ split && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: `dq-pricing-now${pricing.inPeakNow ? " dq-pricing-now--peak" : ""}`, children: [
391
451
  "\u5F53\u524D ",
392
452
  pricing.inPeakNow ? "\u9AD8\u5CF0\u65F6\u6BB5" : "\u95F2\u65F6"
393
453
  ] })
394
454
  ] }),
395
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-pricing-body", children: [
396
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("table", { className: "dq-pricing-table", children: [
397
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("tr", { children: [
398
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("th", { children: "\u6A21\u578B" }),
399
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("th", { children: split ? "\u65F6\u6BB5" : "\u5355\u4EF7" }),
400
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("th", { children: "\u8F93\u5165\xB7\u7F13\u5B58\u547D\u4E2D" }),
401
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("th", { children: "\u8F93\u5165\xB7\u672A\u547D\u4E2D" }),
402
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("th", { children: "\u8F93\u51FA" })
455
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-pricing-body", children: [
456
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("table", { className: "dq-pricing-table", children: [
457
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("tr", { children: [
458
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("th", { children: "\u6A21\u578B" }),
459
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("th", { children: split ? "\u65F6\u6BB5" : "\u5355\u4EF7" }),
460
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("th", { children: "\u8F93\u5165\xB7\u7F13\u5B58\u547D\u4E2D" }),
461
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("th", { children: "\u8F93\u5165\xB7\u672A\u547D\u4E2D" }),
462
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("th", { children: "\u8F93\u51FA" })
403
463
  ] }) }),
404
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("tbody", { children: pricing.tiers.map((tier) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react2.Fragment, { children: [
405
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("tr", { children: [
406
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { rowSpan: tier.offPeak !== null ? 2 : 1, children: tier.model }),
407
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { children: split ? "\u9AD8\u5CF0" : "\u56FA\u5B9A" }),
408
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { children: rate(tier.peak.cacheHit) }),
409
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { children: rate(tier.peak.input) }),
410
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { children: rate(tier.peak.output) })
464
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("tbody", { children: pricing.tiers.map((tier) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react3.Fragment, { children: [
465
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("tr", { children: [
466
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("td", { rowSpan: tier.offPeak !== null ? 2 : 1, children: tier.model }),
467
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("td", { children: split ? "\u9AD8\u5CF0" : "\u56FA\u5B9A" }),
468
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("td", { children: rate(tier.peak.cacheHit) }),
469
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("td", { children: rate(tier.peak.input) }),
470
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("td", { children: rate(tier.peak.output) })
411
471
  ] }),
412
- tier.offPeak !== null && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("tr", { children: [
413
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { children: "\u95F2\u65F6" }),
414
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { children: rate(tier.offPeak.cacheHit) }),
415
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { children: rate(tier.offPeak.input) }),
416
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { children: rate(tier.offPeak.output) })
472
+ tier.offPeak !== null && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("tr", { children: [
473
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("td", { children: "\u95F2\u65F6" }),
474
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("td", { children: rate(tier.offPeak.cacheHit) }),
475
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("td", { children: rate(tier.offPeak.input) }),
476
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("td", { children: rate(tier.offPeak.output) })
417
477
  ] })
418
478
  ] }, tier.model)) })
419
479
  ] }),
420
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "dq-pricing-foot", children: [
480
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "dq-pricing-foot", children: [
421
481
  "\u5355\u4F4D\uFF1A",
422
482
  pricing.currency,
423
483
  " / \u767E\u4E07 tokens\u3002",
@@ -428,85 +488,85 @@ function PricingNote(props) {
428
488
  ] });
429
489
  }
430
490
  function Stat(props) {
431
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-stat", children: [
432
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-stat-label", children: props.label }),
491
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-stat", children: [
492
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-stat-label", children: props.label }),
433
493
  props.children
434
494
  ] });
435
495
  }
436
496
  function Link(props) {
437
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("a", { className: "dq-link", href: props.href, target: "_blank", rel: "noreferrer", children: props.children });
497
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("a", { className: "dq-link", href: props.href, target: "_blank", rel: "noreferrer", children: props.children });
438
498
  }
439
499
  var modelKeyOf = (m) => m.provider !== "" ? `${m.provider}/${m.model}` : m.model;
440
500
  var modelNameOf = (m) => m.model !== "" ? m.model : "\u672A\u77E5\u6A21\u578B";
441
501
  function CacheCard(props) {
442
502
  const { totals } = props;
443
503
  const prompt = totals.input + totals.cache;
444
- if (prompt === 0) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-empty", children: "\u8FD8\u6CA1\u6709 prompt token \u53EF\u7EDF\u8BA1\u7F13\u5B58\u547D\u4E2D\u3002" });
504
+ if (prompt === 0) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-empty", children: "\u8FD8\u6CA1\u6709 prompt token \u53EF\u7EDF\u8BA1\u7F13\u5B58\u547D\u4E2D\u3002" });
445
505
  const rate2 = totals.cache / prompt;
446
506
  const wouldHaveCost = totals.cost + totals.cacheSavings;
447
507
  const low = rate2 < 0.6;
448
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-cache", children: [
449
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-cache-figures", children: [
450
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-stat", children: [
451
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-stat-label", children: "\u7F13\u5B58\u547D\u4E2D\u7387" }),
452
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `dq-stat-value${low ? " dq-stat-value--warn" : " dq-stat-value--ok"}`, children: [
508
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-cache", children: [
509
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-cache-figures", children: [
510
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-stat", children: [
511
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-stat-label", children: "\u7F13\u5B58\u547D\u4E2D\u7387" }),
512
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: `dq-stat-value${low ? " dq-stat-value--warn" : " dq-stat-value--ok"}`, children: [
453
513
  (rate2 * 100).toFixed(1),
454
514
  "%"
455
515
  ] })
456
516
  ] }),
457
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-stat", children: [
458
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-stat-label", children: "\u5DF2\u8282\u7701\u8D39\u7528\uFF08\u4F30\u7B97\uFF09" }),
459
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-stat-value", children: [
517
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-stat", children: [
518
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-stat-label", children: "\u5DF2\u8282\u7701\u8D39\u7528\uFF08\u4F30\u7B97\uFF09" }),
519
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-stat-value", children: [
460
520
  "\xA5 ",
461
521
  fmt(totals.cacheSavings)
462
522
  ] })
463
523
  ] }),
464
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-stat", children: [
465
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-stat-label", children: "\u82E5\u5168\u90E8\u672A\u547D\u4E2D" }),
466
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-stat-value dq-muted-value", children: [
524
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-stat", children: [
525
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-stat-label", children: "\u82E5\u5168\u90E8\u672A\u547D\u4E2D" }),
526
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-stat-value dq-muted-value", children: [
467
527
  "\xA5 ",
468
528
  fmt(wouldHaveCost)
469
529
  ] })
470
530
  ] })
471
531
  ] }),
472
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-cache-track", role: "img", "aria-label": `\u7F13\u5B58\u547D\u4E2D ${(rate2 * 100).toFixed(1)}%\uFF0C\u672A\u547D\u4E2D ${((1 - rate2) * 100).toFixed(1)}%`, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-cache-fill", style: { width: `${rate2 * 100}%` } }) }),
473
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-cache-legend", children: [
474
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { children: [
475
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dq-legend-swatch dq-legend-swatch--hit" }),
532
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-cache-track", role: "img", "aria-label": `\u7F13\u5B58\u547D\u4E2D ${(rate2 * 100).toFixed(1)}%\uFF0C\u672A\u547D\u4E2D ${((1 - rate2) * 100).toFixed(1)}%`, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-cache-fill", style: { width: `${rate2 * 100}%` } }) }),
533
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-cache-legend", children: [
534
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { children: [
535
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dq-legend-swatch dq-legend-swatch--hit" }),
476
536
  "\u7F13\u5B58\u547D\u4E2D ",
477
537
  fmtCompact(totals.cache)
478
538
  ] }),
479
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { children: [
480
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dq-legend-swatch dq-legend-swatch--miss" }),
539
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { children: [
540
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dq-legend-swatch dq-legend-swatch--miss" }),
481
541
  "\u672A\u547D\u4E2D ",
482
542
  fmtCompact(totals.input),
483
543
  "\uFF08\u6309\u672A\u547D\u4E2D\u4EF7\u8BA1\u8D39\uFF09"
484
544
  ] })
485
545
  ] }),
486
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dq-cache-foot", children: low ? "\u547D\u4E2D\u7387\u504F\u4F4E\uFF1A\u9891\u7E41\u6539\u52A8 system prompt / \u5DE5\u5177\u5B9A\u4E49\u4F1A\u8BA9\u524D\u7F00\u7F13\u5B58\u5931\u6548\uFF0C\u628A\u7A33\u5B9A\u5185\u5BB9\u653E\u5728\u5BF9\u8BDD\u6700\u524D\u9762\u80FD\u63D0\u9AD8\u547D\u4E2D\u7387\u3002" : "\u524D\u7F00\u7F13\u5B58\u628A\u91CD\u590D\u7684 prompt \u524D\u7F00\u6309\u547D\u4E2D\u4EF7\u8BA1\u8D39\uFF0C\u662F\u8FD9\u4EFD\u8D26\u5355\u4E0A\u6700\u5927\u7684\u7701\u94B1\u6760\u6746\u3002" })
546
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "dq-cache-foot", children: low ? "\u547D\u4E2D\u7387\u504F\u4F4E\uFF1A\u9891\u7E41\u6539\u52A8 system prompt / \u5DE5\u5177\u5B9A\u4E49\u4F1A\u8BA9\u524D\u7F00\u7F13\u5B58\u5931\u6548\uFF0C\u628A\u7A33\u5B9A\u5185\u5BB9\u653E\u5728\u5BF9\u8BDD\u6700\u524D\u9762\u80FD\u63D0\u9AD8\u547D\u4E2D\u7387\u3002" : "\u524D\u7F00\u7F13\u5B58\u628A\u91CD\u590D\u7684 prompt \u524D\u7F00\u6309\u547D\u4E2D\u4EF7\u8BA1\u8D39\uFF0C\u662F\u8FD9\u4EFD\u8D26\u5355\u4E0A\u6700\u5927\u7684\u7701\u94B1\u6760\u6746\u3002" })
487
547
  ] });
488
548
  }
489
549
  function PeakCard(props) {
490
550
  const { split, pricing, currentCost } = props;
491
551
  const total = split.peak.total + split.offPeak.total;
492
- if (total === 0) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-empty", children: "\u8FD8\u6CA1\u6709\u53EF\u6309\u65F6\u6BB5\u5F52\u7C7B\u7684\u7528\u91CF\u3002" });
552
+ if (total === 0) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-empty", children: "\u8FD8\u6CA1\u6709\u53EF\u6309\u65F6\u6BB5\u5F52\u7C7B\u7684\u7528\u91CF\u3002" });
493
553
  const peakShare = split.peak.total / total;
494
554
  const shiftSaving = split.peakEraCost - split.offPeakEraCost;
495
555
  const increase = split.peakEraCost - currentCost;
496
556
  const increasePercent = currentCost > 0 ? increase / currentCost * 100 : 0;
497
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-peak", children: [
498
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
557
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-peak", children: [
558
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
499
559
  "div",
500
560
  {
501
561
  className: "dq-peak-track",
502
562
  role: "img",
503
563
  "aria-label": `\u9AD8\u5CF0\u65F6\u6BB5 ${(peakShare * 100).toFixed(1)}%\uFF0C\u95F2\u65F6 ${((1 - peakShare) * 100).toFixed(1)}%`,
504
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-peak-fill", style: { width: `${peakShare * 100}%` } })
564
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-peak-fill", style: { width: `${peakShare * 100}%` } })
505
565
  }
506
566
  ),
507
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-peak-legend", children: [
508
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { children: [
509
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dq-legend-swatch dq-legend-swatch--peak" }),
567
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-peak-legend", children: [
568
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { children: [
569
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dq-legend-swatch dq-legend-swatch--peak" }),
510
570
  "\u9AD8\u5CF0 ",
511
571
  (peakShare * 100).toFixed(1),
512
572
  "% \xB7 ",
@@ -515,8 +575,8 @@ function PeakCard(props) {
515
575
  fmtInt(split.peak.calls),
516
576
  " \u6B21"
517
577
  ] }),
518
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { children: [
519
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dq-legend-swatch dq-legend-swatch--offpeak" }),
578
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { children: [
579
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dq-legend-swatch dq-legend-swatch--offpeak" }),
520
580
  "\u95F2\u65F6 ",
521
581
  ((1 - peakShare) * 100).toFixed(1),
522
582
  "% \xB7 ",
@@ -526,32 +586,32 @@ function PeakCard(props) {
526
586
  " \u6B21"
527
587
  ] })
528
588
  ] }),
529
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-peak-figures", children: [
530
- !pricing.splitActive && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-stat", children: [
531
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-stat-label", children: "\u540C\u6837\u7528\u91CF\u5728\u65B0\u4EF7\u4E0B" }),
532
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-stat-value", children: [
589
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-peak-figures", children: [
590
+ !pricing.splitActive && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-stat", children: [
591
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-stat-label", children: "\u540C\u6837\u7528\u91CF\u5728\u65B0\u4EF7\u4E0B" }),
592
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-stat-value", children: [
533
593
  "\xA5 ",
534
594
  fmt(split.peakEraCost),
535
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dq-peak-delta", children: [
595
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "dq-peak-delta", children: [
536
596
  "\u8F83\u73B0\u4EF7 +",
537
597
  increasePercent.toFixed(0),
538
598
  "%"
539
599
  ] })
540
600
  ] })
541
601
  ] }),
542
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-stat", children: [
543
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-stat-label", children: "\u82E5\u9AD8\u5CF0\u7528\u91CF\u90FD\u632A\u5230\u95F2\u65F6" }),
544
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-stat-value", children: [
602
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-stat", children: [
603
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-stat-label", children: "\u82E5\u9AD8\u5CF0\u7528\u91CF\u90FD\u632A\u5230\u95F2\u65F6" }),
604
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-stat-value", children: [
545
605
  "\xA5 ",
546
606
  fmt(split.offPeakEraCost),
547
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dq-peak-delta dq-peak-delta--save", children: [
607
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "dq-peak-delta dq-peak-delta--save", children: [
548
608
  "\u53EF\u7701 \xA5",
549
609
  fmt(shiftSaving)
550
610
  ] })
551
611
  ] })
552
612
  ] })
553
613
  ] }),
554
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "dq-peak-foot", children: [
614
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "dq-peak-foot", children: [
555
615
  "\u9AD8\u5CF0\u65F6\u6BB5\u4E3A\u5317\u4EAC\u65F6\u95F4 ",
556
616
  pricing.peakWindows.join("\u3001"),
557
617
  "\uFF0C\u95F2\u65F6\u4EF7\u683C\u51CF\u534A\u3002",
@@ -569,33 +629,33 @@ function agoText(ms) {
569
629
  }
570
630
  function SessionRanking(props) {
571
631
  const { sessions, count, totalCost } = props;
572
- if (sessions.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-empty", children: "\u8FD8\u6CA1\u6709\u4EA7\u751F\u8D39\u7528\u7684\u4F1A\u8BDD\u3002" });
632
+ if (sessions.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-empty", children: "\u8FD8\u6CA1\u6709\u4EA7\u751F\u8D39\u7528\u7684\u4F1A\u8BDD\u3002" });
573
633
  const top = sessions[0].cost;
574
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
575
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("ol", { className: "dq-sessions", children: sessions.map((s) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("li", { className: "dq-session", children: [
576
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-session-head", children: [
577
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dq-session-title", title: `${s.title}
634
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
635
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ol", { className: "dq-sessions", children: sessions.map((s) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "dq-session", children: [
636
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-session-head", children: [
637
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dq-session-title", title: `${s.title}
578
638
  ${s.id}`, children: s.title }),
579
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dq-session-cost", children: [
639
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "dq-session-cost", children: [
580
640
  "\xA5 ",
581
641
  fmt(s.cost)
582
642
  ] })
583
643
  ] }),
584
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-session-track", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-session-fill", style: { width: `${Math.max(s.cost / (top || 1) * 100, 1.5)}%` } }) }),
585
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-session-sub", children: [
644
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-session-track", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-session-fill", style: { width: `${Math.max(s.cost / (top || 1) * 100, 1.5)}%` } }) }),
645
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-session-sub", children: [
586
646
  fmtCompact(s.total),
587
647
  " tokens \xB7 ",
588
648
  fmtInt(s.calls),
589
649
  " \u6B21\u8C03\u7528 \xB7 ",
590
650
  agoText(s.lastActive),
591
- totalCost > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
651
+ totalCost > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
592
652
  " \xB7 \u5360 ",
593
653
  (s.cost / totalCost * 100).toFixed(1),
594
654
  "%"
595
655
  ] })
596
656
  ] })
597
657
  ] }, s.id)) }),
598
- count > sessions.length && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "dq-session-foot", children: [
658
+ count > sessions.length && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "dq-session-foot", children: [
599
659
  "\u5171 ",
600
660
  fmtInt(count),
601
661
  " \u4E2A\u4F1A\u8BDD\u6709\u7528\u91CF\uFF0C\u4E0A\u9762\u662F\u6700\u8D35\u7684 ",
@@ -606,35 +666,35 @@ ${s.id}`, children: s.title }),
606
666
  }
607
667
  function ModelRanking(props) {
608
668
  const { models, totalCost } = props;
609
- if (models.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-empty", children: "\u8FD8\u6CA1\u6709\u53EF\u5F52\u7C7B\u7684\u6A21\u578B\u7528\u91CF\u3002" });
610
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-rank", children: models.map((m) => {
669
+ if (models.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-empty", children: "\u8FD8\u6CA1\u6709\u53EF\u5F52\u7C7B\u7684\u6A21\u578B\u7528\u91CF\u3002" });
670
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-rank", children: models.map((m) => {
611
671
  const key = modelKeyOf(m);
612
672
  const share = totalCost > 0 ? m.cost / totalCost : 0;
613
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-rank-row", children: [
614
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-rank-head", children: [
615
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dq-rank-name", title: key, children: [
616
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dq-legend-swatch", style: { background: props.colorOf(key) } }),
673
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-rank-row", children: [
674
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-rank-head", children: [
675
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "dq-rank-name", title: key, children: [
676
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dq-legend-swatch", style: { background: props.colorOf(key) } }),
617
677
  modelNameOf(m)
618
678
  ] }),
619
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dq-rank-cost", children: [
679
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "dq-rank-cost", children: [
620
680
  "\xA5 ",
621
681
  fmt(m.cost),
622
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dq-rank-share", children: [
682
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "dq-rank-share", children: [
623
683
  (share * 100).toFixed(1),
624
684
  "%"
625
685
  ] })
626
686
  ] })
627
687
  ] }),
628
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
688
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
629
689
  "div",
630
690
  {
631
691
  className: "dq-rank-track",
632
692
  role: "img",
633
693
  "aria-label": `${modelNameOf(m)} \u5360\u603B\u8D39\u7528 ${(share * 100).toFixed(1)}%`,
634
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-rank-fill", style: { width: `${Math.max(share * 100, 1.5)}%`, background: props.colorOf(key) } })
694
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-rank-fill", style: { width: `${Math.max(share * 100, 1.5)}%`, background: props.colorOf(key) } })
635
695
  }
636
696
  ),
637
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-rank-sub", children: [
697
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-rank-sub", children: [
638
698
  fmtCompact(m.total),
639
699
  " tokens \xB7 ",
640
700
  fmtInt(m.calls),
@@ -651,9 +711,9 @@ function ModelRanking(props) {
651
711
  function ModelPicker(props) {
652
712
  const { models } = props;
653
713
  if (models.length === 0) return null;
654
- const [open, setOpen] = (0, import_react2.useState)(false);
655
- const rootRef = (0, import_react2.useRef)(null);
656
- (0, import_react2.useEffect)(() => {
714
+ const [open, setOpen] = (0, import_react3.useState)(false);
715
+ const rootRef = (0, import_react3.useRef)(null);
716
+ (0, import_react3.useEffect)(() => {
657
717
  if (!open) return;
658
718
  const onDown = (e) => {
659
719
  if (rootRef.current !== null && !rootRef.current.contains(e.target)) setOpen(false);
@@ -667,11 +727,11 @@ function ModelPicker(props) {
667
727
  );
668
728
  };
669
729
  const label = props.selected.length === 0 ? "\u5168\u90E8\u6A21\u578B" : `\u6A21\u578B \xD7${props.selected.length}`;
670
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-model-picker", ref: rootRef, children: [
671
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dq-model-btn", onClick: () => setOpen(!open), children: label }),
672
- open && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-model-menu", children: [
673
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("label", { className: "dq-model-item dq-model-item--all", children: [
674
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
730
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-model-picker", ref: rootRef, children: [
731
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "dq-model-btn", onClick: () => setOpen(!open), children: label }),
732
+ open && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-model-menu", children: [
733
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "dq-model-item dq-model-item--all", children: [
734
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
675
735
  "input",
676
736
  {
677
737
  type: "checkbox",
@@ -679,15 +739,15 @@ function ModelPicker(props) {
679
739
  onChange: () => props.onChange([])
680
740
  }
681
741
  ),
682
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "\u5168\u90E8\u6A21\u578B" })
742
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "\u5168\u90E8\u6A21\u578B" })
683
743
  ] }),
684
744
  models.map((m) => {
685
745
  const key = modelKeyOf(m);
686
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("label", { className: "dq-model-item", children: [
687
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("input", { type: "checkbox", checked: props.selected.includes(key), onChange: () => toggle(key) }),
688
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dq-legend-swatch", style: { background: props.colorOf(key) } }),
689
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: modelNameOf(m) }),
690
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dq-model-tag", children: fmtCompact(m.total) })
746
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "dq-model-item", children: [
747
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("input", { type: "checkbox", checked: props.selected.includes(key), onChange: () => toggle(key) }),
748
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dq-legend-swatch", style: { background: props.colorOf(key) } }),
749
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: modelNameOf(m) }),
750
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dq-model-tag", children: fmtCompact(m.total) })
691
751
  ] }, key);
692
752
  })
693
753
  ] })
@@ -696,18 +756,18 @@ function ModelPicker(props) {
696
756
  function BalanceDashboard() {
697
757
  const cachedBalance = getCachedBalance();
698
758
  const cachedUsage = getCachedUsage();
699
- const [balance, setBalance] = (0, import_react2.useState)(cachedBalance?.data ?? null);
700
- const [usage, setUsage] = (0, import_react2.useState)(cachedUsage?.data ?? null);
701
- const [error, setError] = (0, import_react2.useState)(null);
702
- const [notice, setNotice] = (0, import_react2.useState)(null);
703
- const [loadingBalance, setLoadingBalance] = (0, import_react2.useState)(cachedBalance === null);
704
- const [loadingUsage, setLoadingUsage] = (0, import_react2.useState)(cachedUsage === null);
705
- const [refreshing, setRefreshing] = (0, import_react2.useState)(false);
706
- const hadDataRef = (0, import_react2.useRef)(cachedBalance !== null || cachedUsage !== null);
707
- const [widgetOn, setWidgetOn] = (0, import_react2.useState)(widgetVisibleStore.get());
708
- const [lowBalance, setLowBalance] = (0, import_react2.useState)(lowBalanceStore.get());
709
- const [barMode, setBarMode] = (0, import_react2.useState)("daily");
710
- const [selectedModels, setSelectedModels] = (0, import_react2.useState)([]);
759
+ const [balance, setBalance] = (0, import_react3.useState)(cachedBalance?.data ?? null);
760
+ const [usage, setUsage] = (0, import_react3.useState)(cachedUsage?.data ?? null);
761
+ const [error, setError] = (0, import_react3.useState)(null);
762
+ const [notice, setNotice] = (0, import_react3.useState)(null);
763
+ const [loadingBalance, setLoadingBalance] = (0, import_react3.useState)(cachedBalance === null);
764
+ const [loadingUsage, setLoadingUsage] = (0, import_react3.useState)(cachedUsage === null);
765
+ const [refreshing, setRefreshing] = (0, import_react3.useState)(false);
766
+ const hadDataRef = (0, import_react3.useRef)(cachedBalance !== null || cachedUsage !== null);
767
+ const [widgetOn, setWidgetOn] = (0, import_react3.useState)(widgetVisibleStore.get());
768
+ const [lowBalance, setLowBalance] = (0, import_react3.useState)(lowBalanceStore.get());
769
+ const [barMode, setBarMode] = (0, import_react3.useState)("daily");
770
+ const [selectedModels, setSelectedModels] = (0, import_react3.useState)([]);
711
771
  const errText = (err) => err?.message ?? String(err);
712
772
  const load = async (force) => {
713
773
  setError(null);
@@ -746,7 +806,7 @@ function BalanceDashboard() {
746
806
  setNotice(`\u7528\u91CF\u5237\u65B0\u5931\u8D25\uFF0C\u6B63\u5728\u5C55\u793A\u7F13\u5B58\u7528\u91CF\uFF08${usageError}\uFF09`);
747
807
  }
748
808
  };
749
- (0, import_react2.useEffect)(() => {
809
+ (0, import_react3.useEffect)(() => {
750
810
  void load(false);
751
811
  }, []);
752
812
  const toggle = () => {
@@ -812,15 +872,15 @@ function BalanceDashboard() {
812
872
  }))
813
873
  };
814
874
  });
815
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-balance", children: [
816
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-status-row", children: [
817
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
818
- (loadingBalance || loadingUsage) && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dq-muted", children: "\u52A0\u8F7D\u4E2D\u2026" }),
819
- !loadingBalance && !loadingUsage && refreshing && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dq-muted", children: "\u66F4\u65B0\u4E2D\u2026" }),
820
- notice !== null && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dq-warn", children: notice }),
821
- error !== null && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dq-error", children: error })
875
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-balance", children: [
876
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-status-row", children: [
877
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
878
+ (loadingBalance || loadingUsage) && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dq-muted", children: "\u52A0\u8F7D\u4E2D\u2026" }),
879
+ !loadingBalance && !loadingUsage && refreshing && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dq-muted", children: "\u66F4\u65B0\u4E2D\u2026" }),
880
+ notice !== null && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dq-warn", children: notice }),
881
+ error !== null && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dq-error", children: error })
822
882
  ] }),
823
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
883
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
824
884
  "button",
825
885
  {
826
886
  type: "button",
@@ -832,16 +892,16 @@ function BalanceDashboard() {
832
892
  void load(true);
833
893
  },
834
894
  children: [
835
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: `dq-refresh-icon${refreshing ? " dq-refresh-icon--spin" : ""}`, children: "\u21BB" }),
895
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: `dq-refresh-icon${refreshing ? " dq-refresh-icon--spin" : ""}`, children: "\u21BB" }),
836
896
  refreshing ? "\u5237\u65B0\u4E2D" : "\u5237\u65B0"
837
897
  ]
838
898
  }
839
899
  )
840
900
  ] }),
841
- balanceLow && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-alert", role: "status", children: [
842
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dq-alert-icon", "aria-hidden": "true", children: "!" }),
843
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
844
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("strong", { children: [
901
+ balanceLow && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-alert", role: "status", children: [
902
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dq-alert-icon", "aria-hidden": "true", children: "!" }),
903
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
904
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("strong", { children: [
845
905
  "\u4F59\u989D ",
846
906
  fmt(balanceValue),
847
907
  " ",
@@ -849,40 +909,40 @@ function BalanceDashboard() {
849
909
  " \u5DF2\u4F4E\u4E8E\u9884\u8B66\u7EBF ",
850
910
  fmt(lowBalance)
851
911
  ] }),
852
- daysLeft !== null && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
912
+ daysLeft !== null && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
853
913
  "\uFF0C\u6309\u8FD1\u671F\u7528\u91CF\u4F30\u8BA1\u8FD8\u80FD\u6491 ",
854
914
  daysLeftText
855
915
  ] }),
856
916
  "\u3002",
857
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("a", { className: "dq-alert-link", href: "https://platform.deepseek.com/top_up", target: "_blank", rel: "noreferrer", children: "\u53BB\u5145\u503C" })
917
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("a", { className: "dq-alert-link", href: "https://platform.deepseek.com/top_up", target: "_blank", rel: "noreferrer", children: "\u53BB\u5145\u503C" })
858
918
  ] })
859
919
  ] }),
860
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-card", children: [
861
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-card-title", children: "\u8D26\u6237\u4F59\u989D" }),
862
- primary !== null ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-balance-grid", children: [
863
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-stat", children: [
864
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-stat-label", children: "\u5269\u4F59\u4F59\u989D" }),
865
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-stat-value dq-remaining", children: [
866
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { children: [
920
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-card", children: [
921
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-card-title", children: "\u8D26\u6237\u4F59\u989D" }),
922
+ primary !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-balance-grid", children: [
923
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-stat", children: [
924
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-stat-label", children: "\u5269\u4F59\u4F59\u989D" }),
925
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-stat-value dq-remaining", children: [
926
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { children: [
867
927
  fmt(primary.total),
868
928
  " ",
869
929
  primary.currency
870
930
  ] }),
871
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-remaining-breakdown", children: [
872
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { children: [
931
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-remaining-breakdown", children: [
932
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { children: [
873
933
  "\u5145\u503C\u989D\u5EA6 ",
874
934
  fmt(primary.toppedUp)
875
935
  ] }),
876
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dq-remaining-granted", children: [
936
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "dq-remaining-granted", children: [
877
937
  "\u8D60\u9001\u989D\u5EA6 ",
878
938
  fmt(primary.granted)
879
939
  ] })
880
940
  ] })
881
941
  ] })
882
942
  ] }),
883
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-stat", children: [
884
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-stat-label", children: "\u9884\u8BA1\u53EF\u7528" }),
885
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
943
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-stat", children: [
944
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-stat-label", children: "\u9884\u8BA1\u53EF\u7528" }),
945
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
886
946
  "div",
887
947
  {
888
948
  className: `dq-stat-value dq-runway${daysLeft !== null && daysLeft < 3 ? " dq-stat-value--bad" : ""}`,
@@ -891,50 +951,50 @@ function BalanceDashboard() {
891
951
  }
892
952
  )
893
953
  ] }),
894
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Stat, { label: "\u72B6\u6001", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: `dq-stat-value${balance?.isAvailable === false ? " dq-stat-value--bad" : " dq-stat-value--ok"}`, children: balance?.isAvailable === false ? "\u4E0D\u53EF\u7528" : "\u53EF\u7528" }) })
895
- ] }) : loadingBalance ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BalanceSkeleton, {}) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-empty", children: "\u8BFB\u4E0D\u5230\u4F59\u989D\u3002\u8BF7\u786E\u8BA4\u300C\u8BBE\u7F6E \u2192 \u6A21\u578B\u300D\u91CC\u5DF2\u586B DEEPSEEK_API_KEY\uFF0C\u7136\u540E\u70B9\u53F3\u4E0A\u89D2\u5237\u65B0\u3002" })
954
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: "\u72B6\u6001", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: `dq-stat-value${balance?.isAvailable === false ? " dq-stat-value--bad" : " dq-stat-value--ok"}`, children: balance?.isAvailable === false ? "\u4E0D\u53EF\u7528" : "\u53EF\u7528" }) })
955
+ ] }) : loadingBalance ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(BalanceSkeleton, {}) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-empty", children: "\u8BFB\u4E0D\u5230\u4F59\u989D\u3002\u8BF7\u786E\u8BA4\u300C\u8BBE\u7F6E \u2192 \u6A21\u578B\u300D\u91CC\u5DF2\u586B DEEPSEEK_API_KEY\uFF0C\u7136\u540E\u70B9\u53F3\u4E0A\u89D2\u5237\u65B0\u3002" })
896
956
  ] }),
897
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-card", children: [
898
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-card-title", children: "\u6D88\u8017\u6982\u89C8\uFF08\u8D39\u7528\u4E3A\u4F30\u7B97\uFF09" }),
899
- usage !== null ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-period-grid", children: [
900
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Period, { label: "\u4ECA\u65E5", period: usage.summary.today, previous: usage.summary.yesterday, compare: "\u8F83\u6628\u65E5" }),
901
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Period, { label: "\u672C\u6708", period: usage.summary.month, previous: usage.summary.lastMonthToDate, compare: "\u8F83\u4E0A\u6708\u540C\u671F" }),
902
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
957
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-card", children: [
958
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-card-title", children: "\u6D88\u8017\u6982\u89C8\uFF08\u8D39\u7528\u4E3A\u4F30\u7B97\uFF09" }),
959
+ usage !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-period-grid", children: [
960
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Period, { label: "\u4ECA\u65E5", period: usage.summary.today, previous: usage.summary.yesterday, compare: "\u8F83\u6628\u65E5" }),
961
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Period, { label: "\u672C\u6708", period: usage.summary.month, previous: usage.summary.lastMonthToDate, compare: "\u8F83\u4E0A\u6708\u540C\u671F" }),
962
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
903
963
  Period,
904
964
  {
905
965
  label: "\u7D2F\u8BA1",
906
966
  period: { total: usage.totals.total, cost: usage.totals.cost, calls: usage.totals.calls }
907
967
  }
908
968
  )
909
- ] }) : loadingUsage ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-period-grid", children: [0, 1, 2].map((i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-period", children: [
910
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Skel, { w: 40, h: 11 }),
911
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Skel, { w: 104, h: 24 }),
912
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Skel, { w: 132, h: 11 })
913
- ] }, i)) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-empty", children: "\u8FD8\u6CA1\u6709\u53EF\u7EDF\u8BA1\u7684\u6D88\u8017\u3002" }),
914
- usage !== null && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PricingNote, { pricing: usage.pricing })
969
+ ] }) : loadingUsage ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-period-grid", children: [0, 1, 2].map((i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-period", children: [
970
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Skel, { w: 40, h: 11 }),
971
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Skel, { w: 104, h: 24 }),
972
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Skel, { w: 132, h: 11 })
973
+ ] }, i)) }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-empty", children: "\u8FD8\u6CA1\u6709\u53EF\u7EDF\u8BA1\u7684\u6D88\u8017\u3002" }),
974
+ usage !== null && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PricingNote, { pricing: usage.pricing })
915
975
  ] }),
916
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-card", children: [
917
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-card-title", children: "DSH \u7528\u91CF\uFF08tokens\uFF09" }),
918
- usage !== null ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
919
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-usage-totals", children: [
920
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Stat, { label: "\u8F93\u5165", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-stat-value", children: fmtCompact(usage.totals.input) }) }),
921
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Stat, { label: "\u8F93\u51FA", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-stat-value", children: fmtCompact(usage.totals.output) }) }),
922
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Stat, { label: "\u7F13\u5B58\u547D\u4E2D", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-stat-value", children: fmtCompact(usage.totals.cache) }) }),
923
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Stat, { label: "\u6A21\u578B\u8C03\u7528", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-stat-value", children: fmtInt(usage.totals.calls) }) })
976
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-card", children: [
977
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-card-title", children: "DSH \u7528\u91CF\uFF08tokens\uFF09" }),
978
+ usage !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
979
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-usage-totals", children: [
980
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: "\u8F93\u5165", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-stat-value", children: fmtCompact(usage.totals.input) }) }),
981
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: "\u8F93\u51FA", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-stat-value", children: fmtCompact(usage.totals.output) }) }),
982
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: "\u7F13\u5B58\u547D\u4E2D", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-stat-value", children: fmtCompact(usage.totals.cache) }) }),
983
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stat, { label: "\u6A21\u578B\u8C03\u7528", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-stat-value", children: fmtInt(usage.totals.calls) }) })
924
984
  ] }),
925
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-chart-block-head", children: [
926
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-chart-title", children: [
985
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-chart-block-head", children: [
986
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-chart-title", children: [
927
987
  barMode === "daily" ? "\u8FD1 30 \u5929 \xB7 \u9010\u5929\u7528\u91CF" : "\u6309\u5C0F\u65F6\u5206\u5E03\uFF080\u201323 \u70B9\uFF09",
928
- chartPeak > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dq-chart-peak", children: [
988
+ chartPeak > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "dq-chart-peak", children: [
929
989
  "\u5CF0\u503C ",
930
990
  fmtCompact(chartPeak),
931
991
  " tokens"
932
992
  ] })
933
993
  ] }),
934
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-chart-controls", children: [
935
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ModelPicker, { models: modelList, selected: effectiveSelection, colorOf, onChange: setSelectedModels }),
936
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-chart-switch", role: "tablist", "aria-label": "\u5207\u6362\u56FE\u8868\u7EF4\u5EA6", children: [
937
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
994
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-chart-controls", children: [
995
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ModelPicker, { models: modelList, selected: effectiveSelection, colorOf, onChange: setSelectedModels }),
996
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-chart-switch", role: "tablist", "aria-label": "\u5207\u6362\u56FE\u8868\u7EF4\u5EA6", children: [
997
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
938
998
  "button",
939
999
  {
940
1000
  type: "button",
@@ -945,7 +1005,7 @@ function BalanceDashboard() {
945
1005
  children: "\u9010\u5929"
946
1006
  }
947
1007
  ),
948
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1008
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
949
1009
  "button",
950
1010
  {
951
1011
  type: "button",
@@ -959,8 +1019,8 @@ function BalanceDashboard() {
959
1019
  ] })
960
1020
  ] })
961
1021
  ] }),
962
- grouped.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
963
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1022
+ grouped.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
1023
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
964
1024
  GroupedBars,
965
1025
  {
966
1026
  series: grouped,
@@ -968,66 +1028,66 @@ function BalanceDashboard() {
968
1028
  labelEvery: barMode === "daily" ? 5 : 3
969
1029
  }
970
1030
  ),
971
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-legend", children: grouped.map((s) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dq-legend-item", children: [
972
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dq-legend-swatch", style: { background: s.color } }),
1031
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-legend", children: grouped.map((s) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "dq-legend-item", children: [
1032
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dq-legend-swatch", style: { background: s.color } }),
973
1033
  s.name
974
1034
  ] }, s.key)) })
975
- ] }) : barMode === "daily" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Bars, { data: dailyBars, height: 120, labelEvery: 5 }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Bars, { data: hourlyBars, height: 100, labelEvery: 3 }),
976
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-chart-title", children: "\u8FD1 12 \u5468 \xB7 \u6BCF\u65E5\u7528\u91CF\u70ED\u529B\u56FE" }),
977
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Heatmap, { data: usage.heatmap })
978
- ] }) : loadingUsage ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(UsageSkeleton, {}) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-empty", children: "\u8FD8\u6CA1\u6709\u7528\u91CF\u8BB0\u5F55\u3002\u5728 DSH \u91CC\u8DD1\u4E00\u8F6E\u5BF9\u8BDD\uFF0C\u8FD9\u91CC\u4F1A\u51FA\u73B0\u9010\u5929 / \u9010\u5C0F\u65F6\u7EDF\u8BA1\u4E0E\u8D39\u7528\u4F30\u7B97\u3002" })
1035
+ ] }) : barMode === "daily" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Bars, { data: dailyBars, height: 120, labelEvery: 5 }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Bars, { data: hourlyBars, height: 100, labelEvery: 3 }),
1036
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-chart-title", children: "\u8FD1 12 \u5468 \xB7 \u6BCF\u65E5\u7528\u91CF\u70ED\u529B\u56FE" }),
1037
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Heatmap, { data: usage.heatmap })
1038
+ ] }) : loadingUsage ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(UsageSkeleton, {}) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-empty", children: "\u8FD8\u6CA1\u6709\u7528\u91CF\u8BB0\u5F55\u3002\u5728 DSH \u91CC\u8DD1\u4E00\u8F6E\u5BF9\u8BDD\uFF0C\u8FD9\u91CC\u4F1A\u51FA\u73B0\u9010\u5929 / \u9010\u5C0F\u65F6\u7EDF\u8BA1\u4E0E\u8D39\u7528\u4F30\u7B97\u3002" })
979
1039
  ] }),
980
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-card", children: [
981
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-card-title", children: "\u9AD8\u5CF0 / \u95F2\u65F6\u5206\u5E03" }),
982
- usage !== null ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PeakCard, { split: usage.peakSplit, pricing: usage.pricing, currentCost: usage.totals.cost }) : loadingUsage ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
983
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-peak-track" }),
984
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-peak-figures", children: [
985
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Skel, { w: 120, h: 11 }),
986
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Skel, { w: 96, h: 20 })
1040
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-card", children: [
1041
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-card-title", children: "\u9AD8\u5CF0 / \u95F2\u65F6\u5206\u5E03" }),
1042
+ usage !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PeakCard, { split: usage.peakSplit, pricing: usage.pricing, currentCost: usage.totals.cost }) : loadingUsage ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
1043
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-peak-track" }),
1044
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-peak-figures", children: [
1045
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Skel, { w: 120, h: 11 }),
1046
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Skel, { w: 96, h: 20 })
987
1047
  ] })
988
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-empty", children: "\u8FD8\u6CA1\u6709\u53EF\u6309\u65F6\u6BB5\u5F52\u7C7B\u7684\u7528\u91CF\u3002" })
1048
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-empty", children: "\u8FD8\u6CA1\u6709\u53EF\u6309\u65F6\u6BB5\u5F52\u7C7B\u7684\u7528\u91CF\u3002" })
989
1049
  ] }),
990
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-card", children: [
991
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-card-title", children: "\u7F13\u5B58\u547D\u4E2D\u4E0E\u8282\u7701" }),
992
- usage !== null ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CacheCard, { totals: usage.totals }) : loadingUsage ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-cache-figures", children: [60, 96, 72].map((w, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-stat", children: [
993
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Skel, { w, h: 11 }),
994
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Skel, { w: 72, h: 20 })
995
- ] }, i)) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-empty", children: "\u8FD8\u6CA1\u6709 prompt token \u53EF\u7EDF\u8BA1\u7F13\u5B58\u547D\u4E2D\u3002" })
1050
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-card", children: [
1051
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-card-title", children: "\u7F13\u5B58\u547D\u4E2D\u4E0E\u8282\u7701" }),
1052
+ usage !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CacheCard, { totals: usage.totals }) : loadingUsage ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-cache-figures", children: [60, 96, 72].map((w, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-stat", children: [
1053
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Skel, { w, h: 11 }),
1054
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Skel, { w: 72, h: 20 })
1055
+ ] }, i)) }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-empty", children: "\u8FD8\u6CA1\u6709 prompt token \u53EF\u7EDF\u8BA1\u7F13\u5B58\u547D\u4E2D\u3002" })
996
1056
  ] }),
997
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-card", children: [
998
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-card-title", children: "\u6A21\u578B\u6210\u672C\u6392\u884C" }),
999
- usage !== null ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ModelRanking, { models: modelList, totalCost: modelCostTotal, colorOf }) : loadingUsage ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-rank", children: [0, 1].map((i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-rank-row", children: [
1000
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Skel, { w: 148, h: 13 }),
1001
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-rank-track" }),
1002
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Skel, { w: 230, h: 11 })
1003
- ] }, i)) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-empty", children: "\u8FD8\u6CA1\u6709\u53EF\u5F52\u7C7B\u7684\u6A21\u578B\u7528\u91CF\u3002" })
1057
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-card", children: [
1058
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-card-title", children: "\u6A21\u578B\u6210\u672C\u6392\u884C" }),
1059
+ usage !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ModelRanking, { models: modelList, totalCost: modelCostTotal, colorOf }) : loadingUsage ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-rank", children: [0, 1].map((i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-rank-row", children: [
1060
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Skel, { w: 148, h: 13 }),
1061
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-rank-track" }),
1062
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Skel, { w: 230, h: 11 })
1063
+ ] }, i)) }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-empty", children: "\u8FD8\u6CA1\u6709\u53EF\u5F52\u7C7B\u7684\u6A21\u578B\u7528\u91CF\u3002" })
1004
1064
  ] }),
1005
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-card", children: [
1006
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-card-title", children: "\u4F1A\u8BDD\u6210\u672C\u6392\u884C" }),
1007
- usage !== null ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SessionRanking, { sessions: usage.sessions, count: usage.sessionCount, totalCost: usage.totals.cost }) : loadingUsage ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-sessions", children: [0, 1, 2].map((i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-session", children: [
1008
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Skel, { w: 200, h: 13 }),
1009
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-session-track" }),
1010
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Skel, { w: 250, h: 11 })
1011
- ] }, i)) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-empty", children: "\u8FD8\u6CA1\u6709\u4EA7\u751F\u8D39\u7528\u7684\u4F1A\u8BDD\u3002" })
1065
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-card", children: [
1066
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-card-title", children: "\u4F1A\u8BDD\u6210\u672C\u6392\u884C" }),
1067
+ usage !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SessionRanking, { sessions: usage.sessions, count: usage.sessionCount, totalCost: usage.totals.cost }) : loadingUsage ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-sessions", children: [0, 1, 2].map((i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-session", children: [
1068
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Skel, { w: 200, h: 13 }),
1069
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-session-track" }),
1070
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Skel, { w: 250, h: 11 })
1071
+ ] }, i)) }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-empty", children: "\u8FD8\u6CA1\u6709\u4EA7\u751F\u8D39\u7528\u7684\u4F1A\u8BDD\u3002" })
1012
1072
  ] }),
1013
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-card", children: [
1014
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-card-title", children: "\u5B98\u65B9\u5E73\u53F0" }),
1015
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-links", children: [
1016
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Link, { href: "https://platform.deepseek.com/usage", children: "\u67E5\u770B\u989D\u5EA6 / \u7528\u91CF" }),
1017
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Link, { href: "https://platform.deepseek.com/api_keys", children: "\u751F\u6210 API Key" }),
1018
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Link, { href: "https://status.deepseek.com", children: "\u670D\u52A1\u72B6\u6001" })
1073
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-card", children: [
1074
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-card-title", children: "\u5B98\u65B9\u5E73\u53F0" }),
1075
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-links", children: [
1076
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Link, { href: "https://platform.deepseek.com/usage", children: "\u67E5\u770B\u989D\u5EA6 / \u7528\u91CF" }),
1077
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Link, { href: "https://platform.deepseek.com/api_keys", children: "\u751F\u6210 API Key" }),
1078
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Link, { href: "https://status.deepseek.com", children: "\u670D\u52A1\u72B6\u6001" })
1019
1079
  ] })
1020
1080
  ] }),
1021
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-card", children: [
1022
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dq-card-title", children: "\u8BBE\u7F6E" }),
1023
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("label", { className: "dq-toggle", children: [
1024
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("input", { type: "checkbox", checked: widgetOn, onChange: toggle }),
1025
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "\u663E\u793A\u53F3\u4E0B\u89D2\u60AC\u6D6E\u989D\u5EA6\u7A97\u53E3" })
1081
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-card", children: [
1082
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dq-card-title", children: "\u8BBE\u7F6E" }),
1083
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "dq-toggle", children: [
1084
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("input", { type: "checkbox", checked: widgetOn, onChange: toggle }),
1085
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "\u663E\u793A\u53F3\u4E0B\u89D2\u60AC\u6D6E\u989D\u5EA6\u7A97\u53E3" })
1026
1086
  ] }),
1027
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-setting", children: [
1028
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { className: "dq-setting-label", htmlFor: "dq-low-balance", children: "\u4F59\u989D\u9884\u8B66\u7EBF" }),
1029
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dq-setting-control", children: [
1030
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1087
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-setting", children: [
1088
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { className: "dq-setting-label", htmlFor: "dq-low-balance", children: "\u4F59\u989D\u9884\u8B66\u7EBF" }),
1089
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dq-setting-control", children: [
1090
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1031
1091
  "input",
1032
1092
  {
1033
1093
  id: "dq-low-balance",
@@ -1039,7 +1099,7 @@ function BalanceDashboard() {
1039
1099
  onChange: (e) => changeLowBalance(Math.max(0, Number(e.target.value) || 0))
1040
1100
  }
1041
1101
  ),
1042
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dq-setting-hint", children: lowBalance > 0 ? `\u4F59\u989D\u4F4E\u4E8E ${fmt(lowBalance)} ${primary?.currency ?? "CNY"} \u65F6\uFF0C\u8FD9\u91CC\u548C\u60AC\u6D6E\u7A97\u90FD\u4F1A\u8F6C\u4E3A\u8B66\u793A\u8272\u3002\u586B 0 \u5173\u95ED\u3002` : "\u5DF2\u5173\u95ED\u4F59\u989D\u9884\u8B66\u3002\u586B\u4E00\u4E2A\u5927\u4E8E 0 \u7684\u6570\u5F00\u542F\u3002" })
1102
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dq-setting-hint", children: lowBalance > 0 ? `\u4F59\u989D\u4F4E\u4E8E ${fmt(lowBalance)} ${primary?.currency ?? "CNY"} \u65F6\uFF0C\u8FD9\u91CC\u548C\u60AC\u6D6E\u7A97\u90FD\u4F1A\u8F6C\u4E3A\u8B66\u793A\u8272\u3002\u586B 0 \u5173\u95ED\u3002` : "\u5DF2\u5173\u95ED\u4F59\u989D\u9884\u8B66\u3002\u586B\u4E00\u4E2A\u5927\u4E8E 0 \u7684\u6570\u5F00\u542F\u3002" })
1043
1103
  ] })
1044
1104
  ] })
1045
1105
  ] })
@@ -1229,6 +1289,7 @@ var css = `
1229
1289
  .dq-muted{color:var(--dsw-alias-label-secondary,#59636e)}
1230
1290
  .dq-error{color:var(--dsw-alias-state-error-primary,#cf222e)}
1231
1291
  .dq-warn{color:var(--dsw-alias-state-warning-primary,#9a6700)}
1292
+ .dq-crash{margin:10px 0 14px;padding:10px 12px;background:var(--dsw-alias-bg-layer-2,rgba(120,130,150,.10));border-radius:8px;font-size:11.5px;line-height:1.5;color:var(--dsw-alias-state-error-primary,#cf222e);white-space:pre-wrap;word-break:break-word;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
1232
1293
  .dq-empty{color:var(--dsw-alias-label-secondary,#59636e);font-size:12.5px;line-height:1.6;padding:6px 0}
1233
1294
  .dq-skel{background:linear-gradient(90deg,rgba(125,135,155,.10) 25%,rgba(125,135,155,.20) 37%,rgba(125,135,155,.10) 63%);background-size:400% 100%;border-radius:5px;animation:dq-shimmer 1.5s ease-in-out infinite}
1234
1295
  .dq-stat .dq-skel+.dq-skel{margin-top:6px}
@@ -1248,8 +1309,8 @@ var css = `
1248
1309
  `;
1249
1310
 
1250
1311
  // src/client/widget.tsx
1251
- var import_react3 = require("react");
1252
- var import_jsx_runtime3 = require("react/jsx-runtime");
1312
+ var import_react4 = require("react");
1313
+ var import_jsx_runtime4 = require("react/jsx-runtime");
1253
1314
  var MARGIN = 16;
1254
1315
  var CORNER_KEY = "widget.corner";
1255
1316
  var COLLAPSED_KEY = "widget.collapsed";
@@ -1319,26 +1380,26 @@ function cornerPos(corner, node, bounds) {
1319
1380
  return { x: xRight, y: yBottom };
1320
1381
  }
1321
1382
  function QuotaWidget() {
1322
- const [visible, setVisible] = (0, import_react3.useState)(widgetVisibleStore.get());
1323
- (0, import_react3.useEffect)(() => widgetVisibleStore.subscribe(() => setVisible(widgetVisibleStore.get())), []);
1324
- const [lowBalance, setLowBalance] = (0, import_react3.useState)(lowBalanceStore.get());
1325
- (0, import_react3.useEffect)(() => lowBalanceStore.subscribe(() => setLowBalance(lowBalanceStore.get())), []);
1383
+ const [visible, setVisible] = (0, import_react4.useState)(widgetVisibleStore.get());
1384
+ (0, import_react4.useEffect)(() => widgetVisibleStore.subscribe(() => setVisible(widgetVisibleStore.get())), []);
1385
+ const [lowBalance, setLowBalance] = (0, import_react4.useState)(lowBalanceStore.get());
1386
+ (0, import_react4.useEffect)(() => lowBalanceStore.subscribe(() => setLowBalance(lowBalanceStore.get())), []);
1326
1387
  const cachedBalance = getCachedBalance();
1327
- const [data, setData] = (0, import_react3.useState)(cachedBalance?.data ?? null);
1328
- const [error, setError] = (0, import_react3.useState)(null);
1329
- const [loading, setLoading] = (0, import_react3.useState)(cachedBalance === null);
1330
- const [collapsed, setCollapsed] = (0, import_react3.useState)(() => loadPref(COLLAPSED_KEY, isBoolean, false));
1331
- const [pos, setPos] = (0, import_react3.useState)(null);
1332
- const [corner, setCorner] = (0, import_react3.useState)(() => loadPref(CORNER_KEY, isCorner, "br"));
1333
- const [dragging, setDragging] = (0, import_react3.useState)(false);
1334
- const rootRef = (0, import_react3.useRef)(null);
1335
- const dragRef = (0, import_react3.useRef)(null);
1388
+ const [data, setData] = (0, import_react4.useState)(cachedBalance?.data ?? null);
1389
+ const [error, setError] = (0, import_react4.useState)(null);
1390
+ const [loading, setLoading] = (0, import_react4.useState)(cachedBalance === null);
1391
+ const [collapsed, setCollapsed] = (0, import_react4.useState)(() => loadPref(COLLAPSED_KEY, isBoolean, false));
1392
+ const [pos, setPos] = (0, import_react4.useState)(null);
1393
+ const [corner, setCorner] = (0, import_react4.useState)(() => loadPref(CORNER_KEY, isCorner, "br"));
1394
+ const [dragging, setDragging] = (0, import_react4.useState)(false);
1395
+ const rootRef = (0, import_react4.useRef)(null);
1396
+ const dragRef = (0, import_react4.useRef)(null);
1336
1397
  const readUsage = () => {
1337
1398
  const cached = getCachedUsage();
1338
1399
  return { data: cached?.ok === true ? cached.data ?? null : null, at: getCachedUsageAt() };
1339
1400
  };
1340
- const [usage, setUsage] = (0, import_react3.useState)(readUsage);
1341
- (0, import_react3.useEffect)(() => subscribeUsage(() => setUsage(readUsage())), []);
1401
+ const [usage, setUsage] = (0, import_react4.useState)(readUsage);
1402
+ (0, import_react4.useEffect)(() => subscribeUsage(() => setUsage(readUsage())), []);
1342
1403
  const load = async (showLoading, force = false) => {
1343
1404
  if (showLoading) setLoading(true);
1344
1405
  try {
@@ -1357,14 +1418,14 @@ function QuotaWidget() {
1357
1418
  setLoading(false);
1358
1419
  }
1359
1420
  };
1360
- (0, import_react3.useEffect)(() => {
1421
+ (0, import_react4.useEffect)(() => {
1361
1422
  void load(true);
1362
1423
  const id = setInterval(() => {
1363
1424
  void load(false);
1364
1425
  }, 6e4);
1365
1426
  return () => clearInterval(id);
1366
1427
  }, []);
1367
- (0, import_react3.useLayoutEffect)(() => {
1428
+ (0, import_react4.useLayoutEffect)(() => {
1368
1429
  if (!visible) return;
1369
1430
  const node = rootRef.current;
1370
1431
  if (node === null) return;
@@ -1493,34 +1554,34 @@ function QuotaWidget() {
1493
1554
  let body = null;
1494
1555
  if (!collapsed) {
1495
1556
  if (loading && data === null && error === null) {
1496
- body = /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dsh-quota-body", children: "\u67E5\u8BE2\u4E2D\u2026" });
1557
+ body = /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "dsh-quota-body", children: "\u67E5\u8BE2\u4E2D\u2026" });
1497
1558
  } else if (error !== null && data === null) {
1498
- body = /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dsh-quota-body dsh-quota-error", children: error });
1559
+ body = /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "dsh-quota-body dsh-quota-error", children: error });
1499
1560
  } else if (primary !== null) {
1500
- body = /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-quota-body", children: [
1501
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dsh-quota-remaining-label", children: "\u5269\u4F59\u4F59\u989D" }),
1502
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { title: low ? `\u4F59\u989D\u4F4E\u4E8E\u9884\u8B66\u7EBF ${fmt(lowBalance)}` : void 0, children: [
1503
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: `dsh-quota-total${low ? " dsh-quota-total--low" : ""}`, children: fmt(primary.total) }),
1504
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dsh-quota-currency", children: primary.currency })
1561
+ body = /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "dsh-quota-body", children: [
1562
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "dsh-quota-remaining-label", children: "\u5269\u4F59\u4F59\u989D" }),
1563
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { title: low ? `\u4F59\u989D\u4F4E\u4E8E\u9884\u8B66\u7EBF ${fmt(lowBalance)}` : void 0, children: [
1564
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: `dsh-quota-total${low ? " dsh-quota-total--low" : ""}`, children: fmt(primary.total) }),
1565
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "dsh-quota-currency", children: primary.currency })
1505
1566
  ] }),
1506
- usage.data !== null && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-quota-row", title: `\u4ECA\u65E5\u6D88\u8017\uFF08\u4F30\u7B97\uFF09\xB7 ${usageAgeText}`, children: [
1507
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dsh-quota-label", children: "\u4ECA\u65E5\u6D88\u8017" }),
1508
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "dsh-quota-value", children: [
1567
+ usage.data !== null && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "dsh-quota-row", title: `\u4ECA\u65E5\u6D88\u8017\uFF08\u4F30\u7B97\uFF09\xB7 ${usageAgeText}`, children: [
1568
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "dsh-quota-label", children: "\u4ECA\u65E5\u6D88\u8017" }),
1569
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "dsh-quota-value", children: [
1509
1570
  "\xA5 ",
1510
1571
  fmt(usage.data.summary.today.cost)
1511
1572
  ] })
1512
1573
  ] }),
1513
- data?.isAvailable === false && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-quota-row", children: [
1514
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dsh-quota-label", children: "\u72B6\u6001" }),
1515
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dsh-quota-value dsh-quota-error", children: "\u4E0D\u53EF\u7528" })
1574
+ data?.isAvailable === false && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "dsh-quota-row", children: [
1575
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "dsh-quota-label", children: "\u72B6\u6001" }),
1576
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "dsh-quota-value dsh-quota-error", children: "\u4E0D\u53EF\u7528" })
1516
1577
  ] })
1517
1578
  ] });
1518
1579
  } else {
1519
- body = /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dsh-quota-body dsh-quota-error", children: "\u6682\u65E0\u4F59\u989D\u6570\u636E" });
1580
+ body = /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "dsh-quota-body dsh-quota-error", children: "\u6682\u65E0\u4F59\u989D\u6570\u636E" });
1520
1581
  }
1521
1582
  }
1522
1583
  const style = pos !== null ? { left: `${pos.x}px`, top: `${pos.y}px`, right: "auto", bottom: "auto" } : void 0;
1523
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: `dsh-quota-root${dragging ? " dsh-quota-dragging" : ""}`, style, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1584
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: `dsh-quota-root${dragging ? " dsh-quota-dragging" : ""}`, style, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1524
1585
  "div",
1525
1586
  {
1526
1587
  ref: rootRef,
@@ -1532,19 +1593,19 @@ function QuotaWidget() {
1532
1593
  onPointerCancel: () => endDrag(false),
1533
1594
  onLostPointerCapture: () => endDrag(false),
1534
1595
  children: [
1535
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-quota-header", children: [
1536
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-quota-title", children: [
1537
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dsh-quota-grip", title: "\u62D6\u52A8\u4EE5\u79FB\u52A8", children: "\u2807" }),
1538
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: dotClass }),
1539
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dsh-quota-name", children: "DeepSeek \u989D\u5EA6" }),
1540
- collapsed && primary !== null && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: `dsh-quota-collapsed-total${low ? " dsh-quota-total--low" : ""}`, children: [
1596
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "dsh-quota-header", children: [
1597
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "dsh-quota-title", children: [
1598
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "dsh-quota-grip", title: "\u62D6\u52A8\u4EE5\u79FB\u52A8", children: "\u2807" }),
1599
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: dotClass }),
1600
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "dsh-quota-name", children: "DeepSeek \u989D\u5EA6" }),
1601
+ collapsed && primary !== null && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: `dsh-quota-collapsed-total${low ? " dsh-quota-total--low" : ""}`, children: [
1541
1602
  fmt(primary.total),
1542
1603
  " ",
1543
1604
  primary.currency
1544
1605
  ] })
1545
1606
  ] }),
1546
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-quota-actions", children: [
1547
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1607
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "dsh-quota-actions", children: [
1608
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1548
1609
  "button",
1549
1610
  {
1550
1611
  className: "dsh-quota-btn",
@@ -1559,7 +1620,7 @@ function QuotaWidget() {
1559
1620
  children: "\u21BB"
1560
1621
  }
1561
1622
  ),
1562
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1623
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1563
1624
  "button",
1564
1625
  {
1565
1626
  className: "dsh-quota-btn",
@@ -1584,7 +1645,7 @@ function QuotaWidget() {
1584
1645
  }
1585
1646
 
1586
1647
  // src/client/index.tsx
1587
- var import_jsx_runtime4 = require("react/jsx-runtime");
1648
+ var import_jsx_runtime5 = require("react/jsx-runtime");
1588
1649
  var name = "dsh-usage-dashboard";
1589
1650
  var inject = ["slots"];
1590
1651
  function apply(ctx) {
@@ -1596,11 +1657,11 @@ function apply(ctx) {
1596
1657
  }
1597
1658
  ctx.slots.inject("shell.overlay", () => ctx.slots.register(
1598
1659
  { name: "shell.overlay", id: "deepseek-quota", order: 1e3, label: "DeepSeek \u989D\u5EA6" },
1599
- () => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(QuotaWidget, {})
1660
+ () => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ErrorBoundary, { silent: true, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(QuotaWidget, {}) })
1600
1661
  ));
1601
1662
  ctx.slots.inject("conversation.view", () => ctx.slots.register(
1602
1663
  { name: "conversation.view", id: "balance", order: 20, label: "\u989D\u5EA6" },
1603
- () => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(BalanceDashboard, {})
1664
+ () => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ErrorBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(BalanceDashboard, {}) })
1604
1665
  ));
1605
1666
  }
1606
1667
  return module.exports; } });