@ipv9/tokentracker-cli 0.39.22 → 0.39.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dashboard/dist/assets/ActivityHeatmap-DPWjzqNf.js +42 -0
- package/dashboard/dist/assets/{Card-Dm-vV5fT.js → Card-B6l7DFB6.js} +1 -1
- package/dashboard/dist/assets/DashboardPage-COqvftnM.js +19 -0
- package/dashboard/dist/assets/{DevicePage-DL2Evorm.js → DevicePage-BTX6oiNV.js} +1 -1
- package/dashboard/dist/assets/{DialogTitle-BGPDFPkc.js → DialogTitle-Bqdf6lRl.js} +1 -1
- package/dashboard/dist/assets/{FadeIn-CQ_YmrFw.js → FadeIn-C0eGg9YT.js} +1 -1
- package/dashboard/dist/assets/{InsforgeUserHeaderControls-YPHdtTTd.js → InsforgeUserHeaderControls-BvVeuzmy.js} +1 -1
- package/dashboard/dist/assets/{IpCheckPage-BVvV3tEl.js → IpCheckPage-BCxj95za.js} +1 -1
- package/dashboard/dist/assets/{LandingPage-C53O19r8.js → LandingPage-DkW_-IUq.js} +1 -1
- package/dashboard/dist/assets/{LeaderboardAvatar-vmpdj2pR.js → LeaderboardAvatar-CdvMXLQJ.js} +1 -1
- package/dashboard/dist/assets/{LeaderboardPage-no6kgyFi.js → LeaderboardPage-CEsp6t6E.js} +3 -3
- package/dashboard/dist/assets/{LeaderboardProfileModal-fTDvlvZN.js → LeaderboardProfileModal--rW0KlHw.js} +1 -1
- package/dashboard/dist/assets/LeaderboardProfilePage-CxUYiGeW.js +1 -0
- package/dashboard/dist/assets/{LimitsPage-DcTgsN6X.js → LimitsPage-BXMCGGdO.js} +2 -2
- package/dashboard/dist/assets/{LocalOnlyNotice-VeVP185X.js → LocalOnlyNotice-CaueKPwt.js} +1 -1
- package/dashboard/dist/assets/{LoginPage-CY-qZZy0.js → LoginPage-DJClCMkk.js} +1 -1
- package/dashboard/dist/assets/{PopoverPopup-be0Sxsht.js → PopoverPopup-ClB7lBvx.js} +1 -1
- package/dashboard/dist/assets/{Select-DNNgvQEV.js → Select-DCwfhdKp.js} +1 -1
- package/dashboard/dist/assets/{SelectItemText-CBPoUy8w.js → SelectItemText-BroYKgBb.js} +1 -1
- package/dashboard/dist/assets/SettingsPage-hFiQM-_N.js +1 -0
- package/dashboard/dist/assets/{SkillsPage-DCb1zS1J.js → SkillsPage-DmJIQF8f.js} +1 -1
- package/dashboard/dist/assets/{WidgetsPage-BRVmAgq1.js → WidgetsPage-CO8R-tlm.js} +1 -1
- package/dashboard/dist/assets/{WrappedPage-BcuXD45L.js → WrappedPage-CCpOup2F.js} +1 -1
- package/dashboard/dist/assets/{arrow-up-right-Cyh3-4de.js → arrow-up-right-JK3-vzAg.js} +1 -1
- package/dashboard/dist/assets/{download-C3eW5ynF.js → download-BZ6S1rdH.js} +1 -1
- package/dashboard/dist/assets/{info-CSAnLIAh.js → info-35FGjeST.js} +1 -1
- package/dashboard/dist/assets/main-B4M18BsA.css +1 -0
- package/dashboard/dist/assets/{main-BAdX_7hM.js → main-Bs0wIGxU.js} +2 -2
- package/dashboard/dist/assets/{use-limits-display-prefs-BKBMjWGn.js → use-limits-display-prefs-BnIRF1GH.js} +1 -1
- package/dashboard/dist/assets/{use-native-settings-CQuCbPc9.js → use-native-settings-CHMWJ78h.js} +1 -1
- package/dashboard/dist/assets/{use-spring-BTelsGuG.js → use-spring-D6NY3otb.js} +1 -1
- package/dashboard/dist/assets/{use-usage-limits-a7G_-yhi.js → use-usage-limits-BY-Kdrvn.js} +1 -1
- package/dashboard/dist/assets/{useCurrency-BnMdRysu.js → useCurrency--TEilWkm.js} +1 -1
- package/dashboard/dist/assets/{useOpenInteractionType-DunsezWq.js → useOpenInteractionType-uDQvb3tj.js} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/dashboard/dist/share.html +2 -2
- package/package.json +1 -1
- package/src/lib/pricing/seed-snapshot.json +1 -1
- package/src/lib/rollout.js +153 -27
- package/dashboard/dist/assets/ActivityHeatmap-DqpmSECi.js +0 -42
- package/dashboard/dist/assets/DashboardPage-CcTjnozw.js +0 -19
- package/dashboard/dist/assets/LeaderboardProfilePage-CAFncZz7.js +0 -1
- package/dashboard/dist/assets/SettingsPage-DxP5qY9l.js +0 -1
- package/dashboard/dist/assets/main-fhNSX8yD.css +0 -1
package/src/lib/rollout.js
CHANGED
|
@@ -49,6 +49,29 @@ async function listClaudeProjectFiles(projectsDir) {
|
|
|
49
49
|
return out;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
// Fingerprint the first bytes of a file so rotation is detected even when the
|
|
53
|
+
// OS reuses the inode after unlink+recreate (Linux logrotate). Returns "" on
|
|
54
|
+
// any error so callers treat "no fingerprint" as "not changed". Also returns
|
|
55
|
+
// "" when the file is shorter than the fingerprint window: for a sub-256B
|
|
56
|
+
// file that is still being appended to, the window would extend into the
|
|
57
|
+
// not-yet-written append zone, so plain growth (not rotation) would shift
|
|
58
|
+
// the hash and produce a false "rotated" signal.
|
|
59
|
+
function readFileHeadSignature(filePath) {
|
|
60
|
+
try {
|
|
61
|
+
const fd = fssync.openSync(filePath, "r");
|
|
62
|
+
try {
|
|
63
|
+
const buf = Buffer.alloc(256);
|
|
64
|
+
const bytes = fssync.readSync(fd, buf, 0, 256, 0);
|
|
65
|
+
if (bytes < 256) return "";
|
|
66
|
+
return crypto.createHash("sha1").update(buf.subarray(0, bytes)).digest("hex");
|
|
67
|
+
} finally {
|
|
68
|
+
fssync.closeSync(fd);
|
|
69
|
+
}
|
|
70
|
+
} catch {
|
|
71
|
+
return "";
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
52
75
|
async function listGeminiSessionFiles(tmpDir) {
|
|
53
76
|
const out = [];
|
|
54
77
|
const roots = await safeReadDir(tmpDir);
|
|
@@ -116,9 +139,18 @@ async function parseRolloutIncremental({
|
|
|
116
139
|
const key = filePath;
|
|
117
140
|
const prev = cursors.files[key] || null;
|
|
118
141
|
const inode = st.ino || 0;
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
142
|
+
// Reuse the saved offset only when the inode matches AND the head
|
|
143
|
+
// fingerprint is unchanged AND the file hasn't shrunk below the saved
|
|
144
|
+
// offset — any of those signals flipping means the file was rotated
|
|
145
|
+
// (e.g. Linux logrotate reuses the inode after unlink+recreate).
|
|
146
|
+
const headSig = readFileHeadSignature(filePath);
|
|
147
|
+
const headChanged =
|
|
148
|
+
!!prev && typeof prev.head === "string" && prev.head !== "" && prev.head !== headSig;
|
|
149
|
+
const shrunk = !!prev && typeof prev.offset === "number" && st.size < prev.offset;
|
|
150
|
+
const sameFile = !!prev && prev.inode === inode && !headChanged && !shrunk;
|
|
151
|
+
const startOffset = sameFile ? prev.offset || 0 : 0;
|
|
152
|
+
const lastTotal = sameFile ? prev.lastTotal || null : null;
|
|
153
|
+
const lastModel = sameFile ? prev.lastModel || null : null;
|
|
122
154
|
|
|
123
155
|
const projectContext = projectEnabled
|
|
124
156
|
? await resolveProjectContextForFile({
|
|
@@ -154,6 +186,7 @@ async function parseRolloutIncremental({
|
|
|
154
186
|
offset: result.endOffset,
|
|
155
187
|
lastTotal: result.lastTotal,
|
|
156
188
|
lastModel: result.lastModel,
|
|
189
|
+
head: headSig,
|
|
157
190
|
updatedAt: new Date().toISOString(),
|
|
158
191
|
};
|
|
159
192
|
|
|
@@ -233,7 +266,16 @@ async function parseClaudeIncremental({
|
|
|
233
266
|
const key = filePath;
|
|
234
267
|
const prev = cursors.files[key] || null;
|
|
235
268
|
const inode = st.ino || 0;
|
|
236
|
-
|
|
269
|
+
// Reuse the saved offset only when the inode matches AND the head
|
|
270
|
+
// fingerprint is unchanged AND the file hasn't shrunk below the saved
|
|
271
|
+
// offset — a rotator that reuses the inode (Linux logrotate) would
|
|
272
|
+
// otherwise leave the old offset stuck and skip the new prefix.
|
|
273
|
+
const headSig = readFileHeadSignature(filePath);
|
|
274
|
+
const headChanged =
|
|
275
|
+
!!prev && typeof prev.head === "string" && prev.head !== "" && prev.head !== headSig;
|
|
276
|
+
const shrunk = !!prev && typeof prev.offset === "number" && st.size < prev.offset;
|
|
277
|
+
const sameFile = !!prev && prev.inode === inode && !headChanged && !shrunk;
|
|
278
|
+
const startOffset = sameFile ? prev.offset || 0 : 0;
|
|
237
279
|
|
|
238
280
|
const projectContext = projectEnabled
|
|
239
281
|
? await resolveProjectContextForFile({
|
|
@@ -263,6 +305,7 @@ async function parseClaudeIncremental({
|
|
|
263
305
|
cursors.files[key] = {
|
|
264
306
|
inode,
|
|
265
307
|
offset: result.endOffset,
|
|
308
|
+
head: headSig,
|
|
266
309
|
updatedAt: new Date().toISOString(),
|
|
267
310
|
};
|
|
268
311
|
|
|
@@ -342,9 +385,18 @@ async function parseGeminiIncremental({
|
|
|
342
385
|
const key = filePath;
|
|
343
386
|
const prev = cursors.files[key] || null;
|
|
344
387
|
const inode = st.ino || 0;
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
388
|
+
// Reuse the saved message index only when the inode matches AND the head
|
|
389
|
+
// fingerprint is unchanged AND the file hasn't shrunk below its last
|
|
390
|
+
// recorded size — a rotator that reuses the inode (Linux logrotate)
|
|
391
|
+
// would otherwise leave the old index stuck and skip replayed messages.
|
|
392
|
+
const headSig = readFileHeadSignature(filePath);
|
|
393
|
+
const headChanged =
|
|
394
|
+
!!prev && typeof prev.head === "string" && prev.head !== "" && prev.head !== headSig;
|
|
395
|
+
const shrunk = !!prev && typeof prev.size === "number" && st.size < prev.size;
|
|
396
|
+
const sameFile = !!prev && prev.inode === inode && !headChanged && !shrunk;
|
|
397
|
+
let startIndex = sameFile ? Number(prev.lastIndex || -1) : -1;
|
|
398
|
+
let lastTotals = sameFile ? prev.lastTotals || null : null;
|
|
399
|
+
let lastModel = sameFile ? prev.lastModel || null : null;
|
|
348
400
|
|
|
349
401
|
const projectContext = projectEnabled
|
|
350
402
|
? await resolveProjectContextForFile({
|
|
@@ -374,9 +426,11 @@ async function parseGeminiIncremental({
|
|
|
374
426
|
|
|
375
427
|
cursors.files[key] = {
|
|
376
428
|
inode,
|
|
429
|
+
size: st.size,
|
|
377
430
|
lastIndex: result.lastIndex,
|
|
378
431
|
lastTotals: result.lastTotals,
|
|
379
432
|
lastModel: result.lastModel,
|
|
433
|
+
head: headSig,
|
|
380
434
|
updatedAt: new Date().toISOString(),
|
|
381
435
|
};
|
|
382
436
|
|
|
@@ -456,8 +510,18 @@ async function parseOpencodeIncremental({
|
|
|
456
510
|
const inode = st.ino || 0;
|
|
457
511
|
const size = Number.isFinite(st.size) ? st.size : 0;
|
|
458
512
|
const mtimeMs = Number.isFinite(st.mtimeMs) ? st.mtimeMs : 0;
|
|
513
|
+
// Head fingerprint guards against a rotator that reuses the inode (Linux
|
|
514
|
+
// logrotate): if the head changed we must never treat the file as
|
|
515
|
+
// "unchanged", even when inode/size/mtimeMs happen to match.
|
|
516
|
+
const headSig = readFileHeadSignature(filePath);
|
|
517
|
+
const headChanged =
|
|
518
|
+
!!prev && typeof prev.head === "string" && prev.head !== "" && prev.head !== headSig;
|
|
459
519
|
const unchanged =
|
|
460
|
-
prev &&
|
|
520
|
+
prev &&
|
|
521
|
+
prev.inode === inode &&
|
|
522
|
+
prev.size === size &&
|
|
523
|
+
prev.mtimeMs === mtimeMs &&
|
|
524
|
+
!headChanged;
|
|
461
525
|
if (unchanged) {
|
|
462
526
|
filesProcessed += 1;
|
|
463
527
|
if (cb) {
|
|
@@ -510,6 +574,7 @@ async function parseOpencodeIncremental({
|
|
|
510
574
|
mtimeMs,
|
|
511
575
|
lastTotals: result.lastTotals,
|
|
512
576
|
messageKey: result.messageKey || null,
|
|
577
|
+
head: headSig,
|
|
513
578
|
updatedAt: new Date().toISOString(),
|
|
514
579
|
};
|
|
515
580
|
|
|
@@ -591,7 +656,16 @@ async function parseOpenclawIncremental({
|
|
|
591
656
|
const key = filePath;
|
|
592
657
|
const prev = cursors.files[key] || null;
|
|
593
658
|
const inode = st.ino || 0;
|
|
594
|
-
|
|
659
|
+
// Reuse the saved offset only when the inode matches AND the head
|
|
660
|
+
// fingerprint is unchanged AND the file hasn't shrunk below the saved
|
|
661
|
+
// offset — a rotator that reuses the inode (Linux logrotate) would
|
|
662
|
+
// otherwise leave the old offset stuck and skip the new prefix.
|
|
663
|
+
const headSig = readFileHeadSignature(filePath);
|
|
664
|
+
const headChanged =
|
|
665
|
+
!!prev && typeof prev.head === "string" && prev.head !== "" && prev.head !== headSig;
|
|
666
|
+
const shrunk = !!prev && typeof prev.offset === "number" && st.size < prev.offset;
|
|
667
|
+
const sameFile = !!prev && prev.inode === inode && !headChanged && !shrunk;
|
|
668
|
+
const startOffset = sameFile ? prev.offset || 0 : 0;
|
|
595
669
|
|
|
596
670
|
const result = await parseOpenclawSessionFile({
|
|
597
671
|
filePath,
|
|
@@ -606,6 +680,7 @@ async function parseOpenclawIncremental({
|
|
|
606
680
|
cursors.files[key] = {
|
|
607
681
|
inode,
|
|
608
682
|
offset: result.endOffset,
|
|
683
|
+
head: headSig,
|
|
609
684
|
updatedAt: new Date().toISOString(),
|
|
610
685
|
};
|
|
611
686
|
|
|
@@ -4205,8 +4280,11 @@ async function parseKimiIncremental({ wireFiles, cursors, queuePath, onProgress,
|
|
|
4205
4280
|
const prevEntry = fileOffsets[filePath] || {};
|
|
4206
4281
|
const prevSize = Number(prevEntry.size) || 0;
|
|
4207
4282
|
const prevIno = prevEntry.ino;
|
|
4283
|
+
const headSig = readFileHeadSignature(filePath);
|
|
4208
4284
|
const inodeChanged = typeof prevIno === "number" && prevIno !== stat.ino;
|
|
4209
|
-
const
|
|
4285
|
+
const headChanged =
|
|
4286
|
+
typeof prevEntry.head === "string" && prevEntry.head !== "" && prevEntry.head !== headSig;
|
|
4287
|
+
const startOffset = stat.size < prevSize || inodeChanged || headChanged ? 0 : prevSize;
|
|
4210
4288
|
if (stat.size <= startOffset) continue;
|
|
4211
4289
|
|
|
4212
4290
|
let stream;
|
|
@@ -4275,7 +4353,12 @@ async function parseKimiIncremental({ wireFiles, cursors, queuePath, onProgress,
|
|
|
4275
4353
|
|
|
4276
4354
|
let postStat = stat;
|
|
4277
4355
|
try { postStat = fssync.statSync(filePath); } catch {}
|
|
4278
|
-
fileOffsets[filePath] = {
|
|
4356
|
+
fileOffsets[filePath] = {
|
|
4357
|
+
size: postStat.size,
|
|
4358
|
+
mtimeMs: postStat.mtimeMs,
|
|
4359
|
+
ino: postStat.ino,
|
|
4360
|
+
head: readFileHeadSignature(filePath),
|
|
4361
|
+
};
|
|
4279
4362
|
}
|
|
4280
4363
|
|
|
4281
4364
|
// Cap seenIds to last 10k to bound cursor state size
|
|
@@ -4384,8 +4467,11 @@ async function parseKimiCodeIncremental({ wireFiles, cursors, queuePath, onProgr
|
|
|
4384
4467
|
const prevEntry = fileOffsets[filePath] || {};
|
|
4385
4468
|
const prevSize = Number(prevEntry.size) || 0;
|
|
4386
4469
|
const prevIno = prevEntry.ino;
|
|
4470
|
+
const headSig = readFileHeadSignature(filePath);
|
|
4387
4471
|
const inodeChanged = typeof prevIno === "number" && prevIno !== stat.ino;
|
|
4388
|
-
const
|
|
4472
|
+
const headChanged =
|
|
4473
|
+
typeof prevEntry.head === "string" && prevEntry.head !== "" && prevEntry.head !== headSig;
|
|
4474
|
+
const startOffset = stat.size < prevSize || inodeChanged || headChanged ? 0 : prevSize;
|
|
4389
4475
|
// Model is declared in a `config.update` near the file head; persist it on
|
|
4390
4476
|
// the cursor so incremental resumes (which start past that line) keep it.
|
|
4391
4477
|
let fileModel = (typeof prevEntry.model === "string" && prevEntry.model) || fallbackModel;
|
|
@@ -4480,7 +4566,13 @@ async function parseKimiCodeIncremental({ wireFiles, cursors, queuePath, onProgr
|
|
|
4480
4566
|
|
|
4481
4567
|
let postStat = stat;
|
|
4482
4568
|
try { postStat = fssync.statSync(filePath); } catch {}
|
|
4483
|
-
fileOffsets[filePath] = {
|
|
4569
|
+
fileOffsets[filePath] = {
|
|
4570
|
+
size: postStat.size,
|
|
4571
|
+
mtimeMs: postStat.mtimeMs,
|
|
4572
|
+
ino: postStat.ino,
|
|
4573
|
+
model: fileModel,
|
|
4574
|
+
head: readFileHeadSignature(filePath),
|
|
4575
|
+
};
|
|
4484
4576
|
}
|
|
4485
4577
|
|
|
4486
4578
|
const seenArr = Array.from(seenIds);
|
|
@@ -4619,10 +4711,14 @@ async function parseCodebuddyIncremental({
|
|
|
4619
4711
|
const prevEntry = fileOffsets[filePath] || {};
|
|
4620
4712
|
const prevSize = Number(prevEntry.size) || 0;
|
|
4621
4713
|
const prevIno = prevEntry.ino;
|
|
4622
|
-
|
|
4623
|
-
//
|
|
4714
|
+
const headSig = readFileHeadSignature(filePath);
|
|
4715
|
+
// Re-read from start if file shrunk (truncate/rewrite), inode changed
|
|
4716
|
+
// (file deleted + recreated), or the head fingerprint changed (rotator
|
|
4717
|
+
// reused the inode). Otherwise pick up after the last read offset.
|
|
4624
4718
|
const inodeChanged = typeof prevIno === "number" && prevIno !== stat.ino;
|
|
4625
|
-
const
|
|
4719
|
+
const headChanged =
|
|
4720
|
+
typeof prevEntry.head === "string" && prevEntry.head !== "" && prevEntry.head !== headSig;
|
|
4721
|
+
const startOffset = stat.size < prevSize || inodeChanged || headChanged ? 0 : prevSize;
|
|
4626
4722
|
if (stat.size <= startOffset) continue;
|
|
4627
4723
|
|
|
4628
4724
|
let stream;
|
|
@@ -4748,6 +4844,7 @@ async function parseCodebuddyIncremental({
|
|
|
4748
4844
|
size: postStat.size,
|
|
4749
4845
|
mtimeMs: postStat.mtimeMs,
|
|
4750
4846
|
ino: postStat.ino,
|
|
4847
|
+
head: readFileHeadSignature(filePath),
|
|
4751
4848
|
};
|
|
4752
4849
|
}
|
|
4753
4850
|
|
|
@@ -6508,9 +6605,13 @@ async function parseOmpIncremental({
|
|
|
6508
6605
|
const prevEntry = fileOffsets[filePath] || {};
|
|
6509
6606
|
const prevSize = Number(prevEntry.size) || 0;
|
|
6510
6607
|
const prevIno = prevEntry.ino;
|
|
6511
|
-
|
|
6608
|
+
const headSig = readFileHeadSignature(filePath);
|
|
6609
|
+
// Re-read from start if file shrunk (truncate/rewrite), inode changed, or
|
|
6610
|
+
// the head fingerprint changed (rotator reused the inode).
|
|
6512
6611
|
const inodeChanged = typeof prevIno === "number" && prevIno !== stat.ino;
|
|
6513
|
-
const
|
|
6612
|
+
const headChanged =
|
|
6613
|
+
typeof prevEntry.head === "string" && prevEntry.head !== "" && prevEntry.head !== headSig;
|
|
6614
|
+
const startOffset = stat.size < prevSize || inodeChanged || headChanged ? 0 : prevSize;
|
|
6514
6615
|
if (stat.size <= startOffset) continue;
|
|
6515
6616
|
|
|
6516
6617
|
let stream;
|
|
@@ -6616,6 +6717,7 @@ async function parseOmpIncremental({
|
|
|
6616
6717
|
size: postStat.size,
|
|
6617
6718
|
mtimeMs: postStat.mtimeMs,
|
|
6618
6719
|
ino: postStat.ino,
|
|
6720
|
+
head: readFileHeadSignature(filePath),
|
|
6619
6721
|
};
|
|
6620
6722
|
}
|
|
6621
6723
|
|
|
@@ -6756,8 +6858,11 @@ async function parsePiIncremental({
|
|
|
6756
6858
|
const prevEntry = fileOffsets[filePath] || {};
|
|
6757
6859
|
const prevSize = Number(prevEntry.size) || 0;
|
|
6758
6860
|
const prevIno = prevEntry.ino;
|
|
6861
|
+
const headSig = readFileHeadSignature(filePath);
|
|
6759
6862
|
const inodeChanged = typeof prevIno === "number" && prevIno !== stat.ino;
|
|
6760
|
-
const
|
|
6863
|
+
const headChanged =
|
|
6864
|
+
typeof prevEntry.head === "string" && prevEntry.head !== "" && prevEntry.head !== headSig;
|
|
6865
|
+
const startOffset = stat.size < prevSize || inodeChanged || headChanged ? 0 : prevSize;
|
|
6761
6866
|
if (stat.size <= startOffset) continue;
|
|
6762
6867
|
|
|
6763
6868
|
let stream;
|
|
@@ -6855,6 +6960,7 @@ async function parsePiIncremental({
|
|
|
6855
6960
|
size: postStat.size,
|
|
6856
6961
|
mtimeMs: postStat.mtimeMs,
|
|
6857
6962
|
ino: postStat.ino,
|
|
6963
|
+
head: readFileHeadSignature(filePath),
|
|
6858
6964
|
};
|
|
6859
6965
|
}
|
|
6860
6966
|
|
|
@@ -7400,12 +7506,15 @@ async function parseCopilotIncremental({ otelPaths, cursors, queuePath, onProgre
|
|
|
7400
7506
|
const prevEntry = fileOffsets[filePath] || {};
|
|
7401
7507
|
const prevSize = Number(prevEntry.size) || 0;
|
|
7402
7508
|
const prevIno = prevEntry.ino;
|
|
7403
|
-
|
|
7404
|
-
//
|
|
7405
|
-
//
|
|
7406
|
-
// the
|
|
7509
|
+
const headSig = readFileHeadSignature(filePath);
|
|
7510
|
+
// Re-read from start if (a) file shrunk (truncate/rewrite in place),
|
|
7511
|
+
// (b) inode changed (rotator deleted + recreated at same path), or
|
|
7512
|
+
// (c) the head fingerprint changed (rotator reused the inode — Linux
|
|
7513
|
+
// logrotate — and produced a same-or-larger file, so (a)/(b) miss it).
|
|
7407
7514
|
const inodeChanged = typeof prevIno === "number" && prevIno !== stat.ino;
|
|
7408
|
-
const
|
|
7515
|
+
const headChanged =
|
|
7516
|
+
typeof prevEntry.head === "string" && prevEntry.head !== "" && prevEntry.head !== headSig;
|
|
7517
|
+
const startOffset = stat.size < prevSize || inodeChanged || headChanged ? 0 : prevSize;
|
|
7409
7518
|
if (stat.size <= startOffset) continue;
|
|
7410
7519
|
|
|
7411
7520
|
let stream;
|
|
@@ -7510,7 +7619,12 @@ async function parseCopilotIncremental({ otelPaths, cursors, queuePath, onProgre
|
|
|
7510
7619
|
try {
|
|
7511
7620
|
postStat = fssync.statSync(filePath);
|
|
7512
7621
|
} catch (_e) {}
|
|
7513
|
-
fileOffsets[filePath] = {
|
|
7622
|
+
fileOffsets[filePath] = {
|
|
7623
|
+
size: postStat.size,
|
|
7624
|
+
mtimeMs: postStat.mtimeMs,
|
|
7625
|
+
ino: postStat.ino,
|
|
7626
|
+
head: readFileHeadSignature(filePath),
|
|
7627
|
+
};
|
|
7514
7628
|
}
|
|
7515
7629
|
|
|
7516
7630
|
// Cap dedup set to last 10k IDs to bound state size
|
|
@@ -8016,9 +8130,20 @@ async function parseAntigravityIncremental({
|
|
|
8016
8130
|
const inode = st.ino || 0;
|
|
8017
8131
|
const size = Number.isFinite(st.size) ? st.size : 0;
|
|
8018
8132
|
const mtimeMs = Number.isFinite(st.mtimeMs) ? st.mtimeMs : 0;
|
|
8133
|
+
// Head fingerprint + shrink guard against a rotator that reuses the
|
|
8134
|
+
// inode (Linux logrotate): either signal flipping means the cached
|
|
8135
|
+
// progress (unchanged skip, or lastLine/context resume) must not be reused.
|
|
8136
|
+
const headSig = readFileHeadSignature(filePath);
|
|
8137
|
+
const headChanged =
|
|
8138
|
+
!!prev && typeof prev.head === "string" && prev.head !== "" && prev.head !== headSig;
|
|
8139
|
+
const shrunk = !!prev && typeof prev.size === "number" && size < prev.size;
|
|
8019
8140
|
|
|
8020
8141
|
const unchanged =
|
|
8021
|
-
prev &&
|
|
8142
|
+
prev &&
|
|
8143
|
+
prev.inode === inode &&
|
|
8144
|
+
prev.size === size &&
|
|
8145
|
+
prev.mtimeMs === mtimeMs &&
|
|
8146
|
+
!headChanged;
|
|
8022
8147
|
if (unchanged) {
|
|
8023
8148
|
filesProcessed += 1;
|
|
8024
8149
|
if (cb) {
|
|
@@ -8034,7 +8159,7 @@ async function parseAntigravityIncremental({
|
|
|
8034
8159
|
continue;
|
|
8035
8160
|
}
|
|
8036
8161
|
|
|
8037
|
-
const sameFile = prev && prev.inode === inode;
|
|
8162
|
+
const sameFile = !!prev && prev.inode === inode && !headChanged && !shrunk;
|
|
8038
8163
|
const lastLine = sameFile ? Number(prev.lastLine || 0) : 0;
|
|
8039
8164
|
const initialContextTokens = sameFile ? Number(prev.contextTokens || 0) : 0;
|
|
8040
8165
|
const initialPrevContext = sameFile ? Number(prev.previousContextTokens || 0) : 0;
|
|
@@ -8075,6 +8200,7 @@ async function parseAntigravityIncremental({
|
|
|
8075
8200
|
contextTokens: result.contextTokens,
|
|
8076
8201
|
previousContextTokens: result.previousContextTokens,
|
|
8077
8202
|
currentModel: result.currentModel,
|
|
8203
|
+
head: headSig,
|
|
8078
8204
|
updatedAt: new Date().toISOString(),
|
|
8079
8205
|
};
|
|
8080
8206
|
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import{c as ue,r as i,j as e,A as n,aw as We,l as Fe,C as He,X as Ie,aj as Ge,D as Oe}from"./main-BAdX_7hM.js";import{u as qe}from"./useCurrency-BnMdRysu.js";import{I as Ze}from"./info-CSAnLIAh.js";const Ke=[["path",{d:"M15 3h6v6",key:"1q9fwt"}],["path",{d:"m21 3-7 7",key:"1l2asr"}],["path",{d:"m3 21 7-7",key:"tjx5ai"}],["path",{d:"M9 21H3v-6",key:"wtvkvv"}]],Ve=ue("maximize-2",Ke);const Je=[["rect",{x:"14",y:"3",width:"5",height:"18",rx:"1",key:"kaeet6"}],["rect",{x:"5",y:"3",width:"5",height:"18",rx:"1",key:"1wsw3u"}]],Qe=ue("pause",Je);const et=[["path",{d:"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z",key:"10ikf1"}]],tt=ue("play",et);const at=[["path",{d:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",key:"1357e3"}],["path",{d:"M3 3v5h5",key:"1xhq8a"}]],rt=ue("rotate-ccw",at);const ot=[["path",{d:"M12 19h8",key:"baeox8"}],["path",{d:"m4 17 6-6-6-6",key:"1yngyt"}]],nt=ue("terminal",ot),Q={emerald:{light:["#ebedf0","#a7f3d0","#6ee7b7","#34d399","#10b981"],dark:["#2d333b","#065f46","#059669","#10b981","#34d399"],gridColor:{light:"rgba(16, 185, 129, 0.12)",dark:"rgba(52, 211, 153, 0.08)"}},ocean:{light:["#f1f5f9","#93c5fd","#60a5fa","#3b82f6","#1d4ed8"],dark:["#1e293b","#1e3a8a","#2563eb","#3b82f6","#60a5fa"],gridColor:{light:"rgba(59, 130, 246, 0.12)",dark:"rgba(96, 165, 250, 0.08)"}},neon:{light:["#faf5ff","#ebd5ff","#c084fc","#a855f7","#7e22ce"],dark:["#2e1065","#581c87","#8b5cf6","#a855f7","#c084fc"],gridColor:{light:"rgba(168, 85, 247, 0.12)",dark:"rgba(192, 132, 252, 0.08)"}},amber:{light:["#fffbeb","#fde68a","#f59e0b","#d97706","#b45309"],dark:["#451a03","#78350f","#b45309","#d97706","#f59e0b"],gridColor:{light:"rgba(245, 158, 11, 0.12)",dark:"rgba(245, 158, 11, 0.08)"}}};function st(l,x){const p=/^#([0-9a-f]{6})$/i.exec(l);if(!p)return l;const c=parseInt(p[1],16),z=c>>16&255,P=c>>8&255,$=c&255,S=E=>Math.max(0,Math.min(255,Math.round(E*x)));return`rgb(${S(z)}, ${S(P)}, ${S($)})`}function O(l,x,p,c,z){const P=Math.cos(c),$=Math.sin(c),S=l*P-x*$,E=l*$+x*P,L=p,_=Math.cos(z),m=Math.sin(z),N=S,ee=E*_-L*m,te=E*m+L*_;return{x:N,y:ee,z:te}}function lt(l,x,p,c,z){return O(l,x,p,c,z)}function Se(l,x){const p=Number(x).toLocaleString();if(l>=4){const c=Math.floor(Math.random()*3)+1;return n(`heatmap.3d.voxel.joke.${c}`,{value:p})}else return l===3?n("heatmap.3d.voxel.level3",{value:p}):l===2?n("heatmap.3d.voxel.level2",{value:p}):l===1?n("heatmap.3d.voxel.level1",{value:p}):n("heatmap.3d.voxel.level0")}function _e({weeks:l,palette:x="auto",isDark:p=!1,interactive:c=!1,autoRotateInit:z=!1,onResetViewRef:P=null}){const $=Q[x]||(x==="auto"?Q.emerald:null),S=$?p?$.dark:$.light:Array.isArray(x)?x:p?Q.emerald.dark:Q.emerald.light,E=$?p?$.gridColor.dark:$.gridColor.light:p?"rgba(255,255,255,0.06)":"rgba(0,0,0,0.06)",L=-.2,_=.88,[m,N]=i.useState({yaw:L,pitch:_}),[ee,te]=i.useState(z),[he,R]=i.useState(1),j=c?13:10.5,pe=i.useMemo(()=>{const t=[],r=l.length;if(r===0||!c)return[];for(let s=0;s<=7;s++){const o=(s-3.5)*j,d=O(-r/2*j,o,0,m.yaw,m.pitch),h=O(r/2*j,o,0,m.yaw,m.pitch);t.push({d:`M${d.x},${d.y} L${h.x},${h.y}`,key:`horiz-${s}`})}for(let s=0;s<=r;s+=4){const o=(s-r/2)*j,d=O(o,-3.5*j,0,m.yaw,m.pitch),h=O(o,3.5*j,0,m.yaw,m.pitch);t.push({d:`M${d.x},${d.y} L${h.x},${h.y}`,key:`vert-${s}`})}if(r%4!==0){const s=(r-r/2)*j,o=O(s,-3.5*j,0,m.yaw,m.pitch),d=O(s,3.5*j,0,m.yaw,m.pitch);t.push({d:`M${o.x},${o.y} L${d.x},${d.y}`,key:"vert-last"})}return t},[l.length,m,j,c]);i.useEffect(()=>{P&&(P.current={reset:()=>{N({yaw:L,pitch:_}),te(!1),R(1),ye()},toggleAutoRotate:t=>{te(t)}})},[P]);const q=i.useRef(null),F=i.useRef(null),W=i.useRef(!1),ie=i.useRef({x:0,y:0}),Z=i.useRef({yaw:L,pitch:_}),Y=i.useRef({x:0,y:0}),oe=i.useRef({x:0,y:0,time:0}),ne=i.useRef(null),[fe,ge]=i.useState(0),K=i.useRef(null),se=i.useRef(!0);i.useEffect(()=>(se.current=!0,()=>{se.current=!1}),[]);const ye=()=>{K.current&&cancelAnimationFrame(K.current),ge(0);const t=performance.now(),r=1200,s=o=>{if(!se.current)return;const d=o-t,h=Math.min(1,d/r),k=1-Math.pow(1-h,3);ge(k),h<1?K.current=requestAnimationFrame(s):K.current=null};K.current=requestAnimationFrame(s)};i.useEffect(()=>(ye(),()=>{K.current&&cancelAnimationFrame(K.current)}),[c]),i.useEffect(()=>{if(!ee||W.current||typeof window>"u"||typeof window.matchMedia=="function"&&window.matchMedia("(prefers-reduced-motion: reduce)").matches)return;let r;const s=()=>{if(typeof document<"u"&&document.visibilityState==="hidden"){r=requestAnimationFrame(s);return}N(o=>({yaw:o.yaw+.002,pitch:o.pitch})),r=requestAnimationFrame(s)};return r=requestAnimationFrame(s),()=>cancelAnimationFrame(r)},[ee]);const ce=(t,r)=>{c&&(W.current=!0,ie.current={x:t,y:r},Z.current={yaw:m.yaw,pitch:m.pitch},Y.current={x:0,y:0},oe.current={x:t,y:r,time:performance.now()},ne.current&&cancelAnimationFrame(ne.current))},U=(t,r)=>{if(!W.current)return;const s=t-ie.current.x,o=r-ie.current.y,d=performance.now(),h=d-oe.current.time;h>0&&(Y.current={x:(t-oe.current.x)/h,y:(r-oe.current.y)/h}),oe.current={x:t,y:r,time:d};const k=.005,f=Z.current.yaw-s*k,g=Math.PI/2.3,D=Math.max(-g,Math.min(g,Z.current.pitch-o*k));N({yaw:f,pitch:D})},be=()=>{if(!W.current)return;W.current=!1;let t=-Y.current.x*12,r=-Y.current.y*12;const s=.95,o=()=>{W.current||(t*=s,r*=s,!(Math.abs(t)<.01&&Math.abs(r)<.01)&&(N(d=>{const h=d.yaw+t*.005,k=Math.PI/2.3,f=Math.max(-k,Math.min(k,d.pitch+r*.005));return{yaw:h,pitch:f}}),ne.current=requestAnimationFrame(o)))};ne.current=requestAnimationFrame(o)},[b,de]=i.useState(null),[V,xe]=i.useState({x:0,y:0,shiftX:0}),y=i.useRef(null);i.useEffect(()=>()=>{y.current&&clearTimeout(y.current)},[]),i.useEffect(()=>{if(!c||!F.current)return;const t=s=>{s.preventDefault();const o=-s.deltaY*.0025;R(d=>{const h=d+o;return Math.max(.5,Math.min(3,h))})},r=F.current;return r.addEventListener("wheel",t,{passive:!1}),()=>{r.removeEventListener("wheel",t)}},[c]);const C=i.useMemo(()=>{const t=[];return l.forEach((r,s)=>{(Array.isArray(r)?r:[]).forEach((o,d)=>{o&&t.push({key:o.day||`${s}-${d}`,col:s,row:d,level:o.level||0,value:o.value||0,day:o.day,models:o.models||null})})}),t},[l]),ve=j-(c?1.8:1.5),ke=c?38:28,J=t=>Math.max(1.8,Number(t)/4*ke),ae=i.useMemo(()=>{if(C.length===0)return[];const t=l.length;return C.map(r=>{const s=J(r.level),o=Math.sqrt(Math.pow(r.col-t/2,2)+Math.pow(r.row-3.5,2)),d=Math.sqrt(Math.pow(t/2,2)+Math.pow(3.5,2)),h=o/d*.4,k=Math.min(1,Math.max(0,(fe-h)*(1/.6))),f=s*k,g=(r.col-t/2)*j,D=(r.row-3.5)*j,w=ve/2,H=[{x:g-w,y:D-w,z:0},{x:g+w,y:D-w,z:0},{x:g+w,y:D+w,z:0},{x:g-w,y:D+w,z:0},{x:g-w,y:D-w,z:f},{x:g+w,y:D-w,z:f},{x:g+w,y:D+w,z:f},{x:g-w,y:D+w,z:f}].map(B=>O(B.x,B.y,B.z,m.yaw,m.pitch)),me=O(g,D,f/2,m.yaw,m.pitch),Le=[{name:"top",indices:[4,5,6,7],scale:1,normal:[0,0,1]},{name:"bottom",indices:[3,2,1,0],scale:.4,normal:[0,0,-1]},{name:"left",indices:[3,0,4,7],scale:.55,normal:[-1,0,0]},{name:"right",indices:[1,2,6,5],scale:.75,normal:[1,0,0]},{name:"front",indices:[0,1,5,4],scale:.85,normal:[0,-1,0]},{name:"back",indices:[2,3,7,6],scale:.65,normal:[0,1,0]}],Ae=S[Math.min(4,Math.max(0,Number(r.level)||0))],Ne=[],Re=.35,De=-.4,Pe=.83;return Le.forEach(B=>{const we=lt(B.normal[0],B.normal[1],B.normal[2],m.yaw,m.pitch);if(we.z>.001){const Ce=H[B.indices[0]],ze=H[B.indices[1]],Me=H[B.indices[2]],Te=H[B.indices[3]],Ye=`M${Ce.x},${Ce.y} L${ze.x},${ze.y} L${Me.x},${Me.y} L${Te.x},${Te.y} Z`,Ue=we.x*Re+we.y*De+we.z*Pe,Xe=p?.18:0,Be=B.scale*(.82+.28*Math.max(0,Ue))+Xe;Ne.push({name:B.name,d:Ye,fill:st(Ae,Be)})}}),{...r,centerProj:me,renderedFaces:Ne}})},[C,m,S,l.length,fe,j,ve,ke]),le=i.useMemo(()=>[...ae].sort((t,r)=>t.centerProj.z-r.centerProj.z),[ae]),M=i.useMemo(()=>{if(le.length===0)return{minX:-100,minY:-100,maxX:100,maxY:100};let t=1/0,r=1/0,s=-1/0,o=-1/0;return le.forEach(d=>{const h=j*2,k=d.centerProj.x,f=d.centerProj.y;k-h<t&&(t=k-h),k+h>s&&(s=k+h),f-h<r&&(r=f-h),f+h>o&&(o=f+h)}),{minX:t,minY:r,maxX:s,maxY:o}},[le,j]),A=12,a=M.maxX-M.minX+A*2,u=M.maxY-M.minY+A*2,T=a/he,v=u/he,X=M.minX-A+(a-T)/2,I=M.minY-A+(u-v)/2,G=`${X} ${I} ${T} ${v}`;return C.length===0?e.jsx("div",{className:"py-8 text-center text-sm text-oai-gray-500",children:n("heatmap.empty")}):e.jsxs("div",{ref:F,className:`relative select-none outline-none ${c?"cursor-grab active:cursor-grabbing w-full h-full flex items-center justify-center":"w-full overflow-hidden flex justify-center"}`,onMouseDown:t=>{if(!c)return;ce(t.clientX,t.clientY);const r=o=>U(o.clientX,o.clientY),s=()=>{be(),window.removeEventListener("mousemove",r),window.removeEventListener("mouseup",s)};window.addEventListener("mousemove",r),window.addEventListener("mouseup",s)},onTouchStart:t=>{!c||t.touches.length===0||ce(t.touches[0].clientX,t.touches[0].clientY)},onTouchMove:t=>{!c||t.touches.length===0||U(t.touches[0].clientX,t.touches[0].clientY)},onTouchEnd:()=>{c&&be()},children:[e.jsxs("svg",{ref:q,viewBox:G,width:c?"95%":"100%",height:c?"95%":"auto",role:"img","aria-label":n("heatmap.iso.aria")||"3D interactive activity heatmap",style:{display:"block",width:"100%",height:"auto",maxWidth:c?"none":`${a}px`,maxHeight:c?"78vh":"none"},className:"transition-transform duration-300 ease-out",children:[c&&pe.map(t=>e.jsx("path",{d:t.d,fill:"none",stroke:E,strokeWidth:.25,strokeDasharray:"1.5 2.5",strokeLinecap:"round"},t.key)),le.map(t=>{const r=b&&b.key===t.key;return e.jsxs("g",{onMouseEnter:s=>{if(y.current&&(clearTimeout(y.current),y.current=null),de(t),c&&q.current){const o=O((t.col-l.length/2)*j,(t.row-3.5)*j,J(t.level),m.yaw,m.pitch);let d=0,h=0;const k=q.current;if(F.current&&typeof k.createSVGPoint=="function"&&typeof k.getScreenCTM=="function")try{const w=k.createSVGPoint();w.x=o.x,w.y=o.y;const re=k.getScreenCTM();if(re){const H=w.matrixTransform(re),me=F.current.getBoundingClientRect();d=H.x-me.left,h=H.y-me.top}}catch{const re=k.getBoundingClientRect(),H=M.maxX-M.minX+A*2,me=M.maxY-M.minY+A*2;d=(o.x-(M.minX-A))/H*re.width,h=(o.y-(M.minY-A))/me*re.height}else{const w=k.getBoundingClientRect(),re=M.maxX-M.minX+A*2,H=M.maxY-M.minY+A*2;d=(o.x-(M.minX-A))/re*w.width,h=(o.y-(M.minY-A))/H*w.height}const f=140;let g=0;const D=F.current?F.current.getBoundingClientRect().width:k.getBoundingClientRect().width;d<f?g=f-d:d>D-f&&(g=D-f-d),xe({x:d,y:h,shiftX:g})}},onMouseLeave:()=>{y.current&&clearTimeout(y.current),y.current=setTimeout(()=>{de(null)},150)},className:"transition-all duration-200",style:{filter:r?"brightness(1.15) drop-shadow(0 4px 6px rgba(0,0,0,0.15))":"none",cursor:c?"pointer":"default"},children:[!c&&t.day&&e.jsx("title",{children:`${t.day}: ${Number(t.value).toLocaleString()} tokens`}),t.renderedFaces.map((s,o)=>e.jsx("path",{d:s.d,fill:s.fill,stroke:s.fill,strokeWidth:.25,strokeLinejoin:"round"},o))]},t.key)})]}),c&&b&&e.jsxs("div",{onMouseEnter:()=>{y.current&&(clearTimeout(y.current),y.current=null)},onMouseLeave:()=>{y.current&&clearTimeout(y.current),y.current=setTimeout(()=>{de(null)},150)},className:"absolute z-[9999] w-0 h-0 transition-all duration-100 ease-out",style:{left:`${V.x}px`,top:`${V.y}px`},children:[e.jsxs("div",{className:"absolute left-0 bottom-[10px] backdrop-blur-md bg-white/90 dark:bg-oai-gray-900/90 border border-oai-gray-200/50 dark:border-oai-gray-800/50 shadow-xl rounded-xl p-3.5 max-w-[280px] min-w-[200px] flex flex-col gap-2 animate-in fade-in zoom-in-95 duration-100",style:{transform:`translateX(calc(-50% + ${V.shiftX}px))`},children:[e.jsxs("div",{className:"flex items-center justify-between border-b border-oai-gray-100 dark:border-oai-gray-800/80 pb-1.5",children:[e.jsx("span",{className:"text-[11px] font-semibold text-oai-gray-500 dark:text-oai-gray-400",children:b.day}),(()=>{const t=b.level===0?p?"#9ca3af":"#6b7280":S[b.level];return e.jsxs("span",{className:"text-[10px] px-2 py-0.5 rounded-full font-medium",style:{backgroundColor:t+"22",color:t,border:`1px solid ${t}44`},children:["Level ",b.level]})})()]}),e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-baseline gap-1",children:[e.jsx("span",{className:"text-lg font-bold text-oai-gray-900 dark:text-white leading-none",children:Number(b.value).toLocaleString()}),e.jsx("span",{className:"text-[10px] text-oai-gray-400 uppercase tracking-wider font-semibold",children:"Tokens"})]}),b.models&&Object.keys(b.models).length>0?e.jsxs("div",{className:"mt-1.5 border-t border-oai-gray-100 dark:border-oai-gray-800/60 pt-2 flex flex-col gap-1.5",children:[e.jsx("div",{className:"text-[10px] font-semibold text-oai-gray-400 dark:text-oai-gray-500 uppercase tracking-wider",children:"Model Breakdown"}),e.jsx("div",{className:"flex flex-col gap-2 max-h-[150px] overflow-y-auto pr-1.5 scrollbar-thin",children:Object.entries(b.models).map(([t,r])=>({name:t,val:Number(r)})).sort((t,r)=>r.val-t.val).map(({name:t,val:r})=>{const s=Number(b.value)||1,o=Math.round(r/s*100);return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex items-center justify-between text-[11px] gap-3",children:[e.jsx("span",{className:"font-medium text-oai-gray-750 dark:text-oai-gray-200 truncate max-w-[120px]",title:t,children:t}),e.jsxs("div",{className:"flex items-center gap-1.5 shrink-0",children:[e.jsx("span",{className:"font-mono text-oai-gray-900 dark:text-oai-gray-100 font-semibold",children:r.toLocaleString()}),e.jsxs("span",{className:"text-[9px] text-oai-gray-450 dark:text-oai-gray-500 min-w-[28px] text-right font-medium",children:[o,"%"]})]})]}),e.jsx("div",{className:"w-full h-1 bg-oai-gray-100 dark:bg-oai-gray-800/85 rounded-full overflow-hidden",children:e.jsx("div",{className:"h-full rounded-full transition-all duration-300",style:{width:`${o}%`,backgroundColor:S[4],boxShadow:`0 0 4px ${S[4]}55`}})})]},t)})})]}):e.jsx("p",{className:"text-[11px] text-oai-gray-600 dark:text-oai-gray-300 leading-relaxed font-normal mt-1 border-t border-dashed border-oai-gray-100 dark:border-oai-gray-800/60 pt-1.5",children:Se(b.level,b.value)})]})]}),e.jsx("div",{className:"absolute bottom-[6px] left-0 -translate-x-1/2 w-2.5 h-2.5 rotate-45 bg-white dark:bg-oai-gray-900 border-r border-b border-oai-gray-200/50 dark:border-oai-gray-800/50 shadow-sm",style:{marginBottom:"1px"}})]})]})}const it=12,ct=3,dt=26,mt=["#ebedf0","#f7d08a","#f2b757","#eca02f","#d9861a"],xt=["#30363d","#7a4711","#bf7015","#eca02f","#f7c877"];function $e(l){const x=Number(l);return Number.isFinite(x)?x<1e3?x.toLocaleString():Oe(x,{decimals:2}):"0"}function ut(l){if(typeof l!="string")return null;const x=/^(\d{4})-(\d{2})-(\d{2})$/.exec(l.trim());if(!x)return null;const p=new Date(Date.UTC(Number(x[1]),Number(x[2])-1,Number(x[3])));return Number.isFinite(p.getTime())?p:null}function Ee(l,x){return new Date(Date.UTC(l.getUTCFullYear(),l.getUTCMonth(),l.getUTCDate()+x))}function ht(l,x){return Math.floor((Date.UTC(x.getUTCFullYear(),x.getUTCMonth(),x.getUTCDate())-Date.UTC(l.getUTCFullYear(),l.getUTCMonth(),l.getUTCDate()))/864e5)}function pt(l,x){const p=x==="mon"?1:0,c=l.getUTCDay();return Ee(l,-((c-p+7)%7))}function ft(l,x,p,c){if(!l)return[];const z=ut(x)||new Date,P=[];for(let _=11;_>=0;_-=1)P.push(new Date(Date.UTC(z.getUTCFullYear(),z.getUTCMonth()-_,1)));const $=pt(z,p),S=Ee($,-(l-1)*7),E=[],L=new Set;for(const _ of P){const m=Math.floor(ht(S,_)/7);m<0||m>=l||L.has(m)||(L.add(m),E.push({label:c[_.getUTCMonth()],index:m}))}return E}function vt({heatmap:l,timeZoneLabel:x,timeZoneShortLabel:p,hideLegend:c=!1,embedded:z=!1}){const{resolvedTheme:P}=We(),{currency:$,rate:S}=qe(),E=P==="dark",L=E?xt:mt,_=i.useRef(null),m=i.useRef(null),[N,ee]=i.useState(null),[te,he]=i.useState({x:0,y:0,shiftX:0}),R=i.useRef(null);i.useEffect(()=>()=>{R.current&&clearTimeout(R.current)},[]);const[j,pe]=i.useState(!1),[q,F]=i.useState(!1),[W,ie]=i.useState(!1),Z=i.useRef(null),[Y,oe]=i.useState("amber"),ne=[n("heatmap.month.jan"),n("heatmap.month.feb"),n("heatmap.month.mar"),n("heatmap.month.apr"),n("heatmap.month.may"),n("heatmap.month.jun"),n("heatmap.month.jul"),n("heatmap.month.aug"),n("heatmap.month.sep"),n("heatmap.month.oct"),n("heatmap.month.nov"),n("heatmap.month.dec")],fe=(a,u)=>{if(!u||!u.day)return;R.current&&(clearTimeout(R.current),R.current=null),ee(u);const T=a.currentTarget.getBoundingClientRect(),v=typeof window<"u"?window.innerWidth:1024,X=T.left+T.width/2,I=T.top,G=140;let t=0;X<G?t=G-X:X>v-G&&(t=v-G-X),he({x:X,y:I,shiftX:t})},ge=()=>{R.current&&clearTimeout(R.current),R.current=setTimeout(()=>{ee(null)},150)},K=()=>{F(!1),pe(!0)},se=()=>{F(!0)},ye=a=>{a.target===a.currentTarget&&q&&(pe(!1),F(!1))};i.useEffect(()=>{if(!j||q)return;const a=u=>{u.key==="Escape"&&se()};return window.addEventListener("keydown",a),()=>{window.removeEventListener("keydown",a)}},[j,q]);const ce=i.useMemo(()=>({emerald:{accentText:"text-emerald-500 dark:text-emerald-400",accentBg:"bg-emerald-500/10 dark:bg-emerald-400/10",accentBorder:"border-emerald-500/20 dark:border-emerald-400/15",hoverBorder:"hover:border-emerald-500/30 dark:hover:border-emerald-400/30",hoverGlow:"hover:shadow-[0_0_20px_-3px_rgba(16,185,129,0.15)] hover:dark:shadow-[0_0_20px_-3px_rgba(52,211,153,0.25)]",rawColor:"#10b981"},ocean:{accentText:"text-blue-500 dark:text-blue-400",accentBg:"bg-blue-500/10 dark:bg-blue-400/10",accentBorder:"border-blue-500/20 dark:border-blue-400/15",hoverBorder:"hover:border-blue-500/30 dark:hover:border-blue-400/30",hoverGlow:"hover:shadow-[0_0_20px_-3px_rgba(59,130,246,0.15)] hover:dark:shadow-[0_0_20px_-3px_rgba(96,165,250,0.25)]",rawColor:"#3b82f6"},neon:{accentText:"text-purple-500 dark:text-purple-400",accentBg:"bg-purple-500/10 dark:bg-purple-400/10",accentBorder:"border-purple-500/20 dark:border-purple-400/15",hoverBorder:"hover:border-purple-500/30 dark:hover:border-purple-400/30",hoverGlow:"hover:shadow-[0_0_20px_-3px_rgba(168,85,247,0.15)] hover:dark:shadow-[0_0_20px_-3px_rgba(192,132,252,0.25)]",rawColor:"#a855f7"},amber:{accentText:"text-amber-500 dark:text-amber-400",accentBg:"bg-amber-500/10 dark:bg-amber-400/10",accentBorder:"border-amber-500/20 dark:border-amber-400/15",hoverBorder:"hover:border-amber-500/30 dark:hover:border-amber-400/30",hoverGlow:"hover:shadow-[0_0_20px_-3px_rgba(245,158,11,0.15)] hover:dark:shadow-[0_0_20px_-3px_rgba(245,158,11,0.25)]",rawColor:"#f59e0b"}}),[]),U=ce[Y]||ce.emerald,be=Q[Y]?E?Q[Y].dark:Q[Y].light:E?Q.emerald.dark:Q.emerald.light,[b,de]=i.useState(()=>{if(z)return"2d";try{return window.localStorage?.getItem("tt:heatmap-view")==="3d"?"3d":"2d"}catch{return"2d"}});i.useEffect(()=>{if(!z)try{window.localStorage?.setItem("tt:heatmap-view",b)}catch{}},[b,z]),i.useEffect(()=>{if(b!=="2d")return;const a=_.current;a&&(a.scrollLeft=a.scrollWidth)},[l?.weeks,b]),i.useEffect(()=>{const a=_.current;if(!a)return;const u=()=>{R.current&&(clearTimeout(R.current),R.current=null),ee(null)};return a.addEventListener("scroll",u),()=>a.removeEventListener("scroll",u)},[]);const V=l?.week_starts_on==="mon"?"mon":"sun",xe=i.useMemo(()=>{const a=Array.isArray(l?.weeks)?l.weeks:[];if(!a.length)return{weeks:[]};const u=[];for(const T of a)for(const v of Array.isArray(T)?T:[])v?.day&&u.push({day:v.day,total_tokens:v.total_tokens??v.value??0,billable_total_tokens:v.billable_total_tokens??v.value??v.total_tokens??0,models:v.models??null});return Fe({dailyRows:u,weeks:Math.max(52,a.length),to:l?.to,weekStartsOn:V})},[l?.to,l?.weeks,V]),y=xe?.weeks||[],C=i.useMemo(()=>{let a=0,u=0,T={day:"无数据",value:0},v=0,X=0;const I=[];y.forEach(f=>{(Array.isArray(f)?f:[]).forEach(g=>{g&&g.day&&I.push(g)})}),I.sort((f,g)=>f.day.localeCompare(g.day)),I.forEach(f=>{const g=Number(f.value)||0;a+=g,g>0?(u++,v++,v>X&&(X=v)):v=0,g>T.value&&(T={day:f.day,value:g})});const G=I.length||365,t=(u/G*100).toFixed(1);let r="heatmap.3d.modal.ai.eval.default",s="heatmap.3d.modal.ai.title.default";a>=15e6?(s="heatmap.3d.modal.ai.title.peak",r="heatmap.3d.modal.ai.eval.peak"):a>=5e6?(s="heatmap.3d.modal.ai.title.heavy",r="heatmap.3d.modal.ai.eval.heavy"):a>=1e6?(s="heatmap.3d.modal.ai.title.core",r="heatmap.3d.modal.ai.eval.core"):a>=2e4&&(s="heatmap.3d.modal.ai.title.steady",r="heatmap.3d.modal.ai.eval.steady");const o=l?.total_cost_usd,d=Number(o),k=o!=null&&(typeof o!="string"||o.trim()!=="")&&Number.isFinite(d)?d:a/15e5;return{totalTokens:a,activeDays:u,activeRate:t,maxSingleDay:T,maxStreak:X,aiEvaluationTitleKey:s,aiEvaluationKey:r,totalCostUsd:k}},[y,l?.total_cost_usd]),je=i.useMemo(()=>He(C.totalCostUsd,{currency:$,rate:S}),[C.totalCostUsd,$,S]),ve=V==="mon"?["Mon","Tue","Wed","Thu","Fri","Sat","Sun"].map(a=>n(`heatmap.day.${a.toLowerCase()}`)):["Sun","Mon","Tue","Wed","Thu","Fri","Sat"].map(a=>n(`heatmap.day.${a.toLowerCase()}`)),ke=i.useMemo(()=>ft(y.length,xe?.to,V,ne),[xe?.to,y.length,V,ne]);if(!y.length)return e.jsx("div",{className:"py-8 text-center text-sm text-oai-gray-500",children:n("heatmap.empty")});const J=z?10:it,ae=z?2:ct,le=z?22:dt,M=le+y.length*J+Math.max(0,y.length-1)*ae,A=`${le}px repeat(${y.length}, ${J}px)`;return e.jsxs("div",{ref:m,className:z?"relative":"relative rounded-xl border border-oai-gray-200 dark:border-oai-gray-800 bg-white dark:bg-oai-gray-900 p-5",children:[!z&&e.jsxs("div",{className:"flex items-baseline justify-between mb-3",children:[e.jsx("h3",{className:"text-sm font-medium text-oai-gray-500 dark:text-oai-gray-300 uppercase tracking-wide",children:n("heatmap.title")}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("div",{role:"tablist","aria-label":"Heatmap view",className:"flex rounded-md border border-oai-gray-200 dark:border-oai-gray-800 p-0.5 text-[10px]",children:[e.jsx("button",{type:"button",role:"tab","aria-selected":b==="2d",onClick:()=>de("2d"),className:b==="2d"?"px-2 py-0.5 rounded bg-oai-gray-100 text-oai-black dark:bg-oai-gray-800 dark:text-oai-white font-medium":"px-2 py-0.5 rounded text-oai-gray-500 dark:text-oai-gray-400 hover:text-oai-gray-700 dark:hover:text-oai-gray-200",children:n("heatmap.view.2d")}),e.jsx("button",{type:"button",role:"tab","aria-selected":b==="3d",onClick:()=>de("3d"),className:b==="3d"?"px-2 py-0.5 rounded bg-oai-gray-100 text-oai-black dark:bg-oai-gray-800 dark:text-oai-white font-medium":"px-2 py-0.5 rounded text-oai-gray-500 dark:text-oai-gray-400 hover:text-oai-gray-700 dark:hover:text-oai-gray-200",children:n("heatmap.view.3d")})]}),e.jsx("span",{className:"text-xs text-oai-gray-400 dark:text-oai-gray-450",children:p||n("heatmap.legend.utc")})]})]}),b==="3d"&&e.jsxs("div",{onClick:K,className:"cursor-pointer group relative overflow-hidden rounded-lg hover:border-oai-gray-350 dark:hover:border-oai-gray-700 border border-transparent transition-all",title:n("heatmap.3d.hover_tip"),children:[e.jsx(_e,{weeks:y,isDark:E,palette:Y}),e.jsx("div",{className:"absolute inset-0 bg-gradient-to-t from-oai-gray-900/5 to-transparent pointer-events-none opacity-0 group-hover:opacity-100 transition-opacity flex items-end justify-center pb-2",children:e.jsxs("span",{className:"text-[10px] bg-white/95 dark:bg-oai-gray-900/95 shadow border border-oai-gray-200/60 dark:border-oai-gray-800/80 px-2.5 py-1 rounded-full font-medium text-oai-gray-500 dark:text-oai-gray-400 flex items-center gap-1 transform translate-y-2 group-hover:translate-y-0 transition-transform duration-200",children:[e.jsx(Ve,{size:9}),n("heatmap.3d.hover_tip")]})})]}),b==="2d"&&e.jsx("div",{ref:_,className:"overflow-x-auto overflow-y-hidden heatmap-scroll-thin",children:e.jsxs("div",{style:{minWidth:M},children:[e.jsxs("div",{className:"grid text-[10px] uppercase text-oai-gray-400 dark:text-oai-gray-400 mb-1",style:{gridTemplateColumns:A,columnGap:ae},children:[e.jsx("span",{}),ke.map(a=>e.jsx("span",{style:{gridColumnStart:a.index+2},className:"whitespace-nowrap",children:a.label},`${a.label}-${a.index}`))]}),e.jsxs("div",{className:"grid",style:{gridTemplateColumns:A,columnGap:ae},children:[e.jsx("div",{className:"grid text-[10px] text-oai-gray-400 dark:text-oai-gray-400 sticky left-0 bg-white dark:bg-oai-gray-900 pr-2",style:{gridTemplateRows:`repeat(7, ${J}px)`,rowGap:ae},children:ve.map(a=>e.jsx("span",{className:"leading-none",children:a},a))}),e.jsx("div",{className:"grid",style:{gridAutoFlow:"column",gridTemplateRows:`repeat(7, ${J}px)`,gap:ae},children:y.map((a,u)=>(Array.isArray(a)?a:[]).map((T,v)=>{if(!T)return null;const X=T.day||`e-${u}-${v}`,I=Number(T.level)||0,G=L[I]||L[0];return e.jsx("span",{onMouseEnter:t=>fe(t,T),onMouseLeave:ge,className:"rounded-[2px] transition-transform hover:scale-125 hover:z-10 cursor-pointer",style:{width:J,height:J,background:G}},X)}))})]})]})}),!c&&e.jsxs("div",{className:"flex items-center justify-center gap-2 mt-3",children:[e.jsx("span",{className:"text-[10px] text-oai-gray-400 dark:text-oai-gray-400",children:n("heatmap.legend.less")}),e.jsx("div",{className:"flex gap-0.5",children:L.map((a,u)=>e.jsx("span",{className:"rounded-[1px]",style:{width:10,height:10,background:a}},u))}),e.jsx("span",{className:"text-[10px] text-oai-gray-400 dark:text-oai-gray-400",children:n("heatmap.legend.more")})]}),j&&e.jsx("div",{onAnimationEnd:ye,onClick:a=>{a.target===a.currentTarget&&se()},className:`fixed inset-0 z-50 flex items-center justify-center p-3 md:p-6 backdrop-blur-md bg-black/15 dark:bg-black/40 ${q?"animate-tt-fade-out":"animate-tt-fade-in"}`,children:e.jsxs("div",{className:`relative w-full max-w-6xl h-[88vh] backdrop-blur-2xl bg-white/90 dark:bg-oai-gray-900/90 border border-oai-gray-200/50 dark:border-white/10 shadow-2xl rounded-2xl flex flex-col md:flex-row overflow-hidden ${q?"animate-tt-modal-exit":"animate-tt-modal"}`,children:[e.jsx("button",{type:"button",onClick:se,className:"absolute top-4 right-4 z-50 p-2 rounded-full border border-oai-gray-200/60 dark:border-oai-gray-800/60 bg-white/50 dark:bg-oai-gray-900/50 text-oai-gray-500 dark:text-oai-gray-400 hover:text-oai-gray-900 dark:hover:text-white hover:rotate-90 hover:scale-105 active:scale-95 transition-all duration-300",children:e.jsx(Ie,{size:16})}),e.jsxs("div",{className:"w-full md:w-[340px] border-b md:border-b-0 md:border-r border-zinc-200/50 dark:border-zinc-800/40 p-5 md:p-6 flex flex-col gap-6 overflow-y-auto backdrop-blur-md bg-zinc-50/50 dark:bg-zinc-950/50",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-1.5 select-none",children:[e.jsxs("span",{className:"relative flex h-1.5 w-1.5",children:[e.jsx("span",{className:"animate-ping absolute inline-flex h-full w-full rounded-full opacity-75",style:{backgroundColor:U.rawColor}}),e.jsx("span",{className:"relative inline-flex rounded-full h-1.5 w-1.5",style:{backgroundColor:U.rawColor}})]}),e.jsx("span",{className:"text-[9px] font-extrabold uppercase tracking-widest font-mono text-zinc-400 dark:text-zinc-500",children:"3D Insight"})]}),e.jsx("h4",{className:"text-xl font-black text-zinc-900 dark:text-zinc-50 tracking-tight leading-none mt-2 select-none",children:n("heatmap.3d.modal.title")}),e.jsx("p",{className:"text-[11px] leading-relaxed text-zinc-400 dark:text-zinc-500 mt-2 font-normal select-none",children:n("heatmap.3d.modal.desc")})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-x-5 gap-y-5 border-y border-zinc-200/50 dark:border-zinc-800/50 py-5 select-none",children:[e.jsxs("div",{className:"flex flex-col gap-1 relative group cursor-help",children:[e.jsx("div",{className:"absolute left-0 bottom-full mb-2 pointer-events-none opacity-0 translate-y-1 group-hover:opacity-100 group-hover:translate-y-0 transition-all duration-200 z-50",children:e.jsxs("div",{className:"bg-white dark:bg-zinc-950 text-zinc-900 dark:text-zinc-50 text-[10px] font-semibold font-mono rounded-lg px-2.5 py-1.5 shadow-xl border border-zinc-200 dark:border-zinc-800/80 whitespace-nowrap flex flex-col",children:[e.jsx("span",{className:"text-[9px] text-zinc-400 dark:text-zinc-500",children:n("heatmap.3d.modal.stats.precision_total_tokens")}),e.jsxs("span",{className:"mt-0.5 font-bold text-zinc-900 dark:text-zinc-50",children:[C.totalTokens.toLocaleString()," Tokens"]})]})}),e.jsx("span",{className:"text-[9px] font-bold text-zinc-400 dark:text-zinc-500 uppercase tracking-widest font-mono",children:n("heatmap.3d.modal.stats.total_tokens")}),e.jsxs("div",{className:"flex items-baseline gap-1.5",children:[e.jsx("span",{className:"text-xl font-black text-zinc-900 dark:text-zinc-50 tracking-tight font-mono transition-transform duration-200 group-hover:-translate-y-[1px]",children:$e(C.totalTokens)}),e.jsx("div",{className:"opacity-30 group-hover:opacity-60 transition-opacity",children:e.jsx("svg",{width:"24",height:"10",viewBox:"0 0 24 10",fill:"none",children:e.jsx("path",{d:"M1 9C3 7 5 7 7 4C9 1 11 0 13 2C15 4 17 0 23 0",stroke:U.rawColor,strokeWidth:"1.2",strokeLinecap:"round",strokeLinejoin:"round"})})})]})]}),e.jsxs("div",{className:"flex flex-col gap-1 group cursor-default",children:[e.jsx("span",{className:"text-[9px] font-bold text-zinc-400 dark:text-zinc-500 uppercase tracking-widest font-mono",children:n("heatmap.3d.modal.stats.estimated_cost")}),e.jsx("span",{className:"text-xl font-black text-zinc-900 dark:text-zinc-50 tracking-tight font-mono transition-transform duration-200 group-hover:-translate-y-[1px]",children:je})]}),e.jsxs("div",{className:"flex flex-col gap-1 group cursor-default",children:[e.jsx("span",{className:"text-[9px] font-bold text-zinc-400 dark:text-zinc-500 uppercase tracking-widest font-mono",children:n("heatmap.3d.modal.stats.active_rate_days")}),e.jsxs("span",{className:"text-xl font-black text-zinc-900 dark:text-zinc-50 tracking-tight font-mono transition-transform duration-200 group-hover:-translate-y-[1px]",children:[C.activeRate,"% ",e.jsxs("span",{className:"text-[10px] font-bold text-zinc-400 dark:text-zinc-500 font-mono",children:["(",C.activeDays,"D)"]})]})]}),e.jsxs("div",{className:"flex flex-col gap-1 group cursor-default",children:[e.jsx("span",{className:"text-[9px] font-bold text-zinc-400 dark:text-zinc-500 uppercase tracking-widest font-mono",children:n("heatmap.3d.modal.stats.max_streak")}),e.jsxs("span",{className:"text-xl font-black text-amber-500 tracking-tight font-mono transition-transform duration-200 group-hover:-translate-y-[1px]",children:[C.maxStreak," ",e.jsx("span",{className:"text-[10px] font-bold text-amber-500/80 font-mono",children:n("heatmap.3d.modal.stats.days_suffix")})]})]}),e.jsxs("div",{className:"flex flex-col gap-1 col-span-2 relative group cursor-help",children:[e.jsx("div",{className:"absolute left-0 bottom-full mb-2 pointer-events-none opacity-0 translate-y-1 group-hover:opacity-100 group-hover:translate-y-0 transition-all duration-200 z-50",children:e.jsxs("div",{className:"bg-white dark:bg-zinc-950 text-zinc-900 dark:text-zinc-50 text-[10px] font-semibold font-mono rounded-lg px-2.5 py-1.5 shadow-xl border border-zinc-200 dark:border-zinc-800/80 whitespace-nowrap flex flex-col",children:[e.jsx("span",{className:"text-[9px] text-zinc-400 dark:text-zinc-500",children:n("heatmap.3d.modal.stats.precision_peak_value")}),e.jsxs("span",{className:"mt-0.5 font-bold text-zinc-900 dark:text-zinc-50",children:[C.maxSingleDay.value>0?C.maxSingleDay.value.toLocaleString():n("heatmap.3d.modal.stats.no_data")," Tokens"]}),e.jsx("span",{className:"text-[8px] text-zinc-400 dark:text-zinc-500 mt-0.5",children:C.maxSingleDay.day!=="无数据"?C.maxSingleDay.day:n("heatmap.3d.modal.stats.no_data")})]})}),e.jsx("span",{className:"text-[9px] font-bold text-zinc-400 dark:text-zinc-500 uppercase tracking-widest font-mono",children:n("heatmap.3d.modal.stats.peak_day")}),e.jsxs("span",{className:"text-xl font-black text-zinc-900 dark:text-zinc-50 tracking-tight font-mono transition-transform duration-200 group-hover:-translate-y-[1px]",children:[C.maxSingleDay.value>0?$e(C.maxSingleDay.value):n("heatmap.3d.modal.stats.no_data")," ",e.jsxs("span",{className:"text-[10px] font-bold text-zinc-400 dark:text-zinc-500 font-mono",children:["(",C.maxSingleDay.day!=="无数据"?C.maxSingleDay.day:n("heatmap.3d.modal.stats.no_data"),")"]})]})]})]}),e.jsxs("div",{className:"flex flex-col gap-2.5 py-1",children:[e.jsxs("div",{className:"flex items-center gap-1.5 select-none",children:[e.jsx(nt,{size:11,style:{color:U.rawColor}}),e.jsx("span",{className:"text-[9px] font-extrabold uppercase tracking-widest font-mono",style:{color:U.rawColor},children:n(C.aiEvaluationTitleKey)})]}),e.jsxs("div",{className:"pl-3.5 border-l-2 relative transition-all duration-300 group",style:{borderColor:U.rawColor},children:[e.jsx("div",{className:"absolute inset-y-0 left-0 w-[3px] blur-[2px] opacity-15 pointer-events-none rounded-full",style:{backgroundColor:U.rawColor}}),e.jsx("p",{className:"text-[11px] leading-relaxed text-zinc-600 dark:text-zinc-400 font-normal",children:n(C.aiEvaluationKey)})]})]}),e.jsx("div",{className:"mt-auto border-t border-zinc-200/50 dark:border-zinc-800/50 pt-4 select-none",children:e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-[9px] font-bold text-zinc-400 dark:text-zinc-500 uppercase tracking-widest font-mono",children:n("heatmap.3d.modal.legend.title")}),e.jsx("span",{className:"text-[10px] font-medium text-zinc-500 dark:text-zinc-400",children:n(`heatmap.3d.modal.palette.${Y}`)})]}),e.jsx("div",{className:"flex gap-1",children:be.map((a,u)=>e.jsx("div",{className:"flex-1 h-1 rounded-[2px]",style:{backgroundColor:a},title:`Level ${u}`},u))})]})})]}),e.jsxs("div",{className:"flex-1 h-full relative flex items-center justify-center overflow-hidden p-4",children:[e.jsx("div",{className:"absolute top-1/4 left-1/3 w-96 h-96 rounded-full blur-[130px] pointer-events-none -translate-x-1/2 -translate-y-1/2 transition-all duration-500",style:{backgroundColor:U.rawColor+"15"}}),e.jsx("div",{className:"absolute bottom-1/4 right-1/3 w-80 h-80 rounded-full blur-[120px] pointer-events-none translate-x-1/2 translate-y-1/2 bg-purple-500/[0.04] dark:bg-purple-500/[0.08]"}),e.jsxs("div",{className:"absolute top-4 left-1/2 -translate-x-1/2 flex items-center gap-3 p-1.5 backdrop-blur-md bg-white/70 dark:bg-oai-gray-900/75 border border-oai-gray-200/60 dark:border-oai-gray-800/80 rounded-full shadow-lg z-30 select-none",children:[e.jsx("div",{className:"flex items-center gap-1.5 px-2",children:Object.keys(ce).map(a=>{const u=Y===a;return e.jsx("button",{type:"button",onClick:()=>oe(a),title:n(`heatmap.3d.modal.palette.${a}`),className:`w-3.5 h-3.5 rounded-full transition-all duration-200 relative hover:scale-125 ${a==="emerald"?"bg-[#10b981]":a==="ocean"?"bg-[#3b82f6]":a==="neon"?"bg-[#a855f7]":"bg-[#f59e0b]"}`,children:u&&e.jsx("span",{className:"absolute inset-0 rounded-full ring-2 ring-offset-1 ring-offset-white dark:ring-offset-oai-gray-900 ring-oai-gray-900 dark:ring-white scale-110"})},a)})}),e.jsx("div",{className:"w-[1px] h-4 bg-oai-gray-200 dark:bg-oai-gray-800"}),e.jsxs("div",{className:"flex items-center gap-1 pr-1",children:[e.jsx("button",{type:"button",onClick:()=>{const a=!W;ie(a),Z.current&&Z.current.toggleAutoRotate(a)},title:W?n("heatmap.3d.modal.control.pause"):n("heatmap.3d.modal.control.play"),className:`p-1.5 rounded-full transition-all duration-200 hover:bg-oai-gray-100 dark:hover:bg-oai-gray-800 ${W?U.accentText:"text-oai-gray-400 hover:text-oai-gray-600 dark:hover:text-oai-gray-250"}`,children:W?e.jsx(Qe,{size:12}):e.jsx(tt,{size:12})}),e.jsx("button",{type:"button",onClick:()=>{ie(!1),Z.current&&Z.current.reset()},title:n("heatmap.3d.modal.control.reset"),className:"p-1.5 rounded-full text-oai-gray-400 hover:text-oai-gray-600 dark:hover:text-oai-gray-250 hover:bg-oai-gray-100 dark:hover:bg-oai-gray-800 transition-all duration-200",children:e.jsx(rt,{size:12})})]})]}),e.jsx(_e,{weeks:y,isDark:E,interactive:!0,palette:Y,autoRotateInit:W,onResetViewRef:Z}),e.jsxs("div",{className:"absolute bottom-4 right-4 flex items-center gap-1.5 text-[9px] font-bold text-oai-gray-400 bg-white/80 dark:bg-oai-gray-900/80 border border-oai-gray-200/50 dark:border-oai-gray-800/80 rounded-md px-2.5 py-1.5 select-none pointer-events-none backdrop-blur-md shadow-sm",children:[e.jsx(Ze,{size:10,className:U.accentText}),e.jsx("span",{children:n("heatmap.3d.modal.footer.tip")})]})]})]})}),N&&!j&&typeof document<"u"&&Ge.createPortal(e.jsxs("div",{className:"fixed z-[9999] w-0 h-0 transition-all duration-100 ease-out pointer-events-none",style:{left:`${te.x}px`,top:`${te.y}px`},children:[e.jsxs("div",{className:"absolute left-0 bottom-[10px] backdrop-blur-md bg-white/95 dark:bg-oai-gray-900/95 border border-oai-gray-200/50 dark:border-oai-gray-800/50 shadow-xl rounded-xl p-3.5 max-w-[280px] min-w-[200px] flex flex-col gap-2 animate-in fade-in zoom-in-95 duration-100",style:{transform:`translateX(calc(-50% + ${te.shiftX}px))`},children:[e.jsxs("div",{className:"flex items-center justify-between border-b border-oai-gray-100 dark:border-oai-gray-800/80 pb-1.5",children:[e.jsx("span",{className:"text-[11px] font-semibold text-oai-gray-500 dark:text-oai-gray-400",children:N.day}),(()=>{const a=N.level===0?E?"#9ca3af":"#6b7280":L[N.level];return e.jsxs("span",{className:"text-[10px] px-2 py-0.5 rounded-full font-medium",style:{backgroundColor:a+"22",color:a,border:`1px solid ${a}44`},children:["Level ",N.level]})})()]}),e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-baseline gap-1",children:[e.jsx("span",{className:"text-lg font-bold text-oai-gray-900 dark:text-white leading-none",children:Number(N.total_tokens??N.value).toLocaleString()}),e.jsx("span",{className:"text-[10px] text-oai-gray-400 uppercase tracking-wider font-semibold",children:"Tokens"})]}),N.models&&Object.keys(N.models).length>0?e.jsxs("div",{className:"mt-1.5 border-t border-oai-gray-100 dark:border-oai-gray-800/60 pt-2 flex flex-col gap-1.5",children:[e.jsx("div",{className:"text-[10px] font-semibold text-oai-gray-400 dark:text-oai-gray-500 uppercase tracking-wider",children:"Model Breakdown"}),e.jsx("div",{className:"flex flex-col gap-2 max-h-[150px] overflow-y-auto pr-1.5 oai-scrollbar",children:Object.entries(N.models).map(([a,u])=>({name:a,val:Number(u)})).sort((a,u)=>u.val-a.val).map(({name:a,val:u})=>{const T=Number(N.total_tokens??N.value)||1,v=Math.round(u/T*100);return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex items-center justify-between text-[11px] gap-3",children:[e.jsx("span",{className:"font-medium text-oai-gray-750 dark:text-oai-gray-200 truncate max-w-[120px]",title:a,children:a}),e.jsxs("div",{className:"flex items-center gap-1.5 shrink-0",children:[e.jsx("span",{className:"font-mono text-oai-gray-900 dark:text-oai-gray-100 font-semibold",children:u.toLocaleString()}),e.jsxs("span",{className:"text-[9px] text-oai-gray-450 dark:text-oai-gray-500 min-w-[28px] text-right font-medium",children:[v,"%"]})]})]}),e.jsx("div",{className:"w-full h-1 bg-oai-gray-100 dark:bg-oai-gray-800/85 rounded-full overflow-hidden",children:e.jsx("div",{className:"h-full rounded-full transition-all duration-300",style:{width:`${v}%`,backgroundColor:L[4],boxShadow:`0 0 4px ${L[4]}55`}})})]},a)})})]}):e.jsx("p",{className:"text-[11px] text-oai-gray-600 dark:text-oai-gray-300 leading-relaxed font-normal mt-1 border-t border-dashed border-oai-gray-100 dark:border-oai-gray-800/60 pt-1.5",children:Se(N.level,N.total_tokens??N.value)})]})]}),e.jsx("div",{className:"absolute bottom-[6px] left-0 -translate-x-1/2 w-2.5 h-2.5 rotate-45 bg-white dark:bg-oai-gray-900 border-r border-b border-oai-gray-200/50 dark:border-oai-gray-800/50 shadow-sm",style:{marginBottom:"1px"}})]}),document.body),e.jsx("style",{children:`
|
|
2
|
-
@keyframes tt-fade-in {
|
|
3
|
-
from { opacity: 0; }
|
|
4
|
-
to { opacity: 1; }
|
|
5
|
-
}
|
|
6
|
-
@keyframes tt-fade-out {
|
|
7
|
-
from { opacity: 1; }
|
|
8
|
-
to { opacity: 0; }
|
|
9
|
-
}
|
|
10
|
-
@keyframes tt-modal-entrance {
|
|
11
|
-
from {
|
|
12
|
-
opacity: 0;
|
|
13
|
-
transform: scale(0.96) translateY(10px);
|
|
14
|
-
}
|
|
15
|
-
to {
|
|
16
|
-
opacity: 1;
|
|
17
|
-
transform: scale(1) translateY(0);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
@keyframes tt-modal-exit {
|
|
21
|
-
from {
|
|
22
|
-
opacity: 1;
|
|
23
|
-
transform: scale(1) translateY(0);
|
|
24
|
-
}
|
|
25
|
-
to {
|
|
26
|
-
opacity: 0;
|
|
27
|
-
transform: scale(0.96) translateY(10px);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
.animate-tt-fade-in {
|
|
31
|
-
animation: tt-fade-in 0.2s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
|
32
|
-
}
|
|
33
|
-
.animate-tt-fade-out {
|
|
34
|
-
animation: tt-fade-out 0.2s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
|
35
|
-
}
|
|
36
|
-
.animate-tt-modal {
|
|
37
|
-
animation: tt-modal-entrance 0.3s cubic-bezier(0.34, 1.3, 0.64, 1) forwards;
|
|
38
|
-
}
|
|
39
|
-
.animate-tt-modal-exit {
|
|
40
|
-
animation: tt-modal-exit 0.2s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
|
41
|
-
}
|
|
42
|
-
`})]})}export{vt as A,Ve as M,nt as T};
|