GitHub Style

智能高亮 GitHub 活跃仓库:集成 CSS 视觉排序、配置导入/导出,彻底解决 React 冲突与时间闪烁。

2026-07-20 기준 버전입니다. 최신 버전을 확인하세요.

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name           GitHub Style
// @namespace      http://tampermonkey.net/
// @version        1.0.9
// @description    智能高亮 GitHub 活跃仓库:集成 CSS 视觉排序、配置导入/导出,彻底解决 React 冲突与时间闪烁。
// @author         XiMenChuiXue
// @license        MIT
// @icon           https://raw.githubusercontent.com/rational-stars/picgo/refs/heads/main/avatar.jpg
// @match          https://github.com/*
// @match          https://github.com/*/*
// @match          https://github.com/*/*/*
// @match          https://github.com/*/*/*/*
// @exclude        https://github.com/settings/*
// @exclude        https://github.com/notifications/*
// @exclude        https://github.com/marketplace/*
// @grant          GM_registerMenuCommand
// @grant          GM_setValue
// @grant          GM_getValue
// @grant          GM_addStyle
// @grant          GM_getResourceText
// @run-at         document-start
// @require        https://code.jquery.com/jquery-3.6.0.min.js#sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=
// @require        https://cdn.jsdelivr.net/npm/sweetalert2@11
// @require        https://cdn.jsdelivr.net/npm/@simonwep/[email protected]/dist/pickr.min.js
// @require        https://cdn.jsdelivr.net/npm/[email protected]/build/global/luxon.min.js
// @resource       PICKR_CSS https://cdn.jsdelivr.net/npm/@simonwep/[email protected]/dist/themes/classic.min.css
// ==/UserScript==

