// ==UserScript== // @name ChatGPT Reset Expiry|ChatGPT 重置额度有效期查询插件 // @name:en ChatGPT Reset Expiry // @name:zh ChatGPT 重置额度有效期查询插件 // @name:zh-CN ChatGPT 重置额度有效期查询插件 // @name:zh-HK ChatGPT 重置額度有效期查詢插件 // @name:zh-MO ChatGPT 重置額度有效期查詢插件 // @name:zh-TW ChatGPT 重置額度有效期查詢插件 // @name:ja ChatGPT リセットクレジット有効期限確認ツール // @name:ko ChatGPT 리셋 크레딧 만료 시간 확인 도구 // @name:es ChatGPT Reset Expiry|Consulta de caducidad de créditos // @name:de ChatGPT Reset Expiry|Ablaufzeit der Reset-Credits // @name:fr ChatGPT Reset Expiry|Vérification de l’expiration des crédits // @namespace https://github.com/kadto183/chatgpt-reset-expiry // @version 1.16 // @description View the exact expiration time of ChatGPT reset credits in your browser's local timezone.|查询 ChatGPT 重置额度的准确有效期与失效时间,并自动转换为浏览器当前时区。 // @description:en View the exact expiration time of ChatGPT reset credits in your browser's local timezone. // @description:zh 查询 ChatGPT 重置额度的准确有效期与失效时间,精确到秒并自动转换为浏览器当前时区。 // @description:zh-CN 查询 ChatGPT 重置额度的准确有效期与失效时间,精确到秒并自动转换为浏览器当前时区。 // @description:zh-HK 查詢 ChatGPT 重置額度的準確有效期與失效時間,精確到秒並自動轉換為瀏覽器目前時區。 // @description:zh-MO 查詢 ChatGPT 重置額度的準確有效期與失效時間,精確到秒並自動轉換為瀏覽器目前時區。 // @description:zh-TW 查詢 ChatGPT 重置額度的準確有效期與失效時間,精確到秒並自動轉換為瀏覽器目前時區。 // @description:ja ChatGPT のリセットクレジットの正確な有効期限を秒単位で確認し、ブラウザのローカルタイムゾーンで表示します。 // @description:ko ChatGPT 리셋 크레딧의 정확한 만료 시간을 초 단위로 확인하고 브라우저의 현지 시간대로 표시합니다. // @description:es Consulta la hora exacta de caducidad de los créditos de restablecimiento de ChatGPT y conviértela a la zona horaria local del navegador. // @description:de Zeigt die genaue Ablaufzeit der ChatGPT Reset-Credits an und rechnet sie in die lokale Browser-Zeitzone um. // @description:fr Affiche l’heure exacte d’expiration des crédits de réinitialisation ChatGPT et la convertit dans le fuseau horaire local du navigateur. // @author kadto183 // @license MIT // @homepageURL https://github.com/kadto183/chatgpt-reset-expiry // @supportURL https://github.com/kadto183/chatgpt-reset-expiry/issues // @downloadURL https://raw.githubusercontent.com/kadto183/chatgpt-reset-expiry/main/chatgpt-reset-expiry.user.js // @updateURL https://raw.githubusercontent.com/kadto183/chatgpt-reset-expiry/main/chatgpt-reset-expiry.user.js // @match https://chatgpt.com/* // @match https://chat.openai.com/* // @run-at document-start // @grant none // ==/UserScript== (function () { 'use strict'; const PREFIX = '[ChatGPT Reset Expiry]'; // --------------------------------------------------------------------- // Data source // --------------------------------------------------------------------- const RESET_CREDITS_URL = '/backend-api/wham/rate-limit-reset-credits'; const CANDIDATE_URL_RE = /(usage|reset|credit|limit|subscription|plan|wham|rate)/i; const RELATED_KEY_RE = /(expire|expires|expiry|expiration|reset|credit|limit|valid_until)/i; const HIGH_VALUE_KEY_RE = /(expires?_?at|expiry|expiration|reset_?at|reset_?time|valid_?until)/i; // --------------------------------------------------------------------- // Browser timezone and UI language // --------------------------------------------------------------------- const LOCAL_TIME_ZONE = Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC'; const SIMPLIFIED_CHINESE_TIME_ZONES = new Set([ 'Asia/Shanghai', 'Asia/Chongqing', 'Asia/Chungking', 'Asia/Harbin', 'Asia/Urumqi', 'Asia/Kashgar' ]); const TRADITIONAL_CHINESE_TIME_ZONE_LOCALES = { 'Asia/Hong_Kong': 'zh-HK', 'Asia/Macau': 'zh-MO', 'Asia/Taipei': 'zh-TW' }; const IS_SIMPLIFIED_CHINESE_ZONE = SIMPLIFIED_CHINESE_TIME_ZONES.has(LOCAL_TIME_ZONE); const IS_TRADITIONAL_CHINESE_ZONE = Object.prototype.hasOwnProperty.call( TRADITIONAL_CHINESE_TIME_ZONE_LOCALES, LOCAL_TIME_ZONE ); const UI_LANG = IS_SIMPLIFIED_CHINESE_ZONE ? 'zh-Hans' : IS_TRADITIONAL_CHINESE_ZONE ? 'zh-Hant' : 'en'; const UI_LOCALE = IS_SIMPLIFIED_CHINESE_ZONE ? 'zh-CN' : TRADITIONAL_CHINESE_TIME_ZONE_LOCALES[ LOCAL_TIME_ZONE ] || 'en-US'; const CHINESE_ZONE_NAMES = { 'Asia/Shanghai': '中国标准时间', 'Asia/Chongqing': '中国标准时间', 'Asia/Chungking': '中国标准时间', 'Asia/Harbin': '中国标准时间', 'Asia/Urumqi': '中国乌鲁木齐时间', 'Asia/Kashgar': '中国喀什时间', 'Asia/Hong_Kong': '中國香港時間', 'Asia/Macau': '中國澳門時間', 'Asia/Taipei': '中國台灣時間' }; // --------------------------------------------------------------------- // Localized UI text // --------------------------------------------------------------------- const TEXT = { 'zh-Hans': { title: 'GPT 重置额度有效期', subtitle: '查询额度具体到几点失效', more: '更多信息', waiting: '正在检测当前页面…', found: count => `当前有效额度 ${count} 个`, empty: '当前尚未检测到重置额度', noActive: '当前没有有效的重置额度', history: '已失效额度', dataReady: '✓ 已从 ChatGPT 页面数据读取', dataWaiting: '等待 ChatGPT 页面数据', credit: index => `重置额度 ${index}`, nearest: '最近到期', expired: '已失效', copy: '复制全部时间', copied: '已复制', other: '其他检测结果', noOther: '暂无其他检测结果', source: '数据来源', timezone: '当前时区', toggle: '展开或收起', close: '关闭' }, 'zh-Hant': { title: 'GPT 重置額度有效期', subtitle: '查詢額度具體到幾點失效', more: '更多資訊', waiting: '正在偵測目前頁面…', found: count => `目前有效額度 ${count} 個`, empty: '目前尚未偵測到重置額度', noActive: '目前沒有有效的重置額度', history: '已失效額度', dataReady: '✓ 已從 ChatGPT 頁面資料讀取', dataWaiting: '等待 ChatGPT 頁面資料', credit: index => `重置額度 ${index}`, nearest: '最近到期', expired: '已失效', copy: '複製全部時間', copied: '已複製', other: '其他偵測結果', noOther: '暫無其他偵測結果', source: '資料來源', timezone: '目前時區', toggle: '展開或收起', close: '關閉' }, en: { title: 'GPT Reset Expiry', subtitle: 'View the exact expiration time', more: 'More', waiting: 'Checking the current page…', found: count => `${count} active reset credit${count === 1 ? '' : 's'}`, empty: 'No reset credits detected on this page', noActive: 'No active reset credits', history: 'Expired Credits', dataReady: '✓ Read from ChatGPT page data', dataWaiting: 'Waiting for ChatGPT page data', credit: index => `Reset Credit ${index}`, nearest: 'Expires Next', expired: 'Expired', copy: 'Copy All Times', copied: 'Copied', other: 'Other Detected Results', noOther: 'No other results', source: 'Data source', timezone: 'Current time zone', toggle: 'Expand or collapse', close: 'Close' } }; const T = TEXT[UI_LANG]; // --------------------------------------------------------------------- // Runtime state // --------------------------------------------------------------------- const resetCredits = new Map(); const otherMatches = new Map(); let panel = null; let mainList = null; let otherList = null; let statusEl = null; const STORAGE_KEYS = { panelPreference: 'chatgpt-reset-expiry:panel-preference', panelPosition: 'chatgpt-reset-expiry:panel-position' }; function readStorage(key) { try { return localStorage.getItem(key); } catch (_) { return null; } } function writeStorage(key, value) { try { localStorage.setItem(key, value); } catch (_) {} } // Always start quietly. Saved preferences are applied after confirmed // reset-credit data is detected. const savedPanelPreference = readStorage(STORAGE_KEYS.panelPreference); let isExpanded = false; let userCollapsed = savedPanelPreference === 'collapsed'; let autoExpandedOnce = false; let dismissed = false; let suppressHeaderClick = false; // --------------------------------------------------------------------- // Time helpers // --------------------------------------------------------------------- function parseDate(value) { if (value === null || value === undefined) { return null; } let date = null; if (typeof value === 'number') { if (value > 1e9 && value < 1e11) { date = new Date(value * 1000); } else if (value >= 1e11 && value < 1e15) { date = new Date(value); } } if (typeof value === 'string') { const text = value.trim(); if (/^\d{10}$/.test(text)) { date = new Date(Number(text) * 1000); } else if (/^\d{13}$/.test(text)) { date = new Date(Number(text)); } else { const timestamp = Date.parse(text); if (!Number.isNaN(timestamp)) { date = new Date(timestamp); } } } if (!date || Number.isNaN(date.getTime())) { return null; } const year = date.getUTCFullYear(); if (year < 2020 || year > 2100) { return null; } return date; } function getDateParts(date) { const parts = new Intl.DateTimeFormat( 'en-CA', { timeZone: LOCAL_TIME_ZONE, year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hourCycle: 'h23' } ).formatToParts(date); const result = {}; for (const part of parts) { if (part.type !== 'literal') { result[part.type] = part.value; } } return result; } function formatDateOnly(date) { const p = getDateParts(date); return `${p.year}/${p.month}/${p.day}`; } function formatTimeOnly(date) { const p = getDateParts(date); return `${p.hour}:${p.minute}:${p.second}`; } function formatLocal(date) { return `${formatDateOnly(date)} ${formatTimeOnly(date)}`; } function getUtcOffset(date) { try { const parts = new Intl.DateTimeFormat( 'en-US', { timeZone: LOCAL_TIME_ZONE, timeZoneName: 'longOffset' } ).formatToParts(date); const zone = parts.find( part => part.type === 'timeZoneName' )?.value; if (zone) { return zone.replace('GMT', 'UTC'); } } catch (_) {} // LOCAL_TIME_ZONE comes from the browser/system, so this fallback // remains correct for the browser's active local timezone. const offsetMinutes = -date.getTimezoneOffset(); const sign = offsetMinutes >= 0 ? '+' : '-'; const absolute = Math.abs(offsetMinutes); const hours = String( Math.floor(absolute / 60) ).padStart(2, '0'); const minutes = String( absolute % 60 ).padStart(2, '0'); return `UTC${sign}${hours}:${minutes}`; } function getTimeZoneDisplayName(date) { if (CHINESE_ZONE_NAMES[LOCAL_TIME_ZONE]) { return CHINESE_ZONE_NAMES[LOCAL_TIME_ZONE]; } try { const parts = new Intl.DateTimeFormat( UI_LOCALE, { timeZone: LOCAL_TIME_ZONE, timeZoneName: 'long' } ).formatToParts(date); const zoneName = parts.find( part => part.type === 'timeZoneName' )?.value; if (zoneName) { return zoneName; } } catch (_) {} return LOCAL_TIME_ZONE; } function formatTimeZoneLabel(date) { return ( `${getTimeZoneDisplayName(date)} · ` + `${getUtcOffset(date)}` ); } function getCurrentZoneSummary() { return formatTimeZoneLabel(new Date()); } // --------------------------------------------------------------------- // DOM helpers // --------------------------------------------------------------------- function escapeHtml(value) { return String(value) .replaceAll('&', '&') .replaceAll('<', '<') .replaceAll('>', '>') .replaceAll('"', '"') .replaceAll("'", '''); } function applyExpandedState() { if (!panel) { return; } panel.classList.toggle( 'grf-expanded', isExpanded ); panel.classList.toggle( 'grf-collapsed', !isExpanded ); const toggleButton = panel.querySelector('#grf-toggle'); if (toggleButton) { toggleButton.textContent = isExpanded ? '−' : '+'; } } function setExpanded(expanded, byUser = false) { isExpanded = expanded; if (byUser) { userCollapsed = !expanded; writeStorage( STORAGE_KEYS.panelPreference, expanded ? 'expanded' : 'collapsed' ); } applyExpandedState(); } function maybeAutoExpand() { if ( dismissed || autoExpandedOnce || resetCredits.size === 0 ) { return; } autoExpandedOnce = true; if ( savedPanelPreference === 'collapsed' || userCollapsed ) { return; } setExpanded(true, false); } function detectDarkTheme() { const root = document.documentElement; const body = document.body; const explicitTheme = root?.getAttribute('data-theme') || body?.getAttribute?.('data-theme'); if (explicitTheme === 'dark') return true; if (explicitTheme === 'light') return false; if ( root?.classList.contains('dark') || body?.classList?.contains('dark') ) { return true; } if ( root?.classList.contains('light') || body?.classList?.contains('light') ) { return false; } return window.matchMedia?.( '(prefers-color-scheme: dark)' )?.matches ?? true; } function applyTheme() { if (!panel) return; const dark = detectDarkTheme(); panel.classList.toggle( 'grf-dark', dark ); panel.classList.toggle( 'grf-light', !dark ); } function installThemeWatcher() { const observer = new MutationObserver(applyTheme); observer.observe( document.documentElement, { attributes: true, attributeFilter: [ 'class', 'data-theme', 'style' ] } ); const media = window.matchMedia?.( '(prefers-color-scheme: dark)' ); if (media?.addEventListener) { media.addEventListener( 'change', applyTheme ); } } function clampPanelPosition(left, top) { const width = panel?.offsetWidth || 174; const height = panel?.offsetHeight || 44; const margin = 8; return { left: Math.min( Math.max(margin, left), Math.max( margin, window.innerWidth - width - margin ) ), top: Math.min( Math.max(margin, top), Math.max( margin, window.innerHeight - height - margin ) ) }; } function restorePanelPosition() { const raw = readStorage( STORAGE_KEYS.panelPosition ); if (!raw || !panel) return; try { const saved = JSON.parse(raw); if ( !Number.isFinite(saved.left) || !Number.isFinite(saved.top) ) { return; } const pos = clampPanelPosition( saved.left, saved.top ); panel.style.left = `${pos.left}px`; panel.style.top = `${pos.top}px`; panel.style.right = 'auto'; } catch (_) {} } function savePanelPosition() { if (!panel) return; const rect = panel.getBoundingClientRect(); writeStorage( STORAGE_KEYS.panelPosition, JSON.stringify({ left: Math.round(rect.left), top: Math.round(rect.top) }) ); } function installDragBehaviour() { if (!panel) return; const header = panel.querySelector('#grf-header'); if (!header) return; let dragging = false; let startX = 0; let startY = 0; let startLeft = 0; let startTop = 0; let moved = false; header.addEventListener( 'pointerdown', event => { if ( event.button !== 0 || event.target.closest( '#grf-header-actions' ) ) { return; } const rect = panel.getBoundingClientRect(); dragging = true; moved = false; startX = event.clientX; startY = event.clientY; startLeft = rect.left; startTop = rect.top; header.setPointerCapture?.( event.pointerId ); } ); header.addEventListener( 'pointermove', event => { if (!dragging) return; const dx = event.clientX - startX; const dy = event.clientY - startY; if ( Math.abs(dx) > 4 || Math.abs(dy) > 4 ) { moved = true; } if (!moved) return; const pos = clampPanelPosition( startLeft + dx, startTop + dy ); panel.style.left = `${pos.left}px`; panel.style.top = `${pos.top}px`; panel.style.right = 'auto'; event.preventDefault(); } ); const endDrag = event => { if (!dragging) return; dragging = false; if (moved) { suppressHeaderClick = true; savePanelPosition(); setTimeout( () => { suppressHeaderClick = false; }, 0 ); } try { header.releasePointerCapture?.( event.pointerId ); } catch (_) {} }; header.addEventListener( 'pointerup', endDrag ); header.addEventListener( 'pointercancel', endDrag ); window.addEventListener( 'resize', () => { if (!panel) return; const rect = panel.getBoundingClientRect(); const pos = clampPanelPosition( rect.left, rect.top ); panel.style.left = `${pos.left}px`; panel.style.top = `${pos.top}px`; panel.style.right = 'auto'; savePanelPosition(); } ); } // --------------------------------------------------------------------- // UI // --------------------------------------------------------------------- function createPanel() { if ( panel || !document.documentElement ) { return; } const style = document.createElement('style'); style.textContent = ` #gpt-reset-finder-panel { position: fixed; top: 76px; right: 20px; z-index: 2147483647; color: #f0f0f0; background: rgba(24,24,24,.97); border: 1px solid rgba(255,255,255,.11); border-radius: 15px; box-shadow: 0 16px 45px rgba(0,0,0,.35); font-family: "Microsoft YaHei", "Segoe UI", system-ui, -apple-system, sans-serif; overflow: hidden; backdrop-filter: blur(14px); transition: width .18s ease, border-radius .18s ease; } #gpt-reset-finder-panel.grf-collapsed { width: 158px; border-radius: 12px; } #gpt-reset-finder-panel.grf-collapsed #grf-body { display: none; } #gpt-reset-finder-panel.grf-collapsed #grf-header { padding: 9px 9px 9px 11px; border-bottom: 0; cursor: pointer; } #gpt-reset-finder-panel.grf-collapsed #grf-title { font-size: 12px; } #gpt-reset-finder-panel.grf-collapsed #grf-subtitle { display: none; } #gpt-reset-finder-panel.grf-collapsed #grf-close { display: none; } #gpt-reset-finder-panel.grf-expanded { width: 360px; max-height: 70vh; } #grf-header { display: flex; cursor: move; touch-action: none; align-items: center; justify-content: space-between; padding: 11px 12px 10px; border-bottom: 1px solid rgba(255,255,255,.075); background: linear-gradient( 180deg, rgba(255,255,255,.038), rgba(255,255,255,0) ); user-select: none; } #grf-title-wrap { display: flex; flex-direction: column; gap: 0; } #grf-title-line { display: flex; align-items: center; gap: 7px; } #grf-title { font-size: 14px; font-weight: 650; letter-spacing: .1px; } #grf-mini-count { min-width: 17px; height: 17px; display: none; align-items: center; justify-content: center; padding: 0 5px; border-radius: 999px; background: rgba(236,188,72,.14); border: 1px solid rgba(236,188,72,.24); color: #e5c467; font-size: 9px; } #grf-mini-count.grf-visible { display: inline-flex; } #grf-subtitle { display: none; } #grf-header-actions { display: flex; gap: 4px; } .grf-icon-btn { width: 29px; height: 29px; border: 0; border-radius: 7px; background: transparent; color: #999; cursor: pointer; font-size: 16px; } .grf-icon-btn:hover { background: rgba(255,255,255,.075); color: #eee; } #grf-body { max-height: calc(70vh - 52px); overflow-y: auto; } #grf-overview { padding: 9px 12px 2px; } #grf-status { font-size: 12px; color: #999; } #grf-current-zone { display: none; } #grf-main-list { padding: 3px 10px 8px; } .grf-card { position: relative; margin-top: 7px; padding: 10px 11px 11px; background: linear-gradient( 145deg, rgba(255,255,255,.047), rgba(255,255,255,.018) ); border: 1px solid rgba(255,255,255,.095); border-radius: 11px; } .grf-card:hover { border-color: rgba(255,255,255,.16); } .grf-card.grf-nearest { border-color: rgba(236,188,72,.48); background: linear-gradient( 145deg, rgba(236,188,72,.085), rgba(255,255,255,.018) ); box-shadow: inset 2px 0 0 rgba(236,188,72,.72); } .grf-card.grf-expired { opacity: .48; } .grf-card-top { display: flex; justify-content: space-between; align-items: center; margin-bottom: 7px; } .grf-card-name { font-size: 11px; color: #a8a8a8; } .grf-badge, .grf-expired-label { padding: 2px 7px; border-radius: 999px; font-size: 10px; } .grf-badge { background: rgba(236,188,72,.12); border: 1px solid rgba(236,188,72,.25); color: #e5c467; } .grf-expired-label { background: rgba(255,255,255,.035); border: 1px solid rgba(255,255,255,.07); color: #888; } .grf-date-row { display: flex; align-items: baseline; gap: 9px; white-space: nowrap; } .grf-date { font-size: 16px; font-weight: 650; color: #f1f1f1; font-variant-numeric: tabular-nums; } .grf-time { font-size: 16px; font-weight: 650; color: #efc969; font-family: "SFMono-Regular", Consolas, monospace; font-variant-numeric: tabular-nums; } .grf-zone { margin-top: 4px; color: #777; font-size: 9.5px; } #grf-actions { display: flex; padding: 1px 10px 9px; } .grf-action-btn { flex: 1; width: 100%; padding: 7px 9px; border-radius: 7px; border: 1px solid rgba(255,255,255,.10); background: rgba(255,255,255,.043); color: #ccc; cursor: pointer; font-size: 12px; } .grf-action-btn:hover { background: rgba(255,255,255,.075); color: #f2f2f2; } #grf-other-header { display: flex; align-items: center; justify-content: space-between; padding: 10px 14px; border-top: 1px solid rgba(255,255,255,.07); color: #808080; font-size: 11px; cursor: pointer; user-select: none; } #grf-other-header:hover { background: rgba(255,255,255,.025); } #grf-other-list { display: none; padding: 0 14px 12px; max-height: 220px; overflow-y: auto; } .grf-other-item { padding: 8px 0; border-top: 1px solid rgba(255,255,255,.055); color: #858585; font-size: 10px; line-height: 1.55; word-break: break-all; } .grf-other-key { color: #7fa9d8; } .grf-empty { padding: 19px 10px; text-align: center; color: #727272; font-size: 12px; } #grf-more-header { display: flex; align-items: center; justify-content: space-between; padding: 8px 12px; border-top: 1px solid rgba(255,255,255,.07); color: #777; font-size: 10.5px; cursor: pointer; user-select: none; } #grf-more-header:hover { background: rgba(255,255,255,.025); } #grf-more-list { display: none; } #grf-history-header { display: none; align-items: center; justify-content: space-between; padding: 10px 14px; border-top: 1px solid rgba(255,255,255,.07); color: #808080; font-size: 11px; cursor: pointer; user-select: none; } #grf-history-header.grf-visible { display: flex; } #grf-more-list #grf-history-header, #grf-more-list #grf-other-header { padding: 7px 12px; border-top: 0; font-size: 10px; background: transparent; } #grf-history-header:hover { background: rgba(255,255,255,.025); } #grf-history-list { display: none; padding: 0 12px 10px; } #grf-history-list .grf-card { opacity: .55; } #grf-footer { padding: 0 14px 12px; color: #666; font-size: 9.5px; line-height: 1.5; word-break: break-all; } #gpt-reset-finder-panel.grf-light { color: #202123; background: rgba(255,255,255,.98); border-color: rgba(0,0,0,.11); box-shadow: 0 16px 45px rgba(0,0,0,.16); } #gpt-reset-finder-panel.grf-light #grf-header { border-bottom-color: rgba(0,0,0,.08); background: linear-gradient( 180deg, rgba(0,0,0,.025), rgba(0,0,0,0) ); } #gpt-reset-finder-panel.grf-light #grf-title, #gpt-reset-finder-panel.grf-light .grf-date { color: #202123; } #gpt-reset-finder-panel.grf-light #grf-subtitle, #gpt-reset-finder-panel.grf-light #grf-status, #gpt-reset-finder-panel.grf-light .grf-card-name { color: #5f6368; } #gpt-reset-finder-panel.grf-light #grf-current-zone, #gpt-reset-finder-panel.grf-light .grf-zone, #gpt-reset-finder-panel.grf-light #grf-footer { color: #777; } #gpt-reset-finder-panel.grf-light .grf-card { background: linear-gradient( 145deg, rgba(0,0,0,.025), rgba(0,0,0,.012) ); border-color: rgba(0,0,0,.10); } #gpt-reset-finder-panel.grf-light .grf-card.grf-nearest { border-color: rgba(180,130,0,.45); background: linear-gradient( 145deg, rgba(236,188,72,.12), rgba(0,0,0,.01) ); } #gpt-reset-finder-panel.grf-light .grf-time { color: #9a6700; } #gpt-reset-finder-panel.grf-light .grf-icon-btn { color: #666; } #gpt-reset-finder-panel.grf-light .grf-icon-btn:hover, #gpt-reset-finder-panel.grf-light .grf-action-btn:hover { background: rgba(0,0,0,.06); color: #202123; } #gpt-reset-finder-panel.grf-light .grf-action-btn { border-color: rgba(0,0,0,.10); background: rgba(0,0,0,.025); color: #444; } #gpt-reset-finder-panel.grf-light #grf-more-header, #gpt-reset-finder-panel.grf-light #grf-other-header, #gpt-reset-finder-panel.grf-light #grf-history-header { border-top-color: rgba(0,0,0,.07); color: #666; } #gpt-reset-finder-panel.grf-light #grf-more-header:hover, #gpt-reset-finder-panel.grf-light #grf-other-header:hover, #gpt-reset-finder-panel.grf-light #grf-history-header:hover { background: rgba(0,0,0,.025); } #gpt-reset-finder-panel.grf-light .grf-other-item { border-top-color: rgba(0,0,0,.06); color: #666; } #gpt-reset-finder-panel.grf-light .grf-empty { color: #777; } `; document.documentElement.appendChild(style); panel = document.createElement('div'); panel.id = 'gpt-reset-finder-panel'; panel.className = 'grf-collapsed'; panel.innerHTML = `