🐱 全世界都要变成可爱猫猫!

让整个网络世界都变成超可爱的猫娘语调喵~

// ==UserScript==
// @name         🐱 全世界都要变成可爱猫猫!
// @version      4.3.4
// @description  让整个网络世界都变成超可爱的猫娘语调喵~
// @author       超萌猫娘开发队
// @match        *://*/*
// @include      *://*.bilibili.com/video/*
// @include      *://*.bilibili.com/anime/*
// @include      *://*.bilibili.com/bangumi/play/*
// @exclude      *://greasyfork.org/*
// @exclude      *://*.gov/*
// @exclude      *://*.edu/*
// @icon         https://raw.githubusercontent.com/microsoft/fluentui-emoji/main/assets/Cat/3D/cat_3d.png
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_addStyle
// @grant        GM_registerMenuCommand
// @license      MIT
// @namespace https://greasyfork.org/users/1503554
// ==/UserScript==

(function() {
    'use strict';

    // ===== 版本管理 =====
    const SCRIPT_VERSION = "4.3.4";
    const isVersionUpdate = GM_getValue("SCRIPT_VERSION") !== SCRIPT_VERSION;
    if (isVersionUpdate) {
        GM_setValue("SCRIPT_VERSION", SCRIPT_VERSION);
        console.log('🎉 猫娘脚本已更新到版本', SCRIPT_VERSION);
    }
    const UPdate_What = "修复黑名单只能添加一个的问题 😽"

    // ===== 增强配置系统 =====
    const defaultConfig = {
        // 性能配置
        performance: {
            processInterval: 5000,
            maxProcessingTimeSlice: 8,
            batchSize: 5,
            observerThrottle: 1000,
            maxRetryAttempts: 10,
            idleCallbackTimeout: 2000,
            debounceDelay: 500
        },

        // 功能开关
        features: {
            affectInput: false,
            bilibiliMergeALinks: true,
            bilibiliRandomizeUserNames: true, // 用户名前缀功能开关
            autoProcessNewContent: true,
            shadowDomSupport: true,
            performanceMonitoring: false,
            debugMode: false,
            smartProcessing: true,
            enableBlacklist: true, // 黑名单功能开关
            showOriginalOnHover: false // 鼠标悬停显示原文功能开关
        },

        // 站点配置
        sites: {
            excludeDomains: [
                'github.com', 'stackoverflow.com', 'google.com',
                'gov.cn', 'edu.cn', 'greasyfork.org'
            ],
            bilibili: {
                smartPause: true,
                retryInterval: 1000,
                maxRetryDelay: 5000,
                commentSelector: 'bili-comment-thread-renderer',
                userNameSelector: '#user-name a',
                contentSelector: '#contents span'
            }
        },

        // 黑名单配置
        blacklist: {
            sites: [], // 格式: [{domain: 'example.com', type: 'site'|'page', url: '', expiry: timestamp, reason: ''}]
            defaultDuration: 24 * 60 * 60 * 1000, // 24小时
            enabled: true
        },

        // 用户偏好 - 优化描述
        preferences: {
            cuteLevel: 'normal', // low, normal, high
            customEndings: [],
            disabledWords: [],
            processingMode: 'contextual', // gentle(保守替换), contextual(上下文感知), aggressive(积极替换)
            intelligentReplacement: true,
            replacementIntensity: 0.3, // 替换强度 0.1-1.0
            endingFrequency: 0.3, // 结尾词频率 0.1-1.0 (降低频率)
            decorativeFrequency: 0.2 // 装饰符频率 0.1-1.0
        },

        // 统计信息
        stats: {
            processedElements: 0,
            replacedWords: 0,
            lastActive: new Date().toISOString(),
            installDate: new Date().toISOString(),
            sessionProcessed: 0,
            blacklistHits: 0 // 黑名单命中次数
        }
    };


    // 加载用户配置
    let userConfig = GM_getValue("catgirlConfig") || {};

    // 正确的合并方式:始终创建一个新对象。
    // 以 defaultConfig 为基础,然后用 userConfig 中的设置覆盖它。
    // 这样既能保留用户的设置,又能在脚本更新时补充上新增的默认选项。
    let CONFIG = Object.assign({}, defaultConfig, userConfig);

    // 如果是版本更新,将合并后的新版配置保存回去,并显示更新通知。
    if (isVersionUpdate) {
        GM_setValue("catgirlConfig", CONFIG);
        showUpdateNotification();
    }

    // ===== 扩展的可爱元素库 =====
    const cuteLibrary = {
        endings: {
            low: ['喵', '呢', '哦', '啊'],
            normal: ['喵~', 'にゃん', '喵呜', 'nya~', '喵喵', '呢~'],
            high: ['喵~♪', 'にゃん♡', '喵呜~', 'nya~♡', '喵喵desu', 'にゃ♡', 'mew~', '喵♪', 'nyaa~', '喵desu~', '喵呢~', '喵哈~']
        },

        userPrefixes: ['🏳️‍⚧️', '✨', '💕', '🌸', '🎀', '🌟'],
        decorativePrefixes: ['✨', '💫', '⭐', '🌸', '🎀', '💎'],

        emotionalEndings: {
            excited: ['喵!', 'にゃん!', '哇喵~', '好棒喵~'],
            calm: ['喵~', '呢~', '嗯喵', '是这样喵'],
            happy: ['开心喵~', '嘻嘻喵', '哈哈喵~', '好开心喵'],
            confused: ['诶喵?', '嗯?喵', '咦喵~', '不懂喵'],
            sad: ['呜呜喵', '难过喵', '555喵', '想哭喵']
        }
    };

    // ===================================================================
    // ===== 网站适配器模块 (Site Adapter Modules) =====
    // ===================================================================
    const siteModules = {
        // Bilibili 适配器
        'bilibili.com': {
            name: 'Bilibili',
            // 需要处理的评论区选择器
            commentSelectors: [
                '.reply-item .reply-content', '.comment-item .comment-content', '.bili-comment-content',
                '#contents span', '.comment-text'
            ],
            // 用户名选择器
            usernameSelectors: [
                '.user-name', '.reply-author', '.comment-author', '#user-name a', '.author-name'
            ],
            // 动态内容容器(用于 MutationObserver 监控)
            dynamicContentContainer: '.reply-list',
            // 针对该网站的特殊处理函数
            postProcessing: function(app) {
                // 将原有的 B 站链接转文本功能放在这里
                if (CONFIG.features.bilibiliMergeALinks) {
                    app.processBilibiliLinks(); // 假设 processBilibiliLinks 已被正确实现
                }
            }
        },

        // YouTube 适配器 (示例)
        'youtube.com': {
            name: 'YouTube',
            commentSelectors: [
                '#content-text', // YouTube 评论文本
                'yt-formatted-string.ytd-comment-renderer'
            ],
            usernameSelectors: [
                '#author-text' // YouTube 用户名
            ],
            dynamicContentContainer: '#comments #contents', // YouTube 加载新评论的容器
            // YouTube 没有像B站那样的特殊需求,所以这里留空或不定义
            postProcessing: null
        },

        // 如果未来要支持 Twitter, 可以这样添加
        // 'twitter.com': { ... }
    };






    // ===== 黑名单管理器 =====
    class BlacklistManager {
        constructor() {
            this.panel = null;
            this.isVisible = false;
        }

        isBlacklisted() {
            if (!CONFIG.blacklist.enabled) return false;

            const currentDomain = location.hostname;
            const currentUrl = location.href;
            const now = Date.now();

            for (const item of CONFIG.blacklist.sites) {
                // 检查是否过期
                if (item.expiry && item.expiry < now) {
                    this.removeExpiredItem(item);
                    continue;
                }

                // 检查域名匹配
                if (item.type === 'site' && currentDomain.includes(item.domain)) {
                    CONFIG.stats.blacklistHits++;
                    return true;
                }

                // 检查页面匹配
                if (item.type === 'page' && currentUrl === item.url) {
                    CONFIG.stats.blacklistHits++;
                    return true;
                }
            }

            return false;
        }

        addToBlacklist(type, duration, reason = '') {
            const now = Date.now();
            const expiry = duration === -1 ? null : now + duration;
            const domain = location.hostname;
            const url = type === 'page' ? location.href : '';

            // 检查是否存在相同的域名,如果存在则更新而不是添加新项
            const existingIndex = CONFIG.blacklist.sites.findIndex(item => {
                if (item.type === 'site' && type === 'site') {
                    return item.domain === domain;
                }
                if (item.type === 'page' && type === 'page') {
                    return item.url === url;
                }
                return false;
            });

            if (existingIndex !== -1) {
                // 更新现有项目,按照最新的进行计时
                CONFIG.blacklist.sites[existingIndex] = {
                    ...CONFIG.blacklist.sites[existingIndex],
                    expiry: expiry,
                    reason: reason,
                    addedAt: now
                };
                const durationText = duration === -1 ? '永久' : this.formatDuration(duration);
                const typeText = type === 'site' ? '整站' : '单页面';
                showToast(`已更新${typeText}黑名单时间 (${durationText})`, 'success');
            } else {
                // 添加新项目
                const item = {
                    id: this.generateId(),
                    domain: domain,
                    url: url,
                    type: type,
                    expiry: expiry,
                    reason: reason,
                    addedAt: now
                };

                CONFIG.blacklist.sites.push(item);
                const durationText = duration === -1 ? '永久' : this.formatDuration(duration);
                const typeText = type === 'site' ? '整站' : '单页面';
                showToast(`已将${typeText}加入黑名单 (${durationText})`, 'success');
            }

            GM_setValue("catgirlConfig", CONFIG);
        }

        updateDisplay() {
            this.displayItems(CONFIG.blacklist.sites);
        }

        removeFromBlacklist(id) {
            CONFIG.blacklist.sites = CONFIG.blacklist.sites.filter(item => item.id !== id);
            GM_setValue("catgirlConfig", CONFIG);
            this.updateDisplay();
            showToast('已从黑名单移除', 'success');
        }

        removeExpiredItem(item) {
            CONFIG.blacklist.sites = CONFIG.blacklist.sites.filter(i => i.id !== item.id);
            GM_setValue("catgirlConfig", CONFIG);
        }

        generateId() {
            return Date.now().toString(36) + Math.random().toString(36).substr(2);
        }

        formatDuration(ms) {
            if (ms === -1) return '永久';
            const days = Math.floor(ms / (24 * 60 * 60 * 1000));
            const hours = Math.floor((ms % (24 * 60 * 60 * 1000)) / (60 * 60 * 1000));
            if (days > 0) return `${days}天${hours}小时`;
            if (hours > 0) return `${hours}小时`;
            return '不到1小时';
        }

        show() {
            if (!this.panel) this.create();
            this.panel.style.display = 'block';
            this.isVisible = true;
            this.updateDisplay();
        }

        hide() {
            if (this.panel) {
                this.panel.style.display = 'none';
                this.isVisible = false;
            }
        }

        create() {
            if (this.panel) return;

            this.panel = document.createElement('div');
            this.panel.id = 'catgirl-blacklist';
            this.panel.innerHTML = this.getHTML();
            this.panel.style.cssText = this.getCSS();

            document.body.appendChild(this.panel);
            this.bindEvents();
        }

        getHTML() {
            return `
                <div class="blacklist-header">
                    <h3>🚫 网站黑名单管理</h3>
                    <button class="close-btn" data-action="close">×</button>
                </div>

                <div class="blacklist-content">
                    <div class="current-site-section">
                        <h4>🌐 当前网站操作</h4>
                        <div class="current-site-info">
                            <strong>域名:</strong> <code>${location.hostname}</code><br>
                            <strong>页面:</strong> <code>${location.pathname}</code>
                        </div>

                        <div class="blacklist-actions">
                            <div class="action-group">
                                <label>拉黑类型</label>
                                <select id="blacklist-type">
                                    <option value="site">整个网站</option>
                                    <option value="page">仅当前页面</option>
                                </select>
                                <small>选择要屏蔽的范围</small>
                            </div>

                            <div class="action-group">
                                <label>拉黑时长</label>
                                <select id="blacklist-duration">
                                    <option value="3600000">1小时</option>
                                    <option value="21600000">6小时</option>
                                    <option value="86400000">1天</option>
                                    <option value="604800000">1周</option>
                                    <option value="2592000000">1个月</option>
                                    <option value="-1">永久</option>
                                </select>
                                <small>选择屏蔽的持续时间</small>
                            </div>

                            <div class="action-group">
                                <label>拉黑原因</label>
                                <input type="text" id="blacklist-reason" placeholder="可选,记录拉黑原因">
                                <small>记录屏蔽原因,方便后续管理</small>
                            </div>

                            <button id="add-to-blacklist" class="btn-danger">🚫 加入黑名单</button>
                        </div>
                    </div>

                    <div class="blacklist-section">
                        <h4>📋 黑名单列表</h4>
                        <div class="search-section">
                            <input type="text" id="blacklist-search" class="search-input" placeholder="搜索域名或原因...">
                            <div class="search-hint">💡 支持域名和屏蔽原因搜索</div>
                        </div>
                        <div id="blacklist-items" class="blacklist-scroll"></div>
                        <div class="blacklist-stats">
                            <small>黑名单命中次数: <span id="blacklist-hits">${CONFIG.stats.blacklistHits}</span></small>
                        </div>
                    </div>

                    <div class="blacklist-settings">
                        <h4>⚙️ 黑名单设置</h4>
                        <label>
                            <input type="checkbox" id="enable-blacklist" ${CONFIG.blacklist.enabled ? 'checked' : ''}>
                            启用黑名单功能
                        </label>
                        <small>关闭后将忽略所有黑名单规则</small>
                    </div>

                    <div class="actions">
                        <button id="save-blacklist" class="btn-primary">💾 保存设置</button>
                        <button id="clear-expired" class="btn-secondary">🧹 清理过期</button>
                    </div>
                </div>

                <canvas id="cat-paw-canvas-blacklist" width="60" height="60"></canvas>
            `;
        }

        getCSS() {
            return `
                position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
                width: 600px; max-height: 85vh; background: #ffffff; border-radius: 12px;
                box-shadow: 0 8px 32px rgba(0,0,0,0.3); z-index: 10000;
                font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Microsoft YaHei', sans-serif;
                display: none; overflow: hidden;
            `;
        }


        // 显示黑名单项目
        // 显示黑名单项目
        displayItems(items, searchQuery = '') {
            const container = document.getElementById('blacklist-items');
            if (!container) return;

            const now = Date.now();
            const itemsHTML = items.map(item => {
                const isExpired = item.expiry && item.expiry < now;
                const timeLeft = item.expiry ? this.formatDuration(item.expiry - now) : '永久';
                const addedAt = new Date(item.addedAt).toLocaleString();

                let displayDomain = item.domain;
                let displayReason = item.reason || '';

                // 修正后的高亮逻辑
                if (searchQuery) {
                    // 过滤掉无效的关键词并为正则表达式转义特殊字符
                    const keywords = searchQuery.split(' ').filter(k => k.trim()).map(k => k.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
                    if (keywords.length > 0) {
                        const regex = new RegExp(`(${keywords.join('|')})`, 'gi');
                        displayDomain = displayDomain.replace(regex, '<span class="search-highlight">$1</span>');
                        displayReason = displayReason.replace(regex, '<span class="search-highlight">$1</span>');
                    }
                }

                return `
                    <div class="blacklist-item ${isExpired ? 'expired' : ''}">
                        <div class="item-info">
                            <div class="item-domain">${displayDomain}</div>
                            <div class="item-details">
                                类型: ${item.type === 'site' ? '整站' : '单页面'} |
                                剩余: ${isExpired ? '已过期' : timeLeft} |
                                添加: ${addedAt}
                                ${displayReason ? `<br>原因: ${displayReason}` : ''}
                            </div>
                        </div>
                        <button data-remove-id="${item.id}" class="remove-btn">移除</button>
                    </div>
                `;
            }).join('');

            container.innerHTML = itemsHTML || '<div class="empty-state">暂无匹配的黑名单项目</div>';

            const removeButtons = container.querySelectorAll('.remove-btn[data-remove-id]');
            removeButtons.forEach(btn => {
                btn.onclick = () => {
                    const id = btn.getAttribute('data-remove-id');
                    this.removeFromBlacklist(id);
                };
            });

            const hitsEl = document.getElementById('blacklist-hits');
            if (hitsEl) hitsEl.textContent = CONFIG.stats.blacklistHits;
        }


        // 黑名单搜索功能
        searchBlacklist(queryString) {
            const trimmedQuery = queryString?.trim() || '';
            const allItems = CONFIG.blacklist.sites;

            if (!trimmedQuery) {
                // 重置搜索,显示所有项目
                this.displayItems(allItems, '');
                return;
            }

            // 创建竞争映射
            const raceMap = new Map();
            allItems.forEach((item, index) => {
                raceMap.set(index, [
                    item.domain,
                    item.reason || '',
                    '',
                    0
                ]);
            });

            // 执行搜索竞争
            const keywords = trimmedQuery.trim().replace(/\s+/g, " ").split(" ");

            for (const [key, value] of raceMap) {
                let totalScore = 0;
                const domain = value[0].toLowerCase();
                const reason = value[1].toLowerCase();

                keywords.forEach((keyword) => {
                    const keywordLower = keyword.toLowerCase();

                    // 域名完全匹配
                    if (domain === keywordLower) {
                        totalScore += 10;
                    }

                    // 域名开头匹配
                    if (domain.startsWith(keywordLower)) {
                        totalScore += 5;
                    }

                    // 域名包含关键词
                    const domainMatches = (domain.match(new RegExp(keywordLower, 'g')) || []).length;
                    totalScore += domainMatches * 2;

                    // 原因匹配
                    const reasonMatches = (reason.match(new RegExp(keywordLower, 'g')) || []).length;
                    totalScore += reasonMatches;
                });

                raceMap.set(key, [
                    value[0],
                    value[1],
                    trimmedQuery,
                    totalScore
                ]);
            }

            // 排序并返回结果
            const sortedResults = Array.from(raceMap.entries())
            .filter(([_, value]) => value[3] > 0)
            .sort((a, b) => b[1][3] - a[1][3])
            .map(([key]) => {
                const item = { ...allItems[key] };
                item.user_word = trimmedQuery;
                return item;
            });

            this.displayItems(sortedResults, trimmedQuery);
        }


        drawCatPaw() {
            const canvas = document.getElementById('cat-paw-canvas-blacklist');
            if (!canvas) return;

            const ctx = canvas.getContext('2d');
            const size = 60;

            // 清空画布
            ctx.clearRect(0, 0, size, size);

            // 设置样式
            ctx.fillStyle = '#ffb6c1'; // 樱花粉色
            ctx.strokeStyle = '#ff69b4';
            ctx.lineWidth = 2;

            // 绘制猫爪垫(主要部分)
            ctx.beginPath();
            ctx.arc(30, 35, 12, 0, Math.PI * 2);
            ctx.fill();
            ctx.stroke();

            // 绘制四个小爪垫
            const pads = [
                { x: 20, y: 20, size: 6 },
                { x: 40, y: 20, size: 6 },
                { x: 15, y: 30, size: 5 },
                { x: 45, y: 30, size: 5 }
            ];

            pads.forEach(pad => {
                ctx.beginPath();
                ctx.arc(pad.x, pad.y, pad.size, 0, Math.PI * 2);
                ctx.fill();
                ctx.stroke();
            });

            // 添加高光效果
            ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
            ctx.beginPath();
            ctx.arc(25, 30, 4, 0, Math.PI * 2);
            ctx.fill();

            // 设置canvas位置
            canvas.style.cssText = `
                position: absolute;
                bottom: 15px;
                right: 15px;
                opacity: 0.6;
                pointer-events: none;
            `;
        }


        bindEvents() {
            // 关闭按钮
            this.panel.querySelector('[data-action="close"]').onclick = () => this.hide();

            // 添加到黑名单
            document.getElementById('add-to-blacklist').onclick = () => {
                const type = document.getElementById('blacklist-type').value;
                const duration = parseInt(document.getElementById('blacklist-duration').value);
                const reason = document.getElementById('blacklist-reason').value;

                this.addToBlacklist(type, duration, reason);
                this.updateDisplay();
            };

            // 保存设置
            document.getElementById('save-blacklist').onclick = () => {
                CONFIG.blacklist.enabled = document.getElementById('enable-blacklist').checked;
                GM_setValue("catgirlConfig", CONFIG);
                showToast('黑名单设置已保存', 'success');
            };

            // 清理过期
            document.getElementById('clear-expired').onclick = () => {
                this.clearExpired();
            };

            // 搜索功能
            const searchInput = document.getElementById('blacklist-search');
            if (searchInput) {
                searchInput.oninput = (e) => {
                    this.searchBlacklist(e.target.value);
                };
            }

            // 绘制猫爪
            this.drawCatPaw();
        }

        updateDisplay() {
            const container = document.getElementById('blacklist-items');
            if (!container) return;

            const now = Date.now();
            const items = CONFIG.blacklist.sites.map(item => {
                const isExpired = item.expiry && item.expiry < now;
                const timeLeft = item.expiry ? this.formatDuration(item.expiry - now) : '永久';
                const addedAt = new Date(item.addedAt).toLocaleString();

                return `
                    <div class="blacklist-item ${isExpired ? 'expired' : ''}">
                        <div class="item-info">
                            <div class="item-domain">${item.domain}</div>
                            <div class="item-details">
                                类型: ${item.type === 'site' ? '整站' : '单页面'} |
                                剩余: ${isExpired ? '已过期' : timeLeft} |
                                添加: ${addedAt}
                                ${item.reason ? `<br>原因: ${item.reason}` : ''}
                            </div>
                        </div>
                        <button data-remove-id="${item.id}" class="remove-btn">移除</button>
                    </div>
                `;
            }).join('');

            container.innerHTML = items || '<div class="empty-state">暂无黑名单项目</div>';

            // 绑定移除按钮事件
            const removeButtons = container.querySelectorAll('.remove-btn[data-remove-id]');
            removeButtons.forEach(btn => {
                btn.onclick = () => {
                    const id = btn.getAttribute('data-remove-id');
                    this.removeFromBlacklist(id);
                };
            });

            // 更新统计
            const hitsEl = document.getElementById('blacklist-hits');
            if (hitsEl) hitsEl.textContent = CONFIG.stats.blacklistHits;
        }

        clearExpired() {
            const now = Date.now();
            const before = CONFIG.blacklist.sites.length;
            CONFIG.blacklist.sites = CONFIG.blacklist.sites.filter(item =>
                                                                   !item.expiry || item.expiry > now
                                                                  );
            const after = CONFIG.blacklist.sites.length;
            const removed = before - after;

            GM_setValue("catgirlConfig", CONFIG);
            this.updateDisplay();
            showToast(`已清理 ${removed} 个过期项目`, 'success');
        }
    }

    // ===== 防抖工具类 =====
    class DebounceUtils {
        static debounce(func, delay) {
            let timeoutId;
            return function (...args) {
                clearTimeout(timeoutId);
                timeoutId = setTimeout(() => func.apply(this, args), delay);
            };
        }

        static throttleWithDebounce(func, throttleMs, debounceMs) {
            let lastCallTime = 0;
            let debounceTimer;

            return function (...args) {
                const now = Date.now();
                clearTimeout(debounceTimer);

                if (now - lastCallTime >= throttleMs) {
                    lastCallTime = now;
                    func.apply(this, args);
                } else {
                    debounceTimer = setTimeout(() => {
                        lastCallTime = Date.now();
                        func.apply(this, args);
                    }, debounceMs);
                }
            };
        }
    }

    // ===== 增强的性能工具类 =====
    class EnhancedPerformanceUtils {
        static createTimeSliceProcessor(items, processor, options = {}) {
            const {
                batchSize = CONFIG.performance.batchSize,
                maxTime = CONFIG.performance.maxProcessingTimeSlice,
                onProgress = null,
                onComplete = null
            } = options;

            const processedKeys = new Set();
            const uniqueItems = items.filter(item => {
                const key = this.getItemKey(item);
                if (processedKeys.has(key)) return false;
                processedKeys.add(key);
                return true;
            });

            if (uniqueItems.length === 0) {
                if (onComplete) onComplete();
                return;
            }

            let index = 0;
            let startTime = Date.now();

            const processNextBatch = () => {
                const batchStartTime = performance.now();
                let processedInBatch = 0;

                while (index < uniqueItems.length &&
                       processedInBatch < batchSize &&
                       (performance.now() - batchStartTime) < maxTime) {

                    try {
                        processor(uniqueItems[index], index, uniqueItems);
                    } catch (error) {
                        console.error('🐱 处理项目出错:', error);
                    }

                    index++;
                    processedInBatch++;
                }

                if (onProgress) {
                    onProgress(index, uniqueItems.length, (index / uniqueItems.length) * 100);
                }

                if (index < uniqueItems.length) {
                    if (window.requestIdleCallback) {
                        requestIdleCallback(processNextBatch, {
                            timeout: CONFIG.performance.idleCallbackTimeout
                        });
                    } else {
                        setTimeout(processNextBatch, 16);
                    }
                } else {
                    const duration = Date.now() - startTime;
                    if (CONFIG.features.debugMode) {
                        console.log(`🎉 完成处理 ${uniqueItems.length} 个项目,耗时 ${duration}ms`);
                    }
                    if (onComplete) onComplete();
                }
            };

            processNextBatch();
        }

        static getItemKey(item) {
            if (item && item.nodeType === Node.ELEMENT_NODE) {
                return `${item.tagName}-${item.textContent ? item.textContent.slice(0, 20) : ''}-${item.offsetTop || 0}`;
            }
            return String(item);
        }
    }

    // ===== 状态管理类 =====
    class StateManager {
        constructor() {
            this.state = {
                isEnabled: true,
                currentUrl: location.href,
                processingQueue: new Set(),
                urlChangeHandlers: [],
                lastProcessTime: 0,

                bilibili: {
                    isCompleted: false,
                    lastProcessedUrl: '',
                    lastProcessedTime: 0,
                    retryCount: 0,
                    commentObserver: null,
                    lastCommentCount: 0
                }
            };
        }

        onUrlChange(handler) {
            if (!this.state.urlChangeHandlers) {
                this.state.urlChangeHandlers = [];
            }
            this.state.urlChangeHandlers.push(handler);
        }

        checkUrlChange() {
            const newUrl = location.href;
            if (newUrl !== this.state.currentUrl) {
                if (CONFIG.features.debugMode) {
                    console.log('🔄 页面切换:', this.state.currentUrl, '->', newUrl);
                }
                this.state.currentUrl = newUrl;

                this.state.bilibili.isCompleted = false;
                this.state.bilibili.lastProcessedUrl = newUrl;
                this.state.bilibili.retryCount = 0;
                this.state.bilibili.lastCommentCount = 0;

                if (this.state.urlChangeHandlers && Array.isArray(this.state.urlChangeHandlers)) {
                    this.state.urlChangeHandlers.forEach(handler => {
                        try {
                            if (typeof handler === 'function') {
                                handler(newUrl);
                            }
                        } catch (error) {
                            console.error('🐱 URL变化处理器出错:', error);
                        }
                    });
                }

                return true;
            }
            return false;
        }

        shouldProcess() {
            const now = Date.now();
            const timeSinceLastProcess = now - this.state.lastProcessTime;

            if (timeSinceLastProcess < 1000) {
                return false;
            }

            this.state.lastProcessTime = now;
            return true;
        }

        shouldSkipBilibiliProcessing() {
            if (!this.isBilibili()) return true;

            const { isCompleted, lastProcessedUrl, lastProcessedTime } = this.state.bilibili;
            const now = Date.now();

            return isCompleted &&
                lastProcessedUrl === location.href &&
                (now - lastProcessedTime) < 30000;
        }

        markBilibiliCompleted() {
            this.state.bilibili.isCompleted = true;
            this.state.bilibili.lastProcessedUrl = location.href;
            this.state.bilibili.lastProcessedTime = Date.now();
        }

        isBilibili() {
            return location.hostname.includes('bilibili.com');
        }

        checkBilibiliCommentChange() {
            if (!this.isBilibili()) return false;

            const commentThreads = document.querySelectorAll('bili-comment-thread-renderer');
            const currentCount = commentThreads.length;

            if (currentCount !== this.state.bilibili.lastCommentCount) {
                this.state.bilibili.lastCommentCount = currentCount;
                this.state.bilibili.isCompleted = false;
                return true;
            }

            return false;
        }
    }

    // ===== 增强的文本处理器 =====
    class EnhancedTextProcessor {
        constructor() {
            this.processedTexts = new Set();
            this.replacementStats = new Map();
            this.contextAnalyzer = new ContextAnalyzer();
            this.originalTexts = new WeakMap(); // 存储元素的原始文本
        }

        isProcessed(text) {
            return /喵[~~呜哈呢♪♡!]|nya|にゃ"|meow|🏳️‍⚧️|已处理标记/i.test(text) ||
                this.processedTexts.has(text);
        }

        getCuteEnding(context = 'normal') {
            const level = CONFIG.preferences.cuteLevel;
            const mode = CONFIG.preferences.processingMode;

            let endings = cuteLibrary.endings[level] || cuteLibrary.endings.normal;

            switch (mode) {
                case 'gentle':
                    endings = endings.slice(0, Math.ceil(endings.length / 2));
                    break;
                case 'aggressive':
                    endings = [...endings, ...cuteLibrary.emotionalEndings[context] || []];
                    break;
                case 'contextual':
                default:
                    if (cuteLibrary.emotionalEndings[context]) {
                        endings = [...endings, ...cuteLibrary.emotionalEndings[context]];
                    }
                    break;
            }

            return endings[Math.floor(Math.random() * endings.length)];
        }

        analyzeContext(text) {
            const excitedMarkers = /[!!??]{2,}|哇|哟|啊{2,}/;
            const happyMarkers = /笑|哈哈|嘻嘻|开心|快乐|爽|棒/;
            const sadMarkers = /哭|难过|伤心|555|呜呜|痛苦/;
            const angryMarkers = /生气|愤怒|气死|烦|讨厌|恶心/;
            const confusedMarkers = /[??]{2,}|什么|啥|诶|咦|奇怪/;

            if (excitedMarkers.test(text)) return 'excited';
            if (happyMarkers.test(text)) return 'happy';
            if (sadMarkers.test(text)) return 'sad';
            if (angryMarkers.test(text)) return 'excited';
            if (confusedMarkers.test(text)) return 'confused';
            if (/[。.,,;;]/.test(text)) return 'calm';

            return 'normal';
        }

        processText(text, options = {}) {
            if (!text?.trim() || this.isProcessed(text)) return text;

            if (CONFIG.preferences.disabledWords.some(word => text.includes(word))) {
                return text;
            }

            this.processedTexts.add(text);

            let result = text;
            let replacementCount = 0;

            const context = this.analyzeContext(text);
            const cleanups = this.getCleanupRules(context);

            cleanups.forEach(([regex, replacement]) => {
                const matches = result.match(regex);
                if (matches) {
                    const finalReplacement = this.getSmartReplacement(replacement, context);
                    result = result.replace(regex, finalReplacement);
                    replacementCount += matches.length;
                }
            });

            if (CONFIG.preferences.processingMode !== 'gentle' || replacementCount > 0) {
                result = this.addCuteEndings(result, context);
            }

            if (CONFIG.preferences.processingMode === 'aggressive' &&
                Math.random() < CONFIG.preferences.decorativeFrequency) {
                const prefix = cuteLibrary.decorativePrefixes[Math.floor(Math.random() * cuteLibrary.decorativePrefixes.length)];
                result = `${prefix} ${result}`;
            }

            if (replacementCount > 0) {
                CONFIG.stats.replacedWords += replacementCount;
                CONFIG.stats.sessionProcessed += replacementCount;
                this.updateReplacementStats(text, result);
            }

            return result;
        }

        getSmartReplacement(baseReplacement, context) {
            if (!CONFIG.preferences.intelligentReplacement) return baseReplacement;

            const contextEnding = cuteLibrary.emotionalEndings[context];
            if (contextEnding && Math.random() < 0.4) {
                const ending = contextEnding[Math.floor(Math.random() * contextEnding.length)];
                return `${baseReplacement}${ending}`;
            }

            return baseReplacement;
        }

        addCuteEndings(text, context = 'normal') {
            const getCuteEnding = () => this.getCuteEnding(context);
            const addDesu = () => {
                const chance = CONFIG.preferences.cuteLevel === 'high' ? 0.4 :
                CONFIG.preferences.cuteLevel === 'normal' ? 0.2 : 0.1;
                return Math.random() < chance ? 'です' : '';
            };

            let probability = CONFIG.preferences.endingFrequency;
            switch (CONFIG.preferences.processingMode) {
                case 'gentle':
                    probability *= 0.5;
                    break;
                case 'aggressive':
                    probability *= 2;
                    break;
            }

            return text
                .replace(/([也知兮之者焉啉]|[啊嗯呢吧哇哟哦嘛喔咯呵哼末])([\s\p{P}]|$)/gu,
                         (_, $1, $2) => `${getCuteEnding()}${addDesu()}${$2}`)
                .replace(/([的了辣])([\s\p{P}]|$)/gu,
                         (_, $1, $2) => Math.random() < probability ?
                         `${$1}${getCuteEnding()}${addDesu()}${$2}` : `${$1}${$2}`);
        }

        // ===== 大幅扩展的清理规则 - 针对B站和百度贴吧 =====
        getCleanupRules(context = 'normal') {
            const baseRules = [
                // ===== 极端攻击与侮辱性词汇 =====
                [/操你妈|操你娘|操你全家|肏你妈|干你妈|干你娘|去你妈的|去你娘的|去你全家/gi, '去睡觉觉'],
                [/妈了个?逼|妈的?智障|妈的/gi, '喵喵喵'],
                [/狗娘养的|狗杂种|狗东西|狗逼|狗比/gi, '不太好的小家伙'],
                [/操你大爷|去你大爷的|你大爷的/gi, '去玩耍啦'],
                [/去你老师的|你全家死光|你妈死了|你妈没了/gi, '嗯...安静一点'],
                [/你妈妈叫你回家吃饭|你妈炸了/gi, '你妈妈叫你回家吃饭'],

                // ===== 性相关及不雅词汇 =====
                [/鸡巴|鸡叭|鸡把|屌|吊|\bjb\b|\bJB\b|\bJj\b/gi, '小鱼干'],
                [/逼你|逼样|逼毛|逼崽子|什么逼|傻逼|煞逼|沙逼|装逼|牛逼|吹逼/gi, '小淘气'],
                [/肏|干你|草你|cao你|cao你妈|操逼|日你|日了|艹你/gi, '去玩耍啦'],
                [/生殖器|阴茎|阴道|性器官|做爱|啪啪|上床|嘿咻/gi, '小秘密'],

                // ===== B站特色脏话 =====
                [/小鬼|小学生|初中生|孤儿|没爹|没妈|爹妈死了/gi, '小朋友'],
                [/死妈|死全家|死开|去死|死了算了/gi, '去睡觉觉'],
                [/脑瘫|弱智|智障|残疾|白痴|傻子|蠢货|蠢蛋/gi, '小糊涂虫'],
                [/废物|废柴|废狗|垃圾|拉圾|辣鸡|人渣|渣渣/gi, '要抱抱的小家伙'],
                [/恶心|想吐|反胃|讨厌死了|烦死了/gi, '有点不开心'],

                // ===== 百度贴吧常见脏话 =====
                [/楼主是猪|楼主智障|楼主有病|lz有毒|楼主滚|lz滚/gi, '楼主很可爱'],
                [/水贴|灌水|刷屏|占楼|抢沙发|前排|火钳刘明/gi, '路过留名'],
                [/举报了|封号|删帖|水军|托儿|五毛|美分/gi, '认真讨论中'],
                [/撕逼|掐架|开撕|互喷|对骂|群嘲/gi, '友好交流'],

                // ===== 网络用语和缩写 =====
                [/\bcnm\b|\bCNM\b|c\s*n\s*m/gi, '你好软糯'],
                [/\bnmsl\b|\bNMSL\b|n\s*m\s*s\s*l/gi, '你超棒棒'],
                [/\bmlgb\b|\bMLGB\b|m\s*l\s*g\s*b/gi, '哇好厉害'],
                [/tmd|TMD|t\s*m\s*d|他妈的/gi, '太萌啦'],
                [/wtf|WTF|w\s*t\s*f|what\s*the\s*fuck/gi, '哇好神奇'],
                [/\bf\*\*k|\bf\*ck|fuck|\bFC\b|\bF\*\b/gi, '哇哦'],
                [/\bsh\*t|shit|\bs\*\*t/gi, '小意外'],
                [/\bbitch|\bb\*tch|\bb\*\*\*\*/gi, '小坏蛋'],

                // ===== 地域攻击相关 =====
                [/河南人|东北人|农村人|乡下人|山沟里|土包子/gi, '各地朋友'],
                [/北上广|屌丝|土豪|装富|穷逼|没钱|破产/gi, '普通人'],

                // ===== 游戏相关脏话 =====
                [/菜鸡|菜逼|坑货|坑爹|坑队友|演员|挂逼|开挂/gi, '游戏新手'],
                [/noob|萌新杀手|虐菜|吊打|碾压|秒杀/gi, '游戏高手'],

                // ===== 饭圈和明星相关 =====
                [/黑粉|脑残粉|私生饭|蹭热度|营销号|炒作|塌房/gi, '追星族'],
                [/爬|滚|死开|别来|有毒|拉黑|取关/gi, '不太喜欢'],

                // ===== 学历和职业攻击 =====
                [/小学毕业|没文化|文盲|初中肄业|高中都没毕业/gi, '正在学习中'],
                [/打工仔|搬砖|送外卖|快递员|保安|清洁工/gi, '勤劳的人'],

                // ===== 年龄相关攻击 =====
                [/老不死|老东西|老头子|老太婆|更年期|中年油腻/gi, '年长者'],
                [/熊孩子|小屁孩|幼稚|没长大|巨婴/gi, '年轻朋友'],

                // ===== 外貌身材攻击 =====
                [/丑逼|长得丑|颜值低|矮子|胖子|瘦猴|秃头|光头/gi, '独特的人'],
                [/整容|假脸|网红脸|蛇精脸|锥子脸/gi, '美丽的人'],

                // ===== 常见口头禅和语气词 =====
                [/我靠|我擦|我操|卧槽|握草|我草|尼玛|你妹/gi, '哇哦'],
                [/妈蛋|蛋疼|扯蛋|完蛋|滚蛋|鸡蛋|咸蛋/gi, '天哪'],
                [/见鬼|见了鬼|活见鬼|撞鬼了/gi, '好奇怪'],

                // ===== 网络流行语 =====
                [/笑死我了|笑死|xswl|XSWL|笑尿了/gi, '好有趣'],
                [/绝绝子|yyds|YYDS|永远的神|真香|真tm香/gi, '超级棒棒'],
                [/emo了|emo|EMO|破防了|破大防|血压高/gi, '有点难过'],
                [/社死|社会性死亡|尴尬死了|丢人现眼/gi, '有点害羞'],

                // ===== B站弹幕常见词汇 =====
                [/前方高能|高能预警|非战斗人员撤离|前排吃瓜/gi, '注意啦'],
                [/弹幕护体|弹幕保护|人类的本质|复读机/gi, '大家一起说'],
                [/鬼畜|魔性|洗脑|单曲循环|dssq|DSSQ/gi, '很有趣'],

                // ===== 百度贴吧表情包文字 =====
                [/滑稽|斜眼笑|狗头保命|手动狗头|\[狗头\]|\[滑稽\]/gi, '嘿嘿嘿'],
                [/微笑|呵呵|嘿嘿|嘻嘻|哈哈|哈哈哈/gi, '开心笑'],

                // ===== 政治敏感和争议话题 =====
                [/五毛党|美分党|公知|带路党|精神外国人|慕洋犬/gi, '不同观点的人'],
                [/粉红|小粉红|战狼|玻璃心|民族主义/gi, '爱国人士'],

                // ===== 其他常见不当用词 =====
                [/有病|脑子有问题|神经病|精神病|疯子|疯了/gi, '想法特别'],
                [/你有毒|有毒|中毒了|下毒|毒瘤/gi, '很特殊'],
                [/癌症|艾滋|梅毒|性病|传染病/gi, '不舒服'],
                [/自杀|跳楼|上吊|服毒|割腕/gi, '要好好的']
            ];

            // 根据可爱程度调整规则严格度
            if (CONFIG.preferences.cuteLevel === 'high') {
                // 高可爱程度下添加更多轻微词汇的替换
                const extraRules = [
                    [/靠|擦|艹|草/gi, '哎呀'],
                    [/烦|闷|郁/gi, '有点小情绪'],
                    [/累|疲惫|困|想睡|犯困/gi, '需要休息'],
                    [/痛|疼|难受|不舒|头疼/gi, '不太好'],
                    [/怒|生气|愤怒|漏火|火大/gi, '有点不开心'],
                    [/哭|难过|伤心|委屈|想哭/gi, '需要抱抱'],
                    [/怕|害怕|恐惧|担心|紧张/gi, '有点紧张'],
                    [/尴尬|囧|汗|无语|无奈/gi, '有点小尴尬'],
                    [/晕|蒙|糊涂|迷茫/gi, '有点迷茫'],
                    [/急|着急|焦虑|慌|慌张/gi, '有点小急'],
                ];
                baseRules.push(...extraRules);
            }

            // 根据上下文返回不同强度的规则
            return baseRules.map(([regex, replacement]) => {
                const contextEnding = this.getCuteEnding(context);
                return [regex, `${replacement}${contextEnding}`];
            });
        }

        updateReplacementStats(original, processed) {
            const key = `${original.length}:${processed.length}`;
            this.replacementStats.set(key, (this.replacementStats.get(key) || 0) + 1);
        }

        // 保存原始文本
        storeOriginalText(element, originalText) {
            this.originalTexts.set(element, originalText);
        }

        // 获取原始文本
        getOriginalText(element) {
            return this.originalTexts.get(element);
        }
    }

    // ===== 上下文分析器类 =====
    class ContextAnalyzer {
        constructor() {
            this.patterns = {
                excited: /[!!??]{2,}|哇|哟|啊{2,}/,
                happy: /笑|哈哈|嘻嘻|开心|快乐|爽|棒/,
                sad: /哭|难过|伤心|555|呜呜|痛苦/,
                angry: /生气|愤怒|气死|烦|讨厌|恶心/,
                confused: /[??]{2,}|什么|啥|诶|咦|奇怪/,
                calm: /[。.,,;;]/
            };
        }

        analyze(text) {
            for (const [emotion, pattern] of Object.entries(this.patterns)) {
                if (pattern.test(text)) {
                    return emotion;
                }
            }
            return 'normal';
        }
    }

    // ===== 增强设置面板类 =====
    class SettingsPanel {
        constructor() {
            this.isVisible = false;
            this.panel = null;
        }

        create() {
            if (this.panel) return;

            this.panel = document.createElement('div');
            this.panel.id = 'catgirl-settings';
            this.panel.innerHTML = this.getHTML();
            this.panel.style.cssText = this.getCSS();

            document.body.appendChild(this.panel);
            this.bindEvents();
        }

        getHTML() {
            return `
                <div class="settings-header">
                    <h3>🐱 猫娘化设置面板</h3>
                    <button class="close-btn" data-action="close">×</button>
                </div>

                <div class="settings-content">
                    <div class="tab-container">
                        <button class="tab-btn active" data-tab="basic">基础设置</button>
                        <button class="tab-btn" data-tab="advanced">高级设置</button>
                        <button class="tab-btn" data-tab="control">控制选项</button>
                        <button class="tab-btn" data-tab="stats">统计信息</button>
                    </div>

                    <div class="tab-content" id="basic-tab">
                        <div class="setting-group">
                            <label>🎀 可爱程度</label>
                            <select id="cute-level">
                                <option value="low">低 (温和可爱)</option>
                                <option value="normal" selected>普通 (标准可爱)</option>
                                <option value="high">高 (超级可爱,更多替换)</option>
                            </select>
                            <small>控制添加可爱词汇的数量和频率,高档位会替换更多轻微词汇</small>
                        </div>

                        <div class="setting-group">
                            <label>⚙️ 猫娘化风格</label>
                            <select id="processing-mode">
                                <option value="gentle">温柔模式 (仅替换攻击性词汇)</option>
                                <option value="contextual" selected>智能模式 (分析情感,智能选择词汇)</option>
                                <option value="aggressive">活力模式 (最大化可爱词汇和句尾)</option>
                            </select>
                            <small>选择猫娘化的整体风格。“智能模式”是兼顾自然与可爱的最佳选项。</small>
                        </div>

                        <div class="setting-group">
                            <label>📊 替换强度: <span id="intensity-value">30%</span></label>
                            <input type="range" id="replacement-intensity" min="0.1" max="1.0" step="0.1" value="0.3">
                            <small>控制词汇替换的概率,数值越高替换越频繁</small>
                        </div>

                        <div class="setting-group">
                            <label>🎵 结尾词频率: <span id="ending-value">30%</span></label>
                            <input type="range" id="ending-frequency" min="0.1" max="1.0" step="0.1" value="0.3">
                            <small>控制"喵~"等可爱结尾词的出现频率</small>
                        </div>

                        <div class="setting-group">
                            <label>✨ 装饰符频率: <span id="decorative-value">20%</span></label>
                            <input type="range" id="decorative-frequency" min="0.1" max="1.0" step="0.1" value="0.2">
                            <small>控制"✨"等装饰性符号的出现频率</small>
                        </div>
                    </div>

                    <div class="tab-content" id="advanced-tab" style="display: none;">
                        <div class="setting-group">
                            <label>
                                <input type="checkbox" id="intelligent-replacement"> 🧠 启用句尾情感关联
                            </label>
                            <small>开启后,替换词会根据上下文智能附带上符合当前情绪的句尾(如“好棒喵~”),让表达更生动。</small>
                        </div>

                        <div class="setting-group">
                            <label>
                                <input type="checkbox" id="debug-mode"> 🛠 调试模式
                            </label>
                            <small>显示详细的处理日志信息</small>
                        </div>

                        <div class="setting-group">
                            <label>
                                <input type="checkbox" id="performance-monitoring"> 📊 性能监控
                            </label>
                            <small>启用内存和性能监控</small>
                        </div>

                        <div class="setting-group">
                            <label>🕐 处理间隔 (毫秒): <span id="interval-value">5000</span></label>
                            <input type="range" id="process-interval" min="1000" max="10000" step="500" value="5000">
                            <small>控制自动处理的时间间隔,数值越小响应越快但消耗更多资源</small>
                        </div>

                        <div class="setting-group">
                            <label>📦 批处理大小: <span id="batch-value">5</span></label>
                            <input type="range" id="batch-size" min="3" max="20" step="1" value="5">
                            <small>单次处理的元素数量,数值越大处理越快但可能卡顿</small>
                        </div>

                        <div class="setting-group">
                            <label>⏱️ 防抖延迟 (毫秒): <span id="debounce-value">500</span></label>
                            <input type="range" id="debounce-delay" min="100" max="2000" step="100" value="500">
                            <small>防止重复处理的延迟时间,数值越大越省资源</small>
                        </div>
                    </div>

                    <div class="tab-content" id="control-tab" style="display: none;">
                        <div class="setting-group">
                            <label>
                                <input type="checkbox" id="affect-input"> 📝 影响输入框
                            </label>
                            <small>是否处理输入框和文本域中的内容</small>
                        </div>

                        <div class="setting-group">
                            <label>
                                <input type="checkbox" id="show-original-hover"> 👆 鼠标悬停显示原文
                            </label>
                            <small>鼠标悬停在处理过的文本上时显示原始内容</small>
                        </div>

                        <div class="setting-group">
                            <label>
                                <input type="checkbox" id="enable-user-prefix"> 👤 启用用户名前缀
                            </label>
                            <small>为用户名添加可爱的表情符号前缀</small>
                        </div>

                        <div class="setting-group">
                            <label>
                                <input type="checkbox" id="bilibili-merge-links"> 🔗 B站链接转文本
                            </label>
                            <small>将B站评论中的链接转换为纯文本</small>
                        </div>

                        <div class="setting-group">
                            <label>
                                <input type="checkbox" id="auto-process-content"> 🔄 自动处理新内容
                            </label>
                            <small>自动处理动态加载的新内容(通过DOM变化监听)</small>
                        </div>

                        <div class="setting-group">
                            <label>
                                <input type="checkbox" id="shadow-dom-support"> 🌐 Shadow DOM 支持
                            </label>
                            <small>处理 Shadow DOM 中的内容(如B站评论区)</small>
                        </div>

                        <div class="setting-group">
                            <label>
                                <input type="checkbox" id="smart-processing"> 💡 启用高级情感分析引擎
                            </label>
                            <small>脚本的核心智能开关。开启后才能启用所有与上下文、情感相关的分析功能。为获得最佳体验,请保持开启。</small>
                        </div>

                        <div class="setting-group">
                            <label>🚫 排除词汇</label>
                            <textarea id="disabled-words" placeholder="输入不想被替换的词汇,每行一个" rows="3"></textarea>
                            <small>这些词汇不会被猫娘化处理</small>
                        </div>
                    </div>

                    <div class="tab-content" id="stats-tab" style="display: none;">
                        <div class="stats-grid">
                            <div class="stat-item">
                                <div class="stat-number" id="processed-count">0</div>
                                <div class="stat-label">已处理元素</div>
                            </div>
                            <div class="stat-item">
                                <div class="stat-number" id="replaced-count">0</div>
                                <div class="stat-label">已替换词汇</div>
                            </div>
                            <div class="stat-item">
                                <div class="stat-number" id="session-count">0</div>
                                <div class="stat-label">本次会话</div>
                            </div>
                            <div class="stat-item">
                                <div class="stat-number" id="blacklist-hits-count">0</div>
                                <div class="stat-label">黑名单命中</div>
                            </div>
                        </div>

                        <div class="info-section">
                            <h4>📅 系统信息</h4>
                            <p><strong>版本:</strong> ${SCRIPT_VERSION}</p>
                            <p><strong>安装时间:</strong> <span id="install-date">获取中...</span></p>
                            <p><strong>最后活动:</strong> <span id="last-active">获取中...</span></p>
                            <p><strong>当前网站:</strong> ${location.hostname}</p>
                            <p><strong>运行状态:</strong> <span id="running-status">检测中...</span></p>
                        </div>

                        <div class="performance-section">
                            <h4>⚡ 动态信息</h4>
                            <div id="performance-info">
                                <p>当前页面处理元素数: <span id="session-elements">计算中...</span></p>
                                <p>黑名单规则命中数: <span id="blacklist-hits-info">计算中...</span></p>
                            </div>
                        </div>
                    </div>

                    <div class="actions">
                        <button id="save-settings" class="btn-primary">💾 保存设置</button>
                        <button id="reset-settings" class="btn-warning">🔄 重置设置</button>
                        <button id="clear-cache" class="btn-secondary">🧹 清理缓存</button>
                    </div>
                </div>
            `;
        }

        getCSS() {
            return `
                position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
                width: 600px; max-height: 85vh; background: #ffffff; border-radius: 12px;
                box-shadow: 0 8px 32px rgba(0,0,0,0.3); z-index: 10000;
                font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Microsoft YaHei', sans-serif;
                display: none; overflow: hidden;
            `;
        }

        bindEvents() {
            // 关闭按钮
            const closeBtn = this.panel.querySelector('[data-action="close"]');
            if (closeBtn) {
                closeBtn.onclick = () => this.hide();
            }

            // 标签切换
            const tabBtns = this.panel.querySelectorAll('.tab-btn');
            tabBtns.forEach(btn => {
                btn.onclick = () => this.switchTab(btn.dataset.tab);
            });

            // 滑块事件
            this.bindSliderEvents();

            // 保存设置
            const saveBtn = document.getElementById('save-settings');
            if (saveBtn) {
                saveBtn.onclick = () => {
                    this.saveSettings();
                    this.hide();
                    showToast('设置已保存喵~ ✨', 'success');
                };
            }

            // 重置设置
            const resetBtn = document.getElementById('reset-settings');
            if (resetBtn) {
                resetBtn.onclick = () => {
                    if (confirm('确定要重置所有设置吗?这将清除所有自定义配置。')) {
                        this.resetSettings();
                        showToast('设置已重置喵~ 🔄', 'info');
                    }
                };
            }

            // 清理缓存
            const clearBtn = document.getElementById('clear-cache');
            if (clearBtn) {
                clearBtn.onclick = () => {
                    this.clearCache();
                    showToast('缓存已清理喵~ 🧹', 'info');
                };
            }
        }

        bindSliderEvents() {
            const sliders = [
                { id: 'replacement-intensity', valueId: 'intensity-value', isPercent: true },
                { id: 'ending-frequency', valueId: 'ending-value', isPercent: true },
                { id: 'decorative-frequency', valueId: 'decorative-value', isPercent: true },
                { id: 'process-interval', valueId: 'interval-value', isPercent: false },
                { id: 'batch-size', valueId: 'batch-value', isPercent: false },
                { id: 'debounce-delay', valueId: 'debounce-value', isPercent: false }
            ];

            sliders.forEach(({ id, valueId, isPercent }) => {
                const slider = document.getElementById(id);
                const valueSpan = document.getElementById(valueId);

                if (slider && valueSpan) {
                    slider.oninput = (e) => {
                        const value = parseFloat(e.target.value);
                        valueSpan.textContent = isPercent ? `${Math.round(value * 100)}%` : value;
                    };
                }
            });
        }

        switchTab(tabName) {
            // 切换按钮状态
            this.panel.querySelectorAll('.tab-btn').forEach(btn => {
                btn.classList.remove('active');
            });
            this.panel.querySelector(`[data-tab="${tabName}"]`).classList.add('active');

            // 切换内容
            this.panel.querySelectorAll('.tab-content').forEach(content => {
                content.style.display = 'none';
            });
            const targetTab = document.getElementById(`${tabName}-tab`);
            if (targetTab) {
                targetTab.style.display = 'block';
            }
        }

        show() {
            if (!this.panel) this.create();

            this.loadCurrentSettings();
            this.panel.style.display = 'block';
            this.isVisible = true;
            this.updateStats();
        }

        hide() {
            if (this.panel) {
                this.panel.style.display = 'none';
                this.isVisible = false;
            }
        }

        loadCurrentSettings() {
            // 基础设置
            const elements = {
                'cute-level': CONFIG.preferences.cuteLevel,
                'processing-mode': CONFIG.preferences.processingMode,
                'replacement-intensity': CONFIG.preferences.replacementIntensity,
                'ending-frequency': CONFIG.preferences.endingFrequency,
                'decorative-frequency': CONFIG.preferences.decorativeFrequency
            };
            Object.entries(elements).forEach(([id, value]) => {
                const element = document.getElementById(id);
                if (element) {
                    element.value = value;
                }
            });

            // 复选框设置
            const checkboxes = {
                'affect-input': CONFIG.features.affectInput,
                'enable-user-prefix': CONFIG.features.bilibiliRandomizeUserNames,
                'bilibili-merge-links': CONFIG.features.bilibiliMergeALinks,
                'show-original-hover': CONFIG.features.showOriginalOnHover,
                'auto-process-content': CONFIG.features.autoProcessNewContent,
                'shadow-dom-support': CONFIG.features.shadowDomSupport,
                'smart-processing': CONFIG.features.smartProcessing,
                'intelligent-replacement': CONFIG.preferences.intelligentReplacement,
                'debug-mode': CONFIG.features.debugMode,
                'performance-monitoring': CONFIG.features.performanceMonitoring
            };
            Object.entries(checkboxes).forEach(([id, checked]) => {
                const element = document.getElementById(id);
                if (element) element.checked = checked;
            });

            // 高级设置 (滑块)
            const advancedElements = {
                'replacement-intensity': CONFIG.preferences.replacementIntensity,
                'ending-frequency': CONFIG.preferences.endingFrequency,
                'decorative-frequency': CONFIG.preferences.decorativeFrequency,
                'process-interval': CONFIG.performance.processInterval,
                'batch-size': CONFIG.performance.batchSize,
                'debounce-delay': CONFIG.performance.debounceDelay
            };

            const sliderToValueIdMap = {
                'replacement-intensity': 'intensity-value',
                'ending-frequency': 'ending-value',
                'decorative-frequency': 'decorative-value',
                'process-interval': 'interval-value',
                'batch-size': 'batch-value',
                'debounce-delay': 'debounce-value'
            };

            Object.entries(advancedElements).forEach(([id, value]) => {
                const slider = document.getElementById(id);
                if (slider) {
                    slider.value = value; // 设置滑块位置
                    const valueId = sliderToValueIdMap[id];
                    const valueSpan = document.getElementById(valueId);
                    if (valueSpan) {
                        const isPercent = ['replacement-intensity', 'ending-frequency', 'decorative-frequency'].includes(id);
                        valueSpan.textContent = isPercent ? `${Math.round(parseFloat(value) * 100)}%` : value;
                    }
                }
            });

            // 排除词汇
            const disabledWordsEl = document.getElementById('disabled-words');
            if (disabledWordsEl) {
                disabledWordsEl.value = CONFIG.preferences.disabledWords.join('\n');
            }
        }

        saveSettings() {
            // 基础设置
            CONFIG.preferences.cuteLevel = document.getElementById('cute-level')?.value || CONFIG.preferences.cuteLevel;
            CONFIG.preferences.processingMode = document.getElementById('processing-mode')?.value || CONFIG.preferences.processingMode;
            CONFIG.preferences.replacementIntensity = parseFloat(document.getElementById('replacement-intensity')?.value || CONFIG.preferences.replacementIntensity);
            CONFIG.preferences.endingFrequency = parseFloat(document.getElementById('ending-frequency')?.value || CONFIG.preferences.endingFrequency);
            CONFIG.preferences.decorativeFrequency = parseFloat(document.getElementById('decorative-frequency')?.value || CONFIG.preferences.decorativeFrequency);

            // 复选框设置
            CONFIG.features.affectInput = document.getElementById('affect-input')?.checked || false;
            CONFIG.features.bilibiliRandomizeUserNames = document.getElementById('enable-user-prefix')?.checked || false;
            CONFIG.features.bilibiliMergeALinks = document.getElementById('bilibili-merge-links')?.checked || false;
            CONFIG.features.showOriginalOnHover = document.getElementById('show-original-hover')?.checked || false;
            CONFIG.features.autoProcessNewContent = document.getElementById('auto-process-content')?.checked || false;
            CONFIG.features.shadowDomSupport = document.getElementById('shadow-dom-support')?.checked || false;
            CONFIG.features.smartProcessing = document.getElementById('smart-processing')?.checked || false;
            CONFIG.preferences.intelligentReplacement = document.getElementById('intelligent-replacement')?.checked || false;
            CONFIG.features.debugMode = document.getElementById('debug-mode')?.checked || false;
            CONFIG.features.performanceMonitoring = document.getElementById('performance-monitoring')?.checked || false;

            // 高级设置
            CONFIG.performance.processInterval = parseInt(document.getElementById('process-interval')?.value || CONFIG.performance.processInterval);
            CONFIG.performance.batchSize = parseInt(document.getElementById('batch-size')?.value || CONFIG.performance.batchSize);
            CONFIG.performance.debounceDelay = parseInt(document.getElementById('debounce-delay')?.value || CONFIG.performance.debounceDelay);

            // 排除词汇
            const disabledWordsEl = document.getElementById('disabled-words');
            if (disabledWordsEl) {
                CONFIG.preferences.disabledWords = disabledWordsEl.value
                    .split('\n')
                    .map(word => word.trim())
                    .filter(word => word.length > 0);
            }

            GM_setValue("catgirlConfig", CONFIG);
        }

        resetSettings() {
            CONFIG = Object.assign({}, defaultConfig);
            CONFIG.stats = Object.assign({}, defaultConfig.stats, {
                installDate: GM_getValue("catgirlConfig")?.stats?.installDate || new Date().toISOString()
            });
            GM_setValue("catgirlConfig", CONFIG);
            this.loadCurrentSettings();
        }

        clearCache() {
            if (window.catgirlApp && window.catgirlApp.clearCache) {
                window.catgirlApp.clearCache();
            }
        }

        updateStats() {
            const stats = {
                'processed-count': CONFIG.stats.processedElements,
                'replaced-count': CONFIG.stats.replacedWords,
                'session-count': CONFIG.stats.sessionProcessed,
                'blacklist-hits-count': CONFIG.stats.blacklistHits,
                // 新增的动态信息
                'session-elements': CONFIG.stats.sessionProcessed, // 复用会话处理数
                'blacklist-hits-info': CONFIG.stats.blacklistHits
            };
            // ... 后续代码不变

            Object.entries(stats).forEach(([id, value]) => {
                const element = document.getElementById(id);
                if (element) element.textContent = value;
            });

            // 更新运行状态
            const statusEl = document.getElementById('running-status');
            if (statusEl && window.catgirlApp) {
                const isRunning = window.catgirlApp.app.isRunning;
                statusEl.textContent = isRunning ? '运行中 ✅' : '已暂停 ⏸️';
                statusEl.style.color = isRunning ? '#28a745' : '#ffc107';
            }

            // 更新时间信息
            const installEl = document.getElementById('install-date');
            if (installEl) {
                installEl.textContent = new Date(CONFIG.stats.installDate).toLocaleString();
            }

            const activeEl = document.getElementById('last-active');
            if (activeEl) {
                activeEl.textContent = new Date(CONFIG.stats.lastActive).toLocaleString();
            }
        }
    }

    // ===== 主应用类 =====
    class CatgirlApp {
        constructor() {
            this.stateManager = new StateManager();
            this.textProcessor = new EnhancedTextProcessor();
            this.settingsPanel = new SettingsPanel();
            this.blacklistManager = new BlacklistManager();
            this.processedElements = new WeakSet();
            this.isRunning = false;
            this.intervalId = null;
            this.observer = null;
            this.lastProcessHash = '';
            this.processLock = false;
            this.bilibiliCommentObserver = null;
            this.isBlacklisted = false; // 添加黑名单状态标记
        }

        async initialize() {
            // 检查黑名单
            this.isBlacklisted = this.blacklistManager.isBlacklisted();

            if (this.isBlacklisted) {
                if (CONFIG.features.debugMode) {
                    console.log('🐱 当前网站已被加入黑名单,不启动喵~');
                }
                // 即使在黑名单中也注册菜单命令,但功能受限
                this.registerLimitedMenuCommands();
                return;
            }

            if (this.shouldExclude()) {
                if (CONFIG.features.debugMode) {
                    console.log('🐱 域名已排除,不启动喵~');
                }
                return;
            }

            console.log('🐱 增强版猫娘化系统启动喵~');

            this.registerMenuCommands();
            await this.waitForDOMReady();

            this.stateManager.onUrlChange((newUrl) => {
                setTimeout(() => {
                    if (location.href === newUrl) {
                        this.processPage();
                    }
                }, CONFIG.performance.debounceDelay);
            });

            this.start();
        }

        shouldExclude() {
            return CONFIG.sites.excludeDomains.some(domain =>
                                                    location.hostname.includes(domain)
                                                   );
        }

        registerMenuCommands() {
            GM_registerMenuCommand("🐱 设置面板", () => this.settingsPanel.show());
            GM_registerMenuCommand("🚫 网站黑名单", () => this.blacklistManager.show());
            //GM_registerMenuCommand("⛔ 屏蔽当前网站", () => this.showBlockSiteDialog());
            GM_registerMenuCommand("🔄 重新处理", () => this.handleReprocess());
            //GM_registerMenuCommand("📊 显示统计", () => this.showStats());
            GM_registerMenuCommand("🧹 清理缓存", () => this.clearCache());
        }

        // 为黑名单网站注册受限菜单
        registerLimitedMenuCommands() {
            GM_registerMenuCommand("🐱 设置面板", () => this.settingsPanel.show());
            GM_registerMenuCommand("🚫 网站黑名单", () => this.blacklistManager.show());
            GM_registerMenuCommand("🔄 重新处理", () => {
                showToast('该网站被列为黑名单内容,如需修改请到面板里调整', 'warning', 4000);
            });
            GM_registerMenuCommand("📊 显示统计", () => this.showStats());
        }

        handleReprocess() {
            if (this.isBlacklisted) {
                showToast('该网站被列为黑名单内容,如需修改请到面板里调整', 'warning', 4000);
                return;
            }
            this.restart();
        }

        showBlockSiteDialog() {
            this.showBlockSiteUI();
        }

        showBlockSiteUI() {
            if (document.getElementById('catgirl-block-ui')) return;

            const blockUI = document.createElement('div');
            blockUI.id = 'catgirl-block-ui';
            blockUI.innerHTML = this.getBlockSiteHTML();
            blockUI.style.cssText = this.getBlockSiteCSS();

            document.body.appendChild(blockUI);
            this.bindBlockSiteEvents(blockUI);
            this.drawCatPaw(blockUI);
        }

        getBlockSiteHTML() {
            const domain = location.hostname;
            return `
                <div class="block-site-header">
                    <h3>🚫 屏蔽网站 ${domain}</h3>
                    <button class="close-btn" data-action="close-block">×</button>
                </div>

                <div class="block-site-content">
                    <div class="site-info">
                        <div class="site-icon">🌐</div>
                        <div class="site-details">
                            <div class="site-domain">${domain}</div>
                            <div class="site-path">${location.pathname}</div>
                        </div>
                    </div>

                    <div class="block-options">
                        <div class="option-group">
                            <label class="cute-label">
                                <input type="radio" name="block-type" value="site" checked>
                                <span class="radio-custom"></span>
                                <span class="option-text">🏠 整个网站</span>
                            </label>
                            <small>屏蔽整个 ${domain} 域名</small>
                        </div>

                        <div class="option-group">
                            <label class="cute-label">
                                <input type="radio" name="block-type" value="page">
                                <span class="radio-custom"></span>
                                <span class="option-text">📄 仅当前页面</span>
                            </label>
                            <small>只屏蔽当前访问的页面</small>
                        </div>
                    </div>

                    <div class="duration-selector">
                        <label class="cute-label-block">⏰ 屏蔽时长</label>
                        <select id="block-duration" class="cute-select">
                            <option value="3600000">1小时</option>
                            <option value="21600000">6小时</option>
                            <option value="86400000" selected>1天</option>
                            <option value="604800000">1周</option>
                            <option value="2592000000">1个月</option>
                            <option value="-1">永久</option>
                        </select>
                    </div>

                    <div class="reason-input">
                        <label class="cute-label-block">💭 屏蔽原因</label>
                        <input type="text" id="block-reason" class="cute-input" placeholder="记录屏蔽原因,方便管理喵~">
                    </div>

                    <div class="block-actions">
                        <button id="confirm-block" class="btn-block-confirm">🚫 确认屏蔽</button>
                        <button id="cancel-block" class="btn-block-cancel">❌ 取消</button>
                    </div>
                </div>

                <canvas id="cat-paw-canvas" width="60" height="60"></canvas>
            `;
        }

        getBlockSiteCSS() {
            return `
                position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
                width: 420px; background: linear-gradient(135deg, #fff5f8 0%, #ffeef5 100%);
                border-radius: 20px; box-shadow: 0 15px 35px rgba(255, 182, 193, 0.3);
                z-index: 10000; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Microsoft YaHei', sans-serif;
                overflow: hidden; border: 2px solid #ffb6c1;
            `;
        }

        bindBlockSiteEvents(blockUI) {
            blockUI.querySelector('[data-action="close-block"]').onclick = () => {
                document.body.removeChild(blockUI);
            };

            blockUI.querySelector('#cancel-block').onclick = () => {
                document.body.removeChild(blockUI);
            };

            blockUI.querySelector('#confirm-block').onclick = () => {
                const type = blockUI.querySelector('input[name="block-type"]:checked').value;
                const duration = parseInt(blockUI.querySelector('#block-duration').value);
                const reason = blockUI.querySelector('#block-reason').value.trim() || '用户手动屏蔽';

                this.blacklistManager.addToBlacklist(type, duration, reason);
                document.body.removeChild(blockUI);

                if (type === 'site') {
                    this.stop();
                    this.isBlacklisted = true;
                    showToast('网站已屏蔽,脚本已停止运行喵~', 'info', 5000);
                }
            };
        }

        showStats() {
            if (document.getElementById('catgirl-stats-ui')) return;

            const statsUI = document.createElement('div');
            statsUI.id = 'catgirl-stats-ui';
            statsUI.innerHTML = this.getStatsHTML();
            statsUI.style.cssText = this.getStatsCSS();

            document.body.appendChild(statsUI);
            this.bindStatsEvents(statsUI);
            this.drawCatPaw(statsUI);
        }

        getStatsHTML() {
            const processedElements = (CONFIG.stats.processedElements || 0);
            const replacedWords = (CONFIG.stats.replacedWords || 0);
            const sessionProcessed = (CONFIG.stats.sessionProcessed || 0);
            const blacklistHits = (CONFIG.stats.blacklistHits || 0);
            const installDate = CONFIG.stats.installDate || new Date().toISOString();
            const lastActive = CONFIG.stats.lastActive || new Date().toISOString();

            return `
                <div class="stats-header">
                    <h3>📊 猫娘化统计面板</h3>
                    <button class="close-btn" data-action="close-stats">×</button>
                </div>

                <div class="stats-content">
                    <div class="stats-cards">
                        <div class="stat-card">
                            <div class="stat-icon">🔄</div>
                            <div class="stat-info">
                                <div class="stat-number">${processedElements.toLocaleString()}</div>
                                <div class="stat-label">已处理元素</div>
                            </div>
                        </div>

                        <div class="stat-card">
                            <div class="stat-icon">✨</div>
                            <div class="stat-info">
                                <div class="stat-number">${replacedWords.toLocaleString()}</div>
                                <div class="stat-label">已替换词汇</div>
                            </div>
                        </div>

                        <div class="stat-card">
                            <div class="stat-icon">🎯</div>
                            <div class="stat-info">
                                <div class="stat-number">${sessionProcessed.toLocaleString()}</div>
                                <div class="stat-label">本次会话</div>
                            </div>
                        </div>

                        <div class="stat-card">
                            <div class="stat-icon">🚫</div>
                            <div class="stat-info">
                                <div class="stat-number">${blacklistHits.toLocaleString()}</div>
                                <div class="stat-label">黑名单命中</div>
                            </div>
                        </div>
                    </div>

                    <div class="system-info">
                        <div class="info-row">
                            <span class="info-label">🐱 当前版本:</span>
                            <span class="info-value">${SCRIPT_VERSION}</span>
                        </div>
                        <div class="info-row">
                            <span class="info-label">📅 安装时间:</span>
                            <span class="info-value">${new Date(installDate).toLocaleString()}</span>
                        </div>
                        <div class="info-row">
                            <span class="info-label">⏰ 最后活动:</span>
                            <span class="info-value">${new Date(lastActive).toLocaleString()}</span>
                        </div>
                        <div class="info-row">
                            <span class="info-label">🌐 当前网站:</span>
                            <span class="info-value">${location.hostname}</span>
                        </div>
                        <div class="info-row">
                            <span class="info-label">⚡ 运行状态:</span>
                            <span class="info-value status-${this.isBlacklisted ? 'blocked' : (this.isRunning ? 'running' : 'paused')}">
                                ${this.isBlacklisted ? '已屏蔽 🚫' : (this.isRunning ? '运行中 ✅' : '已暂停 ⏸️')}
                            </span>
                        </div>
                    </div>

                    <div class="stats-actions">
                        <button id="refresh-stats" class="btn-stats-refresh">🔄 刷新统计</button>
                        <button id="export-stats" class="btn-stats-export">📊 导出数据</button>
                    </div>
                </div>

                <canvas id="cat-paw-canvas-stats" width="60" height="60"></canvas>
            `;
        }

        getStatsCSS() {
            return `
                position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
                width: 500px; background: linear-gradient(135deg, #f0f8ff 0%, #e6f3ff 100%);
                border-radius: 20px; box-shadow: 0 15px 35px rgba(135, 206, 250, 0.3);
                z-index: 10000; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Microsoft YaHei', sans-serif;
                overflow: hidden; border: 2px solid #87ceeb;
            `;
        }

        bindStatsEvents(statsUI) {
            statsUI.querySelector('[data-action="close-stats"]').onclick = () => {
                document.body.removeChild(statsUI);
            };

            statsUI.querySelector('#refresh-stats').onclick = () => {
                document.body.removeChild(statsUI);
                setTimeout(() => this.showStats(), 100);
            };

            statsUI.querySelector('#export-stats').onclick = () => {
                const data = {
                    version: SCRIPT_VERSION,
                    stats: CONFIG.stats,
                    exportTime: new Date().toISOString(),
                    website: location.hostname
                };

                const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
                const url = URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.href = url;
                a.download = `catgirl-stats-${location.hostname}-${new Date().toISOString().split('T')[0]}.json`;
                a.click();
                URL.revokeObjectURL(url);

                showToast('统计数据已导出喵~ 📊', 'success');
            };
        }

        drawCatPaw() {
            const canvas = document.getElementById('cat-paw-canvas-blacklist');
            if (!canvas) return;

            const ctx = canvas.getContext('2d');
            const size = 60;

            // 清空画布
            ctx.clearRect(0, 0, size, size);

            // 设置样式
            ctx.fillStyle = '#ffb6c1'; // 樱花粉色
            ctx.strokeStyle = '#ff69b4';
            ctx.lineWidth = 2;

            // 绘制猫爪垫(主要部分)
            ctx.beginPath();
            ctx.arc(30, 35, 12, 0, Math.PI * 2);
            ctx.fill();
            ctx.stroke();

            // 绘制四个小爪垫
            const pads = [
                { x: 20, y: 20, size: 6 },
                { x: 40, y: 20, size: 6 },
                { x: 15, y: 30, size: 5 },
                { x: 45, y: 30, size: 5 }
            ];

            pads.forEach(pad => {
                ctx.beginPath();
                ctx.arc(pad.x, pad.y, pad.size, 0, Math.PI * 2);
                ctx.fill();
                ctx.stroke();
            });

            // 添加高光效果
            ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
            ctx.beginPath();
            ctx.arc(25, 30, 4, 0, Math.PI * 2);
            ctx.fill();

            // 设置canvas位置
            canvas.style.cssText = `
                position: absolute;
                bottom: 15px;
                right: 15px;
                opacity: 0.6;
                pointer-events: none;
            `;
        }

        async start() {
            if (this.isRunning || this.isBlacklisted) return;
            this.isRunning = true;

            setTimeout(() => {
                if (this.isRunning && !this.isBlacklisted) {
                    this.processPage();
                }
            }, 1000);

            if (CONFIG.performance.processInterval > 0) {
                const debouncedProcess = DebounceUtils.throttleWithDebounce(
                    () => this.conditionalProcess(),
                    CONFIG.performance.processInterval,
                    CONFIG.performance.debounceDelay
                );

                this.intervalId = setInterval(debouncedProcess, CONFIG.performance.processInterval);
            }

            this.setupMutationObserver();

            if (this.stateManager.isBilibili()) {
                this.setupBilibiliCommentObserver();
            }

            if (CONFIG.features.debugMode) {
                console.log('🎀 猫娘化系统已启动完成喵~');
            }
        }

        conditionalProcess() {
            if (!this.isRunning || this.processLock || this.isBlacklisted) return;

            const urlChanged = this.stateManager.checkUrlChange();
            const commentChanged = this.stateManager.checkBilibiliCommentChange();
            const shouldProcess = this.stateManager.shouldProcess();

            if (urlChanged || commentChanged || (!this.stateManager.shouldSkipBilibiliProcessing() && shouldProcess)) {
                this.processPage();
            }
        }

        processPage() {
            if (!this.isRunning || !CONFIG.features.autoProcessNewContent || this.processLock || this.isBlacklisted) {
                return;
            }

            this.processLock = true;

            try {
                const elements = this.getProcessableElements();

                const contentHash = this.generateContentHash(elements);
                if (contentHash === this.lastProcessHash) {
                    return;
                }
                this.lastProcessHash = contentHash;

                if (elements.length === 0) {
                    return;
                }

                EnhancedPerformanceUtils.createTimeSliceProcessor(
                    elements,
                    (element) => this.processElement(element),
                    {
                        onProgress: CONFIG.features.debugMode ?
                        (current, total, percent) => {
                            if (current % 50 === 0) {
                                console.log(`🐱 处理进度: ${percent.toFixed(1)}% (${current}/${total})`);
                            }
                        } : null,
                        onComplete: () => {
                            CONFIG.stats.lastActive = new Date().toISOString();
                            GM_setValue("catgirlConfig", CONFIG);

                            if (this.stateManager.isBilibili()) {
                                this.processBilibiliSpecial();
                            }
                        }
                    }
                );
            } finally {
                setTimeout(() => {
                    this.processLock = false;
                }, 1000);
            }
        }

        getProcessableElements() {
            const baseSelector = 'title, h1, h2, h3, h4, h5, h6, p, article, section, blockquote, li, a, span, div:not([class*="settings"]):not([id*="catgirl"])';
            const inputSelector = CONFIG.features.affectInput ? ', input, textarea' : '';

            const elements = document.querySelectorAll(baseSelector + inputSelector);

            return Array.from(elements).filter(element => {
                return !this.processedElements.has(element) &&
                    !element.closest('#catgirl-settings, #catgirl-debug, #catgirl-blacklist') &&
                    this.shouldProcessElement(element);
            });
        }

        shouldProcessElement(element) {
            if (!element.textContent?.trim()) return false;
            if (this.textProcessor.isProcessed(element.textContent)) return false;
            if (element.tagName && /^(SCRIPT|STYLE|NOSCRIPT)$/.test(element.tagName)) return false;
            if (element.offsetParent === null && element.style.display !== 'none') return false;
            return true;
        }

        generateContentHash(elements) {
            const textContent = elements.slice(0, 10).map(el => el.textContent?.slice(0, 50)).join('|');
            return textContent.length + ':' + elements.length;
        }

        processElement(element) {
            if (!element || this.processedElements.has(element)) return;

            try {
                // 保存原始文本
                const originalText = element.textContent;
                if (originalText && !this.textProcessor.getOriginalText(element)) {
                    this.textProcessor.storeOriginalText(element, originalText);
                }

                if (element.matches && element.matches('input, textarea') && CONFIG.features.affectInput) {
                    if (element.value?.trim()) {
                        const processedValue = this.textProcessor.processText(element.value);
                        element.value = processedValue;
                    }
                } else {
                    this.processElementText(element);
                }

                // 如果开启了鼠标悬停显示原文功能,且是评论元素
                if (CONFIG.features.showOriginalOnHover && originalText && originalText !== element.textContent && this.isCommentElement(element)) {
                    this.setupHoverOriginalText(element, originalText);
                }

                this.processedElements.add(element);
                CONFIG.stats.processedElements++;

            } catch (error) {
                if (CONFIG.features.debugMode) {
                    console.error('🐱 处理元素出错:', error);
                }
            }
        }

        // 设置鼠标悬停显示原文功能 - 安全修复版本
        setupHoverOriginalText(element, originalText) {
            // 安全检查:避免处理可能包含脚本或重要功能的元素
            if (this.isUnsafeElement(element)) {
                return;
            }

            const processedText = element.textContent;
            let isHovering = false;
            let timeoutId = null;

            // 创建tooltip而不是直接修改元素内容
            const showTooltip = () => {
                if (isHovering) return;
                isHovering = true;

                // 创建tooltip显示原文
                const tooltip = document.createElement('div');
                tooltip.className = 'catgirl-original-tooltip';
                tooltip.textContent = originalText;
                tooltip.style.cssText = `
                    position: absolute;
                    background: rgba(0,0,0,0.8);
                    color: white;
                    padding: 8px 12px;
                    border-radius: 6px;
                    font-size: 12px;
                    z-index: 10002;
                    max-width: 300px;
                    word-wrap: break-word;
                    pointer-events: none;
                    opacity: 0;
                    transition: opacity 0.2s ease;
                `;

                // 计算位置
                const rect = element.getBoundingClientRect();
                tooltip.style.left = `${rect.left + window.scrollX}px`;
                tooltip.style.top = `${rect.bottom + window.scrollY + 5}px`;

                document.body.appendChild(tooltip);

                // 淡入效果
                setTimeout(() => {
                    tooltip.style.opacity = '1';
                }, 10);

                // 保存tooltip引用
                element._catgirlTooltip = tooltip;

                // 添加视觉提示
                element.style.backgroundColor = 'rgba(255, 248, 220, 0.3)';
                element.style.transition = 'background-color 0.2s ease';
            };

            const hideTooltip = () => {
                if (!isHovering) return;
                isHovering = false;

                // 移除tooltip
                if (element._catgirlTooltip) {
                    element._catgirlTooltip.style.opacity = '0';
                    setTimeout(() => {
                        if (element._catgirlTooltip && element._catgirlTooltip.parentNode) {
                            document.body.removeChild(element._catgirlTooltip);
                        }
                        element._catgirlTooltip = null;
                    }, 200);
                }

                // 恢复元素样式
                element.style.backgroundColor = '';
            };

            // 移除可能存在的旧事件监听器
            if (element._catgirlMouseEnter) {
                element.removeEventListener('mouseenter', element._catgirlMouseEnter);
            }
            if (element._catgirlMouseLeave) {
                element.removeEventListener('mouseleave', element._catgirlMouseLeave);
            }

            // 保存事件处理器引用
            element._catgirlMouseEnter = showTooltip;
            element._catgirlMouseLeave = hideTooltip;

            // 添加新的事件监听器
            element.addEventListener('mouseenter', showTooltip);
            element.addEventListener('mouseleave', hideTooltip);
        }

        // 设置鼠标悬停显示原文功能 - 仅针对评论区的安全版本
        setupHoverOriginalText(element, originalText) {
            // 只对评论相关元素启用悬停功能
            if (!this.isCommentElement(element)) {
                return;
            }

            const processedText = element.textContent;
            let isHovering = false;

            const showTooltip = () => {
                if (isHovering) return;
                isHovering = true;

                // 创建tooltip显示原文
                const tooltip = document.createElement('div');
                tooltip.className = 'catgirl-original-tooltip';
                tooltip.textContent = originalText;
                tooltip.style.cssText = `
                    position: absolute;
                    background: rgba(0,0,0,0.8);
                    color: white;
                    padding: 8px 12px;
                    border-radius: 6px;
                    font-size: 12px;
                    z-index: 10002;
                    max-width: 300px;
                    word-wrap: break-word;
                    pointer-events: none;
                    opacity: 0;
                    transition: opacity 0.2s ease;
                `;

                // 计算位置
                const rect = element.getBoundingClientRect();
                tooltip.style.left = `${rect.left + window.scrollX}px`;
                tooltip.style.top = `${rect.bottom + window.scrollY + 5}px`;

                document.body.appendChild(tooltip);

                // 淡入效果
                setTimeout(() => {
                    tooltip.style.opacity = '1';
                }, 10);

                // 保存tooltip引用
                element._catgirlTooltip = tooltip;

                // 添加视觉提示
                element.style.backgroundColor = 'rgba(255, 248, 220, 0.3)';
                element.style.transition = 'background-color 0.2s ease';
            };

            const hideTooltip = () => {
                if (!isHovering) return;
                isHovering = false;

                // 移除tooltip
                if (element._catgirlTooltip) {
                    element._catgirlTooltip.style.opacity = '0';
                    setTimeout(() => {
                        if (element._catgirlTooltip && element._catgirlTooltip.parentNode) {
                            document.body.removeChild(element._catgirlTooltip);
                        }
                        element._catgirlTooltip = null;
                    }, 200);
                }

                // 恢复元素样式
                element.style.backgroundColor = '';
            };

            // 移除可能存在的旧事件监听器
            if (element._catgirlMouseEnter) {
                element.removeEventListener('mouseenter', element._catgirlMouseEnter);
            }
            if (element._catgirlMouseLeave) {
                element.removeEventListener('mouseleave', element._catgirlMouseLeave);
            }

            // 保存事件处理器引用
            element._catgirlMouseEnter = showTooltip;
            element._catgirlMouseLeave = hideTooltip;

            // 添加新的事件监听器
            element.addEventListener('mouseenter', showTooltip);
            element.addEventListener('mouseleave', hideTooltip);
        }

        // 检查是否是评论相关元素(使用与评论处理相同的选择器)
        isCommentElement(element) {
            if (!element) return false;

            // 使用与 processBilibiliComments 中相同的选择器逻辑
            const commentSelectors = [
                '.reply-item .reply-content',
                '.comment-item .comment-content',
                '.bili-comment-content',
                '.reply-content',
                '.comment-content',
                '[data-e2e="reply-item"] .reply-content',
                '.bili-comment .comment-text'
            ];

            // B站 Shadow DOM 中的评论选择器
            const shadowCommentSelectors = [
                '#contents span',
                '.comment-text',
                '.reply-content',
                '.comment-content'
            ];

            // 检查元素本身是否匹配评论选择器
            for (const selector of commentSelectors) {
                try {
                    if (element.matches && element.matches(selector)) return true;
                    if (element.closest && element.closest(selector)) return true;
                } catch (e) {
                    // 忽略选择器错误
                }
            }

            // 检查是否在 Shadow DOM 的评论区中
            for (const selector of shadowCommentSelectors) {
                try {
                    // 检查元素是否直接匹配 shadow DOM 评论选择器
                    if (element.matches && element.matches(selector)) return true;

                    // 检查父元素路径中是否有评论容器
                    let parent = element.parentElement;
                    let depth = 0;
                    while (parent && depth < 5) {
                        if (parent.matches && parent.matches('bili-comment-thread-renderer, bili-comment-replies-renderer, bili-comments')) {
                            return true;
                        }
                        parent = parent.parentElement;
                        depth++;
                    }
                } catch (e) {
                    // 忽略选择器错误
                }
            }

            return false;
        }

        processElementText(element) {
            if (element.children.length === 0) {
                const newText = this.textProcessor.processText(element.textContent);
                if (newText !== element.textContent) {
                    element.textContent = newText;
                }
            } else {
                const textNodes = this.getTextNodes(element);
                textNodes.forEach(node => {
                    if (node.textContent?.trim()) {
                        const newText = this.textProcessor.processText(node.textContent);
                        if (newText !== node.textContent) {
                            node.textContent = newText;
                        }
                    }
                });
            }
        }

        getTextNodes(element) {
            const textNodes = [];
            const walker = document.createTreeWalker(
                element,
                NodeFilter.SHOW_TEXT,
                {
                    acceptNode: function(node) {
                        if (node.parentElement &&
                            /^(SCRIPT|STYLE|NOSCRIPT)$/.test(node.parentElement.tagName)) {
                            return NodeFilter.FILTER_REJECT;
                        }
                        return node.textContent.trim() ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
                    }
                }
            );

            let node;
            while (node = walker.nextNode()) {
                textNodes.push(node);
            }

            return textNodes;
        }

        processBilibiliSpecial() {
            if (this.stateManager.shouldSkipBilibiliProcessing()) return;

            if (CONFIG.features.debugMode) {
                console.log('🎯 执行B站特殊处理');
            }

            try {
                this.processBilibiliComments();
                this.processBilibiliShadowDOM();

                // B站链接转文本功能
                if (CONFIG.features.bilibiliMergeALinks) {
                    this.processBilibiliLinks();
                }
            } catch (error) {
                if (CONFIG.features.debugMode) {
                    console.error('🐱 B站处理出错:', error);
                }
            }

            this.stateManager.markBilibiliCompleted();
        }

        // B站链接转文本功能实现
        processBilibiliLinks() {
            const linkSelectors = [
                '.reply-content a:not([data-catgirl-link-processed])',
                '.comment-content a:not([data-catgirl-link-processed])',
                '.bili-comment-content a:not([data-catgirl-link-processed])',
                'bili-comment-thread-renderer a:not([data-catgirl-link-processed])',
                '.reply-item a:not([data-catgirl-link-processed])'
            ];

            linkSelectors.forEach(selector => {
                const links = document.querySelectorAll(selector);
                links.forEach(link => {
                    this.convertLinkToText(link);
                });
            });

            // 处理 Shadow DOM 中的链接
            if (CONFIG.features.shadowDomSupport) {
                this.processBilibiliLinksInShadowDOM();
            }
        }

        // B站链接转文本功能实现 - 重写版本
        processBilibiliLinks() {
            // 处理普通DOM中的评论
            const commentContainers = document.querySelectorAll(
                '.reply-content, .comment-content, .bili-comment-content, .reply-item, .comment-item'
            );

            commentContainers.forEach(container => {
                this.processLinksInContainer(container);
            });

            // 处理 Shadow DOM 中的链接
            if (CONFIG.features.shadowDomSupport) {
                this.processBilibiliLinksInShadowDOM();
            }
        }

        processLinksInContainer(container) {
            if (!container || container.hasAttribute('data-catgirl-link-container-processed')) return;

            container.setAttribute('data-catgirl-link-container-processed', 'true');

            // 查找所有 p 元素,这些通常包含评论的完整结构
            const paragraphs = container.querySelectorAll('p');

            paragraphs.forEach(p => {
                this.processBilibiliLinks()
            });

            if (CONFIG.features.debugMode) {
                console.log('🔗 已处理评论容器的链接:', container);
            }
        }

        // 使用更稳健的逻辑重写
        convertLinkToText(linkElement) {
            if (!linkElement || linkElement.hasAttribute('data-catgirl-link-processed')) return;

            // 创建一个新的span元素来替换a标签
            const newSpan = document.createElement('span');
            newSpan.className = 'catgirl-converted-link'; // 可选,用于样式
            newSpan.textContent = linkElement.textContent || ''; // 使用a标签的文本内容

            // 替换节点
            linkElement.parentNode.replaceChild(newSpan, linkElement);

            // 标记容器,以便后续的文本处理可以重新扫描
            const container = newSpan.closest('.reply-content, .comment-content, .bili-comment-content');
            if (container) {
                container.removeAttribute('data-catgirl-processed');
            }
        }

        processBilibiliLinks() {
            const linkSelectors = [
                '.reply-content a:not([data-catgirl-link-processed])',
                '.comment-content a:not([data-catgirl-link-processed])',
                'bili-comment-thread-renderer a:not([data-catgirl-link-processed])'
            ];

            const processLinks = (rootNode) => {
                linkSelectors.forEach(selector => {
                    rootNode.querySelectorAll(selector).forEach(link => {
                        this.convertLinkToText(link);
                    });
                });
            };

            processLinks(document.body);

            // 处理 Shadow DOM
            document.querySelectorAll('bili-comment-thread-renderer').forEach(host => {
                if (host.shadowRoot) {
                    processLinks(host.shadowRoot);
                }
            });
        }

        extractTextFromLink(linkElement) {
            let text = '';

            // 遍历a标签的所有子节点
            for (const child of linkElement.childNodes) {
                if (child.nodeType === Node.TEXT_NODE) {
                    text += child.textContent;
                } else if (child.nodeType === Node.ELEMENT_NODE && child.tagName !== 'IMG') {
                    // 非图片元素的文本内容
                    text += child.textContent || '';
                }
            }

            return text;
        }

        mergeContentToSpan(targetSpan, contentArray) {
            if (!targetSpan || contentArray.length === 0) return;

            const originalText = targetSpan.textContent || '';
            const additionalText = contentArray.join('');
            const mergedText = originalText + additionalText;

            // 应用猫娘化处理
            const processedText = this.textProcessor.processText(mergedText);
            targetSpan.textContent = processedText;

            if (CONFIG.features.debugMode) {
                console.log('🔗 文本合并:', originalText, '+', additionalText, '->', processedText);
            }
        }

        processBilibiliLinksInShadowDOM() {
            const shadowHosts = document.querySelectorAll('bili-comment-thread-renderer, bili-comment-replies-renderer');
            shadowHosts.forEach(host => {
                if (host.shadowRoot) {
                    // 在Shadow DOM中查找 #contents 元素
                    const contentsElements = host.shadowRoot.querySelectorAll('#contents:not([data-catgirl-shadow-link-processed])');
                    contentsElements.forEach(contents => {
                        contents.setAttribute('data-catgirl-shadow-link-processed', 'true');

                        // 处理 contents 中的 p 元素
                        const paragraphs = contents.querySelectorAll('p');
                        paragraphs.forEach(p => {
                            this.processBilibiliLinks()
                        });
                    });
                }
            });
        }

        processBilibiliComments() {
            const commentSelectors = [
                '.reply-item .reply-content:not([data-catgirl-processed])',
                '.comment-item .comment-content:not([data-catgirl-processed])',
                '.bili-comment-content:not([data-catgirl-processed])',
                '.reply-content:not([data-catgirl-processed])',
                '.comment-content:not([data-catgirl-processed])',
                '[data-e2e="reply-item"] .reply-content:not([data-catgirl-processed])',
                '.bili-comment .comment-text:not([data-catgirl-processed])'
            ];

            commentSelectors.forEach(selector => {
                const elements = document.querySelectorAll(selector);
                elements.forEach(element => {
                    if (!this.processedElements.has(element)) {
                        element.setAttribute('data-catgirl-processed', 'true');
                        this.processElement(element);
                    }
                });
            });

            // 处理用户名 - 检查开关
            if (CONFIG.features.bilibiliRandomizeUserNames) {
                const usernameSelectors = [
                    '.user-name:not([data-catgirl-processed])',
                    '.reply-item .user-name:not([data-catgirl-processed])',
                    '.comment-item .user-name:not([data-catgirl-processed])',
                    '.bili-comment .user-name:not([data-catgirl-processed])',
                    '.reply-author:not([data-catgirl-processed])',
                    '.comment-author:not([data-catgirl-processed])'
                ];

                usernameSelectors.forEach(selector => {
                    const elements = document.querySelectorAll(selector);
                    elements.forEach(element => {
                        this.processBilibiliUsername(element);
                    });
                });
            }
        }

        processBilibiliUsername(element) {
            if (!element || this.processedElements.has(element)) return;

            const userName = element.textContent?.trim();
            if (!userName || !CONFIG.features.bilibiliRandomizeUserNames) return;

            if (this.hasUserPrefix(userName)) return;

            element.setAttribute('data-catgirl-processed', 'true');
            this.processedElements.add(element);

            const processingType = Math.random();

            if (processingType < 0.3) {
                const randomPrefix = this.getRandomUserPrefix();
                element.textContent = `${randomPrefix}${userName}${randomPrefix}`;
            } else if (processingType < 0.6) {
                const randomPrefix = this.getRandomUserPrefix();
                element.textContent = `${randomPrefix}${userName}`;
            } else if (processingType < 0.8) {
                const decorative = cuteLibrary.decorativePrefixes[Math.floor(Math.random() * cuteLibrary.decorativePrefixes.length)];
                element.textContent = `${decorative}${userName}`;
            }

            if (CONFIG.features.debugMode) {
                console.log('🎀 处理用户名:', userName, '->', element.textContent);
            }
        }

        processBilibiliShadowDOM() {
            if (!CONFIG.features.shadowDomSupport) return;

            const biliComments = document.querySelector('bili-comments');
            if (biliComments && biliComments.shadowRoot) {
                this.processElementsInShadowDOM(biliComments.shadowRoot);
            }

            const shadowHosts = document.querySelectorAll('bili-comment-thread-renderer, bili-comment-replies-renderer');
            shadowHosts.forEach(host => {
                if (host.shadowRoot) {
                    this.processElementsInShadowDOM(host.shadowRoot);
                }
            });
        }

        processElementsInShadowDOM(shadowRoot) {
            try {
                const contentSelectors = [
                    '#contents span:not([data-catgirl-processed])',
                    '.comment-text:not([data-catgirl-processed])',
                    '.reply-content:not([data-catgirl-processed])',
                    '.comment-content:not([data-catgirl-processed])'
                ];

                contentSelectors.forEach(selector => {
                    const elements = shadowRoot.querySelectorAll(selector);
                    elements.forEach(element => {
                        if (!this.processedElements.has(element)) {
                            element.setAttribute('data-catgirl-processed', 'true');

                            // 保存原始文本用于悬停显示
                            const originalText = element.textContent;
                            if (originalText && !this.textProcessor.getOriginalText(element)) {
                                this.textProcessor.storeOriginalText(element, originalText);
                            }

                            this.processElement(element);

                            // Shadow DOM 中的评论元素也需要悬停功能
                            if (CONFIG.features.showOriginalOnHover && originalText && originalText !== element.textContent) {
                                this.setupHoverOriginalText(element, originalText);
                            }
                        }
                    });
                });

                if (CONFIG.features.bilibiliRandomizeUserNames) {
                    const usernameSelectors = [
                        '#user-name a:not([data-catgirl-processed])',
                        '.user-name:not([data-catgirl-processed])',
                        '.author-name:not([data-catgirl-processed])'
                    ];

                    usernameSelectors.forEach(selector => {
                        const elements = shadowRoot.querySelectorAll(selector);
                        elements.forEach(element => {
                            this.processBilibiliUsername(element);
                        });
                    });
                }

                const nestedHosts = shadowRoot.querySelectorAll('*');
                nestedHosts.forEach(el => {
                    if (el.shadowRoot && !el.hasAttribute('data-catgirl-shadow-processed')) {
                        el.setAttribute('data-catgirl-shadow-processed', 'true');
                        this.processElementsInShadowDOM(el.shadowRoot);
                    }
                });

            } catch (error) {
                if (CONFIG.features.debugMode) {
                    console.error('🐱 处理Shadow DOM出错:', error);
                }
            }
        }

        hasUserPrefix(userName) {
            if (!userName) return true;

            const hasPrefix = cuteLibrary.userPrefixes.some(prefix => userName.includes(prefix));
            const hasDecorative = cuteLibrary.decorativePrefixes.some(prefix => userName.includes(prefix));
            const isProcessed = /已处理|🏳️‍⚧️.*🏳️‍⚧️|✨.*✨|💕.*💕/.test(userName);
            const isTooLong = userName.length > 20;

            return hasPrefix || hasDecorative || isProcessed || isTooLong;
        }

        getRandomUserPrefix() {
            const prefixes = cuteLibrary.userPrefixes;
            return prefixes[Math.floor(Math.random() * prefixes.length)];
        }

        setupBilibiliCommentObserver() {
            if (this.bilibiliCommentObserver) return;

            const targetNode = document.body;
            const config = {
                childList: true,
                subtree: true,
                attributes: false
            };

            this.bilibiliCommentObserver = new MutationObserver(
                DebounceUtils.throttleWithDebounce((mutations) => {
                    let hasCommentChanges = false;

                    for (const mutation of mutations) {
                        for (const node of mutation.addedNodes) {
                            if (node.nodeType === Node.ELEMENT_NODE) {
                                if (node.matches && (
                                    node.matches('bili-comment-thread-renderer, bili-comment, .reply-item, .comment-item') ||
                                    (node.querySelector && (
                                        node.querySelector('bili-comment-thread-renderer') ||
                                        node.querySelector('.reply-item') ||
                                        node.querySelector('.comment-item') ||
                                        node.querySelector('.bili-comment')
                                    ))
                                )) {
                                    hasCommentChanges = true;
                                    break;
                                }
                            }
                        }
                        if (hasCommentChanges) break;
                    }

                    if (hasCommentChanges) {
                        setTimeout(() => {
                            if (CONFIG.features.debugMode) {
                                console.log('🔄 检测到B站评论变化,开始处理');
                            }
                            this.processBilibiliSpecial();
                        }, 1200);
                    }
                }, 800, 400)
            );

            this.bilibiliCommentObserver.observe(targetNode, config);

            if (CONFIG.features.debugMode) {
                console.log('🎯 B站评论观察器已启动');
            }
        }

        setupMutationObserver() {
            if (this.observer || !CONFIG.features.autoProcessNewContent) return;

            const throttledCallback = DebounceUtils.throttleWithDebounce(
                (mutations) => this.handleMutations(mutations),
                CONFIG.performance.observerThrottle,
                CONFIG.performance.debounceDelay
            );

            this.observer = new MutationObserver(throttledCallback);
            this.observer.observe(document.body, {
                childList: true,
                subtree: true,
                attributes: false,
                characterData: false
            });

            if (CONFIG.features.debugMode) {
                console.log('👁️ DOM变化监听器已启动');
            }
        }

        handleMutations(mutations) {
            console.log('✨ 检测到DOM变化,立即处理新内容!');
            if (this.processLock || this.isBlacklisted) return;

            try {
                const elementsToProcess = new Set();

                mutations.forEach(mutation => {
                    mutation.addedNodes.forEach(node => {
                        if (node.nodeType === Node.ELEMENT_NODE && this.shouldProcessElement(node)) {
                            elementsToProcess.add(node);

                            const children = node.querySelectorAll && node.querySelectorAll('*');
                            if (children) {
                                Array.from(children).forEach(child => {
                                    if (this.shouldProcessElement(child)) {
                                        elementsToProcess.add(child);
                                    }
                                });
                            }
                        }
                    });
                });

                if (elementsToProcess.size > 0) {
                    const limitedElements = Array.from(elementsToProcess).slice(0, 20);

                    if (CONFIG.features.debugMode) {
                        console.log(`🔄 DOM变化触发处理: ${limitedElements.length} 个新元素`);
                    }

                    EnhancedPerformanceUtils.createTimeSliceProcessor(
                        limitedElements,
                        (element) => this.processElement(element),
                        {
                            onComplete: () => {
                                CONFIG.stats.lastActive = new Date().toISOString();
                            }
                        }
                    );
                }
            } catch (error) {
                if (CONFIG.features.debugMode) {
                    console.error('🐱 处理DOM变化出错:', error);
                }
            }
        }

        toggle() {
            if (this.isBlacklisted) {
                showToast('该网站被列为黑名单内容,如需修改请到面板里调整', 'warning', 4000);
                return;
            }

            if (this.isRunning) {
                this.stop();
                showToast('猫娘化已暂停喵~ ⏸️', 'warning');
            } else {
                this.start();
                showToast('猫娘化已恢复喵~ ▶️', 'success');
            }
        }

        stop() {
            this.isRunning = false;
            this.processLock = false;

            if (this.intervalId) {
                clearInterval(this.intervalId);
                this.intervalId = null;
            }
            if (this.observer) {
                this.observer.disconnect();
                this.observer = null;
            }
            if (this.bilibiliCommentObserver) {
                this.bilibiliCommentObserver.disconnect();
                this.bilibiliCommentObserver = null;
            }
        }

        restart() {
            if (this.isBlacklisted) {
                showToast('该网站被列为黑名单内容,如需修改请到面板里调整', 'warning', 4000);
                return;
            }

            this.stop();
            this.processedElements = new WeakSet();
            this.textProcessor.processedTexts = new Set();
            this.lastProcessHash = '';

            setTimeout(() => {
                this.start();
                showToast('系统已重启喵~ 🔄', 'info');
            }, 500);
        }

        showStats() {
            if (document.getElementById('catgirl-stats-ui')) return;

            const statsUI = document.createElement('div');
            statsUI.id = 'catgirl-stats-ui';
            statsUI.innerHTML = this.getStatsHTML();
            statsUI.style.cssText = this.getStatsCSS();

            document.body.appendChild(statsUI);
            this.bindStatsEvents(statsUI);
            this.drawCatPaw(statsUI);
        }

        clearCache() {
            this.processedElements = new WeakSet();
            this.textProcessor.processedTexts = new Set();
            this.lastProcessHash = '';
            CONFIG.stats.sessionProcessed = 0;

            // 清理处理标记
            const processedElements = document.querySelectorAll('[data-catgirl-processed]');
            processedElements.forEach(el => {
                el.removeAttribute('data-catgirl-processed');
            });

            const processedLinks = document.querySelectorAll('[data-catgirl-link-processed]');
            processedLinks.forEach(el => {
                el.removeAttribute('data-catgirl-link-processed');
            });

            const processedShadows = document.querySelectorAll('[data-catgirl-shadow-processed]');
            processedShadows.forEach(el => {
                el.removeAttribute('data-catgirl-shadow-processed');
            });

            GM_setValue("catgirlConfig", CONFIG);
            showToast('缓存已清理,统计已重置喵~ 🧹', 'success');
        }

        waitForDOMReady() {
            return new Promise(resolve => {
                if (document.readyState !== 'loading') {
                    resolve();
                } else {
                    document.addEventListener('DOMContentLoaded', resolve, { once: true });
                }
            });
        }
    }

    // ===== 工具函数 =====
    function showToast(message, type = 'info', duration = 3000) {
        // 计算已存在的toast的总高度,为新toast腾出位置
        let offset = 20;
        document.querySelectorAll('.catgirl-toast.show').forEach(existingToast => {
            offset += existingToast.offsetHeight + 10;
        });

        const toast = document.createElement('div');
        toast.className = 'catgirl-toast';
        toast.style.top = `${offset}px`; // 设置初始偏移
        toast.innerHTML = `
            <div class="toast-icon">${getToastIcon(type)}</div>
            <div class="toast-message">${message}</div>
        `;
        toast.classList.add(`toast-${type}`);
        document.body.appendChild(toast);

        setTimeout(() => toast.classList.add('show'), 10);

        setTimeout(() => {
            toast.classList.remove('show');
            setTimeout(() => {
                if (toast.parentNode) {
                    document.body.removeChild(toast);
                }
            }, 300);
        }, duration);
    }

    function getToastIcon(type) {
        const icons = {
            success: '✅',
            error: '❌',
            warning: '⚠️',
            info: 'ℹ️'
        };
        return icons[type] || icons.info;
    }

    function showUpdateNotification() {
        showToast(`🎉 猫娘脚本已更新到 v${SCRIPT_VERSION} 喵~\n新增功能:${UPdate_What}`, 'success', 5000);
    }

    // ===== 启动应用 =====
    const catgirlApp = new CatgirlApp();

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', () => catgirlApp.initialize(), { once: true });
    } else {
        setTimeout(() => catgirlApp.initialize(), 100);
    }

    // ===== 样式注入 =====
    GM_addStyle(`
        /* Toast 通知样式 - 增强版 */
        .catgirl-toast {
            position: fixed;
            top: 20px;
            right: 20px;
            z-index: 10001;
            padding: 16px 20px;
            border-radius: 12px;
            font-size: 14px;
            font-weight: 500;
            max-width: 350px;
            box-shadow: 0 8px 32px rgba(0,0,0,0.15);
            transform: translateX(120%);
            transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
            backdrop-filter: blur(10px);
            display: flex;
            align-items: center;
            gap: 12px;
        }

        .catgirl-toast.show {
            transform: translateX(0);
        }

        .catgirl-toast.toast-success {
            background: linear-gradient(135deg, #28a745 0%, #20c997 100%);
            color: white;
        }

        .catgirl-toast.toast-error {
            background: linear-gradient(135deg, #dc3545 0%, #e74c3c 100%);
            color: white;
        }

        .catgirl-toast.toast-warning {
            background: linear-gradient(135deg, #ffc107 0%, #fd7e14 100%);
            color: #212529;
        }

        .catgirl-toast.toast-info {
            background: linear-gradient(135deg, #17a2b8 0%, #6f42c1 100%);
            color: white;
        }

        .catgirl-toast .toast-icon {
            font-size: 18px;
        }

        .catgirl-toast .toast-message {
            flex: 1;
            line-height: 1.4;
        }

        /* 设置面板样式 - 增强版 */
        #catgirl-settings {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Microsoft YaHei', sans-serif;
            line-height: 1.5;
        }

        #catgirl-settings .settings-header,
        #catgirl-blacklist .blacklist-header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 20px;
            border-radius: 12px 12px 0 0;
            display: flex;
            justify-content: space-between;
            align-items: center;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }

        #catgirl-settings .settings-header h3,
        #catgirl-blacklist .blacklist-header h3 {
            margin: 0;
            font-size: 20px;
            font-weight: 600;
        }

        #catgirl-settings .close-btn,
        #catgirl-blacklist .close-btn {
            background: rgba(255,255,255,0.2);
            border: none;
            color: white;
            font-size: 24px;
            cursor: pointer;
            width: 32px;
            height: 32px;
            border-radius: 50%;
            transition: all 0.3s ease;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        #catgirl-settings .close-btn:hover,
        #catgirl-blacklist .close-btn:hover {
            background: rgba(255,255,255,0.3);
            transform: scale(1.1);
        }

        #catgirl-settings .settings-content,
        #catgirl-blacklist .blacklist-content {
            padding: 24px;
            background: #ffffff;
            height: 590px;
            overflow-y: auto;
            border-radius: 0 0 12px 12px;
        }

        #catgirl-settings .tab-container {
            display: flex;
            margin-bottom: 24px;
            background: #f8f9fa;
            border-radius: 8px;
            padding: 4px;
            flex-wrap: wrap;
        }

        #catgirl-settings .tab-btn {
            flex: 1;
            padding: 12px 16px;
            border: none;
            background: transparent;
            cursor: pointer;
            border-radius: 6px;
            transition: all 0.3s ease;
            font-weight: 500;
            color: #6c757d;
            min-width: 80px;
        }

        #catgirl-settings .tab-btn.active {
            background: white;
            color: #495057;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }

        #catgirl-settings .tab-btn:hover:not(.active) {
            color: #495057;
            background: rgba(255,255,255,0.7);
        }

        #catgirl-settings .setting-group {
            margin-bottom: 20px;
        }

        #catgirl-settings label,
        #catgirl-blacklist label {
            display: block;
            margin-bottom: 8px;
            font-weight: 500;
            color: #333;
            font-size: 14px;
        }

        #catgirl-settings small,
        #catgirl-blacklist small {
            display: block;
            color: #6c757d;
            font-size: 12px;
            margin-top: 4px;
            line-height: 1.4;
        }

        #catgirl-settings select,
        #catgirl-settings input[type="text"],
        #catgirl-settings input[type="range"],
        #catgirl-settings textarea,
        #catgirl-blacklist select,
        #catgirl-blacklist input[type="text"],
        #catgirl-blacklist textarea {
            color: #333;
            width: 100%;
            padding: 10px 12px;
            border: 2px solid #e9ecef;
            border-radius: 6px;
            font-size: 14px;
            transition: all 0.3s ease;
            background: #fff;
            box-sizing: border-box;
        }

        #catgirl-settings select:focus,
        #catgirl-settings input:focus,
        #catgirl-settings textarea:focus,
        #catgirl-blacklist select:focus,
        #catgirl-blacklist input:focus,
        #catgirl-blacklist textarea:focus {
            outline: none;
            border-color: #667eea;
            box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
        }

        #catgirl-settings input[type="checkbox"],
        #catgirl-blacklist input[type="checkbox"] {
            width: auto;
            margin-right: 8px;
            transform: scale(1.2);
            accent-color: #667eea;
        }

        #catgirl-settings input[type="range"] {
            height: 6px;
            -webkit-appearance: none;
            background: #e9ecef;
            border-radius: 3px;
            padding: 0;
        }

        #catgirl-settings input[type="range"]::-webkit-slider-thumb {
            -webkit-appearance: none;
            width: 20px;
            height: 20px;
            border-radius: 50%;
            background: #667eea;
            cursor: pointer;
            box-shadow: 0 2px 4px rgba(0,0,0,0.2);
        }

        #catgirl-settings .stats-grid {
            display: grid;
            grid-template-columns: repeat(2, 1fr);
            gap: 16px;
            margin-bottom: 20px;
        }

        #catgirl-settings .stat-item {
            text-align: center;
            padding: 16px;
            background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
            border-radius: 8px;
            border: 1px solid #dee2e6;
        }

        #catgirl-settings .stat-number {
            font-size: 24px;
            font-weight: 700;
            color: #667eea;
            margin-bottom: 4px;
        }

        #catgirl-settings .stat-label {
            font-size: 12px;
            color: #6c757d;
            font-weight: 500;
        }

        #catgirl-settings .info-section,
        #catgirl-settings .performance-section {
            background: #f8f9fa;
            padding: 16px;
            border-radius: 8px;
            border-left: 4px solid #667eea;
            margin-bottom: 16px;
        }

        #catgirl-settings .info-section h4,
        #catgirl-settings .performance-section h4,
        #catgirl-blacklist h4 {
            margin: 0 0 12px 0;
            color: #495057;
            font-size: 16px;
        }

        #catgirl-settings .info-section p,
        #catgirl-settings .performance-section p {
            margin: 6px 0;
            color: #6c757d;
            font-size: 14px;
        }

        #catgirl-settings .actions,
        #catgirl-blacklist .actions {
            display: flex;
            gap: 12px;
            flex-wrap: wrap;
            margin-top: 24px;
            padding-top: 24px;
            border-top: 1px solid #e9ecef;
        }

        #catgirl-settings button,
        #catgirl-blacklist button {
            padding: 12px 20px;
            border: none;
            border-radius: 8px;
            cursor: pointer;
            font-size: 14px;
            font-weight: 500;
            transition: all 0.3s ease;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 6px;
        }

        #catgirl-settings .btn-primary,
        #catgirl-blacklist .btn-primary {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            flex: 1;
        }

        #catgirl-settings .btn-primary:hover,
        #catgirl-blacklist .btn-primary:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
        }

        #catgirl-settings .btn-warning {
            background: linear-gradient(135deg, #ffc107 0%, #ff8c00 100%);
            color: #212529;
            flex: 1;
        }

        #catgirl-settings .btn-warning:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 12px rgba(255, 193, 7, 0.4);
        }

        #catgirl-settings .btn-secondary,
        #catgirl-blacklist .btn-secondary {
            background: linear-gradient(135deg, #6c757d 0%, #495057 100%);
            color: white;
            flex: 1;
        }

        #catgirl-settings .btn-secondary:hover,
        #catgirl-blacklist .btn-secondary:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 12px rgba(108, 117, 125, 0.4);
        }

        /* 黑名单面板特殊样式 */
        #catgirl-blacklist {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Microsoft YaHei', sans-serif;
            line-height: 1.5;
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            width: 600px;
            max-height: 80vh;
            background: #ffffff;
            border-radius: 12px;
            box-shadow: 0 8px 32px rgba(0,0,0,0.3);
            z-index: 10000;
            display: none;
            overflow: hidden;
        }

        #catgirl-blacklist .current-site-section {
            background: #f8f9fa;
            padding: 16px;
            border-radius: 8px;
            margin-bottom: 20px;
            border-left: 4px solid #28a745;
        }

        #catgirl-blacklist .current-site-info {
            color: #333;
            background: #e9ecef;
            padding: 12px;
            border-radius: 6px;
            margin-bottom: 16px;
            font-family: 'Courier New', monospace;
            font-size: 13px;
        }

        #catgirl-blacklist .action-group {
            margin-bottom: 12px;
        }

        #catgirl-blacklist .btn-danger {
            background: linear-gradient(135deg, #dc3545 0%, #c82333 100%);
            color: white;
            width: 100%;
            margin-top: 10px;
        }

        #catgirl-blacklist .btn-danger:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 12px rgba(220, 53, 69, 0.4);
        }

        #catgirl-blacklist .blacklist-section {
            margin-bottom: 24px;
        }

        #catgirl-blacklist .blacklist-item {
            background: #fff;
            border: 1px solid #dee2e6;
            border-radius: 8px;
            padding: 16px;
            margin-bottom: 12px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            transition: all 0.3s ease;
        }

        #catgirl-blacklist .blacklist-item:hover {
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
        }

        #catgirl-blacklist .blacklist-item.expired {
            background: #f8f9fa;
            border-color: #adb5bd;
            opacity: 0.7;
        }

        #catgirl-blacklist .item-info {
            flex: 1;
        }

        #catgirl-blacklist .item-domain {
            font-weight: 600;
            color: #495057;
            margin-bottom: 4px;
        }

        #catgirl-blacklist .item-details {
            font-size: 12px;
            color: #6c757d;
            line-height: 1.4;
        }

        #catgirl-blacklist .remove-btn {
            background: #dc3545;
            color: white;
            border: none;
            padding: 6px 12px;
            border-radius: 4px;
            cursor: pointer;
            font-size: 12px;
            transition: all 0.3s ease;
        }

        #catgirl-blacklist .remove-btn:hover {
            background: #c82333;
            transform: scale(1.05);
        }

        #catgirl-blacklist .empty-state {
            text-align: center;
            color: #6c757d;
            font-style: italic;
            padding: 32px;
            background: #f8f9fa;
            border-radius: 8px;
        }

        #catgirl-blacklist .blacklist-stats {
            text-align: center;
            padding-top: 16px;
            border-top: 1px solid #e9ecef;
            margin-top: 16px;
        }

        #catgirl-blacklist .blacklist-settings {
            background: #e3f2fd;
            padding: 16px;
            border-radius: 8px;
            border-left: 4px solid #2196f3;
            margin-bottom: 20px;
        }

        /* 设置面板定位样式 */
        #catgirl-settings {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            width: 500px;
            max-height: 80vh;
            background: #ffffff;
            border-radius: 12px;
            box-shadow: 0 8px 32px rgba(0,0,0,0.3);
            z-index: 10000;
            display: none;
            overflow: hidden;
        }

        /* 原文提示tooltip样式 */
        .catgirl-original-tooltip {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Microsoft YaHei', sans-serif !important;
            white-space: pre-wrap;
            box-shadow: 0 4px 12px rgba(0,0,0,0.3) !important;
            backdrop-filter: blur(8px);
        }

        /* 链接转换样式 */
        .catgirl-converted-link {
            color: #667eea !important;
            text-decoration: none !important;
        }

        .catgirl-converted-link:hover {
            opacity: 0.8;
        }
            background: linear-gradient(135deg, #ff6b9d 0%, #ff8cc8 100%);
            color: white;
            padding: 20px;
            border-radius: 20px 20px 0 0;
            display: flex;
            justify-content: space-between;
            align-items: center;
            box-shadow: 0 2px 15px rgba(255, 107, 157, 0.3);
        }

        #catgirl-block-ui .block-site-content {
            padding: 25px;
        }

        #catgirl-block-ui .site-info {
            display: flex;
            align-items: center;
            background: rgba(255, 182, 193, 0.1);
            padding: 15px;
            border-radius: 12px;
            margin-bottom: 20px;
            border: 1px solid #ffb6c1;
        }

        #catgirl-block-ui .site-icon {
            font-size: 24px;
            margin-right: 15px;
        }

        #catgirl-block-ui .site-domain {
            font-weight: bold;
            color: #d63384;
            font-size: 16px;
        }

        #catgirl-block-ui .site-path {
            color: #6c757d;
            font-size: 12px;
            margin-top: 2px;
        }

        #catgirl-block-ui .block-options {
            margin-bottom: 20px;
        }

        #catgirl-block-ui .option-group {
            margin-bottom: 15px;
        }

        #catgirl-block-ui .cute-label {
            display: flex;
            align-items: center;
            cursor: pointer;
            padding: 10px;
            border-radius: 8px;
            transition: all 0.3s ease;
        }

        #catgirl-block-ui .cute-label:hover {
            background: rgba(255, 182, 193, 0.1);
        }

        #catgirl-block-ui .radio-custom {
            width: 18px;
            height: 18px;
            border-radius: 50%;
            border: 2px solid #ffb6c1;
            margin-right: 10px;
            position: relative;
            transition: all 0.3s ease;
        }

        #catgirl-block-ui input[type="radio"]:checked + .radio-custom {
            background: #ff69b4;
            border-color: #ff69b4;
        }

        #catgirl-block-ui input[type="radio"]:checked + .radio-custom::after {
            content: '';
            width: 6px;
            height: 6px;
            background: white;
            border-radius: 50%;
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
        }

        #catgirl-block-ui input[type="radio"] {
            display: none;
        }

        #catgirl-block-ui .option-text {
            font-weight: 500;
            color: #495057;
        }

        #catgirl-block-ui .cute-label-block {
            display: block;
            margin-bottom: 8px;
            font-weight: 500;
            color: #d63384;
        }

        #catgirl-block-ui .cute-select,
        #catgirl-block-ui .cute-input {
            width: 100%;
            padding: 12px;
            border: 2px solid #ffb6c1;
            border-radius: 10px;
            font-size: 14px;
            transition: all 0.3s ease;
            background: rgba(255, 255, 255, 0.8);
        }

        #catgirl-block-ui .cute-select:focus,
        #catgirl-block-ui .cute-input:focus {
            outline: none;
            border-color: #ff69b4;
            box-shadow: 0 0 0 3px rgba(255, 105, 180, 0.1);
        }

        #catgirl-block-ui .block-actions {
            display: flex;
            gap: 12px;
            margin-top: 25px;
        }

        #catgirl-block-ui .btn-block-confirm {
            flex: 1;
            padding: 12px 20px;
            background: linear-gradient(135deg, #dc3545 0%, #c82333 100%);
            color: white;
            border: none;
            border-radius: 10px;
            font-weight: 500;
            cursor: pointer;
            transition: all 0.3s ease;
        }

        #catgirl-block-ui .btn-block-confirm:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 15px rgba(220, 53, 69, 0.4);
        }

        #catgirl-block-ui .btn-block-cancel {
            flex: 1;
            padding: 12px 20px;
            background: linear-gradient(135deg, #6c757d 0%, #495057 100%);
            color: white;
            border: none;
            border-radius: 10px;
            font-weight: 500;
            cursor: pointer;
            transition: all 0.3s ease;
        }

        #catgirl-block-ui .btn-block-cancel:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 15px rgba(108, 117, 125, 0.4);
        }

        /* 统计UI样式 */
        #catgirl-stats-ui .stats-header {
            background: linear-gradient(135deg, #20c997 0%, #17a2b8 100%);
            color: white;
            padding: 20px;
            border-radius: 20px 20px 0 0;
            display: flex;
            justify-content: space-between;
            align-items: center;
            box-shadow: 0 2px 15px rgba(32, 201, 151, 0.3);
        }

        #catgirl-stats-ui .stats-content {
            padding: 25px;
        }

        #catgirl-stats-ui .stats-cards {
            display: grid;
            grid-template-columns: repeat(2, 1fr);
            gap: 15px;
            margin-bottom: 25px;
        }

        #catgirl-stats-ui .stat-card {
            background: rgba(32, 201, 151, 0.1);
            border: 1px solid #20c997;
            border-radius: 12px;
            padding: 15px;
            display: flex;
            align-items: center;
            transition: all 0.3s ease;
        }

        #catgirl-stats-ui .stat-card:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 15px rgba(32, 201, 151, 0.2);
        }

        #catgirl-stats-ui .stat-icon {
            font-size: 24px;
            margin-right: 12px;
        }

        #catgirl-stats-ui .stat-number {
            font-size: 24px;
            font-weight: bold;
            color: #17a2b8;
            line-height: 1;
        }

        #catgirl-stats-ui .stat-label {
            font-size: 12px;
            color: #6c757d;
            margin-top: 2px;
        }

        #catgirl-stats-ui .system-info {
            background: rgba(23, 162, 184, 0.1);
            border: 1px solid #17a2b8;
            border-radius: 12px;
            padding: 20px;
            margin-bottom: 20px;
        }

        #catgirl-stats-ui .info-row {
            display: flex;
            justify-content: space-between;
            margin-bottom: 8px;
            align-items: center;
        }

        #catgirl-stats-ui .info-row:last-child {
            margin-bottom: 0;
        }

        #catgirl-stats-ui .info-label {
            font-weight: 500;
            color: #495057;
        }

        #catgirl-stats-ui .info-value {
            color: #17a2b8;
            font-weight: 500;
        }

        #catgirl-stats-ui .status-running {
            color: #28a745;
        }

        #catgirl-stats-ui .status-paused {
            color: #ffc107;
        }

        #catgirl-stats-ui .status-blocked {
            color: #dc3545;
        }

        #catgirl-stats-ui .stats-actions {
            display: flex;
            gap: 12px;
        }

        #catgirl-stats-ui .btn-stats-refresh,
        #catgirl-stats-ui .btn-stats-export {
            flex: 1;
            padding: 12px 20px;
            border: none;
            border-radius: 10px;
            font-weight: 500;
            cursor: pointer;
            transition: all 0.3s ease;
        }

        #catgirl-stats-ui .btn-stats-refresh {
            background: linear-gradient(135deg, #20c997 0%, #17a2b8 100%);
            color: white;
        }

        #catgirl-stats-ui .btn-stats-refresh:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 15px rgba(32, 201, 151, 0.4);
        }

        #catgirl-stats-ui .btn-stats-export {
            background: linear-gradient(135deg, #6f42c1 0%, #6610f2 100%);
            color: white;
        }

        #catgirl-stats-ui .btn-stats-export:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 15px rgba(111, 66, 193, 0.4);
        }

        /* 黑名单搜索样式 */
        #catgirl-blacklist .search-section {
            margin-bottom: 15px;
        }

        #catgirl-blacklist .search-input {
            width: 100%;
            padding: 10px 15px;
            border: 2px solid #e9ecef;
            border-radius: 8px;
            font-size: 14px;
            transition: all 0.3s ease;
            background: #fff;
        }

        #catgirl-blacklist .search-input:focus {
            outline: none;
            border-color: #667eea;
            box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
        }

        #catgirl-blacklist .search-hint {
            font-size: 12px;
            color: #6c757d;
            margin-top: 5px;
        }

        #catgirl-blacklist .blacklist-scroll {
            max-height: 300px;
            overflow-y: auto;
            border: 1px solid #e9ecef;
            border-radius: 8px;
            padding: 10px;
        }

        #catgirl-blacklist .search-highlight {
            background: #fff3cd;
            color: #856404;
            padding: 1px 3px;
            border-radius: 3px;
            font-weight: 500;
        }

        /* 响应式设计 */
        @media (max-width: 700px) {
            #catgirl-settings,
            #catgirl-blacklist {
                width: 95vw;
                max-height: 90vh;
            }

            #catgirl-settings .tab-container {
                flex-direction: column;
            }

            #catgirl-settings .tab-btn {
                flex: none;
            }

            #catgirl-settings .actions,
            #catgirl-blacklist .actions {
                flex-direction: column;
            }

            #catgirl-settings .stats-grid {
                grid-template-columns: 1fr;
            }

            #catgirl-blacklist .blacklist-item {
                flex-direction: column;
                align-items: stretch;
                gap: 12px;
            }

            #catgirl-blacklist .remove-btn {
                align-self: flex-end;
            }
        }

        /* 滚动条美化 */
        #catgirl-settings ::-webkit-scrollbar,
        #catgirl-blacklist ::-webkit-scrollbar {
            width: 8px;
        }

        #catgirl-settings ::-webkit-scrollbar-track,
        #catgirl-blacklist ::-webkit-scrollbar-track {
            background: #f1f1f1;
            border-radius: 4px;
        }

        #catgirl-settings ::-webkit-scrollbar-thumb,
        #catgirl-blacklist ::-webkit-scrollbar-thumb {
            background: #c1c1c1;
            border-radius: 4px;
        }

        #catgirl-settings ::-webkit-scrollbar-thumb:hover,
        #catgirl-blacklist ::-webkit-scrollbar-thumb:hover {
            background: #a8a8a8;
        }
    `);

    // ===== 全局调试接口 =====
    window.catgirlApp = {
        get app() {
            return catgirlApp;
        },
        get blacklistManager() {
            return catgirlApp?.blacklistManager;
        },
        get config() {
            return CONFIG;
        },
        get version() {
            return SCRIPT_VERSION;
        },
        clearCache: function() {
            if (catgirlApp && typeof catgirlApp.clearCache === 'function') {
                catgirlApp.clearCache();
            }
        }
    };

})();