/* global luxon, Pickr, Swal, $ */
(function () {
    'use strict';

    const DateTime = luxon.DateTime;

    const pickrCss = GM_getResourceText('PICKR_CSS');
    if (pickrCss) GM_addStyle(pickrCss);

    // ==================== Styles ====================
    GM_addStyle(`
      .swal2-popup.swal2-modal.swal2-show {
          color: #FFF; border-radius: 20px; background: #31b96c;
          box-shadow: 8px 8px 16px #217e49, -8px -8px 16px #41f48f;
      }
      .formatted-date-span, .custom-time-format {
          white-space: nowrap !important; display: inline-block !important;
          font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif !important;
          font-size: 14px !important; vertical-align: middle;
      }
      div[role="row"] > div:last-child, td[role="gridcell"]:last-child {
          min-width: 135px !important; text-align: right !important; display: flex !important;
          align-items: center; justify-content: flex-end; padding-right: 10px !important;
      }
      #swal2-title a { display: inline-block; height: 40px; margin-right: 10px; border-radius: 10px; overflow: hidden; color: #fff; }
      #swal2-title { display: flex !important; justify-content: center; align-items: center; }

      .row-box select {
          border: 2px solid rgba(255, 255, 255, 0.3); border-radius: 8px;
          background-color: rgba(0, 0, 0, 0.2) !important; color: #fff !important;
          padding: 8px 12px; font-size: 14px; cursor: pointer; outline: none; min-width: 120px;
          -webkit-appearance: none; -moz-appearance: none; appearance: none;
          background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");
          background-repeat: no-repeat; background-position: right 8px center; background-size: 16px; padding-right: 32px;
      }
      .row-box select:hover { border-color: rgba(255, 255, 255, 0.5); background-color: rgba(0, 0, 0, 0.3) !important; }
      .row-box select:focus { border-color: rgba(255, 255, 255, 0.8); background-color: rgba(0, 0, 0, 0.4) !important; box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.1); }
      .row-box select option { background-color: #2d3748 !important; color: #fff !important; padding: 8px; }
      .row-box select:-moz-focusring { color: transparent; text-shadow: 0 0 0 #fff; }

      .row-box { display: flex; margin: 20px 25px; align-items: center; justify-content: space-between; }
      .row-box .swal2-input { height: 40px; background-color: rgba(0, 0, 0, 0.2) !important; color: #fff !important; border: 2px solid rgba(255, 255, 255, 0.3); border-radius: 8px; }
      .row-box .swal2-input:focus { border-color: rgba(255, 255, 255, 0.8); box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.1); }
      .row-box label { margin-right: 10px; color: #fff; font-weight: 500; }
      .row-box main input { background: rgba(15, 172, 83, 1); width: 70px; border: unset; box-shadow: unset; text-align: right; margin: 0; }
      .row-box main { display: flex; align-items: center; gap: 10px; }
      .freshness-stars { padding: 8px; }
      .freshness-updated { margin-left: 5px; }
      .github-freshness-loading { opacity: 0.6; pointer-events: none; }

      input[type="checkbox"] { width: 18px; height: 18px; cursor: pointer; accent-color: #0fac53; }
      input[type="number"], input[type="password"] {
          background-color: rgba(0, 0, 0, 0.2) !important; color: #fff !important;
          border: 2px solid rgba(255, 255, 255, 0.3) !important; border-radius: 8px; padding: 8px; text-align: center;
      }
      input[type="password"] { min-width: 200px; text-align: left; padding: 8px 12px; }
      input[type="number"]:focus, input[type="password"]:focus { border-color: rgba(255, 255, 255, 0.8) !important; outline: none; box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.1); }

      #RESET_DEFAULTS { background-color: #e53e3e !important; color: white !important; border: none !important; padding: 10px 24px !important; border-radius: 8px !important; cursor: pointer; font-weight: 500; transition: all 0.2s; }
      #RESET_DEFAULTS:hover { background-color: #c53030 !important; transform: translateY(-1px); box-shadow: 0 4px 12px rgba(229, 62, 62, 0.4); }
      .swal2-confirm { background-color: #0fac53 !important; border-radius: 8px !important; }
      .swal2-cancel { background-color: #718096 !important; border-radius: 8px !important; }

      relative-time.custom-time-replaced { display: none !important; }

      /* ✅ 修复: 更健壮的 flex 排序样式 */
      .gh-freshness-flex-sort {
          display: flex !important;
          flex-direction: column !important;
      }
      .gh-freshness-flex-sort > [role="row"],
      .gh-freshness-flex-sort > [data-testid="file-list-row"],
      .gh-freshness-flex-sort > .Box-row {
          width: 100% !important;
          box-sizing: border-box !important;
          margin-left: 0 !important;
          margin-right: 0 !important;
          flex-shrink: 0 !important;
      }
    `);

    // ==================== Panel DOM ====================
    const PanelDom = `
      <div class="row-box">
          <label for="THEME-select">主题设置:</label>
          <main>
              <select tabindex="-1" id="THEME-select" class="swal2-input">
                  <option value="light">☀️ Light</option>
                  <option value="dark">🌙 Dark</option>
              </select>
          </main>
      </div>
      <div class="row-box">
          <label id="TIME_BOUNDARY-label">时间阈值:</label>
          <main>
              <input id="TIME_BOUNDARY-number" type="number" class="swal2-input" value="" min="1" max="999" maxlength="3" pattern="\\d{1,3}">
              <select tabindex="-1" id="TIME_BOUNDARY-select" class="swal2-input">
                  <option value="day">📅 日</option>
                  <option value="week">📆 周</option>
                  <option value="month">🗓️ 月</option>
                  <option value="year">📊 年</option>
              </select>
          </main>
      </div>
      <div class="row-box">
          <div><label id="BGC-label">🎨 背景颜色:</label><input type="checkbox" id="BGC-enabled"></div>
          <main>
              <span id="BGC-highlight-color-value"><div id="BGC-highlight-color-pickr"></div></span>
              <span id="BGC-grey-color-value"><div id="BGC-grey-color-pickr"></div></span>
          </main>
      </div>
      <div class="row-box">
          <div><label id="FONT-label">🔤 字体颜色:</label><input type="checkbox" id="FONT-enabled"></div>
          <main>
              <span id="FONT-highlight-color-value"><div id="FONT-highlight-color-pickr"></div></span>
              <span id="FONT-grey-color-value"><div id="FONT-grey-color-pickr"></div></span>
          </main>
      </div>
      <div class="row-box">
          <div><label id="DIR-label">📁 文件夹颜色:</label><input type="checkbox" id="DIR-enabled"></div>
          <main>
              <span id="DIR-highlight-color-value"><div id="DIR-highlight-color-pickr"></div></span>
              <span id="DIR-grey-color-value"><div id="DIR-grey-color-pickr"></div></span>
          </main>
      </div>
      <div class="row-box">
          <div><label id="TIME_FORMAT-label">🕐 时间格式化:</label><input type="checkbox" id="TIME_FORMAT-enabled"></div>
      </div>
      <div class="row-box">
          <div><label id="SORT-label">🔀 文件排序 (CSS视觉排序):</label><input type="checkbox" id="SORT-enabled"></div>
          <main>
              <select tabindex="-1" id="SORT-select" class="swal2-input">
                  <option value="asc">⬆️ 时间正序</option>
                  <option value="desc">⬇️ 时间倒序</option>
              </select>
          </main>
      </div>
      <div class="row-box">
          <label for="CURRENT_THEME-select">🌓 当前主题:</label>
          <main>
              <select tabindex="-1" id="CURRENT_THEME-select" class="swal2-input">
                  <option value="auto">⚡ Auto</option>
                  <option value="light">☀️ Light</option>
                  <option value="dark">🌙 Dark</option>
              </select>
          </main>
      </div>
      <div class="row-box">
          <div>
              <label id="AWESOME-label"><a target="_blank" href="https://github.com/settings/tokens" style="color: #fff; text-decoration: underline;">🔑 AWESOME token:</a></label>
              <input type="checkbox" id="AWESOME-enabled">
          </div>
          <main>
              <input id="AWESOME_TOKEN" type="password" class="swal2-input" value="" placeholder="ghp_xxx 或 github_pat_xxx">
          </main>
      </div>

      <div class="row-box" style="justify-content: center; gap: 15px; margin-top: 25px; flex-wrap: wrap;">
          <button type="button" id="EXPORT_CONFIG" class="swal2-styled" style="background-color: #3182ce !important; border-radius: 8px !important; margin: 5px; padding: 10px 20px !important;">📤 导出配置</button>
          <button type="button" id="IMPORT_CONFIG" class="swal2-styled" style="background-color: #805ad5 !important; border-radius: 8px !important; margin: 5px; padding: 10px 20px !important;">📥 导入配置</button>
      </div>

      <div class="row-box" style="justify-content: center; margin-top: 15px;">
          <button type="button" id="RESET_DEFAULTS" class="swal2-styled">🔄 恢复默认设置</button>
      </div>
      <p style="font-size: 0.85em; opacity: 0.9; text-align: center; margin-top: 15px; color: rgba(255,255,255,0.8);">
          💡 提示:排序采用 CSS Flex 黑科技,不破坏 React 架构。配置码包含 Token,请私密分享。
      </p>
    `;

    // ==================== Default Config ====================
    const default_THEME = {
        BGC: { highlightColor: 'rgba(15, 172, 83, 1)', greyColor: 'rgba(245, 245, 245, 0.24)', isEnabled: true },
        TIME_BOUNDARY: { number: 30, select: 'day' },
        FONT: { highlightColor: 'rgba(252, 252, 252, 1)', greyColor: 'rgba(0, 0, 0, 1)', isEnabled: true },
        DIR: { highlightColor: 'rgba(15, 172, 83, 1)', greyColor: 'rgba(154, 154, 154, 1)', isEnabled: true },
        SORT: { select: 'desc', isEnabled: true },
        AWESOME: { isEnabled: false },
        TIME_FORMAT: { isEnabled: true },
    };

    let CURRENT_THEME = GM_getValue('CURRENT_THEME', 'light');
    let AWESOME_TOKEN = GM_getValue('AWESOME_TOKEN', '');
    let THEME_TYPE = getThemeType();
    let config_JSON = JSON.parse(GM_getValue('config_JSON', JSON.stringify({ light: default_THEME, dark: default_THEME })));
    let THEME = config_JSON[THEME_TYPE] || JSON.parse(JSON.stringify(default_THEME));

    const apiCache = new Map();
    const apiQueue = [];
    let apiProcessing = false;
    const API_DELAY = 100;

    const configPickr = {
        theme: 'classic',
        components: {
            preview: true, opacity: true, hue: true,
            interaction: { rgba: true, input: true, clear: true, save: true },
        },
    };

    // ==================== Utility Functions ====================
    function getThemeType() {
        let themeType = CURRENT_THEME;
        if (CURRENT_THEME === 'auto') {
            themeType = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
        }
        return themeType;
    }

    function initPickr(el_default) {
        const pickr = Pickr.create({ ...configPickr, ...el_default });
        pickr.on('save', (color, instance) => {
            const hex = color.toHEXA().toString();
            instance.options.el.setAttribute('data-pickr-color', hex);
            pickr.hide();
        });
        setTimeout(() => {
            const el = document.querySelector(el_default.el + ' .pcr-button');
            if (el && el_default.default) {
                el.setAttribute('data-pickr-color', el_default.default);
            }
        }, 300);
        return pickr;
    }

    function getUpdatedThemeConfig() {
        let updatedTheme = {};
        for (const [themeKey, themeVal] of Object.entries(default_THEME)) {
            updatedTheme[themeKey] = {};
            for (let [key, val] of Object.entries(themeVal)) {
                if (key === 'highlightColor' || key === 'greyColor') {
                    const type = key === 'highlightColor' ? 'highlight' : 'grey';
                    const $btn = $(`#${themeKey}-${type}-color-value .pcr-button`);
                    let colorVal = $btn.attr('data-pickr-color');
                    if (!colorVal) colorVal = $btn.css('--pcr-color');
                    val = colorVal || val;
                } else if (key === 'isEnabled') {
                    val = $(`#${themeKey}-enabled`).prop('checked');
                } else if (key === 'number' || key === 'select') {
                    val = $(`#${themeKey}-${key}`).val();
                    if (key === 'number') val = parseInt(val) || 30;
                }
                updatedTheme[themeKey][key] = val;
            }
        }
        return updatedTheme;
    }

    function handleData(theme) {
        if (!theme) return;
        for (const [themeKey, themeVal] of Object.entries(theme)) {
            for (const [key, val] of Object.entries(themeVal)) {
                if (key === 'highlightColor' || key === 'greyColor') {
                    const type = key === 'highlightColor' ? 'highlight' : 'grey';
                    const $btn = $(`#${themeKey}-${type}-color-value .pcr-button`);
                    if ($btn.length && val) {
                        $btn.css('--pcr-color', val);
                        $btn.attr('data-pickr-color', val);
                    }
                } else if (key === 'isEnabled') {
                    $(`#${themeKey}-enabled`).prop('checked', val);
                } else if (key === 'number' || key === 'select') {
                    $(`#${themeKey}-${key}`).val(val);
                }
            }
        }
    }

    function resetToDefaults() {
        handleData(default_THEME);
        initPickr({ el: '#BGC-highlight-color-pickr', default: default_THEME.BGC.highlightColor });
        initPickr({ el: '#BGC-grey-color-pickr', default: default_THEME.BGC.greyColor });
        initPickr({ el: '#FONT-highlight-color-pickr', default: default_THEME.FONT.highlightColor });
        initPickr({ el: '#FONT-grey-color-pickr', default: default_THEME.FONT.greyColor });
        initPickr({ el: '#DIR-highlight-color-pickr', default: default_THEME.DIR.highlightColor });
        initPickr({ el: '#DIR-grey-color-pickr', default: default_THEME.DIR.greyColor });
    }

    // ==================== Settings Panel ====================
    function createSettingsPanel() {
        Swal.fire({
            title: `<div style="display: flex; align-items: center; justify-content: center; gap: 10px;">
                <span>🎨</span>
                <span>GitHub Freshness Settings</span>
            </div>`,
            html: PanelDom,
            focusConfirm: false,
            allowOutsideClick: false,
            background: '#31b96c',
            confirmButtonColor: '#0fac53',
            cancelButtonColor: '#718096',
            preConfirm: () => {
                const updated_THEME = getUpdatedThemeConfig();
                CURRENT_THEME = $('#CURRENT_THEME-select').val();
                AWESOME_TOKEN = $('#AWESOME_TOKEN').val().trim();

                const tokenRegex = /^(ghp_[a-zA-Z0-9]{36}|github_pat_[a-zA-Z0-9_]+)$/;
                if (updated_THEME.AWESOME.isEnabled && AWESOME_TOKEN && !AWESOME_TOKEN.match(tokenRegex)) {
                    Swal.showValidationMessage('❌ Token 格式不正确 (支持 ghp_ 或 github_pat_)');
                    return false;
                }

                config_JSON[$('#THEME-select').val()] = updated_THEME;
                GM_setValue('config_JSON', JSON.stringify(config_JSON));
                GM_setValue('CURRENT_THEME', CURRENT_THEME);
                GM_setValue('AWESOME_TOKEN', AWESOME_TOKEN);
                THEME = updated_THEME;
                GitHub_Freshness(updated_THEME);

                Swal.fire({
                    position: 'top-center',
                    background: '#31b96c',
                    icon: 'success',
                    iconColor: '#fff',
                    title: '<span style="color: #fff;">✅ 保存成功!</span>',
                    showConfirmButton: false,
                    timer: 1000,
                    toast: true
                });
            },
            heightAuto: false,
            showCancelButton: true,
            confirmButtonText: '💾 保存',
            cancelButtonText: '❌ 取消',
            didOpen: () => {
                initSettings(THEME);

                $('#THEME-select').on('change', function () {
                    let selectedTheme = $(this).val();
                    let theme = config_JSON[selectedTheme] || JSON.parse(JSON.stringify(default_THEME));
                    handleData(theme);

                    initPickr({ el: '#BGC-highlight-color-pickr', default: theme.BGC.highlightColor });
                    initPickr({ el: '#BGC-grey-color-pickr', default: theme.BGC.greyColor });
                    initPickr({ el: '#FONT-highlight-color-pickr', default: theme.FONT.highlightColor });
                    initPickr({ el: '#FONT-grey-color-pickr', default: theme.FONT.greyColor });
                    initPickr({ el: '#DIR-highlight-color-pickr', default: theme.DIR.highlightColor });
                    initPickr({ el: '#DIR-grey-color-pickr', default: theme.DIR.greyColor });
                });

                $('#RESET_DEFAULTS').on('click', () => {
                    Swal.fire({
                        title: '🔄 确认恢复默认?',
                        text: '当前主题的设置将被重置为默认值',
                        icon: 'warning',
                        iconColor: '#f6e05e',
                        background: '#31b96c',
                        color: '#fff',
                        showCancelButton: true,
                        confirmButtonColor: '#e53e3e',
                        cancelButtonColor: '#718096',
                        confirmButtonText: '⚠️ 确认重置',
                        cancelButtonText: '✋ 取消'
                    }).then((result) => {
                        if (result.isConfirmed) {
                            resetToDefaults();
                            Swal.fire({
                                position: 'top-center',
                                background: '#31b96c',
                                icon: 'success',
                                iconColor: '#fff',
                                title: '<span style="color: #fff;">✅ 已重置为默认值</span>',
                                showConfirmButton: false,
                                timer: 800,
                                toast: true
                            });
                        }
                    });
                });

                // 导出配置
                $('#EXPORT_CONFIG').on('click', () => {
                    const exportData = {
                        config_JSON: config_JSON,
                        CURRENT_THEME: CURRENT_THEME,
                        AWESOME_TOKEN: AWESOME_TOKEN
                    };
                    const b64 = btoa(unescape(encodeURIComponent(JSON.stringify(exportData))));

                    Swal.fire({
                        title: '📤 导出配置',
                        html: `
                            <p style="color: #fff; font-size: 14px; margin-bottom: 10px;">⚠️ 包含 Token 等敏感信息,请妥善保管!</p>
                            <textarea id="export-text" style="width: 100%; height: 150px; background: rgba(0,0,0,0.3); color: #fff; border: 1px solid rgba(255,255,255,0.3); border-radius: 8px; padding: 10px; font-family: monospace; resize: none;">${b64}</textarea>
                        `,
                        background: '#31b96c',
                        color: '#fff',
                        showCancelButton: true,
                        confirmButtonText: '📋 复制并关闭',
                        cancelButtonText: '❌ 关闭',
                        didOpen: () => {
                            const textarea = document.getElementById('export-text');
                            if (textarea) textarea.select();
                        },
                        preConfirm: () => {
                            const textarea = document.getElementById('export-text');
                            if (textarea) {
                                textarea.select();
                                if (navigator.clipboard) {
                                    navigator.clipboard.writeText(textarea.value).catch(() => document.execCommand('copy'));
                                } else {
                                    document.execCommand('copy');
                                }
                            }
                            return true;
                        }
                    });
                });

                // 导入配置
                $('#IMPORT_CONFIG').on('click', () => {
                    Swal.fire({
                        title: '📥 导入配置',
                        html: `
                            <p style="color: #fff; font-size: 14px; margin-bottom: 10px;">请粘贴之前导出的配置码 (Base64):</p>
                            <textarea id="import-text" style="width: 100%; height: 150px; background: rgba(0,0,0,0.3); color: #fff; border: 1px solid rgba(255,255,255,0.3); border-radius: 8px; padding: 10px; font-family: monospace; resize: none;" placeholder="粘贴配置码..."></textarea>
                        `,
                        background: '#31b96c',
                        color: '#fff',
                        showCancelButton: true,
                        confirmButtonText: '✅ 确认导入',
                        cancelButtonText: '❌ 取消',
                        preConfirm: () => {
                            const val = document.getElementById('import-text').value.trim();
                            if (!val) {
                                Swal.showValidationMessage('❌ 配置码不能为空');
                                return false;
                            }
                            try {
                                const jsonStr = decodeURIComponent(escape(atob(val)));
                                const importData = JSON.parse(jsonStr);
                                if (!importData.config_JSON) throw new Error('Invalid format');
                                return importData;
                            } catch (e) {
                                Swal.showValidationMessage('❌ 配置码解析失败,请检查格式');
                                return false;
                            }
                        }
                    }).then((result) => {
                        if (result.isConfirmed && result.value) {
                            const importData = result.value;

                            config_JSON = importData.config_JSON;
                            GM_setValue('config_JSON', JSON.stringify(config_JSON));

                            if (importData.CURRENT_THEME) {
                                CURRENT_THEME = importData.CURRENT_THEME;
                                GM_setValue('CURRENT_THEME', CURRENT_THEME);
                            }
                            if (importData.AWESOME_TOKEN !== undefined) {
                                AWESOME_TOKEN = importData.AWESOME_TOKEN;
                                GM_setValue('AWESOME_TOKEN', AWESOME_TOKEN);
                            }

                            THEME_TYPE = getThemeType();
                            THEME = config_JSON[THEME_TYPE] || JSON.parse(JSON.stringify(default_THEME));

                            Swal.fire({
                                position: 'top-center',
                                background: '#31b96c',
                                icon: 'success',
                                iconColor: '#fff',
                                title: '<span style="color: #fff;">✅ 导入成功!正在刷新...</span>',
                                showConfirmButton: false,
                                timer: 1000,
                                toast: true
                            }).then(() => {
                                Swal.close();
                                createSettingsPanel();
                                runScript();
                            });
                        }
                    });
                });
            }
        });
    }

    function initSettings(theme) {
        if (!theme) theme = JSON.parse(JSON.stringify(default_THEME));

        initPickr({ el: '#BGC-highlight-color-pickr', default: theme.BGC.highlightColor });
        initPickr({ el: '#BGC-grey-color-pickr', default: theme.BGC.greyColor });
        initPickr({ el: '#FONT-highlight-color-pickr', default: theme.FONT.highlightColor });
        initPickr({ el: '#FONT-grey-color-pickr', default: theme.FONT.greyColor });
        initPickr({ el: '#DIR-highlight-color-pickr', default: theme.DIR.highlightColor });
        initPickr({ el: '#DIR-grey-color-pickr', default: theme.DIR.greyColor });

        $('#THEME-select').val(THEME_TYPE);
        $('#CURRENT_THEME-select').val(CURRENT_THEME);
        $('#AWESOME_TOKEN').val(AWESOME_TOKEN);
        handleData(theme);
    }

    // ==================== Element Styling ====================
    function setElementBGC(el, BGC, timeResult) {
        if (el.length && el[0] && BGC.isEnabled) {
            try { el[0].style.setProperty('background-color', timeResult ? BGC.highlightColor : BGC.greyColor, 'important'); } catch (e) {}
        }
    }

    function setElementDIR(el, DIR, timeResult) {
        if (el.length && DIR.isEnabled) {
            const color = timeResult ? DIR.highlightColor : DIR.greyColor;
            try {
                if (el[0]) {
                    el[0].style.setProperty('fill', color, 'important');
                    el[0].style.setProperty('stroke', color, 'important');
                }
                el.attr('fill', color); el.attr('stroke', color);
            } catch (e) {}
        }
    }

    function setElementFONT(el, FONT, timeResult) {
        if (el.length && el[0] && FONT.isEnabled) {
            try { el[0].style.setProperty('color', timeResult ? FONT.highlightColor : FONT.greyColor, 'important'); } catch (e) {}
        }
    }

    // ==================== Time Handling ====================
    function handleTime(time, time_boundary, type = 'ISO8601') {
        if (!time) return false;
        const { number, select } = time_boundary;
        let days = 0;
        switch (select) {
            case 'day': days = parseInt(number) || 30; break;
            case 'week': days = (parseInt(number) || 4) * 7; break;
            case 'month': days = (parseInt(number) || 1) * 30; break;
            case 'year': days = (parseInt(number) || 1) * 365; break;
            default: days = 30;
        }
        const thresholdDate = new Date();
        thresholdDate.setDate(thresholdDate.getDate() - days);
        thresholdDate.setHours(0, 0, 0, 0);

        let inputDate = null;
        if (type === 'UTC') {
            const formats = ["yyyy年M月d日 'GMT'Z HH:mm", "MMM d, yyyy, h:mm a 'GMT'Z", "MMM d, yyyy 'GMT'Z", "yyyy-MM-dd'T'HH:mm:ss'Z'", "yyyy-MM-dd HH:mm:ss"];
            for (const fmt of formats) {
                try {
                    const dt = DateTime.fromFormat(time, fmt, { zone: 'UTC' });
                    if (dt.isValid) { inputDate = dt.toJSDate(); break; }
                } catch (e) { continue; }
            }
            if (!inputDate) {
                const nativeDate = new Date(time);
                if (!isNaN(nativeDate.getTime())) inputDate = nativeDate;
            }
        } else { inputDate = new Date(time); }

        if (!inputDate || isNaN(inputDate.getTime())) return false;
        return inputDate >= thresholdDate;
    }

    // ==================== API ====================
    function toAPIUrl(href) {
        if (!href) return null;
        const match = href.match(/^https:\/\/github\.com\/([^\\/]+)\/([^\\/]+)/);
        return match ? `https://api.github.com/repos/${match[1]}/${match[2]}` : null;
    }

    async function processApiQueue() {
        if (apiProcessing || apiQueue.length === 0) return;
        apiProcessing = true;
        while (apiQueue.length > 0) {
            const { apiHref, callback } = apiQueue.shift();
            if (apiCache.has(apiHref)) { callback(apiCache.get(apiHref)); continue; }
            try {
                const response = await fetch(apiHref, { headers: AWESOME_TOKEN ? { 'Authorization': `token ${AWESOME_TOKEN}` } : {} });
                if (response.status === 403) { callback(null); }
                else if (response.ok) {
                    const data = await response.json();
                    apiCache.set(apiHref, data);
                    setTimeout(() => apiCache.delete(apiHref), 5 * 60 * 1000);
                    callback(data);
                } else { callback(null); }
            } catch (error) { callback(null); }
            if (apiQueue.length > 0) await new Promise(resolve => setTimeout(resolve, API_DELAY));
        }
        apiProcessing = false;
    }

    // ==================== Awesome (Star/Date on repo links) ====================
    function GitHub_FreshnessAwesome(theme) {
        const observer = new IntersectionObserver((entries) => {
            entries.forEach(el => {
                if (el.isIntersecting && el.target.getAttribute('data-requested') !== 'true') {
                    const href = $(el.target).attr('href');
                    const apiHref = toAPIUrl(href);
                    if (!apiHref) return;
                    el.target.setAttribute('data-requested', 'true');
                    $(el.target).addClass('github-freshness-loading');
                    apiQueue.push({
                        apiHref: apiHref,
                        callback: (data) => {
                            $(el.target).removeClass('github-freshness-loading');
                            if (!data) return;
                            const timeResult = handleTime(data.updated_at, theme.TIME_BOUNDARY);
                            if (theme.AWESOME.isEnabled) {
                                const $existing = $(el.target).parent().find('.freshness-stars, .freshness-updated');
                                if ($existing.length === 0) {
                                    $(el.target).after(
                                        `<span class="freshness-stars">★${data.stargazers_count.toLocaleString()}</span>` +
                                        `<span class="freshness-updated">📅${formatDate(data.updated_at)}</span>`
                                    );
                                    $(el.target).css('padding', '0 12px');
                                }
                            }
                            setElementBGC($(el.target), theme.BGC, timeResult);
                            setElementFONT($(el.target), theme.FONT, timeResult);
                        }
                    });
                    processApiQueue();
                }
            });
        }, { threshold: 0.1, rootMargin: '50px' });

        $('.Box-row a, .markdown-body a').each(function () {
            const href = $(this).attr('href');
            if (href && /^https:\/\/github\.com\/[^\\/]+\/[^\\/]+\/?$/.test(href)) {
                observer.observe(this);
            }
        });
    }

    // ==================== Search Page ====================
    function GitHub_FreshnessSearchPage(theme) {
        const elements = $('relative-time[datetime], relative-time[title]');
        if (elements.length === 0) return;
        elements.each(function () {
            const $this = $(this);
            const datetime = $this.attr('datetime');
            const title = $this.attr('title');
            const timeStr = datetime || title;
            if (!timeStr) return;
            const isISO8601 = !!datetime;
            const timeResult = handleTime(timeStr, theme.TIME_BOUNDARY, isISO8601 ? 'ISO8601' : 'UTC');
            const BGC_element = $this.closest('div[data-testid*="results-list"], div[data-testid*="results-card"], li, article, .Box-row');
            setElementBGC(BGC_element, theme.BGC, timeResult);
            setElementFONT($this, theme.FONT, timeResult);
        });
    }

    // ==================== ✅ 修复: 排序辅助函数 ====================

    /**
     * 判断是否为特殊行(commit 信息行、表头行等),需要始终置顶
     */
    function isSpecialRow(row) {
        if (!row) return false;
        // 多种检测方式兼容不同版本的 GitHub DOM
        if (row.querySelector('[data-testid="latest-commit-details"]')) return true;
        if (row.querySelector('[data-testid="latest-commit"]')) return true;
        if (row.querySelector('.react-directory-commit-row')) return true;
        if (row.getAttribute && row.getAttribute('role') === 'columnheader') return true;
        if (row.querySelector('[role="columnheader"]')) return true;
        // 表头行通常没有 relative-time
        if (!row.querySelector('relative-time[datetime]')) return true;
        // 包含 "Latest commit" 或 "Name" 表头文本
        const text = (row.textContent || '').trim();
        if (/^Latest commit/i.test(text)) return true;
        if (/^Name\s/.test(text) && text.length < 50) return true;
        return false;
    }

    /**
     * 从行中提取时间戳(毫秒)
     */
    function getRowTimestamp(row) {
        if (!row) return null;
        const timeEl = row.querySelector('relative-time[datetime]');
        if (!timeEl) return null;
        const datetime = timeEl.getAttribute('datetime');
        if (!datetime) return null;
        const ts = new Date(datetime).getTime();
        return isNaN(ts) ? null : ts;
    }

    // ==================== ✅ 修复: 核心排序函数 ====================
    function applyCSSSortOrder(theme) {
        if (!theme || !theme.SORT || !theme.SORT.isEnabled) return;

        // ✅ 修复 #2: 扩展容器选择器,覆盖 GitHub 当前所有可能的文件列表容器
        const containers = document.querySelectorAll(
            '#repos-file-tree, ' +
            '[role="rowgroup"], ' +
            '[role="grid"], ' +
            '[data-testid="repos-file-tree-container"], ' +
            '[data-testid="file-list-row-container"], ' +
            '.react-directory-truncate, ' +
            '.Box-body, ' +
            'table.files tbody, ' +
            'tbody'
        );

        if (containers.length === 0) return;

        containers.forEach(container => {
            const tag = container.tagName.toUpperCase();
            let rows;

            // ✅ 修复 #3: 根据容器类型使用不同的行选择器
            if (tag === 'TBODY' || tag === 'TABLE') {
                rows = Array.from(container.querySelectorAll(':scope > tr'));
            } else {
                // Div 布局:精确匹配行元素
                rows = Array.from(container.querySelectorAll(
                    ':scope > [role="row"], ' +
                    ':scope > [data-testid="file-list-row"], ' +
                    ':scope > .Box-row'
                ));
                // 回退:带 relative-time 的子 div
                if (rows.length === 0) {
                    rows = Array.from(container.querySelectorAll(':scope > div:has(relative-time[datetime])'));
                }
            }

            if (rows.length <= 1) return;

            // ✅ 修复 #1 & #6: 对 table 布局使用 DOM 重排(flex 会破坏 table 布局)
            if (tag === 'TBODY' || tag === 'TABLE') {
                const sorted = rows.slice().sort((a, b) => {
                    const aSpecial = isSpecialRow(a);
                    const bSpecial = isSpecialRow(b);
                    if (aSpecial && !bSpecial) return -1;
                    if (!aSpecial && bSpecial) return 1;
                    if (aSpecial && bSpecial) return 0;

                    const aTs = getRowTimestamp(a);
                    const bTs = getRowTimestamp(b);
                    if (aTs === null || bTs === null) return 0;
                    return theme.SORT.select === 'desc' ? bTs - aTs : aTs - bTs;
                });
                sorted.forEach(row => container.appendChild(row));
                return;
            }

            // Div 布局:使用 CSS flex order(不破坏 React 架构)
            container.classList.add('gh-freshness-flex-sort');
            rows.forEach(row => {
                // ✅ 修复 #5: 特殊行置顶
                if (isSpecialRow(row)) {
                    row.style.setProperty('order', '-999999999', 'important');
                    return;
                }

                const timestamp = getRowTimestamp(row);
                if (timestamp !== null) {
                    const orderVal = theme.SORT.select === 'desc' ? -timestamp : timestamp;
                    row.style.setProperty('order', String(orderVal), 'important');
                }
            });
        });
    }

    // ==================== ✅ 修复: 主高亮函数 ====================
    function GitHub_Freshness(theme) {
        if (!theme) theme = THEME;
        const matchUrl = isMatchedUrl();
        if (!matchUrl) return;

        if (matchUrl === 'matchSearchPage') {
            GitHub_FreshnessSearchPage(theme);
            return;
        }

        // ✅ 修复 #4: 扩展时间元素选择器
        const timeElements = $(
            '[data-testid="file-list-row"] relative-time, ' +
            '.Box-row relative-time, ' +
            'tr relative-time, ' +
            'div[role="row"] relative-time, ' +
            '#repos-file-tree relative-time, ' +
            '[role="rowgroup"] relative-time'
        );

        // 高亮处理(仅在找到时间元素时执行)
        if (timeElements.length > 0) {
            timeElements.each(function () {
                const $this = $(this);
                const datetime = $this.attr('datetime');
                if (!datetime) return;
                const trElement = $this.closest(
                    '[data-testid="file-list-row"], .Box-row, tr, div[role="row"], [role="rowgroup"] > div'
                );
                if (!trElement.length) return;
                const timeResult = handleTime(datetime, theme.TIME_BOUNDARY);
                let BGC_element = trElement.find(
                    '[data-testid="latest-commit-details"], td:last-child, div[role="gridcell"]:last-child'
                ).first();
                if (BGC_element.length === 0) BGC_element = $this.parent();
                const ICON_element = trElement.find('svg').first();
                setElementBGC(BGC_element, theme.BGC, timeResult);
                setElementDIR(ICON_element, theme.DIR, timeResult);
                setElementFONT($this.parent(), theme.FONT, timeResult);
            });
        }

        // ✅ 修复 #4: 排序始终尝试执行,不再依赖 timeElements 是否找到
        applyCSSSortOrder(theme);
    }

    // ==================== URL Matching ====================
    function isMatchedUrl() {
        const href = window.location.href;
        if (/^https:\/\/github\.com\/search\?.*$/.test(href)) return 'matchSearchPage';
        if (/^https:\/\/github\.com\/[^/]+\/[^/]+(?:\?.*)?$|^https:\/\/github\.com\/[^/]+\/[^/]+\/tree\/.+$/.test(href)) return 'matchRepoPage';
        return null;
    }

    // ==================== Date Formatting ====================
    function formatDate(dateStr) {
        if (!dateStr) return '';
        const date = new Date(dateStr);
        if (isNaN(date.getTime())) return dateStr;
        const Y = date.getFullYear();
        const M = String(date.getMonth() + 1).padStart(2, '0');
        const D = String(date.getDate()).padStart(2, '0');
        return `${Y}-${M}-${D}`;
    }

    function forceFormatRelativeTime() {
        if (!THEME.TIME_FORMAT.isEnabled) return;
        const elements = document.querySelectorAll('relative-time');
        if (elements.length === 0) return;
        elements.forEach((item) => {
            try {
                const dateStr = item.getAttribute('datetime');
                if (!dateStr) return;
                const date = new Date(dateStr);
                if (isNaN(date.getTime())) return;
                const Y = date.getFullYear();
                const M = String(date.getMonth() + 1).padStart(2, '0');
                const D = String(date.getDate()).padStart(2, '0');
                const hh = String(date.getHours()).padStart(2, '0');
                const mm = String(date.getMinutes()).padStart(2, '0');
                const str = `${Y}-${M}-${D} ${hh}:${mm}`;

                if (item.nextElementSibling && item.nextElementSibling.classList.contains('custom-time-format')) {
                    if (item.nextElementSibling.textContent !== str) item.nextElementSibling.textContent = str;
                    return;
                }
                item.classList.add('custom-time-replaced');
                const span = document.createElement('span');
                span.className = 'custom-time-format formatted-date-span';
                span.textContent = str;
                item.parentNode.insertBefore(span, item.nextSibling);
            } catch (e) {}
        });
    }

    // ==================== Debounce & Run ====================
    function debounce(func, wait) {
        let timeout;
        return function (...args) {
            clearTimeout(timeout);
            timeout = setTimeout(() => func.apply(this, args), wait);
        };
    }

    const runScript = debounce(() => {
        try {
            GitHub_Freshness();
            GitHub_FreshnessAwesome(THEME);
            forceFormatRelativeTime();
        } catch (e) { console.error('GitHub Freshness: Script execution error', e); }
    }, 350);

    // ==================== Mutation Observer ====================
    let mutationObserver = null;
    function initMutationObserver() {
        if (mutationObserver) return;
        mutationObserver = new MutationObserver((mutations) => {
            let shouldRun = false;
            for (const mutation of mutations) {
                if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
                    for (const node of mutation.addedNodes) {
                        if (node.nodeType === Node.ELEMENT_NODE) {
                            if (node.matches && (node.matches('relative-time') || node.querySelector && node.querySelector('relative-time, [data-testid="file-list-row"]'))) {
                                shouldRun = true; break;
                            }
                        }
                    }
                }
            }
            if (shouldRun) runScript();
        });
        mutationObserver.observe(document.body, { childList: true, subtree: true });
    }

    // ==================== Init ====================
    $(function() {
        console.log('GitHub Freshness v1.0.9 (Sort Fix) Loaded');
        runScript();
        initMutationObserver();
    });

    document.addEventListener('pjax:end', () => { runScript(); initMutationObserver(); });
    window.addEventListener('popstate', () => setTimeout(runScript, 350));

    const originalPush = history.pushState;
    history.pushState = function (...args) { originalPush.apply(this, args); setTimeout(runScript, 350); };

    const originalReplace = history.replaceState;
    history.replaceState = function (...args) { originalReplace.apply(this, args); setTimeout(runScript, 350); };

    // ==================== Periodic Time Update ====================
    let timeUpdateScheduled = false;
    function scheduleTimeUpdate() {
        if (timeUpdateScheduled) return;
        timeUpdateScheduled = true;
        requestAnimationFrame(() => {
            forceFormatRelativeTime();
            if (THEME.SORT && THEME.SORT.isEnabled) applyCSSSortOrder(THEME);
            timeUpdateScheduled = false;
        });
    }
    setInterval(scheduleTimeUpdate, 2000);

    // ==================== Menu Command ====================
    GM_registerMenuCommand('⚙️ Settings', createSettingsPanel);

    // ==================== Dark Mode Listener ====================
    const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
    darkModeMediaQuery.addEventListener('change', (e) => {
        if (CURRENT_THEME === 'auto') {
            THEME_TYPE = e.matches ? 'dark' : 'light';
            THEME = config_JSON[THEME_TYPE] || JSON.parse(JSON.stringify(default_THEME));
            runScript();
        }
    });

})();