@kenz1117/dsh-ui-usage-billing 0.9.4 → 0.9.6

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
@@ -24,7 +24,7 @@ window.__ModuleLoader__.load({
24
24
  }
25
25
  //#endregion
26
26
  //#region \0dsh-css:/Users/ken/deepseek-harness/packages/client/ui-usage-billing/src/client/UsageBilling.module.css.mjs
27
- const css = ".VWh0dG_railButton{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);width:36px;height:36px;color:var(--dsw-alias-label-secondary);cursor:pointer;border-radius:8px;flex:none;justify-content:center;align-items:center;padding:0;transition:border-color .16s,color .16s;display:flex}.VWh0dG_railButton:hover,.VWh0dG_railButton:focus-visible{border-color:var(--dsw-static-blue-500);color:var(--dsw-static-blue-500);outline:none}.VWh0dG_railButton svg{stroke-width:2px;width:18px;height:18px}.VWh0dG_trigger{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);width:100%;min-width:0;color:var(--dsw-alias-label-primary);cursor:pointer;text-align:left;border-radius:12px;align-items:center;gap:10px;padding:9px 12px;transition:border-color .16s,background-color .16s;display:flex;position:relative;overflow:hidden}.VWh0dG_trigger:hover,.VWh0dG_trigger:focus-visible{border-color:var(--dsw-static-blue-500);outline:none}.VWh0dG_triggerIcon{background:linear-gradient(135deg, var(--dsw-static-blue-500), var(--dsw-static-blue-400));width:30px;height:30px;color:var(--dsw-static-neutral-bluish-00);box-shadow:0 2px 8px -2px color-mix(in srgb, var(--dsw-static-blue-500) 55%, transparent);border-radius:10px;flex:none;justify-content:center;align-items:center;display:inline-flex}.VWh0dG_triggerIcon svg{stroke-width:2px;width:16px;height:16px}.VWh0dG_triggerBody{flex-direction:column;flex:1;gap:1px;min-width:0;display:flex}.VWh0dG_triggerRow{align-items:baseline;gap:5px;min-width:0;display:inline-flex}.VWh0dG_triggerAmount{color:var(--dsw-alias-label-primary);letter-spacing:-.02em;font-variant-numeric:tabular-nums;white-space:nowrap;font-size:16px;font-weight:700;line-height:20px}.VWh0dG_triggerSub{color:var(--dsw-alias-label-tertiary);white-space:nowrap;text-overflow:ellipsis;font-size:10px;line-height:14px;overflow:hidden}.VWh0dG_triggerMeta{color:var(--dsw-alias-label-tertiary);white-space:nowrap;letter-spacing:.02em;text-transform:uppercase;font-size:9.5px;font-weight:600;line-height:12px}.VWh0dG_triggerSpark{flex:none;align-items:flex-end;gap:2px;height:20px;display:flex}.VWh0dG_triggerSparkBar,.VWh0dG_triggerSparkHot{background:var(--dsw-static-blue-500);opacity:.6;border-radius:1px 1px 0 0;width:3px}.VWh0dG_triggerSparkHot{opacity:1}.VWh0dG_triggerWrap{flex:auto;width:100%;min-width:0;display:block;position:relative}.VWh0dG_triggerPop{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);box-shadow:var(--dsw-shadow-lv2);opacity:0;pointer-events:none;z-index:10;border-radius:10px;flex-direction:column;gap:6px;padding:12px 14px;transition:opacity .16s,transform .16s;display:flex;position:absolute;bottom:calc(100% + 8px);left:0;right:0;transform:translateY(4px)}.VWh0dG_triggerWrap:hover .VWh0dG_triggerPop,.VWh0dG_triggerWrap:focus-within .VWh0dG_triggerPop{opacity:1;transform:translateY(0)}.VWh0dG_triggerPopRow{justify-content:space-between;align-items:baseline;gap:12px;display:flex}.VWh0dG_triggerPopLabel{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px}.VWh0dG_triggerPopValue{color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;font-size:13px;font-weight:600;line-height:18px}.VWh0dG_triggerPopBars{border-top:1px solid var(--dsw-alias-border-l1);align-items:flex-end;gap:4px;height:22px;margin-top:4px;padding-top:8px;display:flex}.VWh0dG_triggerPopBar{background:var(--dsw-static-blue-500);border-radius:2px;flex:1;transition:height .2s}.VWh0dG_dashboardModal{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);width:min(760px,100vw - 48px);max-height:min(760px,88vh);box-shadow:var(--dsw-shadow-lv3);animation:.18s ease-out VWh0dG_dashboardIn}@keyframes VWh0dG_dashboardIn{0%{opacity:0;transform:translateY(8px)scale(.98)}to{opacity:1;transform:none}}div[role=presentation]:has(>.dsh-billing-modal)>div[aria-hidden=true]:first-child{backdrop-filter:blur(8px)saturate(1.25)}.VWh0dG_dashboard{flex-direction:column;width:100%;max-height:min(760px,88vh);display:flex}.VWh0dG_dashboardHead{border-bottom:1px solid var(--dsw-alias-border-l1);justify-content:space-between;align-items:flex-start;gap:12px;padding:20px 24px 14px;display:flex}.VWh0dG_dashboardTitle{color:var(--dsw-alias-label-primary);margin:0;font-size:17px;font-weight:600;line-height:24px}.VWh0dG_dashboardSubtitle{color:var(--dsw-alias-label-caption);margin:3px 0 0;font-size:12px;line-height:17px}.VWh0dG_closeButton{width:30px;height:30px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:8px;flex:none;justify-content:center;align-items:center;transition:background-color .14s;display:inline-flex}.VWh0dG_closeButton:hover{background:var(--dsw-alias-interactive-bg-hover)}.VWh0dG_closeButton svg{stroke-width:2px;width:16px;height:16px}.VWh0dG_dashboardBody{flex-direction:column;gap:14px;padding:16px 24px 24px;display:flex;overflow-y:auto}.VWh0dG_tabNav{border-bottom:1px solid var(--dsw-alias-border-l1);align-items:center;gap:4px;padding:10px 24px;display:flex}.VWh0dG_tabButton{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:999px;padding:5px 14px;font-size:12.5px;font-weight:500;line-height:18px;transition:background-color .16s,color .16s,box-shadow .16s}.VWh0dG_tabButton:hover,.VWh0dG_tabButton:focus-visible{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover);outline:none}.VWh0dG_tabButtonActive,.VWh0dG_tabButtonActive:hover,.VWh0dG_tabButtonActive:focus-visible{background:var(--dsw-static-blue-500);color:var(--dsw-static-neutral-bluish-00);font-weight:600}.VWh0dG_tabPanel{flex-direction:column;gap:14px;animation:.14s ease-out VWh0dG_tabPanelIn;display:flex}@keyframes VWh0dG_tabPanelIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}.VWh0dG_hero{border:1px solid var(--dsw-alias-border-l1);background:linear-gradient(180deg, var(--dsw-alias-bg-layer-2), var(--dsw-alias-bg-layer-1));box-shadow:inset 0 1px 0 color-mix(in srgb, var(--dsw-static-neutral-bluish-00) 30%, transparent);border-radius:16px;flex-direction:column;gap:18px;padding:22px 24px;display:flex;position:relative;overflow:hidden}.VWh0dG_heroTop{justify-content:space-between;align-items:center;gap:24px;display:flex}.VWh0dG_heroMain{flex-direction:column;gap:2px;min-width:0;display:flex}.VWh0dG_heroLabel{color:var(--dsw-alias-label-tertiary);text-transform:uppercase;letter-spacing:.08em;white-space:nowrap;font-size:11px;line-height:16px}.VWh0dG_heroReadout{align-items:baseline;gap:4px;display:flex}.VWh0dG_heroCurrency{letter-spacing:-.01em;color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;font-size:20px;font-weight:600;line-height:30px}.VWh0dG_heroValue{letter-spacing:-.03em;font-variant-numeric:tabular-nums;white-space:nowrap;color:var(--dsw-alias-label-primary);font-size:56px;font-weight:700;line-height:64px}.VWh0dG_heroMeta{color:var(--dsw-alias-label-caption);white-space:nowrap;margin-top:4px;font-size:12px;line-height:17px}.VWh0dG_heroGauge{flex:none;width:96px;height:96px;position:relative}.VWh0dG_heroGaugeSvg{width:100%;height:100%;display:block;transform:rotate(-90deg)}.VWh0dG_heroGaugeTrack{fill:none;stroke:var(--dsw-alias-bg-module-platform);stroke-width:9px}.VWh0dG_heroGaugeArc{fill:none;stroke:var(--dsw-static-blue-500);stroke-width:9px;stroke-linecap:round;transition:stroke-dasharray .26s}.VWh0dG_heroGaugeArcOver{stroke:var(--dsw-static-red-500)}.VWh0dG_heroGaugeCenter{flex-direction:column;justify-content:center;align-items:center;gap:1px;display:flex;position:absolute;inset:0}.VWh0dG_heroGaugePct{letter-spacing:-.02em;font-variant-numeric:tabular-nums;color:var(--dsw-alias-label-primary);font-size:18px;font-weight:700;line-height:22px}.VWh0dG_heroGaugePctOver{color:var(--dsw-static-red-500)}.VWh0dG_heroGaugeLabel{color:var(--dsw-alias-label-tertiary);font-size:10px;line-height:14px}.VWh0dG_heroSide{border-top:1px solid var(--dsw-alias-border-l1);align-items:stretch;padding-top:14px;display:flex}.VWh0dG_heroSideItem{flex-direction:column;flex:1;gap:3px;min-width:0;padding-left:16px;display:flex}.VWh0dG_heroSideItem:first-child{padding-left:0}.VWh0dG_heroSideLabel{color:var(--dsw-alias-label-tertiary);white-space:nowrap;font-size:11px;line-height:15px}.VWh0dG_heroSideValue{color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;letter-spacing:-.01em;white-space:nowrap;align-items:baseline;gap:6px;font-size:18px;font-weight:600;line-height:24px;display:inline-flex}.VWh0dG_heroSideSpacer{flex:1;display:block}.VWh0dG_delta{align-items:center;gap:2px;margin-left:4px;font-size:11px;font-weight:600;line-height:17px;display:inline-flex}.VWh0dG_deltaUp{color:var(--dsw-static-green-500)}.VWh0dG_deltaDown{color:var(--dsw-static-red-500)}.VWh0dG_kpiGrid{grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;display:grid}.VWh0dG_kpiTile{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:14px;flex-direction:column;gap:3px;padding:14px 15px;transition:border-color .16s;display:flex;position:relative;overflow:hidden}.VWh0dG_kpiTile:hover{border-color:var(--dsw-alias-border-l2)}.VWh0dG_kpiLabel{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:15px}.VWh0dG_kpiValue{color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;letter-spacing:-.01em;font-size:22px;font-weight:600;line-height:28px}.VWh0dG_kpiGreen{color:var(--dsw-static-green-500)}.VWh0dG_kpiDetail{color:var(--dsw-alias-label-caption);white-space:nowrap;text-overflow:ellipsis;font-size:11px;line-height:15px;overflow:hidden}.VWh0dG_panel{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:16px;flex-direction:column;gap:10px;padding:16px 18px;transition:border-color .16s;display:flex}.VWh0dG_panelHead{justify-content:space-between;align-items:baseline;gap:10px;display:flex}.VWh0dG_panelTitle{letter-spacing:-.005em;color:var(--dsw-alias-label-primary);margin:0;font-size:14px;font-weight:600;line-height:20px}.VWh0dG_panelHint{color:var(--dsw-alias-label-caption);white-space:nowrap;font-size:11px;line-height:16px}.VWh0dG_pricingTip{color:var(--dsw-alias-label-caption);margin:0 0 2px;font-size:11px;line-height:16px}.VWh0dG_rangeToggle{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:8px;gap:2px;padding:2px;display:inline-flex}.VWh0dG_rangeButton{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:6px;padding:2px 8px;font-size:11px;line-height:16px;transition:background-color .14s,color .14s}.VWh0dG_rangeButtonActive{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);font-weight:600}.VWh0dG_exportBar{justify-content:flex-end;align-items:center;gap:8px;display:flex}.VWh0dG_exportLabel{color:var(--dsw-alias-label-caption);font-size:11px;line-height:16px}.VWh0dG_exportButton{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary);cursor:pointer;border-radius:999px;padding:4px 12px;font-size:11.5px;line-height:16px;transition:border-color .16s,color .16s,background-color .16s}.VWh0dG_exportButton:hover,.VWh0dG_exportButton:focus-visible{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);outline:none}.VWh0dG_shareTrack{background:var(--dsw-alias-bg-module-platform);border-radius:999px;height:10px;display:flex;overflow:hidden}.VWh0dG_shareSeg{height:100%;transition:width .2s}.VWh0dG_shareSegPeak{background:var(--dsw-static-blue-500)}.VWh0dG_shareSegOff{background:color-mix(in srgb, var(--dsw-static-blue-500) 25%, var(--dsw-alias-bg-module-platform))}.VWh0dG_shareSegUser{background:var(--dsw-static-blue-500)}.VWh0dG_shareSegAssistant{background:var(--dsw-static-green-500)}.VWh0dG_shareSegTool{background:var(--dsw-static-amber-500)}.VWh0dG_shareLegend{align-items:center;gap:16px;display:flex}.VWh0dG_shareItem{color:var(--dsw-alias-label-secondary);align-items:baseline;gap:6px;font-size:12px;line-height:17px;display:inline-flex}.VWh0dG_bucketCost{align-items:baseline;gap:3px;display:inline-flex}.VWh0dG_bucketOfficial{color:var(--dsw-static-blue-500);font-weight:600}.VWh0dG_bucketSep{color:var(--dsw-alias-label-dimmed)}.VWh0dG_bucketThird{color:var(--dsw-alias-label-secondary)}.VWh0dG_bucketSummary{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;display:grid}.VWh0dG_bucketStat{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);border-radius:12px;flex-direction:column;gap:4px;padding:12px 14px;display:flex}.VWh0dG_bucketStatLabel{color:var(--dsw-alias-label-tertiary);text-transform:uppercase;letter-spacing:.05em;font-size:11px;line-height:15px}.VWh0dG_bucketStatValue{color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;letter-spacing:-.01em;font-size:20px;font-weight:700;line-height:26px}.VWh0dG_bucketStatSub{color:var(--dsw-alias-label-caption);font-variant-numeric:tabular-nums;font-size:11px;line-height:16px}.VWh0dG_shareDot{border-radius:50%;flex:none;align-self:center;width:8px;height:8px}.VWh0dG_shareValue{color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;font-weight:600}.VWh0dG_budget{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:14px;flex-direction:column;gap:8px;padding:12px 16px;display:flex}.VWh0dG_budgetHead{justify-content:space-between;align-items:baseline;gap:10px;display:flex}.VWh0dG_budgetLabel{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:17px}.VWh0dG_budgetValue{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;white-space:nowrap;font-size:12px;line-height:17px}.VWh0dG_budgetControls{align-items:center;gap:8px;min-width:0;display:inline-flex}.VWh0dG_budgetInputWrap{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:6px;align-items:center;gap:2px;padding:2px 6px;display:inline-flex}.VWh0dG_budgetInputWrap:focus-within{border-color:var(--dsw-alias-border-l3)}.VWh0dG_budgetUnit{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px}.VWh0dG_budgetInput{width:64px;color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;text-align:right;background:0 0;border:none;padding:0;font-size:12px;line-height:16px}.VWh0dG_budgetInput:focus-visible{outline:none}.VWh0dG_switch{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-module-platform);cursor:pointer;border-radius:999px;flex:none;width:30px;height:17px;padding:0;transition:background-color .16s,border-color .16s;position:relative}.VWh0dG_switchOn{border-color:var(--dsw-alias-border-l1);background:var(--dsw-alias-label-primary)}.VWh0dG_switchKnob{background:var(--dsw-static-neutral-bluish-00);border-radius:50%;width:11px;height:11px;transition:transform .16s;position:absolute;top:2px;left:2px}.VWh0dG_switchOn .VWh0dG_switchKnob{transform:translate(13px)}.VWh0dG_budgetTrack{background:var(--dsw-alias-bg-module-platform);border-radius:999px;height:6px;overflow:hidden}.VWh0dG_budgetFill{background:var(--dsw-static-blue-500);border-radius:999px;height:100%;transition:width .2s}.VWh0dG_budgetFillWarn{background:var(--dsw-static-amber-500)}.VWh0dG_budgetFillOver{background:var(--dsw-static-red-500);animation:1.6s ease-in-out infinite VWh0dG_budgetOverPulse}@keyframes VWh0dG_budgetOverPulse{50%{opacity:.55}}.VWh0dG_chartWrap{width:100%;position:relative}.VWh0dG_chartSvg{width:100%;height:auto;display:block}.VWh0dG_chartEmpty{height:140px;color:var(--dsw-alias-label-caption);justify-content:center;align-items:center;font-size:13px;display:flex}.VWh0dG_emptyRow{text-align:center;color:var(--dsw-alias-label-caption);padding:28px 0;font-size:13px}.VWh0dG_chartGrid{stroke:var(--dsw-alias-border-l1);stroke-width:1px}.VWh0dG_chartAxisLabel{fill:var(--dsw-alias-label-tertiary);font-size:10px}.VWh0dG_chartBar{fill:var(--dsw-static-blue-500);opacity:.7}.VWh0dG_chartBar:hover{opacity:1}.VWh0dG_chartStack{stroke:var(--dsw-alias-bg-layer-1);stroke-width:.75px}.VWh0dG_chartStack:hover{opacity:.9}.VWh0dG_chartLine{stroke:var(--dsw-static-blue-500);stroke-width:2px;stroke-linecap:round;stroke-linejoin:round}.VWh0dG_chartCrosshair{stroke:var(--dsw-alias-label-dimmed);stroke-width:1px;stroke-dasharray:3 3}.VWh0dG_chartDot{fill:var(--dsw-static-neutral-bluish-00);stroke:var(--dsw-static-blue-500);stroke-width:2px}.VWh0dG_chartTooltip{pointer-events:none;z-index:2;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);box-shadow:none;white-space:nowrap;border-radius:8px;padding:8px 10px;position:absolute;transform:translate(-50%,calc(-100% - 10px))}.VWh0dG_chartTooltipDate{color:var(--dsw-alias-label-primary);margin-bottom:3px;font-size:11px;font-weight:600}.VWh0dG_chartTooltipRow{color:var(--dsw-alias-label-secondary);align-items:center;gap:5px;font-size:11px;line-height:17px;display:flex}.VWh0dG_chartTooltipRow strong{color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;font-weight:600}.VWh0dG_chartLegendLine{background:var(--dsw-static-blue-500);border-radius:2px;width:10px;height:3px;display:inline-block}.VWh0dG_chartLegendBar{background:var(--dsw-static-blue-500);opacity:.5;border-radius:2px;width:7px;height:7px;display:inline-block}.VWh0dG_chartTooltipSwatch{border-radius:3px;flex:none;width:8px;height:8px;display:inline-block}.VWh0dG_chartLegend{color:var(--dsw-alias-label-tertiary);justify-content:flex-end;gap:14px;margin-top:2px;font-size:11px;display:flex}.VWh0dG_chartLegend span{align-items:center;gap:5px;display:inline-flex}.VWh0dG_tableScroll{border:1px solid var(--dsw-alias-border-l1);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:12px;overflow:auto}.VWh0dG_modelTable,.VWh0dG_pricingTable{border-collapse:collapse;width:100%;font-size:12.5px}.VWh0dG_modelTable th,.VWh0dG_modelTable td,.VWh0dG_pricingTable th,.VWh0dG_pricingTable td{border-bottom:1px solid var(--dsw-alias-border-l1);text-align:left;white-space:nowrap;padding:9px 12px}.VWh0dG_modelTable tbody tr:last-child td,.VWh0dG_pricingTable tbody tr:last-child td{border-bottom:0}.VWh0dG_modelTable thead th,.VWh0dG_pricingTable thead th{color:var(--dsw-alias-label-tertiary);text-transform:uppercase;letter-spacing:.05em;background:0 0;font-size:11px;font-weight:600}.VWh0dG_modelTable tbody tr,.VWh0dG_pricingTable tbody tr{transition:background-color .12s}.VWh0dG_modelTable tbody tr:hover,.VWh0dG_pricingTable tbody tr:hover{background:0 0}.VWh0dG_numCol{text-align:right;font-variant-numeric:tabular-nums}.VWh0dG_costCol{color:var(--dsw-alias-label-primary);font-weight:600}.VWh0dG_na{color:var(--dsw-alias-label-dimmed)}.VWh0dG_modelCell{align-items:center;gap:8px;display:inline-flex}.VWh0dG_modelDot{border-radius:50%;flex:none;width:9px;height:9px}.VWh0dG_modelName{color:var(--dsw-alias-label-primary);font-weight:500;line-height:16px;display:block}.VWh0dG_modelProvider{color:var(--dsw-alias-label-caption);font-size:10.5px;line-height:14px;display:block}.VWh0dG_pricingToggle{cursor:pointer;text-align:left;background:0 0;border:none;justify-content:space-between;align-items:center;gap:10px;width:100%;padding:0;display:flex}.VWh0dG_pricingToggle:hover .VWh0dG_panelTitle,.VWh0dG_pricingToggle:focus-visible .VWh0dG_panelTitle{color:var(--dsw-alias-label-primary)}.VWh0dG_rateBadge{vertical-align:1px;white-space:nowrap;border-radius:999px;align-items:center;margin-left:6px;padding:1px 6px;font-size:10px;font-weight:500;line-height:14px;display:inline-flex}.VWh0dG_rateBadgeLive{color:var(--dsw-static-green-500);background:var(--dsw-alias-bg-layer-2)}.VWh0dG_rateBadgeBuiltin{color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-bg-layer-2)}.VWh0dG_pricingToggleText{align-items:baseline;gap:10px;min-width:0;display:flex}.VWh0dG_pricingChevron{width:16px;height:16px;color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}.VWh0dG_pricingChevronOpen{transform:rotate(180deg)}.VWh0dG_bandPrice{align-items:baseline;gap:6px;display:inline-flex}.VWh0dG_bandPriceOff{color:var(--dsw-alias-label-caption)}.VWh0dG_bandPriceOff:before{content:\"/\";color:var(--dsw-alias-label-dimmed);margin-right:4px}.VWh0dG_bandTag{color:var(--dsw-alias-label-secondary);flex-direction:column;gap:1px;font-size:10.5px;line-height:14px;display:inline-flex}.VWh0dG_bandTagOff{color:var(--dsw-static-green-500);font-weight:600}.VWh0dG_bandTag>span:first-child{color:var(--dsw-alias-label-primary);font-weight:500}.VWh0dG_flatTag{color:var(--dsw-alias-label-caption);font-size:10.5px;line-height:14px}.VWh0dG_healthDot{border-radius:50%;flex:none;width:8px;height:8px;display:inline-block}.VWh0dG_healthOk{background:var(--dsw-static-green-500)}.VWh0dG_healthBad{background:var(--dsw-static-red-500)}.VWh0dG_healthIdle{background:var(--dsw-static-neutral-bluish-400)}.VWh0dG_dashboardRight{align-items:center;gap:8px;min-width:0;display:flex}.VWh0dG_healthBadge{white-space:nowrap;border-radius:999px;align-items:center;gap:6px;padding:3px 9px;font-size:11px;line-height:16px;display:inline-flex}.VWh0dG_healthBadgeOk{color:var(--dsw-static-green-500);background:var(--dsw-alias-bg-layer-2)}.VWh0dG_healthBadgeBad{color:var(--dsw-static-red-500);background:var(--dsw-alias-bg-layer-2)}.VWh0dG_planTag{color:var(--dsw-static-green-500);background:var(--dsw-alias-bg-layer-2);border-radius:999px;align-items:center;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px;display:inline-flex}.VWh0dG_uncataloguedTag{vertical-align:1px;color:var(--dsw-static-amber-500);background:var(--dsw-alias-bg-layer-2);border-radius:999px;margin-left:6px;padding:0 6px;font-size:10px;font-weight:600;line-height:16px;display:inline-block}.VWh0dG_estimatedTag{vertical-align:1px;color:var(--dsw-static-blue-500);background:var(--dsw-alias-bg-layer-2);border-radius:999px;margin-left:6px;padding:0 6px;font-size:10px;font-weight:600;line-height:16px;display:inline-block}.VWh0dG_liveCostBar{color:var(--dsw-static-neutral-400);font-variant-numeric:tabular-nums;align-items:center;gap:6px;font-size:11px;line-height:16px;display:inline-flex}.VWh0dG_liveCostItem{white-space:nowrap}.VWh0dG_liveCostSep{color:var(--dsw-static-neutral-300)}.VWh0dG_liveTierPeak{color:var(--dsw-static-blue-500);font-weight:600}.VWh0dG_liveTierOff{color:var(--dsw-static-green-500);font-weight:600}.VWh0dG_liveQuotaWarn{color:var(--dsw-static-amber-500);font-weight:600}.VWh0dG_liveQuotaCrit{color:var(--dsw-static-red-500);font-weight:600}.VWh0dG_balanceCell{flex-direction:column;align-items:flex-end;gap:2px;display:inline-flex}.VWh0dG_balanceDays{color:var(--dsw-alias-label-caption);white-space:nowrap;font-size:10.5px;line-height:14px}.VWh0dG_balanceDaysLow{color:var(--dsw-static-red-500);font-weight:600}body[data-zine-mode] .VWh0dG_trigger,body[data-zine-mode] .VWh0dG_triggerPop,body[data-zine-mode] .VWh0dG_railButton{display:none}body[data-zine-mode] .VWh0dG_dashboardHead{background:#000;border-bottom:2px solid #e8ff00}body[data-zine-mode] .VWh0dG_headTitleRow{align-items:center;gap:8px;margin-top:4px;display:flex}body[data-zine-mode] .VWh0dG_dashboardTitle{color:#e8ff00;letter-spacing:.04em;text-transform:uppercase;text-shadow:0 0 8px #e8ff0066;font-weight:900}body[data-zine-mode] .VWh0dG_dashboardSubtitle{color:#c9d98a;letter-spacing:.08em;text-transform:uppercase;font-size:10px}body[data-zine-mode] .VWh0dG_closeButton{color:#0a0a05;background:#ff2d95;border:1.5px solid #ff2d95;border-radius:0;box-shadow:0 0 10px #ff2d9573}body[data-zine-mode] .VWh0dG_hero{background:#000;border:2.5px solid #e8ff00;border-radius:0;position:relative;box-shadow:0 0 0 1px #0009,0 0 24px #e8ff002e}body[data-zine-mode] .VWh0dG_heroLabel{color:#c9d98a;letter-spacing:.12em;text-transform:uppercase;font-size:10px;font-weight:900}body[data-zine-mode] .VWh0dG_heroValue{color:#e8ff00;letter-spacing:-.02em;text-shadow:0 0 12px #e8ff0073;-webkit-text-fill-color:#e8ff00;background:0 0;font-size:38px;font-weight:900}body[data-zine-mode] .VWh0dG_heroMeta{color:#c9d98a;letter-spacing:.06em;text-transform:uppercase;font-size:10.5px}body[data-zine-mode] .VWh0dG_heroSideLabel{color:#c9d98a;letter-spacing:.1em;text-transform:uppercase;font-size:10px;font-weight:900}body[data-zine-mode] .VWh0dG_heroSideValue{color:#e8ff00;text-shadow:0 0 6px #e8ff0059}body[data-zine-mode] .VWh0dG_delta{font-weight:900}body[data-zine-mode] .VWh0dG_deltaUp{color:#ff2d95}body[data-zine-mode] .VWh0dG_deltaDown{color:#c9d98a}body[data-zine-mode] .VWh0dG_tabNav{background:#000;border-bottom:2px solid #e8ff00}body[data-zine-mode] .VWh0dG_tabButton{color:#c9d98a;letter-spacing:.08em;text-transform:uppercase;border-radius:0;font-size:10.5px;font-weight:900}body[data-zine-mode] .VWh0dG_tabButton:hover,body[data-zine-mode] .VWh0dG_tabButton:focus-visible{color:#e8ff00;background:#e8ff001f}body[data-zine-mode] .VWh0dG_tabButtonActive,body[data-zine-mode] .VWh0dG_tabButtonActive:hover,body[data-zine-mode] .VWh0dG_tabButtonActive:focus-visible{color:#0a0a05;background:#e8ff00;box-shadow:0 0 10px #e8ff0073}body[data-zine-mode] .VWh0dG_panel{background:#000;border:2px solid #e8ff00;border-radius:0}body[data-zine-mode] .VWh0dG_trendPanel{position:relative}body[data-zine-mode] .VWh0dG_panelTitle{color:#e8ff00;letter-spacing:.06em;text-transform:uppercase;text-shadow:0 0 6px #e8ff0066;font-weight:900}body[data-zine-mode] .VWh0dG_panelHint{color:#c9d98a;letter-spacing:.08em;text-transform:uppercase;font-size:10px;font-weight:900}body[data-zine-mode] .VWh0dG_modelTableScroll{background:#000;border:1.5px solid #e8ff0080;border-radius:0}.VWh0dG_currencyToggle{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);border-radius:6px;align-items:center;gap:2px;margin-right:8px;padding:2px;display:inline-flex}.VWh0dG_currencyButton{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:4px;padding:4px 7px;font-size:11px;font-weight:700;line-height:1}.VWh0dG_currencyButtonActive{background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary)}.VWh0dG_subscriptionGrid{grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:10px;margin-top:10px;display:grid}.VWh0dG_subscriptionCard{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);border-radius:10px;padding:12px 14px}.VWh0dG_subscriptionHead{flex-wrap:wrap;align-items:baseline;gap:6px;margin-bottom:8px;display:flex}.VWh0dG_subscriptionName{font-size:13px;font-weight:700}.VWh0dG_subscriptionPlan{color:var(--dsw-alias-label-secondary);font-size:11px}.VWh0dG_subscriptionPlan[data-kind=code],.VWh0dG_subscriptionPlan[data-kind=token]{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-3);border-radius:999px;padding:1px 8px;font-weight:500}.VWh0dG_subscriptionTier{color:var(--dsw-alias-label-secondary);margin-left:6px}.VWh0dG_subscriptionAuto{color:var(--dsw-static-blue-500);background:color-mix(in srgb, var(--dsw-static-blue-500) 14%, var(--dsw-alias-bg-layer-2));border-radius:999px;margin-left:6px;padding:1px 6px;font-size:10px}.VWh0dG_subscriptionStatus{color:var(--dsw-alias-label-secondary);margin-bottom:6px;font-size:11px}.VWh0dG_subscriptionWindow{align-items:center;gap:8px;margin-top:6px;font-size:11px;display:flex}.VWh0dG_subscriptionWindowLabel{color:var(--dsw-alias-label-secondary);flex:0 0 44px}.VWh0dG_subscriptionTrack{background:var(--dsw-alias-bg-layer-3);border-radius:3px;flex:1;height:5px;overflow:hidden}.VWh0dG_subscriptionFill{background:var(--dsw-static-blue-500);border-radius:3px;height:100%;transition:width .2s;display:block}.VWh0dG_subscriptionFillWarn{background:var(--dsw-static-amber-500)}.VWh0dG_subscriptionFillOver{background:var(--dsw-static-red-500)}.VWh0dG_subscriptionPct{text-align:right;font-variant-numeric:tabular-nums;flex:none;min-width:52px}.VWh0dG_subscriptionExhausted{color:var(--dsw-static-red-500);min-width:52px;font-weight:600}.VWh0dG_subscriptionReset{color:var(--dsw-alias-label-secondary);flex:none}.VWh0dG_providerGroupList{flex-direction:column;gap:10px;display:flex}.VWh0dG_providerGroup{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:12px;padding:12px 14px}.VWh0dG_providerGroupHead{justify-content:space-between;align-items:baseline;gap:12px;display:flex}.VWh0dG_providerGroupTitle{align-items:center;gap:7px;min-width:0;display:inline-flex}.VWh0dG_providerGroupName{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600;line-height:18px}.VWh0dG_providerGroupMeta{flex:none;align-items:center;gap:10px;display:inline-flex}.VWh0dG_providerGroupBadge{color:var(--dsw-static-green-500);background:var(--dsw-alias-bg-layer-2);border-radius:999px;align-items:center;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px;display:inline-flex}.VWh0dG_providerGroupBalance{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;white-space:nowrap;align-items:baseline;gap:6px;font-size:12px;line-height:17px;display:inline-flex}.VWh0dG_providerGroupBalanceLabel{color:var(--dsw-alias-label-caption);font-size:11px;line-height:17px}.VWh0dG_roundsFlagBadge{color:var(--dsw-static-neutral-bluish-00);background:var(--dsw-static-red-500);border-radius:999px;margin-left:8px;padding:1px 7px;font-size:10px;font-weight:800}.VWh0dG_rounds{margin-top:10px}.VWh0dG_roundsBars{align-items:flex-end;gap:3px;height:124px;padding:16px 2px 0;display:flex;overflow-x:auto}.VWh0dG_roundsBarCol{border-radius:5px 5px 0 0;flex-direction:column;flex:1 0 28px;justify-content:flex-end;align-items:stretch;height:100%;display:flex;position:relative}.VWh0dG_roundsBarColPeak{background:color-mix(in srgb, var(--dsw-static-amber-500) 16%, transparent)}.VWh0dG_roundsBarColOff{background:var(--dsw-alias-bg-module-platform)}.VWh0dG_roundsBarLabel{text-align:center;color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;max-width:100%;font-size:9px;line-height:1.2;position:absolute;bottom:0;left:0;right:0;overflow:hidden;transform:translateY(-100%)}.VWh0dG_roundsBarWrap{flex:1;align-items:flex-end;min-height:0;display:flex}.VWh0dG_roundsBar{background:var(--dsw-static-blue-500);border-radius:2px 2px 0 0;width:100%;min-height:2px;position:relative}.VWh0dG_roundsBarFlagged{background:var(--dsw-static-red-500);border-radius:2px 2px 0 0;width:100%;min-height:2px;position:relative}.VWh0dG_roundsFlagMark{background:var(--dsw-static-red-500);border-radius:50%;width:7px;height:7px;position:absolute;top:-3px;right:-3px}.VWh0dG_roundsAxis{color:var(--dsw-alias-label-secondary);justify-content:space-between;margin-top:6px;font-size:10px;display:flex}.VWh0dG_roundsEmpty{color:var(--dsw-alias-label-secondary);margin-top:10px;font-size:12px}.VWh0dG_heatmap{margin-top:10px}.VWh0dG_heatmapGrid{grid-template-columns:repeat(7,minmax(0,1fr));gap:8px;display:grid}.VWh0dG_heatmapCellEmpty{background:var(--dsw-alias-bg-layer-1);height:30px;color:var(--dsw-alias-label-dimmed);font-variant-numeric:tabular-nums;border-radius:8px;justify-content:center;align-items:center;font-size:11px;display:flex}.VWh0dG_heatmapCell{font-variant-numeric:tabular-nums;cursor:pointer;border:0;border-radius:8px;justify-content:center;align-items:center;height:30px;padding:0;font-size:11px;display:flex}.VWh0dG_heatmapCell[data-level=\"0\"],.VWh0dG_heatmapCell[data-level=\"1\"],.VWh0dG_heatmapCell[data-level=\"2\"]{color:var(--dsw-alias-label-primary)}.VWh0dG_heatmapCell[data-level=\"3\"],.VWh0dG_heatmapCell[data-level=\"4\"]{color:var(--dsw-static-neutral-bluish-00)}.VWh0dG_heatmapFooter{color:var(--dsw-alias-label-secondary);align-items:center;gap:8px;margin-top:10px;font-size:10px;display:flex}.VWh0dG_heatmapLegend{gap:3px;display:inline-flex}.VWh0dG_heatmapLegend i{border-radius:4px;width:14px;height:14px;display:block}.VWh0dG_heatmapHover{font-variant-numeric:tabular-nums;margin-left:auto}.VWh0dG_heatmapYearScroll{padding-bottom:2px;overflow-x:auto}.VWh0dG_heatmapYearGrid{grid-template-rows:repeat(7,11px);grid-auto-flow:column;gap:3px;min-width:max-content;display:grid}.VWh0dG_heatmapYearCell{cursor:pointer;border:0;border-radius:2px;width:11px;height:11px;padding:0}@media (width<=640px){.VWh0dG_kpiGrid{grid-template-columns:repeat(2,minmax(0,1fr))}.VWh0dG_hero{gap:14px}.VWh0dG_heroTop{flex-direction:column;align-items:flex-start;gap:12px}.VWh0dG_heroGauge{width:72px;height:72px}.VWh0dG_heroSide{gap:12px}.VWh0dG_heroSideSpacer{display:none}}.VWh0dG_peakAlert{z-index:2000;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:12px;align-items:center;gap:12px;min-width:300px;max-width:460px;padding:10px 12px;animation:.2s VWh0dG_peakAlertIn;display:flex;position:fixed;box-shadow:0 4px 16px #00000014}.VWh0dG_peakAlertCorner{bottom:18px;right:18px}.VWh0dG_peakAlertCenter{top:20%;left:50%;transform:translate(-50%)}.VWh0dG_peakAlertTag{letter-spacing:.01em;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-3);white-space:nowrap;border-radius:999px;flex:none;align-items:center;gap:6px;padding:3px 9px;font-size:11px;font-weight:650;display:inline-flex}.VWh0dG_peakAlertTag:before{content:\"\";background:currentColor;border-radius:50%;width:6px;height:6px}.VWh0dG_peakAlertPeak .VWh0dG_peakAlertTag{color:var(--dsw-static-amber-500)}.VWh0dG_peakAlertOff .VWh0dG_peakAlertTag{color:var(--dsw-static-blue-500)}.VWh0dG_peakAlertCountdown{font-variant-numeric:tabular-nums;color:var(--dsw-alias-label-primary);flex:none;font-size:18px;font-weight:700;line-height:1}.VWh0dG_peakAlertText{min-width:0;color:var(--dsw-alias-label-secondary);flex:1;font-size:12px;line-height:18px}.VWh0dG_peakAlertClose{width:20px;height:20px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:6px;flex:none;justify-content:center;align-items:center;font-size:15px;line-height:1;transition:background-color .14s,color .14s;display:inline-flex}.VWh0dG_peakAlertClose:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2)}@keyframes VWh0dG_peakAlertIn{0%{opacity:0}to{opacity:1}}.VWh0dG_peakAlertPanel{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:16px;flex-direction:column;gap:10px;padding:14px 16px;display:flex}.VWh0dG_peakAlertPanelHead{justify-content:space-between;align-items:center;gap:10px;display:flex}.VWh0dG_peakAlertPanelLabel{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600}.VWh0dG_peakAlertPanelBody{flex-wrap:wrap;align-items:center;gap:12px 16px;display:flex}.VWh0dG_peakAlertField{color:var(--dsw-alias-label-secondary);align-items:center;gap:8px;font-size:12px;display:inline-flex}.VWh0dG_peakAlertNum{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);width:56px;color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;border-radius:6px;padding:4px 6px}.VWh0dG_peakAlertSelect{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);border-radius:6px;padding:4px 6px;font-size:12px}.VWh0dG_peakAlertCheck{color:var(--dsw-alias-label-secondary);align-items:center;gap:6px;font-size:12px;display:inline-flex}.VWh0dG_peakAlertPreview{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;padding:5px 10px;font-size:12px}.VWh0dG_peakAlertPreview:hover{background:var(--dsw-alias-bg-layer-3)}.VWh0dG_settingsHead{flex-direction:column;gap:4px;margin-bottom:2px;display:flex}.VWh0dG_settingsTitle{letter-spacing:-.005em;color:var(--dsw-alias-label-primary);margin:0;font-size:15px;font-weight:650;line-height:22px}.VWh0dG_settingsHint{color:var(--dsw-alias-label-caption);margin:0;font-size:11px;line-height:16px}.VWh0dG_budgetHint,.VWh0dG_peakAlertHint{color:var(--dsw-alias-label-caption);margin:6px 0 0;font-size:11px;line-height:16px}";
27
+ const css = ".VWh0dG_railButton{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);width:36px;height:36px;color:var(--dsw-alias-label-secondary);cursor:pointer;border-radius:8px;flex:none;justify-content:center;align-items:center;padding:0;transition:border-color .16s,color .16s;display:flex}.VWh0dG_railButton:hover,.VWh0dG_railButton:focus-visible{border-color:var(--dsw-static-blue-500);color:var(--dsw-static-blue-500);outline:none}.VWh0dG_railButton svg{stroke-width:2px;width:18px;height:18px}.VWh0dG_trigger{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);width:100%;min-width:0;color:var(--dsw-alias-label-primary);cursor:pointer;text-align:left;border-radius:12px;align-items:center;gap:10px;padding:9px 12px;transition:border-color .16s,background-color .16s;display:flex;position:relative;overflow:hidden}.VWh0dG_trigger:hover,.VWh0dG_trigger:focus-visible{border-color:var(--dsw-static-blue-500);outline:none}.VWh0dG_triggerIcon{background:linear-gradient(135deg, var(--dsw-static-blue-500), var(--dsw-static-blue-400));width:30px;height:30px;color:var(--dsw-static-neutral-bluish-00);box-shadow:0 2px 8px -2px color-mix(in srgb, var(--dsw-static-blue-500) 55%, transparent);border-radius:10px;flex:none;justify-content:center;align-items:center;display:inline-flex}.VWh0dG_triggerIcon svg{stroke-width:2px;width:16px;height:16px}.VWh0dG_triggerBody{flex-direction:column;flex:1;gap:1px;min-width:0;display:flex}.VWh0dG_triggerRow{align-items:baseline;gap:5px;min-width:0;display:inline-flex}.VWh0dG_triggerAmount{color:var(--dsw-alias-label-primary);letter-spacing:-.02em;font-variant-numeric:tabular-nums;white-space:nowrap;font-size:16px;font-weight:700;line-height:20px}.VWh0dG_triggerSub{color:var(--dsw-alias-label-tertiary);white-space:nowrap;text-overflow:ellipsis;font-size:10px;line-height:14px;overflow:hidden}.VWh0dG_triggerMeta{color:var(--dsw-alias-label-tertiary);white-space:nowrap;letter-spacing:.02em;text-transform:uppercase;font-size:9.5px;font-weight:600;line-height:12px}.VWh0dG_triggerSpark{flex:none;align-items:flex-end;gap:2px;height:20px;display:flex}.VWh0dG_triggerSparkBar,.VWh0dG_triggerSparkHot{background:var(--dsw-static-blue-500);opacity:.6;border-radius:1px 1px 0 0;width:3px}.VWh0dG_triggerSparkHot{opacity:1}.VWh0dG_triggerWrap{flex:auto;width:100%;min-width:0;display:block;position:relative}.VWh0dG_triggerPop{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);box-shadow:var(--dsw-shadow-lv2);opacity:0;pointer-events:none;z-index:10;border-radius:10px;flex-direction:column;gap:6px;padding:12px 14px;transition:opacity .16s,transform .16s;display:flex;position:absolute;bottom:calc(100% + 8px);left:0;right:0;transform:translateY(4px)}.VWh0dG_triggerWrap:hover .VWh0dG_triggerPop,.VWh0dG_triggerWrap:focus-within .VWh0dG_triggerPop{opacity:1;transform:translateY(0)}.VWh0dG_triggerPopRow{justify-content:space-between;align-items:baseline;gap:12px;display:flex}.VWh0dG_triggerPopLabel{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px}.VWh0dG_triggerPopValue{color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;font-size:13px;font-weight:600;line-height:18px}.VWh0dG_triggerPopBars{border-top:1px solid var(--dsw-alias-border-l1);align-items:flex-end;gap:4px;height:22px;margin-top:4px;padding-top:8px;display:flex}.VWh0dG_triggerPopBar{background:var(--dsw-static-blue-500);border-radius:2px;flex:1;transition:height .2s}.VWh0dG_dashboardModal{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);width:min(760px,100vw - 48px);max-height:min(760px,88vh);box-shadow:var(--dsw-shadow-lv3);animation:.18s ease-out VWh0dG_dashboardIn}@keyframes VWh0dG_dashboardIn{0%{opacity:0;transform:translateY(8px)scale(.98)}to{opacity:1;transform:none}}div[role=presentation]:has(>.dsh-billing-modal)>div[aria-hidden=true]:first-child{backdrop-filter:blur(8px)saturate(1.25)}.VWh0dG_dashboard{flex-direction:column;width:100%;max-height:min(760px,88vh);display:flex}.VWh0dG_dashboardHead{border-bottom:1px solid var(--dsw-alias-border-l1);justify-content:space-between;align-items:flex-start;gap:12px;padding:20px 24px 14px;display:flex}.VWh0dG_dashboardTitle{color:var(--dsw-alias-label-primary);margin:0;font-size:17px;font-weight:600;line-height:24px}.VWh0dG_dashboardSubtitle{color:var(--dsw-alias-label-caption);margin:3px 0 0;font-size:12px;line-height:17px}.VWh0dG_closeButton{width:30px;height:30px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:8px;flex:none;justify-content:center;align-items:center;transition:background-color .14s;display:inline-flex}.VWh0dG_closeButton:hover{background:var(--dsw-alias-interactive-bg-hover)}.VWh0dG_closeButton svg{stroke-width:2px;width:16px;height:16px}.VWh0dG_dashboardBody{flex-direction:column;gap:14px;padding:16px 24px 24px;display:flex;overflow-y:auto}.VWh0dG_tabNav{border-bottom:1px solid var(--dsw-alias-border-l1);align-items:center;gap:4px;padding:10px 24px;display:flex}.VWh0dG_tabButton{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:999px;padding:5px 14px;font-size:12.5px;font-weight:500;line-height:18px;transition:background-color .16s,color .16s,box-shadow .16s}.VWh0dG_tabButton:hover,.VWh0dG_tabButton:focus-visible{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover);outline:none}.VWh0dG_tabButtonActive,.VWh0dG_tabButtonActive:hover,.VWh0dG_tabButtonActive:focus-visible{background:var(--dsw-static-blue-500);color:var(--dsw-static-neutral-bluish-00);font-weight:600}.VWh0dG_tabPanel{flex-direction:column;gap:14px;animation:.14s ease-out VWh0dG_tabPanelIn;display:flex}@keyframes VWh0dG_tabPanelIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}.VWh0dG_hero{border:1px solid var(--dsw-alias-border-l1);background:linear-gradient(180deg, var(--dsw-alias-bg-layer-2), var(--dsw-alias-bg-layer-1));box-shadow:inset 0 1px 0 color-mix(in srgb, var(--dsw-static-neutral-bluish-00) 30%, transparent);border-radius:16px;flex-direction:column;gap:18px;padding:22px 24px;display:flex;position:relative;overflow:hidden}.VWh0dG_heroTop{justify-content:space-between;align-items:center;gap:24px;display:flex}.VWh0dG_heroMain{flex-direction:column;gap:2px;min-width:0;display:flex}.VWh0dG_heroLabel{color:var(--dsw-alias-label-tertiary);text-transform:uppercase;letter-spacing:.08em;white-space:nowrap;font-size:11px;line-height:16px}.VWh0dG_heroReadout{align-items:baseline;gap:4px;display:flex}.VWh0dG_heroCurrency{letter-spacing:-.01em;color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;font-size:20px;font-weight:600;line-height:30px}.VWh0dG_heroValue{letter-spacing:-.03em;font-variant-numeric:tabular-nums;white-space:nowrap;color:var(--dsw-alias-label-primary);font-size:56px;font-weight:700;line-height:64px}.VWh0dG_heroMeta{color:var(--dsw-alias-label-caption);white-space:nowrap;margin-top:4px;font-size:12px;line-height:17px}.VWh0dG_heroGauge{flex:none;width:96px;height:96px;position:relative}.VWh0dG_heroGaugeSvg{width:100%;height:100%;display:block;transform:rotate(-90deg)}.VWh0dG_heroGaugeTrack{fill:none;stroke:var(--dsw-alias-bg-module-platform);stroke-width:9px}.VWh0dG_heroGaugeArc{fill:none;stroke:var(--dsw-static-blue-500);stroke-width:9px;stroke-linecap:round;transition:stroke-dasharray .26s}.VWh0dG_heroGaugeArcOver{stroke:var(--dsw-static-red-500)}.VWh0dG_heroGaugeCenter{flex-direction:column;justify-content:center;align-items:center;gap:1px;display:flex;position:absolute;inset:0}.VWh0dG_heroGaugePct{letter-spacing:-.02em;font-variant-numeric:tabular-nums;color:var(--dsw-alias-label-primary);font-size:18px;font-weight:700;line-height:22px}.VWh0dG_heroGaugePctOver{color:var(--dsw-static-red-500)}.VWh0dG_heroGaugeLabel{color:var(--dsw-alias-label-tertiary);font-size:10px;line-height:14px}.VWh0dG_heroSide{border-top:1px solid var(--dsw-alias-border-l1);align-items:stretch;padding-top:14px;display:flex}.VWh0dG_heroSideItem{flex-direction:column;flex:1;gap:3px;min-width:0;padding-left:16px;display:flex}.VWh0dG_heroSideItem:first-child{padding-left:0}.VWh0dG_heroSideLabel{color:var(--dsw-alias-label-tertiary);white-space:nowrap;font-size:11px;line-height:15px}.VWh0dG_heroSideValue{color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;letter-spacing:-.01em;white-space:nowrap;align-items:baseline;gap:6px;font-size:18px;font-weight:600;line-height:24px;display:inline-flex}.VWh0dG_heroSideSpacer{flex:1;display:block}.VWh0dG_delta{align-items:center;gap:2px;margin-left:4px;font-size:11px;font-weight:600;line-height:17px;display:inline-flex}.VWh0dG_deltaUp{color:var(--dsw-static-green-500)}.VWh0dG_deltaDown{color:var(--dsw-static-red-500)}.VWh0dG_kpiGrid{grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;display:grid}.VWh0dG_kpiTile{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:14px;flex-direction:column;gap:3px;padding:14px 15px;transition:border-color .16s;display:flex;position:relative;overflow:hidden}.VWh0dG_kpiTile:hover{border-color:var(--dsw-alias-border-l2)}.VWh0dG_kpiLabel{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:15px}.VWh0dG_kpiValue{color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;letter-spacing:-.01em;font-size:22px;font-weight:600;line-height:28px}.VWh0dG_kpiGreen{color:var(--dsw-static-green-500)}.VWh0dG_kpiDetail{color:var(--dsw-alias-label-caption);white-space:nowrap;text-overflow:ellipsis;font-size:11px;line-height:15px;overflow:hidden}.VWh0dG_panel{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:16px;flex-direction:column;gap:10px;padding:16px 18px;transition:border-color .16s;display:flex}.VWh0dG_panelHead{justify-content:space-between;align-items:baseline;gap:10px;display:flex}.VWh0dG_panelTitle{letter-spacing:-.005em;color:var(--dsw-alias-label-primary);margin:0;font-size:14px;font-weight:600;line-height:20px}.VWh0dG_panelHint{color:var(--dsw-alias-label-caption);white-space:nowrap;font-size:11px;line-height:16px}.VWh0dG_pricingTip{color:var(--dsw-alias-label-caption);margin:0 0 2px;font-size:11px;line-height:16px}.VWh0dG_rangeToggle{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:8px;gap:2px;padding:2px;display:inline-flex}.VWh0dG_rangeButton{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:6px;padding:2px 8px;font-size:11px;line-height:16px;transition:background-color .14s,color .14s}.VWh0dG_rangeButtonActive{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);font-weight:600}.VWh0dG_exportBar{justify-content:flex-end;align-items:center;gap:8px;display:flex}.VWh0dG_exportLabel{color:var(--dsw-alias-label-caption);font-size:11px;line-height:16px}.VWh0dG_exportButton{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary);cursor:pointer;border-radius:999px;padding:4px 12px;font-size:11.5px;line-height:16px;transition:border-color .16s,color .16s,background-color .16s}.VWh0dG_exportButton:hover,.VWh0dG_exportButton:focus-visible{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);outline:none}.VWh0dG_shareTrack{background:var(--dsw-alias-bg-module-platform);border-radius:999px;height:10px;display:flex;overflow:hidden}.VWh0dG_shareSeg{height:100%;transition:width .2s}.VWh0dG_shareSegPeak{background:var(--dsw-static-blue-500)}.VWh0dG_shareSegOff{background:color-mix(in srgb, var(--dsw-static-blue-500) 25%, var(--dsw-alias-bg-module-platform))}.VWh0dG_shareSegUser{background:var(--dsw-static-blue-500)}.VWh0dG_shareSegAssistant{background:var(--dsw-static-green-500)}.VWh0dG_shareSegTool{background:var(--dsw-static-amber-500)}.VWh0dG_shareLegend{align-items:center;gap:16px;display:flex}.VWh0dG_shareItem{color:var(--dsw-alias-label-secondary);align-items:baseline;gap:6px;font-size:12px;line-height:17px;display:inline-flex}.VWh0dG_bucketCost{align-items:baseline;gap:3px;display:inline-flex}.VWh0dG_bucketOfficial{color:var(--dsw-static-blue-500);font-weight:600}.VWh0dG_bucketSep{color:var(--dsw-alias-label-dimmed)}.VWh0dG_bucketThird{color:var(--dsw-alias-label-secondary)}.VWh0dG_bucketSummary{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;display:grid}.VWh0dG_bucketStat{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);border-radius:12px;flex-direction:column;gap:4px;padding:12px 14px;display:flex}.VWh0dG_bucketStatLabel{color:var(--dsw-alias-label-tertiary);text-transform:uppercase;letter-spacing:.05em;font-size:11px;line-height:15px}.VWh0dG_bucketStatValue{color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;letter-spacing:-.01em;font-size:20px;font-weight:700;line-height:26px}.VWh0dG_bucketStatSub{color:var(--dsw-alias-label-caption);font-variant-numeric:tabular-nums;font-size:11px;line-height:16px}.VWh0dG_shareDot{border-radius:50%;flex:none;align-self:center;width:8px;height:8px}.VWh0dG_shareValue{color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;font-weight:600}.VWh0dG_budget{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:14px;flex-direction:column;gap:8px;padding:12px 16px;display:flex}.VWh0dG_budgetHead{justify-content:space-between;align-items:baseline;gap:10px;display:flex}.VWh0dG_budgetLabel{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:17px}.VWh0dG_budgetValue{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;white-space:nowrap;font-size:12px;line-height:17px}.VWh0dG_budgetControls{align-items:center;gap:8px;min-width:0;display:inline-flex}.VWh0dG_budgetInputWrap{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:6px;align-items:center;gap:2px;padding:2px 6px;display:inline-flex}.VWh0dG_budgetInputWrap:focus-within{border-color:var(--dsw-alias-border-l3)}.VWh0dG_budgetUnit{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px}.VWh0dG_budgetInput{width:64px;color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;text-align:right;background:0 0;border:none;padding:0;font-size:12px;line-height:16px}.VWh0dG_budgetInput:focus-visible{outline:none}.VWh0dG_switch{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-module-platform);cursor:pointer;border-radius:999px;flex:none;width:30px;height:17px;padding:0;transition:background-color .16s,border-color .16s;position:relative}.VWh0dG_switchOn{border-color:var(--dsw-alias-border-l1);background:var(--dsw-alias-label-primary)}.VWh0dG_switchKnob{background:var(--dsw-static-neutral-bluish-00);border-radius:50%;width:11px;height:11px;transition:transform .16s;position:absolute;top:2px;left:2px}.VWh0dG_switchOn .VWh0dG_switchKnob{transform:translate(13px)}.VWh0dG_budgetTrack{background:var(--dsw-alias-bg-module-platform);border-radius:999px;height:6px;overflow:hidden}.VWh0dG_budgetFill{background:var(--dsw-static-blue-500);border-radius:999px;height:100%;transition:width .2s}.VWh0dG_budgetFillWarn{background:var(--dsw-static-amber-500)}.VWh0dG_budgetFillOver{background:var(--dsw-static-red-500);animation:1.6s ease-in-out infinite VWh0dG_budgetOverPulse}@keyframes VWh0dG_budgetOverPulse{50%{opacity:.55}}.VWh0dG_chartWrap{width:100%;position:relative}.VWh0dG_chartSvg{width:100%;height:auto;display:block}.VWh0dG_chartEmpty{height:140px;color:var(--dsw-alias-label-caption);justify-content:center;align-items:center;font-size:13px;display:flex}.VWh0dG_emptyRow{text-align:center;color:var(--dsw-alias-label-caption);padding:28px 0;font-size:13px}.VWh0dG_chartGrid{stroke:var(--dsw-alias-border-l1);stroke-width:1px}.VWh0dG_chartAxisLabel{fill:var(--dsw-alias-label-tertiary);font-size:10px}.VWh0dG_chartBar{fill:var(--dsw-static-blue-500);opacity:.7}.VWh0dG_chartBar:hover{opacity:1}.VWh0dG_chartStack{stroke:var(--dsw-alias-bg-layer-1);stroke-width:.75px}.VWh0dG_chartStack:hover{opacity:.9}.VWh0dG_chartLine{stroke:var(--dsw-static-blue-500);stroke-width:2px;stroke-linecap:round;stroke-linejoin:round}.VWh0dG_chartCrosshair{stroke:var(--dsw-alias-label-dimmed);stroke-width:1px;stroke-dasharray:3 3}.VWh0dG_chartDot{fill:var(--dsw-static-neutral-bluish-00);stroke:var(--dsw-static-blue-500);stroke-width:2px}.VWh0dG_chartTooltip{pointer-events:none;z-index:2;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);box-shadow:none;white-space:nowrap;border-radius:8px;padding:8px 10px;position:absolute;transform:translate(-50%,calc(-100% - 10px))}.VWh0dG_chartTooltipDate{color:var(--dsw-alias-label-primary);margin-bottom:3px;font-size:11px;font-weight:600}.VWh0dG_chartTooltipRow{color:var(--dsw-alias-label-secondary);align-items:center;gap:5px;font-size:11px;line-height:17px;display:flex}.VWh0dG_chartTooltipRow strong{color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;font-weight:600}.VWh0dG_chartLegendLine{background:var(--dsw-static-blue-500);border-radius:2px;width:10px;height:3px;display:inline-block}.VWh0dG_chartLegendBar{background:var(--dsw-static-blue-500);opacity:.5;border-radius:2px;width:7px;height:7px;display:inline-block}.VWh0dG_chartTooltipSwatch{border-radius:3px;flex:none;width:8px;height:8px;display:inline-block}.VWh0dG_chartLegend{color:var(--dsw-alias-label-tertiary);justify-content:flex-end;gap:14px;margin-top:2px;font-size:11px;display:flex}.VWh0dG_chartLegend span{align-items:center;gap:5px;display:inline-flex}.VWh0dG_tableScroll{border:1px solid var(--dsw-alias-border-l1);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:12px;overflow:auto}.VWh0dG_modelTable,.VWh0dG_pricingTable{border-collapse:collapse;width:100%;font-size:12.5px}.VWh0dG_modelTable th,.VWh0dG_modelTable td,.VWh0dG_pricingTable th,.VWh0dG_pricingTable td{border-bottom:1px solid var(--dsw-alias-border-l1);text-align:left;white-space:nowrap;padding:9px 12px}.VWh0dG_modelTable tbody tr:last-child td,.VWh0dG_pricingTable tbody tr:last-child td{border-bottom:0}.VWh0dG_modelTable thead th,.VWh0dG_pricingTable thead th{color:var(--dsw-alias-label-tertiary);text-transform:uppercase;letter-spacing:.05em;background:0 0;font-size:11px;font-weight:600}.VWh0dG_modelTable tbody tr,.VWh0dG_pricingTable tbody tr{transition:background-color .12s}.VWh0dG_modelTable tbody tr:hover,.VWh0dG_pricingTable tbody tr:hover{background:0 0}.VWh0dG_numCol{text-align:right;font-variant-numeric:tabular-nums}.VWh0dG_costCol{color:var(--dsw-alias-label-primary);font-weight:600}.VWh0dG_na{color:var(--dsw-alias-label-dimmed)}.VWh0dG_modelCell{align-items:center;gap:8px;display:inline-flex}.VWh0dG_modelDot{border-radius:50%;flex:none;width:9px;height:9px}.VWh0dG_modelName{color:var(--dsw-alias-label-primary);font-weight:500;line-height:16px;display:block}.VWh0dG_modelProvider{color:var(--dsw-alias-label-caption);font-size:10.5px;line-height:14px;display:block}.VWh0dG_pricingToggle{cursor:pointer;text-align:left;background:0 0;border:none;justify-content:space-between;align-items:center;gap:10px;width:100%;padding:0;display:flex}.VWh0dG_pricingToggle:hover .VWh0dG_panelTitle,.VWh0dG_pricingToggle:focus-visible .VWh0dG_panelTitle{color:var(--dsw-alias-label-primary)}.VWh0dG_rateBadge{vertical-align:1px;white-space:nowrap;border-radius:999px;align-items:center;margin-left:6px;padding:1px 6px;font-size:10px;font-weight:500;line-height:14px;display:inline-flex}.VWh0dG_rateBadgeLive{color:var(--dsw-static-green-500);background:var(--dsw-alias-bg-layer-2)}.VWh0dG_rateBadgeBuiltin{color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-bg-layer-2)}.VWh0dG_pricingToggleText{align-items:baseline;gap:10px;min-width:0;display:flex}.VWh0dG_pricingChevron{width:16px;height:16px;color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}.VWh0dG_pricingChevronOpen{transform:rotate(180deg)}.VWh0dG_bandPrice{align-items:baseline;gap:6px;display:inline-flex}.VWh0dG_bandPriceOff{color:var(--dsw-alias-label-caption)}.VWh0dG_bandPriceOff:before{content:\"/\";color:var(--dsw-alias-label-dimmed);margin-right:4px}.VWh0dG_bandTag{color:var(--dsw-alias-label-secondary);flex-direction:column;gap:1px;font-size:10.5px;line-height:14px;display:inline-flex}.VWh0dG_bandTagOff{color:var(--dsw-static-green-500);font-weight:600}.VWh0dG_bandTag>span:first-child{color:var(--dsw-alias-label-primary);font-weight:500}.VWh0dG_flatTag{color:var(--dsw-alias-label-caption);font-size:10.5px;line-height:14px}.VWh0dG_healthDot{border-radius:50%;flex:none;width:8px;height:8px;display:inline-block}.VWh0dG_healthOk{background:var(--dsw-static-green-500)}.VWh0dG_healthBad{background:var(--dsw-static-red-500)}.VWh0dG_healthIdle{background:var(--dsw-static-neutral-bluish-400)}.VWh0dG_dashboardRight{align-items:center;gap:8px;min-width:0;display:flex}.VWh0dG_healthBadge{white-space:nowrap;border-radius:999px;align-items:center;gap:6px;padding:3px 9px;font-size:11px;line-height:16px;display:inline-flex}.VWh0dG_healthBadgeOk{color:var(--dsw-static-green-500);background:var(--dsw-alias-bg-layer-2)}.VWh0dG_healthBadgeBad{color:var(--dsw-static-red-500);background:var(--dsw-alias-bg-layer-2)}.VWh0dG_planTag{color:var(--dsw-static-green-500);background:var(--dsw-alias-bg-layer-2);border-radius:999px;align-items:center;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px;display:inline-flex}.VWh0dG_uncataloguedTag{vertical-align:1px;color:var(--dsw-static-amber-500);background:var(--dsw-alias-bg-layer-2);border-radius:999px;margin-left:6px;padding:0 6px;font-size:10px;font-weight:600;line-height:16px;display:inline-block}.VWh0dG_estimatedTag{vertical-align:1px;color:var(--dsw-static-blue-500);background:var(--dsw-alias-bg-layer-2);border-radius:999px;margin-left:6px;padding:0 6px;font-size:10px;font-weight:600;line-height:16px;display:inline-block}.VWh0dG_liveCostBar{color:var(--dsw-static-neutral-400);font-variant-numeric:tabular-nums;align-items:center;gap:6px;font-size:11px;line-height:16px;display:inline-flex}.VWh0dG_liveCostItem{white-space:nowrap}.VWh0dG_liveCostSep{color:var(--dsw-static-neutral-300)}.VWh0dG_liveTierPeak{color:var(--dsw-static-blue-500);font-weight:600}.VWh0dG_liveTierOff{color:var(--dsw-static-green-500);font-weight:600}.VWh0dG_liveQuotaWarn{color:var(--dsw-static-amber-500);font-weight:600}.VWh0dG_liveQuotaCrit{color:var(--dsw-static-red-500);font-weight:600}.VWh0dG_balanceCell{flex-direction:column;align-items:flex-end;gap:2px;display:inline-flex}.VWh0dG_balanceDays{color:var(--dsw-alias-label-caption);white-space:nowrap;font-size:10.5px;line-height:14px}.VWh0dG_balanceDaysLow{color:var(--dsw-static-red-500);font-weight:600}body[data-zine-mode] .VWh0dG_trigger,body[data-zine-mode] .VWh0dG_triggerPop,body[data-zine-mode] .VWh0dG_railButton{display:none}body[data-zine-mode] .VWh0dG_dashboardHead{background:#000;border-bottom:2px solid #e8ff00}body[data-zine-mode] .VWh0dG_headTitleRow{align-items:center;gap:8px;margin-top:4px;display:flex}body[data-zine-mode] .VWh0dG_dashboardTitle{color:#e8ff00;letter-spacing:.04em;text-transform:uppercase;text-shadow:0 0 8px #e8ff0066;font-weight:900}body[data-zine-mode] .VWh0dG_dashboardSubtitle{color:#c9d98a;letter-spacing:.08em;text-transform:uppercase;font-size:10px}body[data-zine-mode] .VWh0dG_closeButton{color:#0a0a05;background:#ff2d95;border:1.5px solid #ff2d95;border-radius:0;box-shadow:0 0 10px #ff2d9573}body[data-zine-mode] .VWh0dG_hero{background:#000;border:2.5px solid #e8ff00;border-radius:0;position:relative;box-shadow:0 0 0 1px #0009,0 0 24px #e8ff002e}body[data-zine-mode] .VWh0dG_heroLabel{color:#c9d98a;letter-spacing:.12em;text-transform:uppercase;font-size:10px;font-weight:900}body[data-zine-mode] .VWh0dG_heroValue{color:#e8ff00;letter-spacing:-.02em;text-shadow:0 0 12px #e8ff0073;-webkit-text-fill-color:#e8ff00;background:0 0;font-size:38px;font-weight:900}body[data-zine-mode] .VWh0dG_heroMeta{color:#c9d98a;letter-spacing:.06em;text-transform:uppercase;font-size:10.5px}body[data-zine-mode] .VWh0dG_heroSideLabel{color:#c9d98a;letter-spacing:.1em;text-transform:uppercase;font-size:10px;font-weight:900}body[data-zine-mode] .VWh0dG_heroSideValue{color:#e8ff00;text-shadow:0 0 6px #e8ff0059}body[data-zine-mode] .VWh0dG_delta{font-weight:900}body[data-zine-mode] .VWh0dG_deltaUp{color:#ff2d95}body[data-zine-mode] .VWh0dG_deltaDown{color:#c9d98a}body[data-zine-mode] .VWh0dG_tabNav{background:#000;border-bottom:2px solid #e8ff00}body[data-zine-mode] .VWh0dG_tabButton{color:#c9d98a;letter-spacing:.08em;text-transform:uppercase;border-radius:0;font-size:10.5px;font-weight:900}body[data-zine-mode] .VWh0dG_tabButton:hover,body[data-zine-mode] .VWh0dG_tabButton:focus-visible{color:#e8ff00;background:#e8ff001f}body[data-zine-mode] .VWh0dG_tabButtonActive,body[data-zine-mode] .VWh0dG_tabButtonActive:hover,body[data-zine-mode] .VWh0dG_tabButtonActive:focus-visible{color:#0a0a05;background:#e8ff00;box-shadow:0 0 10px #e8ff0073}body[data-zine-mode] .VWh0dG_panel{background:#000;border:2px solid #e8ff00;border-radius:0}body[data-zine-mode] .VWh0dG_trendPanel{position:relative}body[data-zine-mode] .VWh0dG_panelTitle{color:#e8ff00;letter-spacing:.06em;text-transform:uppercase;text-shadow:0 0 6px #e8ff0066;font-weight:900}body[data-zine-mode] .VWh0dG_panelHint{color:#c9d98a;letter-spacing:.08em;text-transform:uppercase;font-size:10px;font-weight:900}body[data-zine-mode] .VWh0dG_modelTableScroll{background:#000;border:1.5px solid #e8ff0080;border-radius:0}.VWh0dG_currencyToggle{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);border-radius:6px;align-items:center;gap:2px;margin-right:8px;padding:2px;display:inline-flex}.VWh0dG_currencyButton{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:4px;padding:4px 7px;font-size:11px;font-weight:700;line-height:1}.VWh0dG_currencyButtonActive{background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary)}.VWh0dG_subscriptionGrid{grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:10px;margin-top:10px;display:grid}.VWh0dG_subscriptionCard{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);border-radius:10px;padding:12px 14px}.VWh0dG_subscriptionHead{flex-wrap:wrap;align-items:baseline;gap:6px;margin-bottom:8px;display:flex}.VWh0dG_subscriptionName{font-size:13px;font-weight:700}.VWh0dG_subscriptionPlan{color:var(--dsw-alias-label-secondary);font-size:11px}.VWh0dG_subscriptionPlan[data-kind=code],.VWh0dG_subscriptionPlan[data-kind=token]{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-3);border-radius:999px;padding:1px 8px;font-weight:500}.VWh0dG_subscriptionTier{color:var(--dsw-alias-label-secondary);margin-left:6px}.VWh0dG_subscriptionAuto{color:var(--dsw-static-blue-500);background:color-mix(in srgb, var(--dsw-static-blue-500) 14%, var(--dsw-alias-bg-layer-2));border-radius:999px;margin-left:6px;padding:1px 6px;font-size:10px}.VWh0dG_subscriptionStatus{color:var(--dsw-alias-label-secondary);margin-bottom:6px;font-size:11px}.VWh0dG_subscriptionWindow{align-items:center;gap:8px;margin-top:6px;font-size:11px;display:flex}.VWh0dG_subscriptionWindowLabel{color:var(--dsw-alias-label-secondary);flex:0 0 44px}.VWh0dG_subscriptionTrack{background:var(--dsw-alias-bg-layer-3);border-radius:3px;flex:1;height:5px;overflow:hidden}.VWh0dG_subscriptionFill{background:var(--dsw-static-blue-500);border-radius:3px;height:100%;transition:width .2s;display:block}.VWh0dG_subscriptionFillWarn{background:var(--dsw-static-amber-500)}.VWh0dG_subscriptionFillOver{background:var(--dsw-static-red-500)}.VWh0dG_subscriptionPct{text-align:right;font-variant-numeric:tabular-nums;flex:none;min-width:52px}.VWh0dG_subscriptionExhausted{color:var(--dsw-static-red-500);min-width:52px;font-weight:600}.VWh0dG_subscriptionReset{color:var(--dsw-alias-label-secondary);flex:none}.VWh0dG_providerGroupList{flex-direction:column;gap:10px;display:flex}.VWh0dG_providerGroup{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:12px;padding:12px 14px}.VWh0dG_providerGroupHead{justify-content:space-between;align-items:baseline;gap:12px;display:flex}.VWh0dG_providerGroupTitle{align-items:center;gap:7px;min-width:0;display:inline-flex}.VWh0dG_providerGroupName{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600;line-height:18px}.VWh0dG_providerGroupMeta{flex:none;align-items:center;gap:10px;display:inline-flex}.VWh0dG_providerGroupBadge{color:var(--dsw-static-green-500);background:var(--dsw-alias-bg-layer-2);border-radius:999px;align-items:center;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px;display:inline-flex}.VWh0dG_providerGroupBalance{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;white-space:nowrap;align-items:baseline;gap:6px;font-size:12px;line-height:17px;display:inline-flex}.VWh0dG_providerGroupBalanceLabel{color:var(--dsw-alias-label-caption);font-size:11px;line-height:17px}.VWh0dG_roundsFlagBadge{color:var(--dsw-static-neutral-bluish-00);background:var(--dsw-static-red-500);border-radius:999px;margin-left:8px;padding:1px 7px;font-size:10px;font-weight:800}.VWh0dG_rounds{margin-top:10px}.VWh0dG_roundsBars{align-items:flex-end;gap:3px;height:124px;padding:16px 2px 0;display:flex;overflow-x:auto}.VWh0dG_roundsBarCol{border-radius:5px 5px 0 0;flex-direction:column;flex:1 0 28px;justify-content:flex-end;align-items:stretch;height:100%;display:flex;position:relative}.VWh0dG_roundsBarColPeak{background:color-mix(in srgb, var(--dsw-static-amber-500) 16%, transparent)}.VWh0dG_roundsBarColOff{background:var(--dsw-alias-bg-module-platform)}.VWh0dG_roundsBarLabel{text-align:center;color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;max-width:100%;font-size:9px;line-height:1.2;position:absolute;bottom:0;left:0;right:0;overflow:hidden;transform:translateY(-100%)}.VWh0dG_roundsBarWrap{flex:1;align-items:flex-end;min-height:0;display:flex}.VWh0dG_roundsBar{background:var(--dsw-static-blue-500);border-radius:2px 2px 0 0;width:100%;min-height:2px;position:relative}.VWh0dG_roundsBarFlagged{background:var(--dsw-static-red-500);border-radius:2px 2px 0 0;width:100%;min-height:2px;position:relative}.VWh0dG_roundsFlagMark{background:var(--dsw-static-red-500);border-radius:50%;width:7px;height:7px;position:absolute;top:-3px;right:-3px}.VWh0dG_roundsAxis{color:var(--dsw-alias-label-secondary);justify-content:space-between;margin-top:6px;font-size:10px;display:flex}.VWh0dG_roundsEmpty{color:var(--dsw-alias-label-secondary);margin-top:10px;font-size:12px}.VWh0dG_heatmap{margin-top:10px}.VWh0dG_heatmapGrid{grid-template-columns:repeat(7,minmax(0,1fr));gap:8px;display:grid}.VWh0dG_heatmapCellEmpty{background:var(--dsw-alias-bg-layer-1);height:30px;color:var(--dsw-alias-label-dimmed);font-variant-numeric:tabular-nums;border-radius:8px;justify-content:center;align-items:center;font-size:11px;display:flex}.VWh0dG_heatmapCell{font-variant-numeric:tabular-nums;cursor:pointer;border:0;border-radius:8px;justify-content:center;align-items:center;height:30px;padding:0;font-size:11px;display:flex}.VWh0dG_heatmapCell[data-level=\"0\"],.VWh0dG_heatmapCell[data-level=\"1\"],.VWh0dG_heatmapCell[data-level=\"2\"]{color:var(--dsw-alias-label-primary)}.VWh0dG_heatmapCell[data-level=\"3\"],.VWh0dG_heatmapCell[data-level=\"4\"]{color:var(--dsw-static-neutral-bluish-00)}.VWh0dG_heatmapFooter{color:var(--dsw-alias-label-secondary);align-items:center;gap:8px;margin-top:10px;font-size:10px;display:flex}.VWh0dG_heatmapLegend{gap:3px;display:inline-flex}.VWh0dG_heatmapLegend i{border-radius:4px;width:14px;height:14px;display:block}.VWh0dG_heatmapHover{font-variant-numeric:tabular-nums;margin-left:auto}.VWh0dG_heatmapYearScroll{padding-bottom:2px;overflow-x:auto}.VWh0dG_heatmapYearGrid{grid-template-rows:repeat(7,11px);grid-auto-flow:column;gap:3px;min-width:max-content;display:grid}.VWh0dG_heatmapYearCell{cursor:pointer;border:0;border-radius:2px;width:11px;height:11px;padding:0}.VWh0dG_pluginInfo{flex-direction:column;gap:8px;margin-top:10px;display:flex}.VWh0dG_pluginInfoRow{align-items:baseline;gap:12px;font-size:12px;display:flex}.VWh0dG_pluginInfoLabel{color:var(--dsw-alias-label-secondary);flex:0 0 72px}.VWh0dG_pluginInfoValue{color:var(--dsw-alias-label-primary);word-break:break-all}.VWh0dG_pluginInfoLink{color:var(--dsw-static-blue-500);word-break:break-all;text-decoration:none}.VWh0dG_pluginInfoLink:hover{text-decoration:underline}.VWh0dG_tokenPanel{flex-direction:column;gap:14px;display:flex}.VWh0dG_tokenModelBar{background:var(--dsw-alias-bg-layer-2);border-radius:999px;height:8px;overflow:hidden}.VWh0dG_tokenModelParts{height:100%;display:flex}.VWh0dG_tokenModelPartIn{background:var(--dsw-static-blue-500)}.VWh0dG_tokenModelPartOut{background:var(--dsw-static-amber-500)}.VWh0dG_tokenModelShareRow{align-items:center;gap:6px;display:inline-flex}@media (width<=640px){.VWh0dG_kpiGrid{grid-template-columns:repeat(2,minmax(0,1fr))}.VWh0dG_hero{gap:14px}.VWh0dG_heroTop{flex-direction:column;align-items:flex-start;gap:12px}.VWh0dG_heroGauge{width:72px;height:72px}.VWh0dG_heroSide{gap:12px}.VWh0dG_heroSideSpacer{display:none}}.VWh0dG_peakAlert{z-index:2000;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:12px;align-items:center;gap:12px;min-width:300px;max-width:460px;padding:10px 12px;animation:.2s VWh0dG_peakAlertIn;display:flex;position:fixed;box-shadow:0 4px 16px #00000014}.VWh0dG_peakAlertCorner{bottom:18px;right:18px}.VWh0dG_peakAlertCenter{top:20%;left:50%;transform:translate(-50%)}.VWh0dG_peakAlertTag{letter-spacing:.01em;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-3);white-space:nowrap;border-radius:999px;flex:none;align-items:center;gap:6px;padding:3px 9px;font-size:11px;font-weight:650;display:inline-flex}.VWh0dG_peakAlertTag:before{content:\"\";background:currentColor;border-radius:50%;width:6px;height:6px}.VWh0dG_peakAlertPeak .VWh0dG_peakAlertTag{color:var(--dsw-static-amber-500)}.VWh0dG_peakAlertOff .VWh0dG_peakAlertTag{color:var(--dsw-static-blue-500)}.VWh0dG_peakAlertCountdown{font-variant-numeric:tabular-nums;color:var(--dsw-alias-label-primary);flex:none;font-size:18px;font-weight:700;line-height:1}.VWh0dG_peakAlertText{min-width:0;color:var(--dsw-alias-label-secondary);flex:1;font-size:12px;line-height:18px}.VWh0dG_peakAlertClose{width:20px;height:20px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:6px;flex:none;justify-content:center;align-items:center;font-size:15px;line-height:1;transition:background-color .14s,color .14s;display:inline-flex}.VWh0dG_peakAlertClose:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2)}@keyframes VWh0dG_peakAlertIn{0%{opacity:0}to{opacity:1}}.VWh0dG_peakAlertPanel{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:16px;flex-direction:column;gap:10px;padding:14px 16px;display:flex}.VWh0dG_peakAlertPanelHead{justify-content:space-between;align-items:center;gap:10px;display:flex}.VWh0dG_peakAlertPanelLabel{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600}.VWh0dG_peakAlertPanelBody{flex-wrap:wrap;align-items:center;gap:12px 16px;display:flex}.VWh0dG_peakAlertField{color:var(--dsw-alias-label-secondary);align-items:center;gap:8px;font-size:12px;display:inline-flex}.VWh0dG_peakAlertNum{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);width:56px;color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;border-radius:6px;padding:4px 6px}.VWh0dG_peakAlertSelect{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);border-radius:6px;padding:4px 6px;font-size:12px}.VWh0dG_peakAlertCheck{color:var(--dsw-alias-label-secondary);align-items:center;gap:6px;font-size:12px;display:inline-flex}.VWh0dG_peakAlertPreview{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;padding:5px 10px;font-size:12px}.VWh0dG_peakAlertPreview:hover{background:var(--dsw-alias-bg-layer-3)}.VWh0dG_settingsHead{flex-direction:column;gap:4px;margin-bottom:2px;display:flex}.VWh0dG_settingsTitle{letter-spacing:-.005em;color:var(--dsw-alias-label-primary);margin:0;font-size:15px;font-weight:650;line-height:22px}.VWh0dG_settingsHint{color:var(--dsw-alias-label-caption);margin:0;font-size:11px;line-height:16px}.VWh0dG_budgetHint,.VWh0dG_peakAlertHint{color:var(--dsw-alias-label-caption);margin:6px 0 0;font-size:11px;line-height:16px}";
28
28
  const tagId = "@kenz1117/dsh-ui-usage-billing/UsageBilling.module.css";
29
29
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
30
30
  const tag = document.createElement("style");
@@ -34,255 +34,266 @@ window.__ModuleLoader__.load({
34
34
  document.head.appendChild(tag);
35
35
  }
36
36
  var UsageBilling_module_css_default = {
37
- "subscriptionStatus": "VWh0dG_subscriptionStatus",
38
- "triggerPopBar": "VWh0dG_triggerPopBar",
39
- "currencyButton": "VWh0dG_currencyButton",
40
- "chartSvg": "VWh0dG_chartSvg",
41
- "heroSideSpacer": "VWh0dG_heroSideSpacer",
42
- "roundsBarColPeak": "VWh0dG_roundsBarColPeak",
43
- "budgetFillWarn": "VWh0dG_budgetFillWarn",
44
- "rangeButton": "VWh0dG_rangeButton",
45
- "modelProvider": "VWh0dG_modelProvider",
46
- "trigger": "VWh0dG_trigger",
47
- "estimatedTag": "VWh0dG_estimatedTag",
48
- "triggerIcon": "VWh0dG_triggerIcon",
49
- "roundsBarCol": "VWh0dG_roundsBarCol",
37
+ "budgetFillOver": "VWh0dG_budgetFillOver",
38
+ "kpiValue": "VWh0dG_kpiValue",
39
+ "chartTooltip": "VWh0dG_chartTooltip",
40
+ "heatmapYearGrid": "VWh0dG_heatmapYearGrid",
41
+ "deltaDown": "VWh0dG_deltaDown",
42
+ "budget": "VWh0dG_budget",
50
43
  "chartDot": "VWh0dG_chartDot",
51
- "switchKnob": "VWh0dG_switchKnob",
52
- "triggerSparkHot": "VWh0dG_triggerSparkHot",
53
- "switchOn": "VWh0dG_switchOn",
54
- "kpiLabel": "VWh0dG_kpiLabel",
55
- "bucketStatSub": "VWh0dG_bucketStatSub",
56
- "dashboardModal": "VWh0dG_dashboardModal",
57
- "pricingChevron": "VWh0dG_pricingChevron",
58
- "chartLegendBar": "VWh0dG_chartLegendBar",
59
44
  "bandPriceOff": "VWh0dG_bandPriceOff",
60
- "liveQuotaCrit": "VWh0dG_liveQuotaCrit",
61
- "triggerSpark": "VWh0dG_triggerSpark",
62
- "na": "VWh0dG_na",
63
- "rateBadge": "VWh0dG_rateBadge",
64
- "budgetHead": "VWh0dG_budgetHead",
65
- "providerGroupName": "VWh0dG_providerGroupName",
66
- "modelName": "VWh0dG_modelName",
45
+ "planTag": "VWh0dG_planTag",
67
46
  "budgetInput": "VWh0dG_budgetInput",
68
- "peakAlertField": "VWh0dG_peakAlertField",
69
- "budgetInputWrap": "VWh0dG_budgetInputWrap",
70
- "heroGaugeCenter": "VWh0dG_heroGaugeCenter",
47
+ "subscriptionExhausted": "VWh0dG_subscriptionExhausted",
48
+ "pluginInfoLabel": "VWh0dG_pluginInfoLabel",
49
+ "peakAlertText": "VWh0dG_peakAlertText",
50
+ "dashboardTitle": "VWh0dG_dashboardTitle",
51
+ "budgetFillWarn": "VWh0dG_budgetFillWarn",
52
+ "chartEmpty": "VWh0dG_chartEmpty",
53
+ "deltaUp": "VWh0dG_deltaUp",
54
+ "rounds": "VWh0dG_rounds",
55
+ "roundsEmpty": "VWh0dG_roundsEmpty",
56
+ "chartLine": "VWh0dG_chartLine",
57
+ "peakAlertHint": "VWh0dG_peakAlertHint",
58
+ "rangeToggle": "VWh0dG_rangeToggle",
59
+ "bucketCost": "VWh0dG_bucketCost",
60
+ "heroReadout": "VWh0dG_heroReadout",
61
+ "healthBadgeBad": "VWh0dG_healthBadgeBad",
62
+ "peakAlert": "VWh0dG_peakAlert",
63
+ "modelProvider": "VWh0dG_modelProvider",
64
+ "heroGauge": "VWh0dG_heroGauge",
65
+ "healthBadge": "VWh0dG_healthBadge",
66
+ "providerGroupList": "VWh0dG_providerGroupList",
67
+ "triggerPopBar": "VWh0dG_triggerPopBar",
68
+ "kpiGreen": "VWh0dG_kpiGreen",
69
+ "liveTierOff": "VWh0dG_liveTierOff",
70
+ "heatmapFooter": "VWh0dG_heatmapFooter",
71
+ "triggerPopLabel": "VWh0dG_triggerPopLabel",
72
+ "balanceDaysLow": "VWh0dG_balanceDaysLow",
73
+ "peakAlertPreview": "VWh0dG_peakAlertPreview",
74
+ "panelTitle": "VWh0dG_panelTitle",
71
75
  "budgetHint": "VWh0dG_budgetHint",
76
+ "bucketStat": "VWh0dG_bucketStat",
77
+ "chartWrap": "VWh0dG_chartWrap",
78
+ "roundsBar": "VWh0dG_roundsBar",
79
+ "chartAxisLabel": "VWh0dG_chartAxisLabel",
80
+ "subscriptionPct": "VWh0dG_subscriptionPct",
81
+ "healthBad": "VWh0dG_healthBad",
72
82
  "heroLabel": "VWh0dG_heroLabel",
73
- "tabButtonActive": "VWh0dG_tabButtonActive",
74
- "modelTableScroll": "VWh0dG_modelTableScroll",
75
- "tableScroll": "VWh0dG_tableScroll",
76
- "shareSegUser": "VWh0dG_shareSegUser",
77
- "pricingChevronOpen": "VWh0dG_pricingChevronOpen",
78
- "peakAlert": "VWh0dG_peakAlert",
79
- "emptyRow": "VWh0dG_emptyRow",
80
- "rounds": "VWh0dG_rounds",
81
- "chartCrosshair": "VWh0dG_chartCrosshair",
82
- "heatmapGrid": "VWh0dG_heatmapGrid",
83
- "peakAlertTag": "VWh0dG_peakAlertTag",
84
- "kpiGrid": "VWh0dG_kpiGrid",
85
- "deltaDown": "VWh0dG_deltaDown",
86
83
  "tabPanelIn": "VWh0dG_tabPanelIn",
87
- "heroGaugeTrack": "VWh0dG_heroGaugeTrack",
88
- "healthBadge": "VWh0dG_healthBadge",
89
- "chartTooltipSwatch": "VWh0dG_chartTooltipSwatch",
90
- "triggerPopValue": "VWh0dG_triggerPopValue",
84
+ "hero": "VWh0dG_hero",
85
+ "emptyRow": "VWh0dG_emptyRow",
86
+ "providerGroupName": "VWh0dG_providerGroupName",
87
+ "na": "VWh0dG_na",
88
+ "triggerSpark": "VWh0dG_triggerSpark",
89
+ "chartStack": "VWh0dG_chartStack",
90
+ "chartTooltipRow": "VWh0dG_chartTooltipRow",
91
+ "shareSegPeak": "VWh0dG_shareSegPeak",
92
+ "heatmapLegend": "VWh0dG_heatmapLegend",
91
93
  "dashboardHead": "VWh0dG_dashboardHead",
92
- "providerGroupTitle": "VWh0dG_providerGroupTitle",
93
- "heroMeta": "VWh0dG_heroMeta",
94
- "subscriptionTrack": "VWh0dG_subscriptionTrack",
95
- "heroGaugePct": "VWh0dG_heroGaugePct",
96
- "kpiTile": "VWh0dG_kpiTile",
97
- "heatmapYearCell": "VWh0dG_heatmapYearCell",
98
- "peakAlertPanelLabel": "VWh0dG_peakAlertPanelLabel",
99
- "heatmapFooter": "VWh0dG_heatmapFooter",
94
+ "shareSegOff": "VWh0dG_shareSegOff",
95
+ "heroGaugeArc": "VWh0dG_heroGaugeArc",
96
+ "tokenModelPartOut": "VWh0dG_tokenModelPartOut",
97
+ "tabButton": "VWh0dG_tabButton",
98
+ "heroGaugeLabel": "VWh0dG_heroGaugeLabel",
99
+ "chartLegend": "VWh0dG_chartLegend",
100
+ "triggerPopBars": "VWh0dG_triggerPopBars",
101
+ "dashboardBody": "VWh0dG_dashboardBody",
102
+ "pluginInfoRow": "VWh0dG_pluginInfoRow",
100
103
  "triggerWrap": "VWh0dG_triggerWrap",
104
+ "budgetOverPulse": "VWh0dG_budgetOverPulse",
105
+ "modelDot": "VWh0dG_modelDot",
106
+ "pricingChevronOpen": "VWh0dG_pricingChevronOpen",
107
+ "switchKnob": "VWh0dG_switchKnob",
108
+ "kpiTile": "VWh0dG_kpiTile",
109
+ "shareTrack": "VWh0dG_shareTrack",
110
+ "settingsTitle": "VWh0dG_settingsTitle",
111
+ "triggerMeta": "VWh0dG_triggerMeta",
101
112
  "bandPrice": "VWh0dG_bandPrice",
102
- "shareValue": "VWh0dG_shareValue",
103
- "railButton": "VWh0dG_railButton",
104
- "hero": "VWh0dG_hero",
105
- "liveCostItem": "VWh0dG_liveCostItem",
106
- "liveTierOff": "VWh0dG_liveTierOff",
107
- "dashboard": "VWh0dG_dashboard",
108
- "deltaUp": "VWh0dG_deltaUp",
109
- "healthBad": "VWh0dG_healthBad",
110
- "shareSegAssistant": "VWh0dG_shareSegAssistant",
111
- "subscriptionFill": "VWh0dG_subscriptionFill",
112
- "dashboardRight": "VWh0dG_dashboardRight",
113
- "liveCostSep": "VWh0dG_liveCostSep",
114
- "flatTag": "VWh0dG_flatTag",
115
- "budgetLabel": "VWh0dG_budgetLabel",
116
- "triggerRow": "VWh0dG_triggerRow",
117
- "pricingTable": "VWh0dG_pricingTable",
118
- "pricingToggleText": "VWh0dG_pricingToggleText",
119
- "peakAlertPreview": "VWh0dG_peakAlertPreview",
120
- "heroTop": "VWh0dG_heroTop",
121
- "heatmapHover": "VWh0dG_heatmapHover",
122
- "providerGroupHead": "VWh0dG_providerGroupHead",
123
- "liveQuotaWarn": "VWh0dG_liveQuotaWarn",
124
- "tabNav": "VWh0dG_tabNav",
125
- "heatmapYearGrid": "VWh0dG_heatmapYearGrid",
126
- "providerGroupBalance": "VWh0dG_providerGroupBalance",
127
- "peakAlertPanelBody": "VWh0dG_peakAlertPanelBody",
128
- "triggerSub": "VWh0dG_triggerSub",
129
- "peakAlertClose": "VWh0dG_peakAlertClose",
113
+ "balanceDays": "VWh0dG_balanceDays",
114
+ "currencyToggle": "VWh0dG_currencyToggle",
115
+ "subscriptionGrid": "VWh0dG_subscriptionGrid",
116
+ "subscriptionStatus": "VWh0dG_subscriptionStatus",
117
+ "peakAlertPeak": "VWh0dG_peakAlertPeak",
118
+ "healthOk": "VWh0dG_healthOk",
130
119
  "settingsHint": "VWh0dG_settingsHint",
131
- "healthBadgeOk": "VWh0dG_healthBadgeOk",
132
- "peakAlertCountdown": "VWh0dG_peakAlertCountdown",
133
- "triggerSparkBar": "VWh0dG_triggerSparkBar",
134
- "exportLabel": "VWh0dG_exportLabel",
135
- "chartEmpty": "VWh0dG_chartEmpty",
120
+ "subscriptionTier": "VWh0dG_subscriptionTier",
121
+ "tableScroll": "VWh0dG_tableScroll",
122
+ "heatmapCellEmpty": "VWh0dG_heatmapCellEmpty",
123
+ "roundsBarColOff": "VWh0dG_roundsBarColOff",
124
+ "bandTagOff": "VWh0dG_bandTagOff",
125
+ "modelTableScroll": "VWh0dG_modelTableScroll",
126
+ "roundsAxis": "VWh0dG_roundsAxis",
127
+ "subscriptionFillWarn": "VWh0dG_subscriptionFillWarn",
128
+ "pluginInfoValue": "VWh0dG_pluginInfoValue",
129
+ "estimatedTag": "VWh0dG_estimatedTag",
130
+ "triggerSub": "VWh0dG_triggerSub",
131
+ "heroSideItem": "VWh0dG_heroSideItem",
132
+ "panelHint": "VWh0dG_panelHint",
133
+ "triggerPop": "VWh0dG_triggerPop",
134
+ "liveQuotaWarn": "VWh0dG_liveQuotaWarn",
135
+ "kpiGrid": "VWh0dG_kpiGrid",
136
+ "tokenModelShareRow": "VWh0dG_tokenModelShareRow",
137
+ "heatmapYearCell": "VWh0dG_heatmapYearCell",
138
+ "heroSideSpacer": "VWh0dG_heroSideSpacer",
139
+ "roundsFlagBadge": "VWh0dG_roundsFlagBadge",
140
+ "dashboardIn": "VWh0dG_dashboardIn",
141
+ "uncataloguedTag": "VWh0dG_uncataloguedTag",
136
142
  "subscriptionAuto": "VWh0dG_subscriptionAuto",
137
- "budgetControls": "VWh0dG_budgetControls",
138
- "subscriptionCard": "VWh0dG_subscriptionCard",
139
- "healthDot": "VWh0dG_healthDot",
143
+ "triggerRow": "VWh0dG_triggerRow",
144
+ "liveTierPeak": "VWh0dG_liveTierPeak",
145
+ "exportBar": "VWh0dG_exportBar",
146
+ "providerGroup": "VWh0dG_providerGroup",
147
+ "heatmapGrid": "VWh0dG_heatmapGrid",
148
+ "shareSeg": "VWh0dG_shareSeg",
149
+ "rateBadge": "VWh0dG_rateBadge",
150
+ "heroGaugeCenter": "VWh0dG_heroGaugeCenter",
151
+ "pluginInfoLink": "VWh0dG_pluginInfoLink",
152
+ "shareSegUser": "VWh0dG_shareSegUser",
153
+ "delta": "VWh0dG_delta",
154
+ "trigger": "VWh0dG_trigger",
155
+ "dashboard": "VWh0dG_dashboard",
156
+ "dashboardSubtitle": "VWh0dG_dashboardSubtitle",
157
+ "tabNav": "VWh0dG_tabNav",
158
+ "chartSvg": "VWh0dG_chartSvg",
140
159
  "heroGaugePctOver": "VWh0dG_heroGaugePctOver",
141
- "budgetTrack": "VWh0dG_budgetTrack",
160
+ "flatTag": "VWh0dG_flatTag",
161
+ "chartTooltipSwatch": "VWh0dG_chartTooltipSwatch",
162
+ "panel": "VWh0dG_panel",
163
+ "bucketStatLabel": "VWh0dG_bucketStatLabel",
164
+ "heatmapHover": "VWh0dG_heatmapHover",
142
165
  "heroSideLabel": "VWh0dG_heroSideLabel",
143
- "providerGroupBadge": "VWh0dG_providerGroupBadge",
166
+ "panelHead": "VWh0dG_panelHead",
167
+ "modelTable": "VWh0dG_modelTable",
168
+ "currencyButton": "VWh0dG_currencyButton",
169
+ "roundsBarColPeak": "VWh0dG_roundsBarColPeak",
170
+ "liveCostBar": "VWh0dG_liveCostBar",
144
171
  "shareItem": "VWh0dG_shareItem",
145
- "trendPanel": "VWh0dG_trendPanel",
146
- "chartTooltipDate": "VWh0dG_chartTooltipDate",
172
+ "tokenModelPartIn": "VWh0dG_tokenModelPartIn",
173
+ "peakAlertField": "VWh0dG_peakAlertField",
174
+ "peakAlertCountdown": "VWh0dG_peakAlertCountdown",
147
175
  "heroGaugeSvg": "VWh0dG_heroGaugeSvg",
148
- "budgetValue": "VWh0dG_budgetValue",
149
- "roundsBar": "VWh0dG_roundsBar",
150
- "chartWrap": "VWh0dG_chartWrap",
151
- "rateBadgeBuiltin": "VWh0dG_rateBadgeBuiltin",
152
- "kpiDetail": "VWh0dG_kpiDetail",
153
- "shareDot": "VWh0dG_shareDot",
154
- "balanceCell": "VWh0dG_balanceCell",
155
- "roundsAxis": "VWh0dG_roundsAxis",
156
- "roundsEmpty": "VWh0dG_roundsEmpty",
157
- "switch": "VWh0dG_switch",
158
- "peakAlertIn": "VWh0dG_peakAlertIn",
159
- "roundsBars": "VWh0dG_roundsBars",
160
- "exportButton": "VWh0dG_exportButton",
161
- "subscriptionWindow": "VWh0dG_subscriptionWindow",
162
- "closeButton": "VWh0dG_closeButton",
163
- "exportBar": "VWh0dG_exportBar",
164
- "shareSegOff": "VWh0dG_shareSegOff",
165
- "budgetUnit": "VWh0dG_budgetUnit",
166
- "tabPanel": "VWh0dG_tabPanel",
167
- "heroReadout": "VWh0dG_heroReadout",
168
- "dashboardSubtitle": "VWh0dG_dashboardSubtitle",
169
- "healthIdle": "VWh0dG_healthIdle",
170
- "subscriptionGrid": "VWh0dG_subscriptionGrid",
171
- "pricingTip": "VWh0dG_pricingTip",
172
- "rangeButtonActive": "VWh0dG_rangeButtonActive",
173
- "bucketSummary": "VWh0dG_bucketSummary",
174
- "bandTag": "VWh0dG_bandTag",
175
- "delta": "VWh0dG_delta",
176
- "subscriptionReset": "VWh0dG_subscriptionReset",
177
- "balanceDaysLow": "VWh0dG_balanceDaysLow",
178
- "roundsBarFlagged": "VWh0dG_roundsBarFlagged",
179
- "bucketThird": "VWh0dG_bucketThird",
180
- "shareTrack": "VWh0dG_shareTrack",
181
- "triggerMeta": "VWh0dG_triggerMeta",
182
- "panelHint": "VWh0dG_panelHint",
183
- "chartLine": "VWh0dG_chartLine",
184
- "bucketSep": "VWh0dG_bucketSep",
185
- "heroValue": "VWh0dG_heroValue",
186
- "shareSegTool": "VWh0dG_shareSegTool",
187
- "peakAlertOff": "VWh0dG_peakAlertOff",
188
- "subscriptionPct": "VWh0dG_subscriptionPct",
189
- "subscriptionTier": "VWh0dG_subscriptionTier",
190
- "providerGroupList": "VWh0dG_providerGroupList",
191
- "heroSide": "VWh0dG_heroSide",
192
- "chartBar": "VWh0dG_chartBar",
193
- "peakAlertPeak": "VWh0dG_peakAlertPeak",
194
- "modelTable": "VWh0dG_modelTable",
195
- "tabButton": "VWh0dG_tabButton",
196
176
  "roundsBarWrap": "VWh0dG_roundsBarWrap",
197
- "modelDot": "VWh0dG_modelDot",
198
- "roundsFlagBadge": "VWh0dG_roundsFlagBadge",
199
- "budgetFill": "VWh0dG_budgetFill",
200
- "subscriptionPlan": "VWh0dG_subscriptionPlan",
201
- "bucketStatValue": "VWh0dG_bucketStatValue",
202
- "healthBadgeBad": "VWh0dG_healthBadgeBad",
203
- "budget": "VWh0dG_budget",
177
+ "triggerSparkHot": "VWh0dG_triggerSparkHot",
204
178
  "shareLegend": "VWh0dG_shareLegend",
205
- "chartLegendLine": "VWh0dG_chartLegendLine",
206
- "subscriptionWindowLabel": "VWh0dG_subscriptionWindowLabel",
207
- "kpiValue": "VWh0dG_kpiValue",
208
- "peakAlertCheck": "VWh0dG_peakAlertCheck",
209
- "triggerPopBars": "VWh0dG_triggerPopBars",
210
- "subscriptionExhausted": "VWh0dG_subscriptionExhausted",
211
- "heatmapLegend": "VWh0dG_heatmapLegend",
212
- "numCol": "VWh0dG_numCol",
213
- "rateBadgeLive": "VWh0dG_rateBadgeLive",
214
- "bandTagOff": "VWh0dG_bandTagOff",
215
- "heroGaugeArcOver": "VWh0dG_heroGaugeArcOver",
216
- "providerGroupBalanceLabel": "VWh0dG_providerGroupBalanceLabel",
217
- "bucketStatLabel": "VWh0dG_bucketStatLabel",
218
- "heroGaugeArc": "VWh0dG_heroGaugeArc",
219
- "headTitleRow": "VWh0dG_headTitleRow",
220
- "rangeToggle": "VWh0dG_rangeToggle",
221
- "subscriptionHead": "VWh0dG_subscriptionHead",
222
- "peakAlertCorner": "VWh0dG_peakAlertCorner",
223
- "peakAlertSelect": "VWh0dG_peakAlertSelect",
224
- "budgetFillOver": "VWh0dG_budgetFillOver",
225
- "chartStack": "VWh0dG_chartStack",
226
- "settingsHead": "VWh0dG_settingsHead",
227
- "currencyToggle": "VWh0dG_currencyToggle",
179
+ "tokenModelBar": "VWh0dG_tokenModelBar",
180
+ "heroCurrency": "VWh0dG_heroCurrency",
181
+ "subscriptionReset": "VWh0dG_subscriptionReset",
228
182
  "heroSideValue": "VWh0dG_heroSideValue",
229
- "modelCell": "VWh0dG_modelCell",
230
- "peakAlertCenter": "VWh0dG_peakAlertCenter",
231
- "peakAlertPanelHead": "VWh0dG_peakAlertPanelHead",
232
- "triggerAmount": "VWh0dG_triggerAmount",
233
- "roundsFlagMark": "VWh0dG_roundsFlagMark",
234
- "heatmapCell": "VWh0dG_heatmapCell",
235
- "dashboardBody": "VWh0dG_dashboardBody",
236
- "uncataloguedTag": "VWh0dG_uncataloguedTag",
237
- "peakAlertHint": "VWh0dG_peakAlertHint",
238
- "roundsBarColOff": "VWh0dG_roundsBarColOff",
239
- "peakAlertPanel": "VWh0dG_peakAlertPanel",
240
- "heroSideItem": "VWh0dG_heroSideItem",
241
- "liveCostBar": "VWh0dG_liveCostBar",
242
- "providerGroupMeta": "VWh0dG_providerGroupMeta",
243
- "liveTierPeak": "VWh0dG_liveTierPeak",
244
- "kpiGreen": "VWh0dG_kpiGreen",
245
- "heroGauge": "VWh0dG_heroGauge",
183
+ "peakAlertTag": "VWh0dG_peakAlertTag",
184
+ "subscriptionWindow": "VWh0dG_subscriptionWindow",
185
+ "switchOn": "VWh0dG_switchOn",
186
+ "rateBadgeBuiltin": "VWh0dG_rateBadgeBuiltin",
187
+ "rangeButton": "VWh0dG_rangeButton",
188
+ "budgetInputWrap": "VWh0dG_budgetInputWrap",
246
189
  "heatmap": "VWh0dG_heatmap",
190
+ "peakAlertSelect": "VWh0dG_peakAlertSelect",
191
+ "dashboardRight": "VWh0dG_dashboardRight",
192
+ "liveCostSep": "VWh0dG_liveCostSep",
193
+ "heroMeta": "VWh0dG_heroMeta",
194
+ "healthDot": "VWh0dG_healthDot",
247
195
  "chartGrid": "VWh0dG_chartGrid",
248
- "panel": "VWh0dG_panel",
249
- "heroCurrency": "VWh0dG_heroCurrency",
250
- "planTag": "VWh0dG_planTag",
251
196
  "subscriptionName": "VWh0dG_subscriptionName",
252
- "peakAlertText": "VWh0dG_peakAlertText",
253
- "subscriptionFillWarn": "VWh0dG_subscriptionFillWarn",
254
- "subscriptionFillOver": "VWh0dG_subscriptionFillOver",
255
- "triggerPopLabel": "VWh0dG_triggerPopLabel",
197
+ "liveCostItem": "VWh0dG_liveCostItem",
198
+ "triggerIcon": "VWh0dG_triggerIcon",
199
+ "triggerSparkBar": "VWh0dG_triggerSparkBar",
200
+ "providerGroupBadge": "VWh0dG_providerGroupBadge",
201
+ "pricingTip": "VWh0dG_pricingTip",
202
+ "peakAlertPanelBody": "VWh0dG_peakAlertPanelBody",
203
+ "chartLegendLine": "VWh0dG_chartLegendLine",
204
+ "heroGaugePct": "VWh0dG_heroGaugePct",
205
+ "shareSegAssistant": "VWh0dG_shareSegAssistant",
206
+ "liveQuotaCrit": "VWh0dG_liveQuotaCrit",
207
+ "roundsBarCol": "VWh0dG_roundsBarCol",
208
+ "bucketSummary": "VWh0dG_bucketSummary",
209
+ "heroSide": "VWh0dG_heroSide",
210
+ "balanceCell": "VWh0dG_balanceCell",
256
211
  "pricingToggle": "VWh0dG_pricingToggle",
257
- "bucketOfficial": "VWh0dG_bucketOfficial",
258
- "healthOk": "VWh0dG_healthOk",
259
- "chartLegend": "VWh0dG_chartLegend",
260
- "heatmapCellEmpty": "VWh0dG_heatmapCellEmpty",
261
- "dashboardTitle": "VWh0dG_dashboardTitle",
212
+ "triggerPopValue": "VWh0dG_triggerPopValue",
213
+ "currencyButtonActive": "VWh0dG_currencyButtonActive",
214
+ "tabButtonActive": "VWh0dG_tabButtonActive",
215
+ "heroValue": "VWh0dG_heroValue",
216
+ "peakAlertCheck": "VWh0dG_peakAlertCheck",
217
+ "rangeButtonActive": "VWh0dG_rangeButtonActive",
218
+ "shareSegTool": "VWh0dG_shareSegTool",
219
+ "budgetLabel": "VWh0dG_budgetLabel",
220
+ "modelName": "VWh0dG_modelName",
221
+ "chartCrosshair": "VWh0dG_chartCrosshair",
222
+ "pricingTable": "VWh0dG_pricingTable",
223
+ "subscriptionWindowLabel": "VWh0dG_subscriptionWindowLabel",
224
+ "peakAlertPanelHead": "VWh0dG_peakAlertPanelHead",
225
+ "pricingToggleText": "VWh0dG_pricingToggleText",
226
+ "peakAlertCenter": "VWh0dG_peakAlertCenter",
227
+ "roundsBars": "VWh0dG_roundsBars",
228
+ "tokenPanel": "VWh0dG_tokenPanel",
262
229
  "triggerPopRow": "VWh0dG_triggerPopRow",
263
- "balanceDays": "VWh0dG_balanceDays",
264
- "shareSegPeak": "VWh0dG_shareSegPeak",
265
- "triggerPop": "VWh0dG_triggerPop",
266
- "settingsTitle": "VWh0dG_settingsTitle",
267
- "shareSeg": "VWh0dG_shareSeg",
268
- "chartTooltipRow": "VWh0dG_chartTooltipRow",
269
- "providerGroup": "VWh0dG_providerGroup",
270
- "chartAxisLabel": "VWh0dG_chartAxisLabel",
271
- "roundsBarLabel": "VWh0dG_roundsBarLabel",
272
- "bucketStat": "VWh0dG_bucketStat",
273
- "costCol": "VWh0dG_costCol",
274
- "heatmapYearScroll": "VWh0dG_heatmapYearScroll",
275
- "panelHead": "VWh0dG_panelHead",
230
+ "peakAlertPanel": "VWh0dG_peakAlertPanel",
231
+ "settingsHead": "VWh0dG_settingsHead",
232
+ "shareValue": "VWh0dG_shareValue",
276
233
  "peakAlertNum": "VWh0dG_peakAlertNum",
277
- "panelTitle": "VWh0dG_panelTitle",
278
- "budgetOverPulse": "VWh0dG_budgetOverPulse",
234
+ "kpiDetail": "VWh0dG_kpiDetail",
235
+ "subscriptionPlan": "VWh0dG_subscriptionPlan",
236
+ "peakAlertPanelLabel": "VWh0dG_peakAlertPanelLabel",
279
237
  "triggerBody": "VWh0dG_triggerBody",
280
- "bucketCost": "VWh0dG_bucketCost",
281
- "heroGaugeLabel": "VWh0dG_heroGaugeLabel",
282
- "currencyButtonActive": "VWh0dG_currencyButtonActive",
238
+ "exportButton": "VWh0dG_exportButton",
239
+ "pricingChevron": "VWh0dG_pricingChevron",
240
+ "budgetUnit": "VWh0dG_budgetUnit",
241
+ "bucketStatValue": "VWh0dG_bucketStatValue",
242
+ "exportLabel": "VWh0dG_exportLabel",
243
+ "roundsBarLabel": "VWh0dG_roundsBarLabel",
244
+ "budgetValue": "VWh0dG_budgetValue",
245
+ "peakAlertCorner": "VWh0dG_peakAlertCorner",
246
+ "triggerAmount": "VWh0dG_triggerAmount",
247
+ "budgetHead": "VWh0dG_budgetHead",
248
+ "bucketStatSub": "VWh0dG_bucketStatSub",
249
+ "numCol": "VWh0dG_numCol",
250
+ "heroTop": "VWh0dG_heroTop",
251
+ "rateBadgeLive": "VWh0dG_rateBadgeLive",
252
+ "peakAlertClose": "VWh0dG_peakAlertClose",
253
+ "subscriptionHead": "VWh0dG_subscriptionHead",
254
+ "headTitleRow": "VWh0dG_headTitleRow",
255
+ "chartLegendBar": "VWh0dG_chartLegendBar",
256
+ "peakAlertIn": "VWh0dG_peakAlertIn",
257
+ "bucketThird": "VWh0dG_bucketThird",
258
+ "trendPanel": "VWh0dG_trendPanel",
259
+ "budgetTrack": "VWh0dG_budgetTrack",
283
260
  "heroMain": "VWh0dG_heroMain",
284
- "chartTooltip": "VWh0dG_chartTooltip",
285
- "dashboardIn": "VWh0dG_dashboardIn"
261
+ "providerGroupMeta": "VWh0dG_providerGroupMeta",
262
+ "railButton": "VWh0dG_railButton",
263
+ "heatmapYearScroll": "VWh0dG_heatmapYearScroll",
264
+ "shareDot": "VWh0dG_shareDot",
265
+ "providerGroupBalance": "VWh0dG_providerGroupBalance",
266
+ "subscriptionFill": "VWh0dG_subscriptionFill",
267
+ "peakAlertOff": "VWh0dG_peakAlertOff",
268
+ "healthIdle": "VWh0dG_healthIdle",
269
+ "switch": "VWh0dG_switch",
270
+ "chartTooltipDate": "VWh0dG_chartTooltipDate",
271
+ "providerGroupHead": "VWh0dG_providerGroupHead",
272
+ "roundsFlagMark": "VWh0dG_roundsFlagMark",
273
+ "dashboardModal": "VWh0dG_dashboardModal",
274
+ "chartBar": "VWh0dG_chartBar",
275
+ "bucketSep": "VWh0dG_bucketSep",
276
+ "heroGaugeArcOver": "VWh0dG_heroGaugeArcOver",
277
+ "modelCell": "VWh0dG_modelCell",
278
+ "tabPanel": "VWh0dG_tabPanel",
279
+ "providerGroupBalanceLabel": "VWh0dG_providerGroupBalanceLabel",
280
+ "subscriptionCard": "VWh0dG_subscriptionCard",
281
+ "bucketOfficial": "VWh0dG_bucketOfficial",
282
+ "subscriptionFillOver": "VWh0dG_subscriptionFillOver",
283
+ "budgetControls": "VWh0dG_budgetControls",
284
+ "costCol": "VWh0dG_costCol",
285
+ "tokenModelParts": "VWh0dG_tokenModelParts",
286
+ "healthBadgeOk": "VWh0dG_healthBadgeOk",
287
+ "providerGroupTitle": "VWh0dG_providerGroupTitle",
288
+ "bandTag": "VWh0dG_bandTag",
289
+ "subscriptionTrack": "VWh0dG_subscriptionTrack",
290
+ "roundsBarFlagged": "VWh0dG_roundsBarFlagged",
291
+ "budgetFill": "VWh0dG_budgetFill",
292
+ "closeButton": "VWh0dG_closeButton",
293
+ "heroGaugeTrack": "VWh0dG_heroGaugeTrack",
294
+ "heatmapCell": "VWh0dG_heatmapCell",
295
+ "kpiLabel": "VWh0dG_kpiLabel",
296
+ "pluginInfo": "VWh0dG_pluginInfo"
286
297
  };
287
298
  //#endregion
288
299
  //#region src/client/plan-knowledge.ts
@@ -541,9 +552,10 @@ window.__ModuleLoader__.load({
541
552
  nextSwitchInMs: boundaryMs - dayMs
542
553
  };
543
554
  }
555
+ const firstBoundary = TIER_BOUNDARY_MINUTES[0] ?? 0;
544
556
  return {
545
557
  tier: tierAt(nowMs),
546
- nextSwitchInMs: 864e5 - dayMs + TIER_BOUNDARY_MINUTES[0] * 6e4
558
+ nextSwitchInMs: 864e5 - dayMs + firstBoundary * 6e4
547
559
  };
548
560
  }
549
561
  /**
@@ -1353,9 +1365,9 @@ window.__ModuleLoader__.load({
1353
1365
  * surface stays self-contained and offline.
1354
1366
  */
1355
1367
  /** Fixed viewBox; the SVG scales to its container. */
1356
- const W$1 = 680;
1357
- const H$1 = 220;
1358
- const PAD$1 = {
1368
+ const W$2 = 680;
1369
+ const H$2 = 220;
1370
+ const PAD$2 = {
1359
1371
  top: 18,
1360
1372
  right: 40,
1361
1373
  bottom: 26,
@@ -1367,7 +1379,7 @@ window.__ModuleLoader__.load({
1367
1379
  return `${Number(month)}/${Number(day)}`;
1368
1380
  }
1369
1381
  /** Compact tick label for the calls axis: `1.2K` / `3.4M`. */
1370
- function shortNumber(value) {
1382
+ function shortNumber$1(value) {
1371
1383
  if (value >= 1e6) return `${(value / 1e6).toFixed(1)}M`;
1372
1384
  if (value >= 1e3) return `${(value / 1e3).toFixed(1)}K`;
1373
1385
  return String(Math.round(value));
@@ -1397,16 +1409,16 @@ window.__ModuleLoader__.load({
1397
1409
  const layout = (0, react.useMemo)(() => {
1398
1410
  const n = data.length;
1399
1411
  if (n === 0) return null;
1400
- const plotW = W$1 - PAD$1.left - PAD$1.right;
1401
- const plotH = H$1 - PAD$1.top - PAD$1.bottom;
1412
+ const plotW = W$2 - PAD$2.left - PAD$2.right;
1413
+ const plotH = H$2 - PAD$2.top - PAD$2.bottom;
1402
1414
  const inner = (i) => {
1403
- if (n === 1) return PAD$1.left + plotW / 2;
1404
- return PAD$1.left + plotW * i / (n - 1);
1415
+ if (n === 1) return PAD$2.left + plotW / 2;
1416
+ return PAD$2.left + plotW * i / (n - 1);
1405
1417
  };
1406
1418
  const maxCost = Math.max(...data.map((d) => Math.max(d.cost, Object.values(d.byModel ?? {}).reduce((sum, v) => sum + v, 0))), 1e-4);
1407
- const yCost = (value) => PAD$1.top + plotH - value / maxCost * plotH;
1419
+ const yCost = (value) => PAD$2.top + plotH - value / maxCost * plotH;
1408
1420
  const maxCalls = Math.max(...data.map((d) => d.calls), 1);
1409
- const yCalls = (value) => PAD$1.top + plotH - value / maxCalls * plotH;
1421
+ const yCalls = (value) => PAD$2.top + plotH - value / maxCalls * plotH;
1410
1422
  const groupW = plotW / n;
1411
1423
  const barW = Math.min(18, groupW * .6);
1412
1424
  return {
@@ -1475,7 +1487,7 @@ window.__ModuleLoader__.load({
1475
1487
  className: UsageBilling_module_css_default.chartWrap,
1476
1488
  children: [
1477
1489
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
1478
- viewBox: `0 0 ${W$1} ${H$1}`,
1490
+ viewBox: `0 0 ${W$2} ${H$2}`,
1479
1491
  className: UsageBilling_module_css_default.chartSvg,
1480
1492
  role: "img",
1481
1493
  "aria-label": "Daily cost by model and total calls",
@@ -1484,7 +1496,7 @@ window.__ModuleLoader__.load({
1484
1496
  },
1485
1497
  onMouseMove: (e) => {
1486
1498
  const rect = e.currentTarget.getBoundingClientRect();
1487
- const ratio = ((e.clientX - rect.left) / rect.width * W$1 - PAD$1.left) / plotW;
1499
+ const ratio = ((e.clientX - rect.left) / rect.width * W$2 - PAD$2.left) / plotW;
1488
1500
  const index = Math.round(ratio * (n - 1));
1489
1501
  setHover(Math.min(Math.max(index, 0), n - 1));
1490
1502
  },
@@ -1492,13 +1504,13 @@ window.__ModuleLoader__.load({
1492
1504
  costTicks.map((value, idx) => {
1493
1505
  const y = yCost(value);
1494
1506
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("g", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("line", {
1495
- x1: PAD$1.left,
1496
- x2: W$1 - PAD$1.right,
1507
+ x1: PAD$2.left,
1508
+ x2: W$2 - PAD$2.right,
1497
1509
  y1: y,
1498
1510
  y2: y,
1499
1511
  className: UsageBilling_module_css_default.chartGrid
1500
1512
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("text", {
1501
- x: PAD$1.left - 8,
1513
+ x: PAD$2.left - 8,
1502
1514
  y: y + 3,
1503
1515
  textAnchor: "end",
1504
1516
  className: UsageBilling_module_css_default.chartAxisLabel,
@@ -1522,11 +1534,11 @@ window.__ModuleLoader__.load({
1522
1534
  callsTicks.map((value, idx) => {
1523
1535
  const y = yCalls(value);
1524
1536
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("text", {
1525
- x: W$1 - PAD$1.right + 8,
1537
+ x: W$2 - PAD$2.right + 8,
1526
1538
  y: y + 3,
1527
1539
  textAnchor: "start",
1528
1540
  className: UsageBilling_module_css_default.chartAxisLabel,
1529
- children: shortNumber(value)
1541
+ children: shortNumber$1(value)
1530
1542
  }, `calls-${idx}`);
1531
1543
  }),
1532
1544
  indices.map((i) => {
@@ -1534,7 +1546,7 @@ window.__ModuleLoader__.load({
1534
1546
  if (point === void 0) return null;
1535
1547
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("text", {
1536
1548
  x: inner(i),
1537
- y: H$1 - 6,
1549
+ y: H$2 - 6,
1538
1550
  textAnchor: "middle",
1539
1551
  className: UsageBilling_module_css_default.chartAxisLabel,
1540
1552
  children: shortDate(point.date)
@@ -1543,8 +1555,8 @@ window.__ModuleLoader__.load({
1543
1555
  hover !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("line", {
1544
1556
  x1: inner(hover),
1545
1557
  x2: inner(hover),
1546
- y1: PAD$1.top,
1547
- y2: PAD$1.top + plotH,
1558
+ y1: PAD$2.top,
1559
+ y2: PAD$2.top + plotH,
1548
1560
  className: UsageBilling_module_css_default.chartCrosshair
1549
1561
  })
1550
1562
  ]
@@ -1552,8 +1564,8 @@ window.__ModuleLoader__.load({
1552
1564
  activePoint !== void 0 && hover !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1553
1565
  className: UsageBilling_module_css_default.chartTooltip,
1554
1566
  style: {
1555
- left: `${inner(hover) / W$1 * 100}%`,
1556
- top: `${yCost(activePoint.cost) / H$1 * 100}%`
1567
+ left: `${inner(hover) / W$2 * 100}%`,
1568
+ top: `${yCost(activePoint.cost) / H$2 * 100}%`
1557
1569
  },
1558
1570
  children: [
1559
1571
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -1613,9 +1625,9 @@ window.__ModuleLoader__.load({
1613
1625
  * renders an empty state; the panel never fabricates samples.
1614
1626
  */
1615
1627
  /** Fixed viewBox for the hourly curve; the SVG scales to its container. */
1616
- const W = 680;
1617
- const H = 180;
1618
- const PAD = {
1628
+ const W$1 = 680;
1629
+ const H$1 = 180;
1630
+ const PAD$1 = {
1619
1631
  top: 14,
1620
1632
  right: 42,
1621
1633
  bottom: 22,
@@ -1667,13 +1679,13 @@ window.__ModuleLoader__.load({
1667
1679
  const points = perf === void 0 ? [] : sortHourPoints(perf.byHour);
1668
1680
  if (points.length === 0) return null;
1669
1681
  const n = points.length;
1670
- const plotW = W - PAD.left - PAD.right;
1671
- const plotH = H - PAD.top - PAD.bottom;
1672
- const inner = (i) => n === 1 ? PAD.left + plotW / 2 : PAD.left + plotW * i / (n - 1);
1682
+ const plotW = W$1 - PAD$1.left - PAD$1.right;
1683
+ const plotH = H$1 - PAD$1.top - PAD$1.bottom;
1684
+ const inner = (i) => n === 1 ? PAD$1.left + plotW / 2 : PAD$1.left + plotW * i / (n - 1);
1673
1685
  const maxTtft = Math.max(...points.map((p) => p.ttftMs), 1);
1674
1686
  const maxTps = Math.max(...points.map((p) => p.tps ?? 0), 1);
1675
- const yTtft = (v) => PAD.top + plotH - v / maxTtft * plotH;
1676
- const yTps = (v) => PAD.top + plotH - v / maxTps * plotH;
1687
+ const yTtft = (v) => PAD$1.top + plotH - v / maxTtft * plotH;
1688
+ const yTps = (v) => PAD$1.top + plotH - v / maxTps * plotH;
1677
1689
  const ttftPath = points.map((p, i) => `${i === 0 ? "M" : "L"}${inner(i)} ${yTtft(p.ttftMs)}`).join(" ");
1678
1690
  const tpsPath = points.some((p) => p.tps !== void 0) ? points.map((p, i) => `${i === 0 ? "M" : "L"}${inner(i)} ${yTps(p.tps ?? 0)}`).join(" ") : "";
1679
1691
  const step = Math.max(1, Math.ceil(n / 8));
@@ -1789,7 +1801,7 @@ window.__ModuleLoader__.load({
1789
1801
  className: UsageBilling_module_css_default.chartWrap,
1790
1802
  "data-testid": "billing-perf-hour",
1791
1803
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
1792
- viewBox: `0 0 ${W} ${H}`,
1804
+ viewBox: `0 0 ${W$1} ${H$1}`,
1793
1805
  className: UsageBilling_module_css_default.chartSvg,
1794
1806
  role: "img",
1795
1807
  "aria-label": "Hourly TTFT and generation speed by model",
@@ -1797,74 +1809,700 @@ window.__ModuleLoader__.load({
1797
1809
  hourLayout.ttftTicks.map((value, idx) => {
1798
1810
  const y = hourLayout.yTtft(value);
1799
1811
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("g", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("line", {
1800
- x1: PAD.left,
1801
- x2: W - PAD.right,
1812
+ x1: PAD$1.left,
1813
+ x2: W$1 - PAD$1.right,
1802
1814
  y1: y,
1803
1815
  y2: y,
1804
1816
  className: UsageBilling_module_css_default.chartGrid
1805
1817
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("text", {
1806
- x: PAD.left - 8,
1818
+ x: PAD$1.left - 8,
1807
1819
  y: y + 3,
1808
1820
  textAnchor: "end",
1809
1821
  className: UsageBilling_module_css_default.chartAxisLabel,
1810
1822
  children: value.toFixed(0)
1811
1823
  })] }, `ttft-${idx}`);
1812
1824
  }),
1813
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
1814
- d: hourLayout.ttftPath,
1815
- fill: "none",
1816
- className: UsageBilling_module_css_default.chartLine
1825
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
1826
+ d: hourLayout.ttftPath,
1827
+ fill: "none",
1828
+ className: UsageBilling_module_css_default.chartLine
1829
+ }),
1830
+ hourLayout.tpsPath !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
1831
+ d: hourLayout.tpsPath,
1832
+ fill: "none",
1833
+ className: UsageBilling_module_css_default.chartLine,
1834
+ style: {
1835
+ stroke: "var(--dsw-static-amber-500)",
1836
+ strokeDasharray: "4 4"
1837
+ }
1838
+ }),
1839
+ hourLayout.indices.map((i) => {
1840
+ const point = hourLayout.points[i];
1841
+ if (point === void 0) return null;
1842
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("text", {
1843
+ x: hourLayout.inner(i),
1844
+ y: H$1 - 6,
1845
+ textAnchor: "middle",
1846
+ className: UsageBilling_module_css_default.chartAxisLabel,
1847
+ children: shortHour(point.key)
1848
+ }, point.key);
1849
+ }),
1850
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("text", {
1851
+ x: W$1 - PAD$1.right + 8,
1852
+ y: PAD$1.top + 4,
1853
+ textAnchor: "start",
1854
+ className: UsageBilling_module_css_default.chartAxisLabel,
1855
+ children: [
1856
+ t("billing.perfTpsUnit"),
1857
+ " ",
1858
+ hourLayout.maxTps.toFixed(0)
1859
+ ]
1860
+ })
1861
+ ]
1862
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1863
+ className: UsageBilling_module_css_default.chartLegend,
1864
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
1865
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: UsageBilling_module_css_default.chartLegendLine }),
1866
+ t("billing.perfTtft"),
1867
+ " (ms)"
1868
+ ] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
1869
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1870
+ className: UsageBilling_module_css_default.chartLegendLine,
1871
+ style: { background: "var(--dsw-static-amber-500)" }
1872
+ }),
1873
+ t("billing.perfTps"),
1874
+ " (",
1875
+ t("billing.perfTpsUnit"),
1876
+ ")"
1877
+ ] })]
1878
+ })]
1879
+ })]
1880
+ });
1881
+ }
1882
+ //#endregion
1883
+ //#region src/client/plugin-info.ts
1884
+ /**
1885
+ * 插件元信息(「设置 → 插件信息卡」展示):名称 / 描述 / 作者 / 仓库 / 许可证。
1886
+ * 版本号不含在此——由服务端从自身 package.json 读取(pluginVersion),
1887
+ * 这样发布版版本与源码单一来源,不会两处不同步。
1888
+ */
1889
+ /** npm 包名。 */
1890
+ const PLUGIN_NAME = "@kenz1117/dsh-ui-usage-billing";
1891
+ /** 一句话描述。 */
1892
+ const PLUGIN_DESCRIPTION = "Usage billing dashboard for DeepSeek Harness";
1893
+ /** 作者显示名。 */
1894
+ const PLUGIN_AUTHOR_NAME = "KenZ";
1895
+ /** 作者 GitHub 账号(仓库/作者页链接)。 */
1896
+ const PLUGIN_AUTHOR_HANDLE = "kenz1117";
1897
+ /** 源码仓库(可点击)。 */
1898
+ const PLUGIN_REPOSITORY = "https://github.com/kenz1117/dsh-ui-usage-billing";
1899
+ /** npm 包主页(可点击)。 */
1900
+ const PLUGIN_NPM_URL = "https://www.npmjs.com/package/@kenz1117/dsh-ui-usage-billing";
1901
+ //#endregion
1902
+ //#region src/client/PluginInfoCard.tsx
1903
+ /**
1904
+ * PluginInfoCard: 「设置 → 插件信息」卡——展示头像/作者、GitHub 仓库、版本号、
1905
+ * 许可证等插件元信息。版本号来自服务端 usage-stats 的 `pluginVersion`(读自
1906
+ * 包 package.json),其余元信息静态来自 `plugin-info.ts`。无版本号时显示 em dash。
1907
+ */
1908
+ /** 信息卡 props:locale 函数 + 版本号(服务端下发,可为空)。 */
1909
+ function PluginInfoCard({ t, version }) {
1910
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
1911
+ className: UsageBilling_module_css_default.panel,
1912
+ "data-testid": "billing-plugin-info",
1913
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1914
+ className: UsageBilling_module_css_default.panelHead,
1915
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
1916
+ className: UsageBilling_module_css_default.panelTitle,
1917
+ children: t("billing.pluginInfo")
1918
+ })
1919
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1920
+ className: UsageBilling_module_css_default.pluginInfo,
1921
+ children: [
1922
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1923
+ className: UsageBilling_module_css_default.pluginInfoRow,
1924
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1925
+ className: UsageBilling_module_css_default.pluginInfoLabel,
1926
+ children: t("billing.pluginName")
1927
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1928
+ className: UsageBilling_module_css_default.pluginInfoValue,
1929
+ children: PLUGIN_NAME
1930
+ })]
1931
+ }),
1932
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1933
+ className: UsageBilling_module_css_default.pluginInfoRow,
1934
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1935
+ className: UsageBilling_module_css_default.pluginInfoLabel,
1936
+ children: t("billing.pluginDescription")
1937
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1938
+ className: UsageBilling_module_css_default.pluginInfoValue,
1939
+ children: PLUGIN_DESCRIPTION
1940
+ })]
1941
+ }),
1942
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1943
+ className: UsageBilling_module_css_default.pluginInfoRow,
1944
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1945
+ className: UsageBilling_module_css_default.pluginInfoLabel,
1946
+ children: t("billing.pluginVersion")
1947
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1948
+ className: UsageBilling_module_css_default.pluginInfoValue,
1949
+ children: version === void 0 ? "—" : `v${version}`
1950
+ })]
1951
+ }),
1952
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1953
+ className: UsageBilling_module_css_default.pluginInfoRow,
1954
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1955
+ className: UsageBilling_module_css_default.pluginInfoLabel,
1956
+ children: t("billing.pluginAuthor")
1957
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("a", {
1958
+ className: UsageBilling_module_css_default.pluginInfoLink,
1959
+ href: `https://github.com/${PLUGIN_AUTHOR_HANDLE}`,
1960
+ target: "_blank",
1961
+ rel: "noreferrer",
1962
+ children: [
1963
+ PLUGIN_AUTHOR_NAME,
1964
+ " (",
1965
+ PLUGIN_AUTHOR_HANDLE,
1966
+ ")"
1967
+ ]
1968
+ })]
1969
+ }),
1970
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1971
+ className: UsageBilling_module_css_default.pluginInfoRow,
1972
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1973
+ className: UsageBilling_module_css_default.pluginInfoLabel,
1974
+ children: t("billing.pluginRepository")
1975
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
1976
+ className: UsageBilling_module_css_default.pluginInfoLink,
1977
+ href: PLUGIN_REPOSITORY,
1978
+ target: "_blank",
1979
+ rel: "noreferrer",
1980
+ children: PLUGIN_REPOSITORY
1981
+ })]
1982
+ }),
1983
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1984
+ className: UsageBilling_module_css_default.pluginInfoRow,
1985
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1986
+ className: UsageBilling_module_css_default.pluginInfoLabel,
1987
+ children: t("billing.pluginNpm")
1988
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
1989
+ className: UsageBilling_module_css_default.pluginInfoLink,
1990
+ href: PLUGIN_NPM_URL,
1991
+ target: "_blank",
1992
+ rel: "noreferrer",
1993
+ children: PLUGIN_NAME
1994
+ })]
1995
+ }),
1996
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1997
+ className: UsageBilling_module_css_default.pluginInfoRow,
1998
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1999
+ className: UsageBilling_module_css_default.pluginInfoLabel,
2000
+ children: t("billing.pluginLicense")
2001
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2002
+ className: UsageBilling_module_css_default.pluginInfoValue,
2003
+ children: "MIT"
2004
+ })]
2005
+ })
2006
+ ]
2007
+ })]
2008
+ });
2009
+ }
2010
+ //#endregion
2011
+ //#region src/client/TokenPanel.tsx
2012
+ /**
2013
+ * TokenPanel: 「Token」分区——把 token 从费用里独立出来洞察。
2014
+ * 三个板块 + 导出,全部由 `UsageStats` 的 byDay/byModel/total 派生,服务端零改动:
2015
+ * 1. 每日 Token 堆叠趋势(未命中输入 / 缓存命中 / 输出[含 reasoning]),7/30 天切换;
2016
+ * 2. 模型 Token 总量排行 + 占比;
2017
+ * 3. Token 结构 KPI(缓存命中率 / reasoning 占比 / 输入:输出比 / 峰值日)。
2018
+ */
2019
+ /** 本地时区 `YYYY-MM-DD`(与服务端 dayStamp 一致)。 */
2020
+ function localStamp(time = Date.now()) {
2021
+ const d = new Date(time);
2022
+ const p = (n) => String(n).padStart(2, "0");
2023
+ return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`;
2024
+ }
2025
+ /** 短数字刻度:`1.2M` / `3.4K`。 */
2026
+ function shortNumber(v) {
2027
+ if (v >= 1e6) return `${(v / 1e6).toFixed(1)}M`;
2028
+ if (v >= 1e3) return `${(v / 1e3).toFixed(1)}K`;
2029
+ return String(Math.round(v));
2030
+ }
2031
+ const W = 680;
2032
+ const H = 200;
2033
+ const PAD = {
2034
+ top: 14,
2035
+ right: 18,
2036
+ bottom: 22,
2037
+ left: 46
2038
+ };
2039
+ const MISS_COLOR = "var(--dsw-static-blue-500)";
2040
+ const HIT_COLOR = "var(--dsw-static-cyan-500)";
2041
+ const OUTPUT_COLOR = "var(--dsw-static-amber-500)";
2042
+ /** 导出按日 token CSV。 */
2043
+ function tokenDayCsv(days) {
2044
+ return ["date,missInput,cacheHit,output,reasoning,total", ...days.map((d) => `${d.date},${d.miss},${d.hit},${d.output},${d.reasoning},${d.miss + d.hit + d.output}`)].join("\n");
2045
+ }
2046
+ /**
2047
+ * Token 洞察面板。
2048
+ * @param props.stats - usage-stats 文档(byDay/byModel/total)。
2049
+ * @param props.trendDays - 每日 token 窗口(7/30 天)。
2050
+ * @param props.onTrendDays - 切换趋势窗口。
2051
+ */
2052
+ function TokenPanel(props) {
2053
+ const { stats, currency: _currency, trendDays, onTrendDays, t } = props;
2054
+ const { byDay, byModel, total } = stats;
2055
+ const days = (0, react.useMemo)(() => {
2056
+ const out = [];
2057
+ for (let offset = trendDays - 1; offset >= 0; offset -= 1) {
2058
+ const d = /* @__PURE__ */ new Date();
2059
+ d.setDate(d.getDate() - offset);
2060
+ const date = localStamp(d.getTime());
2061
+ const day = byDay[date];
2062
+ out.push({
2063
+ date,
2064
+ miss: day?.cacheMiss ?? 0,
2065
+ hit: day?.cacheHit ?? 0,
2066
+ output: day?.output ?? 0,
2067
+ reasoning: day?.reasoning ?? 0
2068
+ });
2069
+ }
2070
+ return out;
2071
+ }, [byDay, trendDays]);
2072
+ const models = (0, react.useMemo)(() => {
2073
+ let grand = 0;
2074
+ return Object.entries(byModel).filter(([, d]) => d.calls > 0).map(([key, d]) => {
2075
+ const totalTokens = d.input + d.output;
2076
+ grand += totalTokens;
2077
+ const hitMiss = d.cacheHit + d.cacheMiss;
2078
+ return {
2079
+ key,
2080
+ name: modelOf(key).name,
2081
+ input: d.input,
2082
+ output: d.output,
2083
+ reasoning: d.reasoning ?? 0,
2084
+ calls: d.calls,
2085
+ cacheHit: d.cacheHit,
2086
+ cacheMiss: d.cacheMiss,
2087
+ cacheHitRate: hitMiss > 0 ? d.cacheHit / hitMiss * 100 : 0,
2088
+ total: totalTokens,
2089
+ share: 0
2090
+ };
2091
+ }).sort((a, b) => b.total - a.total).map((r) => ({
2092
+ ...r,
2093
+ share: grand > 0 ? r.total / grand : 0
2094
+ }));
2095
+ }, [byModel]);
2096
+ const kpis = (0, react.useMemo)(() => {
2097
+ const hit = total.cacheHit ?? 0;
2098
+ const miss = total.cacheMiss ?? 0;
2099
+ const input = total.input ?? 0;
2100
+ const output = total.output ?? 0;
2101
+ const reasoning = total.reasoning ?? 0;
2102
+ const hitMiss = hit + miss;
2103
+ const cacheHitRate = hitMiss > 0 ? hit / hitMiss * 100 : 0;
2104
+ const reasoningPct = output > 0 ? reasoning / output * 100 : 0;
2105
+ const io = output > 0 ? input / output : 0;
2106
+ let peak;
2107
+ for (const d of days) {
2108
+ const t2 = d.miss + d.hit + d.output;
2109
+ if (peak === void 0 || t2 > peak.miss + peak.hit + peak.output) peak = d;
2110
+ }
2111
+ return {
2112
+ cacheHitRate,
2113
+ reasoningPct,
2114
+ io,
2115
+ peak,
2116
+ hit,
2117
+ miss,
2118
+ input,
2119
+ output,
2120
+ reasoning
2121
+ };
2122
+ }, [total, days]);
2123
+ const chart = (0, react.useMemo)(() => {
2124
+ const n = days.length;
2125
+ if (n === 0) return null;
2126
+ const plotW = W - PAD.left - PAD.right;
2127
+ const plotH = H - PAD.top - PAD.bottom;
2128
+ const max = Math.max(...days.map((d) => d.miss + d.hit + d.output), 1);
2129
+ const y = (v) => PAD.top + plotH - v / max * plotH;
2130
+ const groupW = plotW / n;
2131
+ const barW = Math.min(20, groupW * .6);
2132
+ const inner = (i) => n === 1 ? PAD.left + plotW / 2 : PAD.left + plotW * i / (n - 1);
2133
+ const step = Math.max(1, Math.ceil(n / 8));
2134
+ const indices = [];
2135
+ for (let i = 0; i < n; i += step) indices.push(i);
2136
+ if (n > 0 && indices[indices.length - 1] !== n - 1) indices.push(n - 1);
2137
+ return {
2138
+ n,
2139
+ plotW,
2140
+ plotH,
2141
+ max,
2142
+ y,
2143
+ barW,
2144
+ inner,
2145
+ indices
2146
+ };
2147
+ }, [days]);
2148
+ const exportTokenCsv = () => {
2149
+ const blob = new Blob([tokenDayCsv(days)], { type: "text/csv" });
2150
+ const a = document.createElement("a");
2151
+ a.href = URL.createObjectURL(blob);
2152
+ a.download = `token-daily-${localStamp()}.csv`;
2153
+ a.click();
2154
+ URL.revokeObjectURL(a.href);
2155
+ };
2156
+ const exportTokenJson = () => {
2157
+ const blob = new Blob([JSON.stringify({
2158
+ days,
2159
+ models,
2160
+ total
2161
+ }, null, 2)], { type: "application/json" });
2162
+ const a = document.createElement("a");
2163
+ a.href = URL.createObjectURL(blob);
2164
+ a.download = `token-${localStamp()}.json`;
2165
+ a.click();
2166
+ URL.revokeObjectURL(a.href);
2167
+ };
2168
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2169
+ className: UsageBilling_module_css_default.tokenPanel,
2170
+ "data-testid": "billing-token-panel",
2171
+ children: [
2172
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2173
+ className: UsageBilling_module_css_default.exportBar,
2174
+ role: "group",
2175
+ "aria-label": t("billing.tokenExport"),
2176
+ children: [
2177
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2178
+ className: UsageBilling_module_css_default.exportLabel,
2179
+ children: t("billing.export")
2180
+ }),
2181
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2182
+ type: "button",
2183
+ className: UsageBilling_module_css_default.exportButton,
2184
+ "data-testid": "billing-token-export-csv",
2185
+ onClick: exportTokenCsv,
2186
+ children: t("billing.tokenExportCsv")
1817
2187
  }),
1818
- hourLayout.tpsPath !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
1819
- d: hourLayout.tpsPath,
1820
- fill: "none",
1821
- className: UsageBilling_module_css_default.chartLine,
1822
- style: {
1823
- stroke: "var(--dsw-static-amber-500)",
1824
- strokeDasharray: "4 4"
1825
- }
2188
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2189
+ type: "button",
2190
+ className: UsageBilling_module_css_default.exportButton,
2191
+ "data-testid": "billing-token-export-json",
2192
+ onClick: exportTokenJson,
2193
+ children: t("billing.exportJson")
2194
+ })
2195
+ ]
2196
+ }),
2197
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2198
+ className: UsageBilling_module_css_default.kpiGrid,
2199
+ "data-testid": "billing-token-kpis",
2200
+ children: [
2201
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2202
+ className: UsageBilling_module_css_default.kpiTile,
2203
+ children: [
2204
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2205
+ className: UsageBilling_module_css_default.kpiLabel,
2206
+ children: t("billing.tokenCacheHitRate")
2207
+ }),
2208
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2209
+ className: UsageBilling_module_css_default.kpiValue,
2210
+ children: [kpis.cacheHitRate.toFixed(1), "%"]
2211
+ }),
2212
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2213
+ className: UsageBilling_module_css_default.kpiDetail,
2214
+ children: [
2215
+ formatTokens(kpis.hit),
2216
+ " / ",
2217
+ formatTokens(kpis.hit + kpis.miss)
2218
+ ]
2219
+ })
2220
+ ]
1826
2221
  }),
1827
- hourLayout.indices.map((i) => {
1828
- const point = hourLayout.points[i];
1829
- if (point === void 0) return null;
1830
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("text", {
1831
- x: hourLayout.inner(i),
1832
- y: H - 6,
1833
- textAnchor: "middle",
1834
- className: UsageBilling_module_css_default.chartAxisLabel,
1835
- children: shortHour(point.key)
1836
- }, point.key);
2222
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2223
+ className: UsageBilling_module_css_default.kpiTile,
2224
+ children: [
2225
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2226
+ className: UsageBilling_module_css_default.kpiLabel,
2227
+ children: t("billing.tokenReasoningShare")
2228
+ }),
2229
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2230
+ className: UsageBilling_module_css_default.kpiValue,
2231
+ children: [kpis.reasoningPct.toFixed(1), "%"]
2232
+ }),
2233
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2234
+ className: UsageBilling_module_css_default.kpiDetail,
2235
+ children: formatTokens(kpis.reasoning)
2236
+ })
2237
+ ]
1837
2238
  }),
1838
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("text", {
1839
- x: W - PAD.right + 8,
1840
- y: PAD.top + 4,
1841
- textAnchor: "start",
1842
- className: UsageBilling_module_css_default.chartAxisLabel,
2239
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2240
+ className: UsageBilling_module_css_default.kpiTile,
1843
2241
  children: [
1844
- t("billing.perfTpsUnit"),
1845
- " ",
1846
- hourLayout.maxTps.toFixed(0)
2242
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2243
+ className: UsageBilling_module_css_default.kpiLabel,
2244
+ children: t("billing.tokenIo")
2245
+ }),
2246
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2247
+ className: UsageBilling_module_css_default.kpiValue,
2248
+ children: kpis.io.toFixed(2)
2249
+ }),
2250
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2251
+ className: UsageBilling_module_css_default.kpiDetail,
2252
+ children: [
2253
+ formatTokens(kpis.input),
2254
+ " / ",
2255
+ formatTokens(kpis.output)
2256
+ ]
2257
+ })
2258
+ ]
2259
+ }),
2260
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2261
+ className: UsageBilling_module_css_default.kpiTile,
2262
+ children: [
2263
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2264
+ className: UsageBilling_module_css_default.kpiLabel,
2265
+ children: t("billing.tokenPeak")
2266
+ }),
2267
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2268
+ className: UsageBilling_module_css_default.kpiValue,
2269
+ children: kpis.peak === void 0 ? "—" : shortNumber(kpis.peak.miss + kpis.peak.hit + kpis.peak.output)
2270
+ }),
2271
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2272
+ className: UsageBilling_module_css_default.kpiDetail,
2273
+ children: kpis.peak?.date ?? "—"
2274
+ })
1847
2275
  ]
1848
2276
  })
1849
2277
  ]
1850
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1851
- className: UsageBilling_module_css_default.chartLegend,
1852
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
1853
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: UsageBilling_module_css_default.chartLegendLine }),
1854
- t("billing.perfTtft"),
1855
- " (ms)"
1856
- ] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
1857
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1858
- className: UsageBilling_module_css_default.chartLegendLine,
1859
- style: { background: "var(--dsw-static-amber-500)" }
1860
- }),
1861
- t("billing.perfTps"),
1862
- " (",
1863
- t("billing.perfTpsUnit"),
1864
- ")"
1865
- ] })]
1866
- })]
1867
- })]
2278
+ }),
2279
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
2280
+ className: UsageBilling_module_css_default.panel,
2281
+ "data-testid": "billing-token-daily",
2282
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2283
+ className: UsageBilling_module_css_default.panelHead,
2284
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
2285
+ className: UsageBilling_module_css_default.panelTitle,
2286
+ children: t("billing.tokenDaily")
2287
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2288
+ className: UsageBilling_module_css_default.rangeToggle,
2289
+ role: "group",
2290
+ "aria-label": t("billing.tokenDaily"),
2291
+ children: [7, 30].map((d) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2292
+ type: "button",
2293
+ className: clsx(UsageBilling_module_css_default.rangeButton, trendDays === d && UsageBilling_module_css_default.rangeButtonActive),
2294
+ "aria-pressed": trendDays === d,
2295
+ onClick: () => {
2296
+ onTrendDays(d);
2297
+ },
2298
+ "data-testid": `billing-token-${d}d`,
2299
+ children: d === 7 ? t("billing.trend7d") : t("billing.trend30d")
2300
+ }, d))
2301
+ })]
2302
+ }), chart === null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2303
+ className: UsageBilling_module_css_default.chartEmpty,
2304
+ children: t("billing.trendEmpty")
2305
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2306
+ className: UsageBilling_module_css_default.chartWrap,
2307
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
2308
+ viewBox: `0 0 ${W} ${H}`,
2309
+ className: UsageBilling_module_css_default.chartSvg,
2310
+ role: "img",
2311
+ "aria-label": t("billing.tokenDaily"),
2312
+ children: [
2313
+ [
2314
+ 0,
2315
+ .5,
2316
+ 1
2317
+ ].map((f) => {
2318
+ const v = chart.max * f;
2319
+ const yy = chart.y(v);
2320
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("g", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("line", {
2321
+ x1: PAD.left,
2322
+ x2: W - PAD.right,
2323
+ y1: yy,
2324
+ y2: yy,
2325
+ className: UsageBilling_module_css_default.chartGrid
2326
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("text", {
2327
+ x: PAD.left - 8,
2328
+ y: yy + 3,
2329
+ textAnchor: "end",
2330
+ className: UsageBilling_module_css_default.chartAxisLabel,
2331
+ children: shortNumber(v)
2332
+ })] }, f);
2333
+ }),
2334
+ days.map((d, i) => {
2335
+ const x = chart.inner(i) - chart.barW / 2;
2336
+ const baseY = chart.y(0);
2337
+ const yMiss = chart.y(d.miss);
2338
+ const yHit = chart.y(d.miss + d.hit);
2339
+ const yOut = chart.y(d.miss + d.hit + d.output);
2340
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("g", { children: [
2341
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
2342
+ x,
2343
+ y: yMiss,
2344
+ width: chart.barW,
2345
+ height: baseY - yMiss,
2346
+ fill: MISS_COLOR
2347
+ }),
2348
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
2349
+ x,
2350
+ y: yHit,
2351
+ width: chart.barW,
2352
+ height: yMiss - yHit,
2353
+ fill: HIT_COLOR
2354
+ }),
2355
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
2356
+ x,
2357
+ y: yOut,
2358
+ width: chart.barW,
2359
+ height: yHit - yOut,
2360
+ fill: OUTPUT_COLOR
2361
+ })
2362
+ ] }, d.date);
2363
+ }),
2364
+ chart.indices.map((i) => {
2365
+ const d = days[i];
2366
+ if (d === void 0) return null;
2367
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("text", {
2368
+ x: chart.inner(i),
2369
+ y: H - 6,
2370
+ textAnchor: "middle",
2371
+ className: UsageBilling_module_css_default.chartAxisLabel,
2372
+ children: d.date.slice(5)
2373
+ }, d.date);
2374
+ })
2375
+ ]
2376
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2377
+ className: UsageBilling_module_css_default.chartLegend,
2378
+ children: [
2379
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2380
+ className: UsageBilling_module_css_default.chartTooltipSwatch,
2381
+ style: { background: MISS_COLOR }
2382
+ }), t("billing.tokenMiss")] }),
2383
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2384
+ className: UsageBilling_module_css_default.chartTooltipSwatch,
2385
+ style: { background: HIT_COLOR }
2386
+ }), t("billing.tokenHit")] }),
2387
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2388
+ className: UsageBilling_module_css_default.chartTooltipSwatch,
2389
+ style: { background: OUTPUT_COLOR }
2390
+ }), t("billing.tokenOutput")] })
2391
+ ]
2392
+ })]
2393
+ })]
2394
+ }),
2395
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
2396
+ className: UsageBilling_module_css_default.panel,
2397
+ "data-testid": "billing-token-models",
2398
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2399
+ className: UsageBilling_module_css_default.panelHead,
2400
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
2401
+ className: UsageBilling_module_css_default.panelTitle,
2402
+ children: t("billing.tokenByModel")
2403
+ })
2404
+ }), models.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2405
+ className: UsageBilling_module_css_default.emptyRow,
2406
+ children: t("billing.noData")
2407
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2408
+ className: UsageBilling_module_css_default.tableScroll,
2409
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", {
2410
+ className: UsageBilling_module_css_default.modelTable,
2411
+ "data-testid": "billing-token-model-table",
2412
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
2413
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("billing.model") }),
2414
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
2415
+ className: UsageBilling_module_css_default.numCol,
2416
+ children: t("billing.inputTokens")
2417
+ }),
2418
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
2419
+ className: UsageBilling_module_css_default.numCol,
2420
+ children: t("billing.outputTokens")
2421
+ }),
2422
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
2423
+ className: UsageBilling_module_css_default.numCol,
2424
+ children: t("billing.tokenReasoningShort")
2425
+ }),
2426
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
2427
+ className: UsageBilling_module_css_default.numCol,
2428
+ children: t("billing.cacheHitRate")
2429
+ }),
2430
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
2431
+ className: UsageBilling_module_css_default.numCol,
2432
+ children: t("billing.tokenTotal")
2433
+ }),
2434
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
2435
+ className: UsageBilling_module_css_default.numCol,
2436
+ children: t("billing.tokenShare")
2437
+ }),
2438
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
2439
+ className: UsageBilling_module_css_default.numCol,
2440
+ children: t("billing.calls")
2441
+ })
2442
+ ] }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", { children: models.map((m) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", {
2443
+ "data-testid": "billing-token-model",
2444
+ children: [
2445
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2446
+ className: UsageBilling_module_css_default.modelName,
2447
+ children: m.name
2448
+ }) }),
2449
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
2450
+ className: UsageBilling_module_css_default.numCol,
2451
+ children: formatTokens(m.input)
2452
+ }),
2453
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
2454
+ className: UsageBilling_module_css_default.numCol,
2455
+ children: formatTokens(m.output)
2456
+ }),
2457
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
2458
+ className: UsageBilling_module_css_default.numCol,
2459
+ children: m.reasoning > 0 ? formatTokens(m.reasoning) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2460
+ className: UsageBilling_module_css_default.na,
2461
+ children: "—"
2462
+ })
2463
+ }),
2464
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("td", {
2465
+ className: UsageBilling_module_css_default.numCol,
2466
+ children: [m.cacheHitRate.toFixed(1), "%"]
2467
+ }),
2468
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
2469
+ className: UsageBilling_module_css_default.numCol,
2470
+ children: formatTokens(m.total)
2471
+ }),
2472
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
2473
+ className: UsageBilling_module_css_default.numCol,
2474
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2475
+ className: UsageBilling_module_css_default.tokenModelShareRow,
2476
+ children: [
2477
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2478
+ className: UsageBilling_module_css_default.tokenModelBar,
2479
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2480
+ className: UsageBilling_module_css_default.tokenModelParts,
2481
+ style: { width: `${(m.share * 100).toFixed(2)}%` },
2482
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2483
+ className: UsageBilling_module_css_default.tokenModelPartIn,
2484
+ style: { width: `${m.total > 0 ? m.input / m.total * 100 : 0}%` }
2485
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2486
+ className: UsageBilling_module_css_default.tokenModelPartOut,
2487
+ style: { width: `${m.total > 0 ? m.output / m.total * 100 : 0}%` }
2488
+ })]
2489
+ })
2490
+ }),
2491
+ (m.share * 100).toFixed(1),
2492
+ "%"
2493
+ ]
2494
+ })
2495
+ }),
2496
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
2497
+ className: UsageBilling_module_css_default.numCol,
2498
+ children: m.calls.toLocaleString()
2499
+ })
2500
+ ]
2501
+ }, m.key)) })]
2502
+ })
2503
+ })]
2504
+ })
2505
+ ]
1868
2506
  });
1869
2507
  }
1870
2508
  //#endregion
@@ -2480,7 +3118,30 @@ window.__ModuleLoader__.load({
2480
3118
  "billing.heatmapMonth": "月",
2481
3119
  "billing.activeDays": "活跃天数",
2482
3120
  "billing.streakDays": "连续使用",
2483
- "billing.subscriptionAutoDetect": "自动识别"
3121
+ "billing.subscriptionAutoDetect": "自动识别",
3122
+ "billing.pluginInfo": "插件信息",
3123
+ "billing.pluginName": "插件名",
3124
+ "billing.pluginDescription": "描述",
3125
+ "billing.pluginVersion": "版本",
3126
+ "billing.pluginAuthor": "作者",
3127
+ "billing.pluginRepository": "仓库",
3128
+ "billing.pluginNpm": "npm",
3129
+ "billing.pluginLicense": "许可证",
3130
+ "billing.tabToken": "用量",
3131
+ "billing.tokenExport": "导出 Token",
3132
+ "billing.tokenExportCsv": "按日 Token CSV",
3133
+ "billing.tokenCacheHitRate": "缓存命中率",
3134
+ "billing.tokenReasoningShare": "思考占比",
3135
+ "billing.tokenReasoningShort": "思考",
3136
+ "billing.tokenIo": "输入/输出比",
3137
+ "billing.tokenPeak": "峰值日",
3138
+ "billing.tokenDaily": "每日 Token",
3139
+ "billing.tokenByModel": "模型 Token",
3140
+ "billing.tokenMiss": "未命中输入",
3141
+ "billing.tokenHit": "缓存命中",
3142
+ "billing.tokenOutput": "输出",
3143
+ "billing.tokenTotal": "总 Token",
3144
+ "billing.tokenShare": "占比"
2484
3145
  };
2485
3146
  const en = {
2486
3147
  "billing.title": "Usage",
@@ -2637,7 +3298,30 @@ window.__ModuleLoader__.load({
2637
3298
  "billing.heatmapMonth": "Month",
2638
3299
  "billing.activeDays": "Active days",
2639
3300
  "billing.streakDays": "Streak",
2640
- "billing.subscriptionAutoDetect": "Auto"
3301
+ "billing.subscriptionAutoDetect": "Auto",
3302
+ "billing.pluginInfo": "Plugin info",
3303
+ "billing.pluginName": "Name",
3304
+ "billing.pluginDescription": "Description",
3305
+ "billing.pluginVersion": "Version",
3306
+ "billing.pluginAuthor": "Author",
3307
+ "billing.pluginRepository": "Repository",
3308
+ "billing.pluginNpm": "npm",
3309
+ "billing.pluginLicense": "License",
3310
+ "billing.tabToken": "Usage",
3311
+ "billing.tokenExport": "Export tokens",
3312
+ "billing.tokenExportCsv": "Daily token CSV",
3313
+ "billing.tokenCacheHitRate": "Cache hit rate",
3314
+ "billing.tokenReasoningShare": "Reasoning share",
3315
+ "billing.tokenReasoningShort": "reasoning",
3316
+ "billing.tokenIo": "In/out ratio",
3317
+ "billing.tokenPeak": "Peak day",
3318
+ "billing.tokenDaily": "Daily tokens",
3319
+ "billing.tokenByModel": "Tokens by model",
3320
+ "billing.tokenMiss": "Uncached input",
3321
+ "billing.tokenHit": "Cache hit",
3322
+ "billing.tokenOutput": "Output",
3323
+ "billing.tokenTotal": "Total tokens",
3324
+ "billing.tokenShare": "Share"
2641
3325
  };
2642
3326
  //#endregion
2643
3327
  //#region src/client/provider-display.ts
@@ -2808,6 +3492,10 @@ window.__ModuleLoader__.load({
2808
3492
  id: "overview",
2809
3493
  labelKey: "billing.tabOverview"
2810
3494
  },
3495
+ {
3496
+ id: "token",
3497
+ labelKey: "billing.tabToken"
3498
+ },
2811
3499
  {
2812
3500
  id: "trends",
2813
3501
  labelKey: "billing.tabTrends"
@@ -2816,10 +3504,6 @@ window.__ModuleLoader__.load({
2816
3504
  id: "providers",
2817
3505
  labelKey: "billing.tabProviders"
2818
3506
  },
2819
- {
2820
- id: "details",
2821
- labelKey: "billing.tabDetails"
2822
- },
2823
3507
  {
2824
3508
  id: "pricing",
2825
3509
  labelKey: "billing.tabPricing"
@@ -3138,7 +3822,8 @@ window.__ModuleLoader__.load({
3138
3822
  output: 0,
3139
3823
  cacheHit: 0,
3140
3824
  cacheMiss: 0,
3141
- cost: 0
3825
+ cost: 0,
3826
+ reasoning: 0
3142
3827
  },
3143
3828
  byModel: {},
3144
3829
  byDay: {},
@@ -3165,7 +3850,8 @@ window.__ModuleLoader__.load({
3165
3850
  ...Array.isArray(candidate.byTurn) ? { byTurn: candidate.byTurn } : {},
3166
3851
  ...Array.isArray(candidate.byWorkspace) ? { byWorkspace: candidate.byWorkspace } : {},
3167
3852
  ...candidate.byRole !== null && typeof candidate.byRole === "object" ? { byRole: candidate.byRole } : {},
3168
- ...candidate.perf !== null && typeof candidate.perf === "object" && candidate.perf.byModel !== null && typeof candidate.perf.byModel === "object" && candidate.perf.byHour !== null && typeof candidate.perf.byHour === "object" ? { perf: candidate.perf } : {}
3853
+ ...candidate.perf !== null && typeof candidate.perf === "object" && candidate.perf.byModel !== null && typeof candidate.perf.byModel === "object" && candidate.perf.byHour !== null && typeof candidate.perf.byHour === "object" ? { perf: candidate.perf } : {},
3854
+ ...typeof candidate.pluginVersion === "string" ? { pluginVersion: candidate.pluginVersion } : {}
3169
3855
  };
3170
3856
  } catch {
3171
3857
  return null;
@@ -3344,7 +4030,7 @@ window.__ModuleLoader__.load({
3344
4030
  className: UsageBilling_module_css_default.triggerPopBars,
3345
4031
  children: sparkHeights.map((_h, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3346
4032
  className: UsageBilling_module_css_default.triggerPopBar,
3347
- style: { height: `${sparkMax > 0 ? 4 + days[index].cost / sparkMax * 18 : 4}px` }
4033
+ style: { height: `${sparkMax > 0 ? 4 + (days[index]?.cost ?? 0) / sparkMax * 18 : 4}px` }
3348
4034
  }, days[index]?.date ?? String(index)))
3349
4035
  })
3350
4036
  ]
@@ -4160,6 +4846,10 @@ window.__ModuleLoader__.load({
4160
4846
  ]
4161
4847
  })
4162
4848
  ]
4849
+ }),
4850
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PluginInfoCard, {
4851
+ t,
4852
+ version: stats.pluginVersion
4163
4853
  })
4164
4854
  ]
4165
4855
  }),
@@ -4304,261 +4994,257 @@ window.__ModuleLoader__.load({
4304
4994
  })()
4305
4995
  ]
4306
4996
  }),
4307
- tab === "providers" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4997
+ tab === "providers" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4308
4998
  className: UsageBilling_module_css_default.tabPanel,
4309
4999
  "data-testid": "billing-tab-panel-providers",
4310
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
4311
- className: UsageBilling_module_css_default.panel,
4312
- "data-testid": "billing-panel-providers",
4313
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4314
- className: UsageBilling_module_css_default.panelHead,
4315
- children: [
4316
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
4317
- className: UsageBilling_module_css_default.panelTitle,
4318
- children: t("billing.providerBilling")
4319
- }),
4320
- renderSlot("billing.dashboard.decor", { position: "models" }),
4321
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4322
- className: UsageBilling_module_css_default.panelHint,
4323
- children: stats.updatedAt !== void 0 ? `${t("billing.lastUpdated")} ${formatClock(stats.updatedAt)}` : ""
4324
- })
4325
- ]
4326
- }), providerGroups.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4327
- className: UsageBilling_module_css_default.emptyRow,
4328
- "data-testid": "billing-provider-empty",
4329
- children: t("billing.noData")
4330
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4331
- className: UsageBilling_module_css_default.providerGroupList,
4332
- "data-testid": "billing-provider-groups",
4333
- children: providerGroups.map((group) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4334
- className: UsageBilling_module_css_default.providerGroup,
4335
- "data-testid": "billing-provider-group",
5000
+ children: [
5001
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
5002
+ className: UsageBilling_module_css_default.panel,
5003
+ "data-testid": "billing-panel-providers",
5004
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5005
+ className: UsageBilling_module_css_default.panelHead,
4336
5006
  children: [
4337
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4338
- className: UsageBilling_module_css_default.providerGroupHead,
4339
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4340
- className: UsageBilling_module_css_default.providerGroupTitle,
4341
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4342
- className: clsx(UsageBilling_module_css_default.healthDot, group.dot),
4343
- "aria-hidden": "true"
4344
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4345
- className: UsageBilling_module_css_default.providerGroupName,
4346
- children: providerName(group.name)
4347
- })]
4348
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4349
- className: UsageBilling_module_css_default.providerGroupMeta,
4350
- children: [group.subscriptions.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4351
- className: UsageBilling_module_css_default.providerGroupBadge,
4352
- "data-testid": "billing-provider-sub-count",
4353
- children: [group.subscriptions.length, " 套餐"]
4354
- }), group.balance !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4355
- className: UsageBilling_module_css_default.providerGroupBalance,
4356
- "data-testid": "billing-provider-balance",
5007
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
5008
+ className: UsageBilling_module_css_default.panelTitle,
5009
+ children: t("billing.providerBilling")
5010
+ }),
5011
+ renderSlot("billing.dashboard.decor", { position: "models" }),
5012
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5013
+ className: UsageBilling_module_css_default.panelHint,
5014
+ children: stats.updatedAt !== void 0 ? `${t("billing.lastUpdated")} ${formatClock(stats.updatedAt)}` : ""
5015
+ })
5016
+ ]
5017
+ }), providerGroups.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5018
+ className: UsageBilling_module_css_default.emptyRow,
5019
+ "data-testid": "billing-provider-empty",
5020
+ children: t("billing.noData")
5021
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5022
+ className: UsageBilling_module_css_default.providerGroupList,
5023
+ "data-testid": "billing-provider-groups",
5024
+ children: providerGroups.map((group) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5025
+ className: UsageBilling_module_css_default.providerGroup,
5026
+ "data-testid": "billing-provider-group",
5027
+ children: [
5028
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5029
+ className: UsageBilling_module_css_default.providerGroupHead,
5030
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
5031
+ className: UsageBilling_module_css_default.providerGroupTitle,
4357
5032
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4358
- className: UsageBilling_module_css_default.providerGroupBalanceLabel,
4359
- children: t("billing.balance")
4360
- }), renderBalance(group.balance)]
5033
+ className: clsx(UsageBilling_module_css_default.healthDot, group.dot),
5034
+ "aria-hidden": "true"
5035
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5036
+ className: UsageBilling_module_css_default.providerGroupName,
5037
+ children: providerName(group.name)
5038
+ })]
5039
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
5040
+ className: UsageBilling_module_css_default.providerGroupMeta,
5041
+ children: [group.subscriptions.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
5042
+ className: UsageBilling_module_css_default.providerGroupBadge,
5043
+ "data-testid": "billing-provider-sub-count",
5044
+ children: [group.subscriptions.length, " 套餐"]
5045
+ }), group.balance !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
5046
+ className: UsageBilling_module_css_default.providerGroupBalance,
5047
+ "data-testid": "billing-provider-balance",
5048
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5049
+ className: UsageBilling_module_css_default.providerGroupBalanceLabel,
5050
+ children: t("billing.balance")
5051
+ }), renderBalance(group.balance)]
5052
+ })]
4361
5053
  })]
4362
- })]
4363
- }),
4364
- group.models.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4365
- className: clsx(UsageBilling_module_css_default.tableScroll, UsageBilling_module_css_default.modelTableScroll),
4366
- "data-testid": "billing-table-scroll",
4367
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", {
4368
- className: UsageBilling_module_css_default.modelTable,
4369
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
4370
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("billing.model") }),
4371
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
4372
- className: UsageBilling_module_css_default.numCol,
4373
- children: t("billing.calls")
4374
- }),
4375
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
4376
- className: UsageBilling_module_css_default.numCol,
4377
- children: t("billing.inputTokens")
4378
- }),
4379
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
4380
- className: UsageBilling_module_css_default.numCol,
4381
- children: t("billing.outputTokens")
4382
- }),
4383
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
4384
- className: UsageBilling_module_css_default.numCol,
4385
- children: t("billing.cacheHitRate")
4386
- }),
4387
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
4388
- className: UsageBilling_module_css_default.numCol,
4389
- children: t("billing.actual")
4390
- })
4391
- ] }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", { children: group.models.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
4392
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4393
- className: UsageBilling_module_css_default.modelCell,
4394
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4395
- className: UsageBilling_module_css_default.modelName,
4396
- children: [
4397
- row.name,
4398
- row.uncatalogued && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4399
- className: UsageBilling_module_css_default.uncataloguedTag,
4400
- "data-testid": "billing-uncatalogued-tag",
4401
- children: t("billing.uncatalogued")
4402
- }),
4403
- row.estimatedPricing && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4404
- className: UsageBilling_module_css_default.estimatedTag,
4405
- "data-testid": "billing-estimated-tag",
4406
- children: t("billing.estimatedPricing")
4407
- })
4408
- ]
4409
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4410
- className: UsageBilling_module_css_default.modelProvider,
4411
- children: providerName(row.provider)
4412
- })] })
4413
- }) }),
4414
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
4415
- className: UsageBilling_module_css_default.numCol,
4416
- children: row.calls.toLocaleString()
4417
- }),
4418
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
4419
- className: UsageBilling_module_css_default.numCol,
4420
- children: formatTokens(row.input)
4421
- }),
4422
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
4423
- className: UsageBilling_module_css_default.numCol,
4424
- children: formatTokens(row.output)
4425
- }),
4426
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
4427
- className: UsageBilling_module_css_default.numCol,
4428
- children: formatPercent(row.cacheHitRate)
4429
- }),
4430
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
4431
- className: UsageBilling_module_css_default.numCol,
4432
- children: row.plan ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4433
- className: UsageBilling_module_css_default.planTag,
4434
- children: t("billing.subscriptionIncluded")
4435
- }) : row.actual !== void 0 ? (() => {
4436
- const official = row.officialCost;
4437
- const third = row.actual - official;
4438
- if (official > 0 && third > 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4439
- className: UsageBilling_module_css_default.bucketCost,
5054
+ }),
5055
+ group.models.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5056
+ className: clsx(UsageBilling_module_css_default.tableScroll, UsageBilling_module_css_default.modelTableScroll),
5057
+ "data-testid": "billing-table-scroll",
5058
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", {
5059
+ className: UsageBilling_module_css_default.modelTable,
5060
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
5061
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("billing.model") }),
5062
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
5063
+ className: UsageBilling_module_css_default.numCol,
5064
+ children: t("billing.calls")
5065
+ }),
5066
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
5067
+ className: UsageBilling_module_css_default.numCol,
5068
+ children: t("billing.inputTokens")
5069
+ }),
5070
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
5071
+ className: UsageBilling_module_css_default.numCol,
5072
+ children: t("billing.outputTokens")
5073
+ }),
5074
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
5075
+ className: UsageBilling_module_css_default.numCol,
5076
+ children: t("billing.cacheHitRate")
5077
+ }),
5078
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
5079
+ className: UsageBilling_module_css_default.numCol,
5080
+ children: t("billing.actual")
5081
+ })
5082
+ ] }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", { children: group.models.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
5083
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5084
+ className: UsageBilling_module_css_default.modelCell,
5085
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
5086
+ className: UsageBilling_module_css_default.modelName,
4440
5087
  children: [
4441
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4442
- className: UsageBilling_module_css_default.bucketOfficial,
4443
- children: money(official)
4444
- }),
4445
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4446
- className: UsageBilling_module_css_default.bucketSep,
4447
- children: "/"
5088
+ row.name,
5089
+ row.uncatalogued && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5090
+ className: UsageBilling_module_css_default.uncataloguedTag,
5091
+ "data-testid": "billing-uncatalogued-tag",
5092
+ children: t("billing.uncatalogued")
4448
5093
  }),
4449
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4450
- className: UsageBilling_module_css_default.bucketThird,
4451
- children: money(third)
5094
+ row.estimatedPricing && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5095
+ className: UsageBilling_module_css_default.estimatedTag,
5096
+ "data-testid": "billing-estimated-tag",
5097
+ children: t("billing.estimatedPricing")
4452
5098
  })
4453
5099
  ]
4454
- });
4455
- return money(row.actual);
4456
- })() : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4457
- className: UsageBilling_module_css_default.na,
4458
- children: "—"
4459
- })
4460
- })
4461
- ] }, row.key)) })]
4462
- })
4463
- }),
4464
- group.subscriptions.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4465
- className: UsageBilling_module_css_default.subscriptionGrid,
4466
- "data-testid": "billing-subscriptions-grid",
4467
- children: group.subscriptions.map((quota) => {
4468
- const statusText = subscriptionStatusText(quota.status, t);
4469
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4470
- className: UsageBilling_module_css_default.subscriptionCard,
4471
- "data-testid": "billing-subscription-card",
4472
- children: [
4473
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4474
- className: UsageBilling_module_css_default.subscriptionHead,
4475
- children: [
4476
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4477
- className: UsageBilling_module_css_default.subscriptionName,
4478
- children: providerName(quota.displayName)
4479
- }),
4480
- quota.planType === "code" && (() => {
4481
- const tier = tierInfoOf(quota.provider);
4482
- const tierFee = tier !== void 0 ? t("billing.subscriptionFeePerMonth").replace("{amount}", tier.currency === "USD" ? `$${tier.amount}` : `¥${tier.amount}`) : void 0;
4483
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4484
- className: UsageBilling_module_css_default.subscriptionPlan,
4485
- "data-kind": "code",
4486
- children: [
4487
- tierFee ?? (quota.subscriptionAmount !== void 0 && quota.subscriptionAmount > 0 ? t("billing.subscriptionFeePerMonth").replace("{amount}", money(quota.subscriptionAmount)) : t("billing.planTypeCode")),
4488
- tier?.label !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4489
- className: UsageBilling_module_css_default.subscriptionTier,
4490
- "data-testid": `billing-tier-${quota.provider}`,
4491
- children: tier.label
4492
- }),
4493
- tier !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4494
- className: UsageBilling_module_css_default.subscriptionAuto,
4495
- "data-testid": `billing-auto-${quota.provider}`,
4496
- children: t("billing.subscriptionAutoDetect")
4497
- })
4498
- ]
4499
- });
4500
- })(),
4501
- quota.planType === "token" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4502
- className: UsageBilling_module_css_default.subscriptionPlan,
4503
- "data-kind": "token",
4504
- children: t("billing.planTypeToken")
4505
- }),
4506
- quota.plan !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4507
- className: UsageBilling_module_css_default.subscriptionPlan,
4508
- children: quota.plan
4509
- })
4510
- ]
5100
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5101
+ className: UsageBilling_module_css_default.modelProvider,
5102
+ children: providerName(row.provider)
5103
+ })] })
5104
+ }) }),
5105
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
5106
+ className: UsageBilling_module_css_default.numCol,
5107
+ children: row.calls.toLocaleString()
5108
+ }),
5109
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
5110
+ className: UsageBilling_module_css_default.numCol,
5111
+ children: formatTokens(row.input)
4511
5112
  }),
4512
- statusText !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4513
- className: UsageBilling_module_css_default.subscriptionStatus,
4514
- children: statusText
5113
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
5114
+ className: UsageBilling_module_css_default.numCol,
5115
+ children: formatTokens(row.output)
4515
5116
  }),
4516
- quota.windows.length === 0 && statusText === "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4517
- className: UsageBilling_module_css_default.subscriptionStatus,
4518
- children: t("billing.subscriptionNoApi")
5117
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
5118
+ className: UsageBilling_module_css_default.numCol,
5119
+ children: formatPercent(row.cacheHitRate)
4519
5120
  }),
4520
- quota.windows.map((window) => (() => {
4521
- const used = Math.min(100, Math.max(0, window.usedPercent));
4522
- const exhausted = Math.min(100, Math.max(0, window.remainingPercent)) <= 0;
4523
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4524
- className: UsageBilling_module_css_default.subscriptionWindow,
5121
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
5122
+ className: UsageBilling_module_css_default.numCol,
5123
+ children: row.plan ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5124
+ className: UsageBilling_module_css_default.planTag,
5125
+ children: t("billing.subscriptionIncluded")
5126
+ }) : row.actual !== void 0 ? (() => {
5127
+ const official = row.officialCost;
5128
+ const third = row.actual - official;
5129
+ if (official > 0 && third > 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
5130
+ className: UsageBilling_module_css_default.bucketCost,
5131
+ children: [
5132
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5133
+ className: UsageBilling_module_css_default.bucketOfficial,
5134
+ children: money(official)
5135
+ }),
5136
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5137
+ className: UsageBilling_module_css_default.bucketSep,
5138
+ children: "/"
5139
+ }),
5140
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5141
+ className: UsageBilling_module_css_default.bucketThird,
5142
+ children: money(third)
5143
+ })
5144
+ ]
5145
+ });
5146
+ return money(row.actual);
5147
+ })() : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5148
+ className: UsageBilling_module_css_default.na,
5149
+ children: "—"
5150
+ })
5151
+ })
5152
+ ] }, row.key)) })]
5153
+ })
5154
+ }),
5155
+ group.subscriptions.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5156
+ className: UsageBilling_module_css_default.subscriptionGrid,
5157
+ "data-testid": "billing-subscriptions-grid",
5158
+ children: group.subscriptions.map((quota) => {
5159
+ const statusText = subscriptionStatusText(quota.status, t);
5160
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5161
+ className: UsageBilling_module_css_default.subscriptionCard,
5162
+ "data-testid": "billing-subscription-card",
5163
+ children: [
5164
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5165
+ className: UsageBilling_module_css_default.subscriptionHead,
4525
5166
  children: [
4526
5167
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4527
- className: UsageBilling_module_css_default.subscriptionWindowLabel,
4528
- children: subscriptionWindowLabel(window.kind, t)
4529
- }),
4530
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4531
- className: UsageBilling_module_css_default.subscriptionTrack,
4532
- "aria-hidden": "true",
4533
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4534
- className: clsx(UsageBilling_module_css_default.subscriptionFill, used >= 100 && UsageBilling_module_css_default.subscriptionFillOver, used >= 80 && used < 100 && UsageBilling_module_css_default.subscriptionFillWarn),
4535
- style: { width: `${used}%` }
4536
- })
5168
+ className: UsageBilling_module_css_default.subscriptionName,
5169
+ children: providerName(quota.displayName)
4537
5170
  }),
4538
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4539
- className: clsx(UsageBilling_module_css_default.subscriptionPct, exhausted && UsageBilling_module_css_default.subscriptionExhausted),
4540
- children: exhausted ? t("billing.subscriptionExhausted") : t("billing.subscriptionRemaining").replace("{pct}", String(window.remainingPercent))
5171
+ quota.planType === "code" && (() => {
5172
+ const tier = tierInfoOf(quota.provider);
5173
+ const tierFee = tier !== void 0 ? t("billing.subscriptionFeePerMonth").replace("{amount}", tier.currency === "USD" ? `$${tier.amount}` : `¥${tier.amount}`) : void 0;
5174
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
5175
+ className: UsageBilling_module_css_default.subscriptionPlan,
5176
+ "data-kind": "code",
5177
+ children: [
5178
+ tierFee ?? (quota.subscriptionAmount !== void 0 && quota.subscriptionAmount > 0 ? t("billing.subscriptionFeePerMonth").replace("{amount}", money(quota.subscriptionAmount)) : t("billing.planTypeCode")),
5179
+ tier?.label !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5180
+ className: UsageBilling_module_css_default.subscriptionTier,
5181
+ "data-testid": `billing-tier-${quota.provider}`,
5182
+ children: tier.label
5183
+ }),
5184
+ tier !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5185
+ className: UsageBilling_module_css_default.subscriptionAuto,
5186
+ "data-testid": `billing-auto-${quota.provider}`,
5187
+ children: t("billing.subscriptionAutoDetect")
5188
+ })
5189
+ ]
5190
+ });
5191
+ })(),
5192
+ quota.planType === "token" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5193
+ className: UsageBilling_module_css_default.subscriptionPlan,
5194
+ "data-kind": "token",
5195
+ children: t("billing.planTypeToken")
4541
5196
  }),
4542
- window.resetsAt !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4543
- className: UsageBilling_module_css_default.subscriptionReset,
4544
- children: t("billing.subscriptionReset").replace("{date}", `${localDayStamp(new Date(window.resetsAt).getTime())} ${formatClock(new Date(window.resetsAt).getTime())}`)
5197
+ quota.plan !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5198
+ className: UsageBilling_module_css_default.subscriptionPlan,
5199
+ children: quota.plan
4545
5200
  })
4546
5201
  ]
4547
- }, window.kind);
4548
- })())
4549
- ]
4550
- }, quota.provider);
5202
+ }),
5203
+ statusText !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5204
+ className: UsageBilling_module_css_default.subscriptionStatus,
5205
+ children: statusText
5206
+ }),
5207
+ quota.windows.length === 0 && statusText === "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5208
+ className: UsageBilling_module_css_default.subscriptionStatus,
5209
+ children: t("billing.subscriptionNoApi")
5210
+ }),
5211
+ quota.windows.map((window) => (() => {
5212
+ const used = Math.min(100, Math.max(0, window.usedPercent));
5213
+ const exhausted = Math.min(100, Math.max(0, window.remainingPercent)) <= 0;
5214
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5215
+ className: UsageBilling_module_css_default.subscriptionWindow,
5216
+ children: [
5217
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5218
+ className: UsageBilling_module_css_default.subscriptionWindowLabel,
5219
+ children: subscriptionWindowLabel(window.kind, t)
5220
+ }),
5221
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5222
+ className: UsageBilling_module_css_default.subscriptionTrack,
5223
+ "aria-hidden": "true",
5224
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5225
+ className: clsx(UsageBilling_module_css_default.subscriptionFill, used >= 100 && UsageBilling_module_css_default.subscriptionFillOver, used >= 80 && used < 100 && UsageBilling_module_css_default.subscriptionFillWarn),
5226
+ style: { width: `${used}%` }
5227
+ })
5228
+ }),
5229
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5230
+ className: clsx(UsageBilling_module_css_default.subscriptionPct, exhausted && UsageBilling_module_css_default.subscriptionExhausted),
5231
+ children: exhausted ? t("billing.subscriptionExhausted") : t("billing.subscriptionRemaining").replace("{pct}", String(window.remainingPercent))
5232
+ }),
5233
+ window.resetsAt !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5234
+ className: UsageBilling_module_css_default.subscriptionReset,
5235
+ children: t("billing.subscriptionReset").replace("{date}", `${localDayStamp(new Date(window.resetsAt).getTime())} ${formatClock(new Date(window.resetsAt).getTime())}`)
5236
+ })
5237
+ ]
5238
+ }, window.kind);
5239
+ })())
5240
+ ]
5241
+ }, quota.provider);
5242
+ })
4551
5243
  })
4552
- })
4553
- ]
4554
- }, group.name))
4555
- })]
4556
- })
4557
- }),
4558
- tab === "details" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4559
- className: UsageBilling_module_css_default.tabPanel,
4560
- "data-testid": "billing-tab-panel-details",
4561
- children: [
5244
+ ]
5245
+ }, group.name))
5246
+ })]
5247
+ }),
4562
5248
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4563
5249
  className: UsageBilling_module_css_default.exportBar,
4564
5250
  "data-testid": "billing-export-bar",
@@ -4598,24 +5284,6 @@ window.__ModuleLoader__.load({
4598
5284
  })
4599
5285
  ]
4600
5286
  }),
4601
- stats.perf !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
4602
- className: UsageBilling_module_css_default.panel,
4603
- "data-testid": "billing-panel-perf",
4604
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4605
- className: UsageBilling_module_css_default.panelHead,
4606
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
4607
- className: UsageBilling_module_css_default.panelTitle,
4608
- children: t("billing.perfTitle")
4609
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4610
- className: UsageBilling_module_css_default.panelHint,
4611
- children: t("billing.perfHint")
4612
- })]
4613
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PerfPanel, {
4614
- perf: stats.perf,
4615
- models: chartModels,
4616
- t
4617
- })]
4618
- }),
4619
5287
  roleRows.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
4620
5288
  className: UsageBilling_module_css_default.panel,
4621
5289
  "data-testid": "billing-panel-roles",
@@ -4844,6 +5512,34 @@ window.__ModuleLoader__.load({
4844
5512
  })
4845
5513
  ]
4846
5514
  }),
5515
+ tab === "token" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5516
+ className: UsageBilling_module_css_default.tabPanel,
5517
+ "data-testid": "billing-tab-panel-token",
5518
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TokenPanel, {
5519
+ stats,
5520
+ currency,
5521
+ trendDays,
5522
+ onTrendDays: setTrendDays,
5523
+ t
5524
+ }), stats.perf !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
5525
+ className: UsageBilling_module_css_default.panel,
5526
+ "data-testid": "billing-panel-perf",
5527
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5528
+ className: UsageBilling_module_css_default.panelHead,
5529
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
5530
+ className: UsageBilling_module_css_default.panelTitle,
5531
+ children: t("billing.perfTitle")
5532
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5533
+ className: UsageBilling_module_css_default.panelHint,
5534
+ children: t("billing.perfHint")
5535
+ })]
5536
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PerfPanel, {
5537
+ perf: stats.perf,
5538
+ models: chartModels,
5539
+ t
5540
+ })]
5541
+ })]
5542
+ }),
4847
5543
  tab === "pricing" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4848
5544
  className: UsageBilling_module_css_default.tabPanel,
4849
5545
  "data-testid": "billing-tab-panel-pricing",