Tokens Usage Number Formatter

将 DeepSeek 使用量统计图表中的 tokens 数字修改为下划线分隔格式 (如 '342054 tokens' -> '342_054 tokens')

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, Greasemonkey alebo Violentmonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey alebo Userscripts.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie správcu používateľských skriptov.

(Už mám správcu používateľských skriptov, nechajte ma ho nainštalovať!)

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

(Už mám správcu používateľských štýlov, nechajte ma ho nainštalovať!)

// ==UserScript==
// @name         Tokens Usage Number Formatter
// @author       ExcuseLme
// @namespace    https://github.com/ExcuseLme
// @version      1.1
// @description  将 DeepSeek 使用量统计图表中的 tokens 数字修改为下划线分隔格式 (如 '342054 tokens' -> '342_054 tokens')
// @match        https://platform.deepseek.com/usage
// @grant        none
// @icon         https://fe-static.deepseek.com/platform/favicon.svg
// @run-at       document-idle
// @license      MIT
// ==/UserScript==

(function () {
  'use strict'

  /**
   * 格式化数字函数
   * 将 342054 转换为 342_054
   */
  const formatNumber = (text) => {
    const regex = /^(\d+)(\s+tokens)$/
    const match = text.match(regex)

    if (match) {
      const num = match[1]
      const unit = match[2]
      // 使用正则每隔三位插入下划线
      const formattedNum = num.replace(/\B(?=(\d{3})+(?!\d))/g, '_')
      return `${formattedNum}${unit}`
    }
    return null
  }

  /**
   * 处理节点函数
   */
  const processNode = (node) => {
    const processTextNode = (textNode) => {
      const originalText = textNode.textContent.trim()
      const newText = formatNumber(originalText)
      if (newText && originalText !== newText) {
        textNode.textContent = newText
      }
    }

    if (node.nodeType === Node.ELEMENT_NODE) {
      // 深度优先检查包含文本的 div
      // 创建自定义过滤器,只处理包含数字的文本节点以提高性能
      const numberFilter = {
        acceptNode: function (textNode) {
          // 只接受包含数字的文本节点
          if (/\d/.test(textNode.textContent)) {
            return NodeFilter.FILTER_ACCEPT
          }
          return NodeFilter.FILTER_SKIP
        }
      }

      const walker = document.createTreeWalker(node, NodeFilter.SHOW_TEXT, numberFilter)
      let textNode
      while ((textNode = walker.nextNode()) !== null) {
        processTextNode(textNode)
      }
    } else if (node.nodeType === Node.TEXT_NODE) {
      // 直接处理文本节点
      processTextNode(node)
    }
  }

  // 实例化观察器
  const observer = new MutationObserver((mutations) => {
    for (const mutation of mutations) {
      // 监听新增节点(浮窗出现时)
      mutation.addedNodes.forEach(node => {
        processNode(node)
      })
      // 监听文本变化(浮窗内容更新时)
      if (mutation.type === 'characterData' || mutation.type === 'childList') {
        processNode(mutation.target)
      }
    }
  })

  // 配置观察选项:子节点、后代节点、文本内容
  const config = {
    childList    : true,
    subtree      : true,
    characterData: true
  }

  // 开始观察 body 元素
  observer.observe(document.body, config)

  console.log('DeepSeek Tokens Formatter 脚本已启动')
})()