B站总赞数统计器

🐾 全网首发原创脚本嗷~ 这是帮你统计B站总赞数的小工具!生成报告,还有超多头衔等你解锁!(ฅ´ω`ฅ)

当前为 2025-10-19 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         B站总赞数统计器
// @namespace    https://greasyfork.org/zh-CN/scripts/553065
// @version      1.0
// @description  🐾 全网首发原创脚本嗷~ 这是帮你统计B站总赞数的小工具!生成报告,还有超多头衔等你解锁!(ฅ´ω`ฅ)
// @author       小小电子xxdz
// @match        https://message.bilibili.com/*
// @grant        GM_addStyle
// @icon         https://article.biliimg.com/bfs/new_dyn/356e12a744df26a2f38a158da87c364b3461569935575626.png
// @license      GPL
// @homepage     https://space.bilibili.com/3461569935575626
// @supportURL   https://miku66ccff.freeflarum.com
// ==/UserScript==

console.log('BiliLike-Counterの脚本已加载')
// 添加Font Awesome样式和正在滚动动画
GM_addStyle(`
    @import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css');
@keyframes scrollProgress {
    0% {
        background-position: 150% 0%;
    }
    100% {
        background-position: -150% 0%;
    }
}
`);

(function() {
    'use strict';

    let isScrolling = false;
    let scrollInterval;
    let lastItemCount = 0;
    let noNewItemsTimer;
    let scrollAttempts = 0;
    let realTimeStats = false;
    let scrollSpeed = 300;
    let performanceMode = false;
    let imageBlockObserver = null;
    let activeWindow = null;
    let isGeneratingReport = false;
    // 保存原始图片URL的映射表
    const originalImageSources = new Map();

    // 需要保留的头像图片特征
    const preserveAvatarUrls = [
        "//i1.hdslb.com/bfs/face/87e609940c74ed2e7dcf6b2b19b3029f8e1566e1.jpg@240w_240h_1c_1s_!web-avatar-nav.webp",
        "https://i1.hdslb.com/bfs/face/87e609940c74ed2e7dcf6b2b19b3029f8e1566e1.jpg@240w_240h_1c_1s_!web-avatar-nav.webp",
        "https://i1.hdslb.com/bfs/face/87e609940c74ed2e7dcf6b2b19b3029f8e1566e1.jpg"
    ];

// 创建打开脚本的小按钮
function createOpenScriptButton() {
    const openButton = document.createElement('div');
    openButton.id = 'openScriptButton';
    openButton.style.cssText = `
        position: fixed;
        top: 80px; /* 向下移动到距离顶部80px的位置 */
        left: 20px;
        width: 50px;
        height: 50px;
        background: #00a1d6;
        color: white;
        border-radius: 50%;
        display: flex;
        justify-content: center;
        align-items: center;
        cursor: pointer;
        z-index: 9999;
        box-shadow: 0 2px 8px rgba(0,0,0,0.3);
        font-size: 24px;
        font-weight: bold;
        transition: all 0.3s ease;
        user-select: none;
        overflow: hidden;
    `;

    // 使用图片图标
    openButton.innerHTML = `
        <img src="https://article.biliimg.com/bfs/new_dyn/356e12a744df26a2f38a158da87c364b3461569935575626.png"
             style="width: 30px; height: 28.3px; object-fit: contain;
                    filter: drop-shadow(0 0 3px white) drop-shadow(0 0 5px white);">
    `;

    openButton.title = '打开B站总赞数统计器(¬ω¬)';

    // 鼠标悬停效果
    openButton.addEventListener('mouseenter', function() {
        this.style.transform = 'scale(1.1)';
        this.style.background = '#fb7299';
    });
    openButton.addEventListener('mouseleave', function() {
        this.style.transform = 'scale(1)';
        this.style.background = '#00a1d6';
    });

    // 点击打开主窗口
    openButton.addEventListener('click', function() {
        const existingWindow = document.getElementById('totalLikesWindow');
        if (!existingWindow) {
            createFloatingWindow();
            // 隐藏小按钮
            openButton.style.display = 'none';
        }
    });

    document.body.appendChild(openButton);
    return openButton;
}

// 创建主控制窗口
function createFloatingWindow() {
    const floatingWindow = document.createElement('div');
    floatingWindow.id = 'totalLikesWindow';
    floatingWindow.style.cssText = `
        position: fixed;
        top: 100px;
        left: 20px;
        width: 380px;
        background: white;
        border: 2px solid #00a1d6;
        border-radius: 0px;
        box-shadow: 0 2px 8px rgba(0,0,0,0.15);
        z-index: 10000;
        font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", sans-serif;
        user-select: none;
        opacity: 0;
        transform: scale(0.8);
        transition: all 0.3s ease-out;
    `;

        const titleBar = document.createElement('div');
        titleBar.style.cssText = `
            background: #00a1d6;
            color: white;
            padding: 12px 16px;
            border-radius: 0px;
            font-weight: bold;
            font-size: 16px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            cursor: move;
        `;
titleBar.innerHTML = `
    <span style="display: flex; align-items: center;">
        <img src="https://article.biliimg.com/bfs/new_dyn/356e12a744df26a2f38a158da87c364b3461569935575626.png"
             style="width: 30px; height: 28.3px; object-fit: contain; margin-right: 8px; filter: drop-shadow(0 0 3px white) drop-shadow(0 0 5px white);">
        B站总赞数统计器
    </span>
    <span style="cursor: pointer; font-size: 18px;" id="closeWindow">×</span>
`;

        const contentContainer = document.createElement('div');
        contentContainer.style.cssText = `padding: 1px; position: relative;`;

        const content = document.createElement('div');
        content.id = 'windowContent';
        content.style.cssText = `cursor: default;`;
        content.innerHTML = `
            <div style="text-align: center; margin-bottom: 15px; position: relative;">
                <div style="font-size: 14px; color: #666; margin-bottom: 5px;">已统计的总赞数OwO</div>
                <div style="position: relative; display: inline-block;">
                    <div style="font-size: 32px; font-weight: bold; color: #00a1d6;" id="totalLikesCount">0</div>
                    <div id="chineseNumber" style="position: absolute; bottom: 2px; right: 0; transform: translateX(100%); font-size: 12px; color: #999; font-weight: normal; white-space: nowrap; padding-left: 5px;">零</div>
                </div>
            </div>
<div style="position: relative; margin-bottom: 15px; min-height: 86.5px;">
    <!-- 统计数据 - 保持居中 -->
    <div style="font-size: 12px; color: #999; text-align: center; position: relative; z-index: 2;">
        <div>动态赞数: <span id="dynamicLikes">0</span></div>
        <div>视频赞数: <span id="videoLikes">0</span></div>
        <div>评论赞数: <span id="commentLikes">0</span></div>
        <div>弹幕赞数: <span id="danmakuLikes">0</span></div>
    </div>

    <!-- 左下角图片 -->
<img src="https://article.biliimg.com/bfs/new_dyn/c7ec01517b138983f344bce5362f57fc3461569935575626.png"
     style="position: absolute; left: 0; bottom: -15px; width: 94px; height: 86.5px; object-fit: contain; z-index: 1;"
     alt="装饰图片">
</div>

            <div style="margin-bottom: 15px; padding: 10px; background: #f5f5f5; border-radius: 0px;">
                <div style="margin-bottom: 10px;">
                    <label style="display: flex; align-items: center; cursor: pointer;">
                        <input type="checkbox" id="realTimeStats" style="margin-right: 8px;">
                        <span style="font-size: 14px;">滚动时就实时统计数据</span>
                    </label>
                </div>
                <div style="margin-bottom: 10px;">
                    <label style="display: flex; align-items: center; cursor: pointer;">
                        <input type="checkbox" id="performanceMode" style="margin-right: 8px;">
                        <span style="font-size: 14px;">性能模式 (会禁止列表加载图片噢)</span>
                    </label>
                </div>
                <div>
                    <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 5px;">
                        <span style="font-size: 14px;">滚动速度(根据设备性能调整嗷):</span>
                        <span id="speedValue" style="font-size: 12px; color: #666;">${scrollSpeed}ms</span>
                    </div>
                    <div style="position: relative;">
                        <input type="range" id="scrollSpeed" min="100" max="1000" step="50" value="${scrollSpeed}"
                               style="width: 100%; height: 6px; border-radius: 0px; background: #ddd; outline: none; -webkit-appearance: none;">
                    </div>
                    <div style="display: flex; justify-content: space-between; font-size: 10px; color: #999; margin-top: 2px;">
                        <span>快</span>
                        <span>慢</span>
                    </div>
                </div>
            </div>

            <div style="background: #fff8e1; border: 1px solid #ffd54f; padding: 8px; margin-bottom: 15px; border-radius: 0px;">
                <div style="font-size: 9px; color: #e65100; text-align: center; line-height: 1.2;">
                    ⚠️ 提示:滚动时请保持当前标签页处于显示状态,也不要最小化浏览器嗷
                </div>
            </div>

            <button id="countLikesBtn" style="
                width: 100%;
                padding: 10px;
                background: #00a1d6;
                color: white;
                border: none;
                border-radius: 0px;
                font-size: 14px;
                cursor: pointer;
                margin-bottom: 8px;
                transition: background 0.3s;
            ">直接统计已加载的数据</button>
            <button id="autoScrollBtn" style="
                width: 100%;
                padding: 10px;
                background: #ff6b6b;
                color: white;
                border: none;
                border-radius: 0px;
                font-size: 14px;
                cursor: pointer;
                margin-bottom: 8px;
                transition: background 0.3s;
            ">【推荐】自动滚动加载(完成后自动统计)</button>
            <button id="viewReportBtn" style="
                width: 100%;
                padding: 10px;
                background: #fb7299;
                color: white;
                border: none;
                border-radius: 0px;
                font-size: 14px;
                cursor: pointer;
                display: none;
                transition: background 0.3s;
            ">查看专属报告(可分享)</button>

<div style="display: flex; justify-content: space-between; align-items: center; margin-top: 10px;">
    <div style="font-size: 10px; color: #999;">
        内部版本<span style="background: #66ccff; color: white; padding: 1px 3px; border-radius: 2px; margin: 0 2px;">v6.5</span>正式版本<span style="background: #66ccff; color: white; padding: 1px 3px; border-radius: 2px; margin: 0 2px;">v1.0</span>
    </div>
    <div style="font-size: 10px; color: #999; cursor: pointer;" id="authorInfoBtn">脚本作者:小小电子xxdz</div>
</div>

<div id="status" style="font-size: 12px; color: #666; text-align: center; margin-top: 10px;"></div>
<div id="scrollStatus" style="font-size: 11px; color: #999; text-align: center; margin-top: 5px;"></div>
`;
        contentContainer.appendChild(content);
        floatingWindow.appendChild(titleBar);
        floatingWindow.appendChild(contentContainer);
        document.body.appendChild(floatingWindow);

        customizeSlider();
        makeDraggable(floatingWindow, titleBar);
        setupWindowFocus(floatingWindow);

        setTimeout(() => {
            floatingWindow.style.opacity = '1';
            floatingWindow.style.transform = 'scale(1)';
        }, 10);

        // 修改关闭窗口的函数,添加显示小按钮的逻辑
        function closeWindowWithAnimation(windowElement) {
            windowElement.style.opacity = '0';
            windowElement.style.transform = 'scale(0.8)';
            setTimeout(() => {
                windowElement.remove();
                // 窗口关闭后显示小按钮
                const openButton = document.getElementById('openScriptButton');
                if (openButton) {
                    openButton.style.display = 'flex';
                }
            }, 300);
        }

        // 修改关闭按钮的事件监听
        document.getElementById('closeWindow').addEventListener('click', () => closeWindowWithAnimation(floatingWindow));

        document.getElementById('realTimeStats').addEventListener('change', () => {
            realTimeStats = document.getElementById('realTimeStats').checked;
            updateScrollStatus(`实时统计: ${realTimeStats ? '开启咯' : '关闭啦'}`);
        });
        document.getElementById('performanceMode').addEventListener('change', () => {
            if (isScrolling) {
                stopAutoScroll();
                setTimeout(() => {
                    performanceMode = document.getElementById('performanceMode').checked;
                    togglePerformanceMode(performanceMode);
                    updateScrollStatus(`性能模式: ${performanceMode ? '开启咯' : '关闭啦'}`);
                    startAutoScroll();
                }, 300);
            } else {
                performanceMode = document.getElementById('performanceMode').checked;
                togglePerformanceMode(performanceMode);
                updateScrollStatus(`性能模式: ${performanceMode ? '开启咯' : '关闭啦'}`);
            }
        });
        document.getElementById('viewReportBtn').addEventListener('click', showReport);
        document.getElementById('authorInfoBtn').addEventListener('click', showAuthorInfo);

        const speedSlider = document.getElementById('scrollSpeed');
        const speedValue = document.getElementById('speedValue');
        speedSlider.addEventListener('input', function() {
            scrollSpeed = parseInt(this.value);
            speedValue.textContent = scrollSpeed + 'ms';
            if (isScrolling) {
                stopAutoScroll();
                setTimeout(startAutoScroll, 100);
            }
        });

        // 初始化页面检查
        if (!document.querySelector('.love-list')) {
// 不在"收到的赞"页面,显示提示呢
setTimeout(() => {
    const status = document.getElementById('status');
    if (status) {
        status.innerHTML = `
            <div style="color: #ff6b6b; text-align: center; font-size: 14px; margin-bottom: 8px; font-weight: bold;">
                ⚠️ 当前不在"收到的赞"页面嗷
            </div>
            <div style="color: #666; text-align: center; font-size: 12px; margin-bottom: 10px;">
                请先切换到"收到的赞"页面再使用统计功能喵~
            </div>
            <button id="switchToLovePageMain" style="
                background: #00a1d6;
                color: white;
                border: none;
                padding: 8px 15px;
                border-radius: 3px;
                cursor: pointer;
                font-size: 12px;
                width: 200px;
            ">点击切换到"收到的赞"页面!</button>
        `;

        // 添加切换按钮事件
        document.getElementById('switchToLovePageMain').addEventListener('click', switchToLovePage);
    }
}, 100);
        }

        simulateHoverToLoadUserInfo();
        updateChineseNumber(0);

        return floatingWindow;
    }

    // 关闭窗口の动画
    function closeWindowWithAnimation(windowElement) {
        windowElement.style.opacity = '0';
        windowElement.style.transform = 'scale(0.8)';
        setTimeout(() => windowElement.remove(), 300);
    }

    // 阿B小电视图片滑块样式
    function customizeSlider() {
        const style = document.createElement('style');
        style.textContent = `
            #scrollSpeed::-webkit-slider-thumb {
                -webkit-appearance: none;
                width: 16px;
                height: 16px;
                background: url('https://article.biliimg.com/bfs/new_dyn/cf84ec14a28d0585c3fe7ff8057f487f3461569935575626.png') center/contain no-repeat;
                cursor: pointer;
                border: none;
                border-radius: 0;
            }
            #scrollSpeed::-moz-range-thumb {
                width: 16px;
                height: 16px;
                background: url('https://article.biliimg.com/bfs/new_dyn/cf84ec14a28d0585c3fe7ff8057f487f3461569935575626.png') center/contain no-repeat;
                cursor: pointer;
                border: none;
                border-radius: 0;
            }
        `;
        document.head.appendChild(style);
    }

    // 设置窗口焦点
    function setupWindowFocus(windowElement) {
        windowElement.addEventListener('mousedown', () => bringToFront(windowElement));
    }

    // 窗口置顶
    function bringToFront(windowElement) {
        if (activeWindow === windowElement) return;
        if (activeWindow) activeWindow.style.zIndex = '10000';
        windowElement.style.zIndex = '10001';
        activeWindow = windowElement;
    }

    // 中文数字转换(中文数字是为了让大家一眼就可以看到单位,方便快捷)
    function numberToChinese(num) {
        if (num === 0) return '零';
        if (num >= 10000) {
            const wan = Math.floor(num / 10000);
            const remainder = num % 10000;
            let result = numberToChinese(wan) + '万';
            if (remainder > 0) result += remainder < 1000 ? '零' + numberToChinese(remainder) : numberToChinese(remainder);
            return result;
        }
        const digits = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'];
        const units = ['', '十', '百', '千'];
        if (num < 10) return digits[num];
        if (num < 20) return num === 10 ? '十' : '十' + digits[num % 10];
        let str = '', temp = num, unitIndex = 0, lastZero = false;
        while (temp > 0) {
            const n = temp % 10;
            if (n === 0) {
                if (!lastZero && unitIndex !== 0) {
                    str = digits[0] + str;
                    lastZero = true;
                }
            } else {
                str = digits[n] + units[unitIndex] + str;
                lastZero = false;
            }
            unitIndex++;
            temp = Math.floor(temp / 10);
        }
        str = str.replace(/^一十/, '十').replace(/零+$/, '').replace(/零[千百十]/g, '零').replace(/零零/g, '零');
        return str;
    }

    // 更新中文数字显示
    function updateChineseNumber(num) {
        const chineseElement = document.getElementById('chineseNumber');
        if (chineseElement) chineseElement.textContent = numberToChinese(num);
    }

    // 模拟悬浮加载用户信息
    function simulateHoverToLoadUserInfo() {
        const headerAvatar = document.querySelector('#message-pc-header .header-entry-mini, .header-avatar-wrap, .bili-avatar');
        if (headerAvatar) {
            headerAvatar.dispatchEvent(new MouseEvent('mouseenter', { bubbles: true }));
            headerAvatar.dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));
            setTimeout(() => {
                headerAvatar.dispatchEvent(new MouseEvent('mouseleave', { bubbles: true }));
                headerAvatar.dispatchEvent(new MouseEvent('mouseout', { bubbles: true }));
            }, 1000);
        }
    }

    // 获取用户信息 - 关键修复:确保获取原始头像URL
    function getUserInfo() {
        let nickname = 'B站用户', avatarUrl = 'https://i0.hdslb.com/bfs/face/member/noface.jpg';
        const nicknameSelectors = [
            '.nickname-item.light', '.header-avatar-wrap .name', '.bili-dropdown .name',
            '.navigation-bar .user-name', '#message-pc-header .nickname-item', '.mini-header .name'
        ];
        for (const selector of nicknameSelectors) {
            const el = document.querySelector(selector);
            if (el && el.textContent.trim()) {
                nickname = el.textContent.trim();
                break;
            }
        }
        const avatarSelectors = [
            '.bili-avatar-img', '.header-avatar-wrap img', '.bili-avatar-face', '.header-avatar img'
        ];
        for (const selector of avatarSelectors) {
            const el = document.querySelector(selector);
            if (el) {
                // 优先从我们保存的原始URL映射表中获取
                let src = originalImageSources.get(el) ||
                          el.getAttribute('data-original-src') ||
                          el.getAttribute('data-src') ||
                          el.src;

                if (src && src.includes('data:image/gif')) {
                    src = originalImageSources.get(el) ||
                          el.getAttribute('data-original-src') ||
                          el.getAttribute('data-src');
                }

                if (src && !src.includes('noface') && !src.includes('base64')) {
                    src = src.startsWith('//') ? 'https:' + src :
                          src.startsWith('/') ? 'https:' + src : src;
                    avatarUrl = src;
                    break;
                }
            }
        }
        return { nickname, avatarUrl };
    }

    // 显示作者小小电子xxdzの信息
    function showAuthorInfo() {
        const authorWindow = document.createElement('div');
        authorWindow.id = 'authorInfoWindow';
        authorWindow.style.cssText = `
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%) scale(0.8);
            width: 400px;
            background: white;
            border: 2px solid #00a1d6;
            border-radius: 0px;
            box-shadow: 0 4px 20px rgba(0, 161, 214, 0.3);
            z-index: 10002;
            font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", sans-serif;
            overflow: hidden;
            user-select: none;
            opacity: 0;
            transition: all 0.3s ease-out;
        `;

        const titleBar = document.createElement('div');
        titleBar.style.cssText = `
            background: #00a1d6;
            color: white;
            padding: 12px 16px;
            font-weight: bold;
            font-size: 16px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            cursor: move;
        `;
        titleBar.innerHTML = `
          <span><i class="fa fa-paw"></i> 关于作者</span>
            <span style="cursor: pointer; font-size: 18px;" id="closeAuthorWindow">×</span>
        `;

const content = document.createElement('div');
content.style.cssText = `padding: 20px; cursor: default;`;
content.innerHTML = `
    <div style="display: flex; align-items: flex-start; margin-bottom: 20px; cursor: pointer;" id="authorProfile">
        <img src="https://i1.hdslb.com/bfs/face/87e609940c74ed2e7dcf6b2b19b3029f8e1566e1.jpg"
             style="width: 60px; height: 60px; border-radius: 3px; margin-right: 15px;">
        <div style="flex: 1;">
            <div style="font-size: 18px; font-weight: bold; color: #00a1d6; margin-bottom: 5px;">小小电子xxdz</div>
            <div style="font-size: 14px; color: #666; line-height: 1.4;">我叫電籽,一只爱好电脑 术曲滴小狼‖XXDZ工作室创始人</div>
        </div>
    </div>

    <div style="display: grid; grid-template-columns: 1fr; gap: 10px; margin-bottom: 20px;">
        <a href="https://www.bilibili.com/video/BV1PtTDzQE6c" target="_blank" style="
            display: block;
            padding: 10px;
            background: #fb7299;
            color: white;
            text-align: center;
            text-decoration: none;
            border-radius: 0px;
            font-size: 14px;
            transition: background 0.3s;
        " onmouseover="this.style.background='#ff8ab0'" onmouseout="this.style.background='#fb7299'">
            观看此插件演示视频
        </a>

        <a href="https://greasyfork.org/zh-CN/scripts/553065" target="_blank" style="
            display: block;
            padding: 10px;
            background: #23c16b;
            color: white;
            text-align: center;
            text-decoration: none;
            border-radius: 0px;
            font-size: 14px;
            transition: background 0.3s;
        " onmouseover="this.style.background='#2cd67a'" onmouseout="this.style.background='#23c16b'">
            检查更新 <span style="font-size: 12px;">(需要VPN)</span>
        </a>

        <a href="https://miku66ccff.freeflarum.com/blog/176-bililike-counter-update-page" target="_blank" style="
            display: block;
            padding: 10px;
            background: #ffb11b;
            color: white;
            text-align: center;
            text-decoration: none;
            border-radius: 0px;
            font-size: 14px;
            transition: background 0.3s;
        " onmouseover="this.style.background='#ffc04d'" onmouseout="this.style.background='#ffb11b'">
            通过UP网站检查更新 <span style="font-size: 12px;">(无需VPN,但需要手动复制源码)</span>
        </a>

        <a href="https://github.com/xxdz-Official/BiliLike-Counter" target="_blank" style="
            display: block;
            padding: 10px;
            background: #333;
            color: white;
            text-align: center;
            text-decoration: none;
            border-radius: 0px;
            font-size: 14px;
            transition: background 0.3s;
        " onmouseover="this.style.background='#555'" onmouseout="this.style.background='#333'">
            <i class="fa fa-github" style="margin-right: 8px;"></i>前往GitHub仓库
        </a>
    </div>

    <button id="closeAuthorBtn" style="
        width: 100%;
        padding: 10px;
        background: #00a1d6;
        color: white;
        border: none;
        border-radius: 0px;
        font-size: 14px;
        cursor: pointer;
        transition: background 0.3s;
    " onmouseover="this.style.background='#33b4de'" onmouseout="this.style.background='#00a1d6'">
        关闭窗口
    </button>
`;

        authorWindow.appendChild(titleBar);
        authorWindow.appendChild(content);
        document.body.appendChild(authorWindow);

        makeDraggable(authorWindow, titleBar);
        setupWindowFocus(authorWindow);
        bringToFront(authorWindow);

        setTimeout(() => {
            authorWindow.style.opacity = '1';
            authorWindow.style.transform = 'translate(-50%, -50%) scale(1)';
        }, 10);

        document.getElementById('authorProfile').addEventListener('click', () => window.open('https://space.bilibili.com/3461569935575626', '_blank'));
        document.getElementById('closeAuthorWindow').addEventListener('click', () => closeWindowWithAnimation(authorWindow));
        document.getElementById('closeAuthorBtn').addEventListener('click', () => closeWindowWithAnimation(authorWindow));
    }

    // 拖动逻辑
    function makeDraggable(element, handle) {
        let isDragging = false, startX, startY, initialX, initialY;
        handle.addEventListener('mousedown', e => {
            isDragging = true;
            startX = e.clientX;
            startY = e.clientY;
            const rect = element.getBoundingClientRect();
            initialX = rect.left;
            initialY = rect.top;
            element.style.position = 'fixed';
            element.style.left = initialX + 'px';
            element.style.top = initialY + 'px';
            element.style.transform = 'none';
            bringToFront(element);
            e.preventDefault();
        });
        document.addEventListener('mousemove', e => {
            if (!isDragging) return;
            const dx = e.clientX - startX;
            const dy = e.clientY - startY;
            element.style.left = (initialX + dx) + 'px';
            element.style.top = (initialY + dy) + 'px';
        });
        document.addEventListener('mouseup', () => isDragging = false);
    }

    // 判断是否为需要保留的头像图片
    function isPreservedAvatar(src) {
        if (!src) return false;
        const normalizedSrc = src.replace(/^https?:/, '');
        return preserveAvatarUrls.some(url => normalizedSrc.includes(url.replace(/^https?:/, '')));
    }

    // 性能模式开关(保留指定作者和用户头像噢)
    function togglePerformanceMode(enabled) {
        if (isGeneratingReport) return;

        if (enabled) {
            // 保存原始函数(仅在未保存时保存)
            if (!window.originalImage) {
                window.originalImage = window.Image;
            }
            if (!window.originalAddEventListener) {
                window.originalAddEventListener = EventTarget.prototype.addEventListener;
            }

            // 重写Image构造函数
            window.Image = function() {
                const img = new window.originalImage();
                Object.defineProperty(img, 'src', {
                    set: function(value) {
                        // 保存原始URL
                        originalImageSources.set(this, value);

                        // 如果是需要保留的头像,则正常加载
                        if (isPreservedAvatar(value)) {
                            this.setAttribute('data-original-src', value);
                            this.__proto__.src = value;
                        } else {
                            // 其他图片阻止加载
                            this.setAttribute('data-blocked-src', value);
                            this.__proto__.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
                        }
                    },
                    get: function() {
                        const blockedSrc = this.getAttribute('data-blocked-src');
                        const originalSrc = this.getAttribute('data-original-src');
                        return originalSrc || blockedSrc || 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
                    }
                });
                return img;
            };

            // 拦截事件监听器
            EventTarget.prototype.addEventListener = function(type, listener, options) {
                if (this.tagName === 'IMG' && (type === 'load' || type === 'error')) {
                    // 保留的头像不拦截事件
                    if (isPreservedAvatar(this.src) || isPreservedAvatar(this.getAttribute('data-src'))) {
                        return window.originalAddEventListener.call(this, type, listener, options);
                    }
                    return;
                }
                return window.originalAddEventListener.call(this, type, listener, options);
            };

            // 立即处理现有图片
            blockAllExistingImages();

            // 启动观察器监控新图片
            startImageBlockingObserver();

            updateScrollStatus('性能模式已开启,会保护某些图片不被侵犯>w<');
        } else {
            // 恢复原始函数(仅在已保存时恢复)
            if (window.originalImage) {
                window.Image = window.originalImage;
            }
            if (window.originalAddEventListener) {
                EventTarget.prototype.addEventListener = window.originalAddEventListener;
            }

            // 停止观察器
            stopImageBlockingObserver();

            // 恢复图片
            restoreBlockedImages();

            // 清空URL映射表
            originalImageSources.clear();

            updateScrollStatus('性能模式已关闭 - 列表の图片加载已恢复');
        }
    }

    // 启动图片阻止观察器
    function startImageBlockingObserver() {
        if (imageBlockObserver) {
            imageBlockObserver.disconnect();
        }

        imageBlockObserver = new MutationObserver(function(mutations) {
            if (isGeneratingReport) return;

            mutations.forEach(function(mutation) {
                if (mutation.type === 'childList') {
                    mutation.addedNodes.forEach(function(node) {
                        if (node.nodeType === 1) {
                            if (node.tagName === 'IMG' || node.tagName === 'PICTURE' || node.tagName === 'SOURCE') {
                                blockImageElement(node);
                            }
                            const images = node.querySelectorAll ? node.querySelectorAll('img, picture, source') : [];
                            images.forEach(blockImageElement);
                        }
                    });
                }
            });
        });

        imageBlockObserver.observe(document.body, {
            childList: true,
            subtree: true
        });
    }

    // 停止图片阻止观察器
    function stopImageBlockingObserver() {
        if (imageBlockObserver) {
            imageBlockObserver.disconnect();
            imageBlockObserver = null;
        }
    }

// 阻止单个图片元素(保留某头像)
function blockImageElement(element) {
    if (isGeneratingReport) return;

    if (element.tagName === 'IMG') {
        const src = element.src || element.getAttribute('data-src') || '';

        // 新增:如果是脚本内的图片,不拦截
        if (element.closest('#totalLikesWindow, #authorInfoWindow, #bilibiliReportWindow')) {
            return;
        }

        // 保存原始URL
        if (!originalImageSources.has(element)) {
            originalImageSources.set(element, src);
        }

        // 保留头像图片
        if (isPreservedAvatar(src)) {
            return;
        }

        if (!element.hasAttribute('data-original-src')) {
            element.setAttribute('data-original-src', src);
        }
        element.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
        element.srcset = '';
    } else if (element.tagName === 'SOURCE') {
        // 新增:如果是脚本内的source元素,不拦截
        if (element.closest('#totalLikesWindow, #authorInfoWindow, #bilibiliReportWindow')) {
            return;
        }

        const srcset = element.srcset || '';
        if (!preserveAvatarUrls.some(url => srcset.includes(url))) {
            element.srcset = '';
        }
    } else if (element.tagName === 'PICTURE') {
        // 新增:如果是脚本内的picture元素,不拦截
        if (element.closest('#totalLikesWindow, #authorInfoWindow, #bilibiliReportWindow')) {
            return;
        }

        const sources = element.querySelectorAll('source');
        sources.forEach(source => {
            const srcset = source.srcset || '';
            if (!preserveAvatarUrls.some(url => srcset.includes(url))) {
                source.srcset = '';
            }
        });
        const img = element.querySelector('img');
        if (img) {
            blockImageElement(img);
        }
    }
}

    // 阻止所有现有图片(保留头像)
    function blockAllExistingImages() {
        const images = document.querySelectorAll('img');
        images.forEach(img => {
            // 保存原始URL
            if (!originalImageSources.has(img)) {
                originalImageSources.set(img, img.src || img.getAttribute('data-src') || '');
            }
            blockImageElement(img);
        });

        const sources = document.querySelectorAll('source');
        sources.forEach(source => {
            const srcset = source.srcset || '';
            if (!preserveAvatarUrls.some(url => srcset.includes(url))) {
                source.srcset = '';
            }
        });

        const pictures = document.querySelectorAll('picture');
        pictures.forEach(picture => {
            const img = picture.querySelector('img');
            if (img) {
                blockImageElement(img);
            }
        });
    }

    // 恢复被阻止的图片
    function restoreBlockedImages() {
        const images = document.querySelectorAll('img[data-original-src]');
        images.forEach(img => {
            const originalSrc = img.getAttribute('data-original-src');
            if (originalSrc) {
                img.src = originalSrc;
            }
            img.removeAttribute('data-original-src');
            img.removeAttribute('data-blocked-src');
        });
    }

    // 显示完成提示
    function showCompletionMessage(currentCount) {
        const stats = countAllLikes();
        updateDisplay(stats);

        const content = document.getElementById('windowContent');
        content.style.background = 'linear-gradient(135deg, #fff5f7, #ffeef2)';
        content.style.borderRadius = '0px';

        document.getElementById('viewReportBtn').style.display = 'block';
        updateScrollStatus(`🎉 统计完成啦!共加载 ${currentCount} 条记录,总赞数: ${stats.total.toLocaleString()}`);
        document.getElementById('status').innerHTML = `
            <div style="color: #fb7299; font-weight: bold; font-size: 14px; margin-bottom: 5px;">🎊 统计完成!</div>
            <div style="color: #666;">共找到 ${currentCount} 条点赞记录<br>总赞数: <strong style="color: #fb7299;">${stats.total.toLocaleString()}</strong></div>
        `;
    }
    // 获取带评分标准的称号显示
    function getTitlesWithCriteria(titles) {
        const criteriaMap = {
            '✨ 动态区的小太阳': '≥ 三万',
            '✨ 动态创作达人': '≥ 一万',
            '✨ 动态小能手': '≥ 三千',
            '🎬 视频区的大佬喵': '≥ 十万',
            '🎬 优质视频阿婆主': '≥ 五万',
            '🎬 视频创作小阿婆': '≥ 一万',
            '💭 评论区的神仙楼主': '≥ 五万',
            '💭 热门评论小达人': '≥ 二万',
            '💭 活跃小话痨': '≥ 五千',
            '💫 弹幕区的气氛组组长': '≥ 五万',
            '💫 弹幕小能手': '≥ 二万',
            '💫 弹幕小可爱': '≥ 五千',
            '🔥 B站千万级顶流UP主': '≥ 千万',
            '👑 B站百万人气UP主': '≥ 百万',
            '🏆 B站三连收割机': '≥ 三十万',
            '⭐ B站三连收割星': '≥ 十五万',
            '🌟 B站活跃UP主': '≥ 五万',
            '👍 B站优质小咕咕': '≥ 二万',
            '🌱 初来乍到的小萌新,加油哦~': '< 二万'
        };

        return titles.map(title => {
            const criteria = criteriaMap[title] || '';
            return `<div style="display: flex; justify-content: space-between; align-items: center;">
                        <span>${title}</span>
                        <span style="font-size: 10px; color: #999; margin-left: 10px;">${criteria}</span>
                    </div>`;
        }).join('');
    }

// 显示报告窗口
function showReport() {
    const stats = countAllLikes();
    const titles = getAccountTitles(stats);
    const accountDefinition = getAccountDefinition(stats);
    const userInfo = getUserInfo();

    // 根据账号评价数量计算需要减少的间距
    const titleCount = titles.length;
    let totalReduction = (titleCount - 1) * 20; // 每多一条减20px
    totalReduction = Math.max(0, totalReduction); // 确保不小于0

    // 分配减少的间距到各个元素
    const userInfoMargin = Math.max(40 - totalReduction * 0.3, 20); // 用户信息区域减少30%
    const totalLikesMargin = Math.max(15 - totalReduction * 0.3, 5); // 总赞数区域减少30%
    const titlesMargin = Math.max(15 - totalReduction * 0.4, 5); // 账号评价区域减少40%

    const reportWindow = document.createElement('div');
    reportWindow.id = 'bilibiliReportWindow';
    reportWindow.style.cssText = `
        position: fixed;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%) scale(0.8);
        width: 800px;
        height: 580px;
        background: #f9f9f9;
        border: 1px solid #e0e0e0;
        border-radius: 4px;
        box-shadow: 0 4px 20px rgba(0,0,0,0.15);
        z-index: 10003;
        font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", sans-serif;
        overflow: hidden;
        user-select: none;
        opacity: 0;
        transition: all 0.3s ease-out;
        max-width: 95vw;
        max-height: 90vh;
    `;

    const titleBar = document.createElement('div');
    titleBar.style.cssText = `
        background: #fb7299; /* 改为哔哩粉 */
        color: white;
        padding: 10px 20px;
        font-weight: bold;
        font-size: 16px;
        display: flex;
        justify-content: space-between;
        align-items: center;
        cursor: move;
    `;
titleBar.innerHTML = `
    <span><i class="fa fa-connectdevelop" style="font-size: 24px; margin-right: 5px;"></i> B站数据报告面板(≧▽≦)</span>
    <div style="display: flex; align-items: center;">
        <button id="saveReportBtn" style="
            background: #23c16b;
            color: white;
            border: none;
            padding: 5px 10px;
            border-radius: 3px;
            margin-right: 15px;
            cursor: pointer;
            display: flex;
            align-items: center;
            font-size: 14px;
        ">
                <span style="font-family: FontAwesome; margin-right: 5px;">&#xf1e0;</span>
                <span><strong>生成图片</strong>,晒出你的报告!<span style="font-size: 10px;">≧▽≦</span></span>
            </button>
            <span style="cursor: pointer; font-size: 18px;" id="closeReportWindow">×</span>
        </div>
    `;

    const content = document.createElement('div');
    content.style.cssText = `display: flex; height: calc(100% - 44px); position: relative;`;

    // 左侧面板 - 根据评价数量动态调整间距
    const leftPanel = document.createElement('div');
    leftPanel.style.cssText = `
        width: 35%;
        padding: 25px;
        background: white;
        border-right: 1px solid #eee;
        overflow: hidden;
    `;

    // 根据评价数量生成不同的HTML
    if (titleCount === 1) {
        leftPanel.innerHTML = `
            <div style="display: flex; align-items: center; margin-bottom: 40px;">
                <img src="${userInfo.avatarUrl}" style="width: 60px; height: 60px; border-radius: 3px; margin-right: 15px; border: 2px solid #eee;">
                <div>
                    <div style="font-size: 18px; font-weight: bold; color: #333; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 180px;">${userInfo.nickname}</div>
                    <div style="font-size: 12px; color: #666;">B站数据统计报告</div>
                </div>
            </div>

            <div style="background: #fff; border: 1px solid #eee; border-radius: 3px; padding: 1px; margin-bottom: 15px;">
                <div style="font-size: 14px; color: #666; margin-bottom: 8px;">总获赞数</div>
                <div style="font-size: 32px; font-weight: bold; color: #fb7299; word-break: break-all;">${stats.total.toLocaleString()}</div>
                <div style="font-size: 12px; color: #999; margin-top: 3px;">${numberToChinese(stats.total)}</div>
            </div>

            <div style="margin-bottom: 15px;">
                <div style="font-size: 14px; font-weight: bold; color: #333; margin-bottom: 8px;">账号评价</div>
                <div style="background: #fff; border: 1px solid #eee; border-radius: 3px; padding: 12px; font-size: 13px; color: #666; line-height: 1.4; max-height: 120px; overflow: hidden;">
                    ${getTitlesWithCriteria(titles)}
                </div>
            </div>

            <div>
                <div style="font-size: 14px; font-weight: bold; color: #333; margin-bottom: 8px;">账号定义</div>
                <div style="background: #fff; border: 1px solid #eee; border-radius: 3px; padding: 12px; font-size: 13px; color: #666; line-height: 1.4; max-height: 80px; overflow: hidden;">
                    ${accountDefinition}
                </div>
            </div>
        `;
    } else if (titleCount === 2) {
        leftPanel.innerHTML = `
            <div style="display: flex; align-items: center; margin-bottom: ${userInfoMargin}px;">
                <img src="${userInfo.avatarUrl}" style="width: 60px; height: 60px; border-radius: 3px; margin-right: 15px; border: 2px solid #eee;">
                <div>
                    <div style="font-size: 18px; font-weight: bold; color: #333; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 180px;">${userInfo.nickname}</div>
                    <div style="font-size: 12px; color: #666;">B站数据统计报告</div>
                </div>
            </div>

            <div style="background: #fff; border: 1px solid #eee; border-radius: 3px; padding: 20px; margin-bottom: ${totalLikesMargin}px;">
                <div style="font-size: 14px; color: #666; margin-bottom: 8px;">总获赞数</div>
                <div style="font-size: 32px; font-weight: bold; color: #fb7299; word-break: break-all;">${stats.total.toLocaleString()}</div>
                <div style="font-size: 12px; color: #999; margin-top: 3px;">${numberToChinese(stats.total)}</div>
            </div>

            <div style="margin-bottom: ${titlesMargin}px;">
                <div style="font-size: 14px; font-weight: bold; color: #333; margin-bottom: 8px;">账号评价</div>
                <div style="background: #fff; border: 1px solid #eee; border-radius: 3px; padding: 12px; font-size: 13px; color: #666; line-height: 1.4; max-height: 120px; overflow: hidden;">
                    ${getTitlesWithCriteria(titles)}
                </div>
            </div>

            <div>
                <div style="font-size: 14px; font-weight: bold; color: #333; margin-bottom: 8px;">账号定义</div>
                <div style="background: #fff; border: 1px solid #eee; border-radius: 3px; padding: 12px; font-size: 13px; color: #666; line-height: 1.4; max-height: 80px; overflow: hidden;">
                    ${accountDefinition}
                </div>
            </div>
        `;
    } else if (titleCount >= 3) {
        leftPanel.innerHTML = `
            <div style="display: flex; align-items: center; margin-bottom: ${userInfoMargin}px;">
                <img src="${userInfo.avatarUrl}" style="width: 60px; height: 60px; border-radius: 3px; margin-right: 15px; border: 2px solid #eee;">
                <div>
                    <div style="font-size: 18px; font-weight: bold; color: #333; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 180px;">${userInfo.nickname}</div>
                    <div style="font-size: 12px; color: #666;">B站数据统计报告</div>
                </div>
            </div>

            <div style="background: #fff; border: 1px solid #eee; border-radius: 3px; padding: 15px; margin-bottom: ${totalLikesMargin}px;">
                <div style="font-size: 14px; color: #666; margin-bottom: 6px;">总获赞数</div>
                <div style="font-size: 28px; font-weight: bold; color: #fb7299; word-break: break-all;">${stats.total.toLocaleString()}</div>
                <div style="font-size: 11px; color: #999; margin-top: 2px;">${numberToChinese(stats.total)}</div>
            </div>

            <div style="margin-bottom: ${titlesMargin}px;">
                <div style="font-size: 14px; font-weight: bold; color: #333; margin-bottom: 6px;">账号评价</div>
                <div style="background: #fff; border: 1px solid #eee; border-radius: 3px; padding: 10px; font-size: 13px; color: #666; line-height: 1.3; max-height: 120px; overflow: hidden;">
                    ${getTitlesWithCriteria(titles)}
                </div>
            </div>

            <div>
                <div style="font-size: 14px; font-weight: bold; color: #333; margin-bottom: 6px;">账号定义</div>
                <div style="background: #fff; border: 1px solid #eee; border-radius: 3px; padding: 10px; font-size: 13px; color: #666; line-height: 1.3; max-height: 80px; overflow: hidden;">
                    ${accountDefinition}
                </div>
            </div>
        `;
    }

    // 右侧面板
    const rightPanel = document.createElement('div');
    rightPanel.style.cssText = `
        width: 65%;
        padding: 0;
        background: #f9f9f9;
        overflow: hidden;
        position: relative;
    `;
    rightPanel.innerHTML = `
        <!-- 饼图和图例区域 -->
        <div style="display: flex; margin: 0; gap: 0; height: 180px;">
            <!-- 饼图容器 -->
            <div style="width: 45%; display: flex; justify-content: center; align-items: center; background: white; border: 1px solid #eee; border-radius: 3px;">
                <canvas id="likesChart" width="140" height="140"></canvas>
            </div>
            <!-- 图例容器 -->
            <div style="width: 55%; background: white; border: 1px solid #eee; border-radius: 3px; padding: 0;">
                <div style="font-size: 14px; font-weight: bold; color: #333; margin: 10px 30px 10px; display: inline-block;">数据分布</div>
                <div style="max-height: 140px; overflow-y: auto; margin: 0 30px;">
                    ${getChartLegend(stats)}
                </div>
            </div>
        </div>

        <!-- 数据卡片区域 -->
        <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px; padding: 20px;">
            <div style="background: white; border: 1px solid #eee; border-radius: 3px; padding: 15px; text-align: center;">
                <div style="font-size: 14px; color: #666; margin-bottom: 10px;">动态赞数</div>
                <div style="font-size: 24px; font-weight: bold; color: #fb7299; word-break: break-all;">${stats.dynamic.toLocaleString()}</div>
            </div>
            <div style="background: white; border: 1px solid #eee; border-radius: 3px; padding: 15px; text-align: center;">
                <div style="font-size: 14px; color: #666; margin-bottom: 10px;">视频赞数</div>
                <div style="font-size: 24px; font-weight: bold; color: #00a1d6; word-break: break-all;">${stats.video.toLocaleString()}</div>
            </div>
            <div style="background: white; border: 1px solid #eee; border-radius: 3px; padding: 15px; text-align: center;">
                <div style="font-size: 14px; color: #666; margin-bottom: 10px;">评论赞数</div>
                <div style="font-size: 24px; font-weight: bold; color: #ffb11b; word-break: break-all;">${stats.comment.toLocaleString()}</div>
            </div>
            <div style="background: white; border: 1px solid #eee; border-radius: 3px; padding: 15px; text-align: center;">
                <div style="font-size: 14px; color: #666; margin-bottom: 10px;">弹幕赞数</div>
                <div style="font-size: 24px; font-weight: bold; color: #23c16b; word-break: break-all;">${stats.danmaku.toLocaleString()}</div>
            </div>
        </div>
    `;

    // 2233furry装饰图片代码(小小电子xxdz原创图)
    const leftDecoration = document.createElement('img');
    leftDecoration.src = 'https://article.biliimg.com/bfs/new_dyn/d891217bd49f98439509f21a194bf1c33461569935575626.png';
    leftDecoration.style.cssText = `
        position: absolute;
        bottom: 0;
        left: 0;
        width: 151.5px;
        height: 114.5px;
        object-fit: contain;
        pointer-events: none;
        z-index: 1;
    `;

    const rightDecoration = document.createElement('img');
    rightDecoration.src = 'https://article.biliimg.com/bfs/new_dyn/74cbb37888b507d1235eb12fbf3b7ff23461569935575626.png';
    rightDecoration.style.cssText = `
        position: absolute;
        bottom: 0;
        right: 0;
        width: 134.5px;
        height: 101.5px;
        object-fit: contain;
        pointer-events: none;
        z-index: 1;
    `;

    const horizontalDecoration = document.createElement('img');
    horizontalDecoration.src = 'https://article.biliimg.com/bfs/new_dyn/84078b8229ee4d864179bce54262da3c3461569935575626.png';
    horizontalDecoration.style.cssText = `
        position: absolute;
        bottom: 0;
        left: 0;
        width: 100%;
        height: auto;
        object-fit: cover;
        pointer-events: none;
        z-index: 0;
        opacity: 0.6;
    `;

    // 作者小小电子xxdzの信息 - 放在最上层
    const authorInfo = document.createElement('div');
    authorInfo.style.cssText = `
        position: absolute;
        bottom: 15px;
        left: 0;
        width: 100%;
        text-align: center;
        z-index: 2;
        pointer-events: none;
    `;
authorInfo.innerHTML = `
    <div style="color: white; font-size: 10px; text-shadow: 0 0 3px rgba(255,255,255,0.8), 0 0 5px rgba(255,255,255,0.6); font-weight: 300; opacity: 0.7;">
        插件作者·小小电子xxdz
    </div>
`;

    content.appendChild(leftPanel);
    content.appendChild(rightPanel);
    content.appendChild(horizontalDecoration);
    content.appendChild(leftDecoration);
    content.appendChild(rightDecoration);
    content.appendChild(authorInfo); // 最后添加xxdz,确保在最上层

    reportWindow.appendChild(titleBar);
    reportWindow.appendChild(content);
    document.body.appendChild(reportWindow);

    makeDraggable(reportWindow, titleBar);
    setupWindowFocus(reportWindow);
    bringToFront(reportWindow);

    setTimeout(() => {
        reportWindow.style.opacity = '1';
        reportWindow.style.transform = 'translate(-50%, -50%) scale(1)';
    }, 10);

    document.getElementById('closeReportWindow').addEventListener('click', () => {
        closeWindowWithAnimation(reportWindow);
        if (isGeneratingReport) {
            isGeneratingReport = false;
            if (performanceMode) {
                blockAllExistingImages();
                startImageBlockingObserver();
            }
        }
    });
    document.getElementById('saveReportBtn').addEventListener('click', () => saveReportAsImage(reportWindow, stats, userInfo, titles, accountDefinition));
    drawPieChart(stats, reportWindow);
}
// 保存报告为图片 - 核心修复:解决性能模式依赖和图例错位问题
function saveReportAsImage(reportWindow, stats, userInfo, titles, accountDefinition) {
    const saveBtn = document.getElementById('saveReportBtn');
    const originalContent = saveBtn.innerHTML;
    saveBtn.innerHTML = '<span>⏳</span><span style="margin-left: 5px;">生成中</span>';
    saveBtn.disabled = true;

    const modal = document.createElement('div');
    modal.style.cssText = `
        position: fixed;
        top: 0;
        left: 0;
        width: 100vw;
        height: 100vh;
        background: rgba(0,0,0,0.7);
        z-index: 10004;
        display: flex;
        justify-content: center;
        align-items: center;
        color: white;
        font-size: 16px;
    `;
    modal.textContent = '正在生成图片...';
    document.body.appendChild(modal);

    // 关键修复:设置生成状态
    isGeneratingReport = true;
    const wasPerformanceMode = performanceMode;
    let originalImageFunc = null;
    let originalAddEventListenerFunc = null;

    // 临时禁用性能模式的图片拦截(无论是否开启过性能模式都能处理)
    if (performanceMode) {
        // 保存原始函数引用
        originalImageFunc = window.originalImage || window.Image;
        originalAddEventListenerFunc = window.originalAddEventListener || EventTarget.prototype.addEventListener;

        // 恢复原始函数
        window.Image = originalImageFunc;
        EventTarget.prototype.addEventListener = originalAddEventListenerFunc;

        stopImageBlockingObserver();
    }

    // 定义安全的图片加载函数,确保不受性能模式影响
    function loadImageForCanvas(url) {
        return new Promise((resolve, reject) => {
            // 关键修复:使用原生Image构造函数,确保能正常加载图片
            const img = originalImageFunc ? new originalImageFunc() : new Image();
            img.crossOrigin = 'anonymous';
            img.onload = () => resolve(img);
            img.onerror = (e) => {
                console.error('图片加载失败:', e);
                // 尝试使用默认头像
                const defaultImg = new Image();
                defaultImg.onload = () => resolve(defaultImg);
                defaultImg.src = 'https://i0.hdslb.com/bfs/face/member/noface.jpg';
            };
            img.src = url;
        });
    }

    // 先加载所有需要的图片再绘图
    Promise.all([
        loadImageForCanvas(userInfo.avatarUrl),
        loadImageForCanvas('https://article.biliimg.com/bfs/new_dyn/d891217bd49f98439509f21a194bf1c33461569935575626.png'),
        loadImageForCanvas('https://article.biliimg.com/bfs/new_dyn/74cbb37888b507d1235eb12fbf3b7ff23461569935575626.png'),
        loadImageForCanvas('https://article.biliimg.com/bfs/new_dyn/84078b8229ee4d864179bce54262da3c3461569935575626.png')
    ]).then(([avatarImg, leftDecorationImg, rightDecorationImg, horizontalDecorationImg]) => {
        try {
            const width = 800, height = 580;
            const canvas = document.createElement('canvas');
            const ctx = canvas.getContext('2d');
            canvas.width = width * 2;
            canvas.height = height * 2;
            ctx.scale(2, 2);
            ctx.fillStyle = '#f9f9f9';
            ctx.fillRect(0, 0, width, height);

// 1. 标题栏 - 改为哔哩粉
ctx.fillStyle = '#fb7299'; // 哔哩粉
ctx.fillRect(0, 0, width, 44);
ctx.fillStyle = 'white';
ctx.font = 'bold 16px Arial';
ctx.textAlign = 'left';

// 绘制Font Awesome图标(使用Unicode字符)
ctx.font = '24px FontAwesome';
ctx.fillText('\uf20e', 20, 28); // fa-connectdevelop 的Unicode

// 绘制文字
ctx.font = 'bold 16px Arial';
ctx.fillText(' B站数据报告面板(≧▽≦)', 48, 28);
            // 2. 左侧面板
            ctx.fillStyle = 'white';
            ctx.fillRect(0, 44, width * 0.35, height - 44);
            ctx.fillStyle = '#eee';
            ctx.fillRect(width * 0.35, 44, 1, height - 44);

            // 3. 用户信息 - 使用预加载的头像图片
            ctx.save();
            ctx.beginPath();
            ctx.rect(20, 64, 60, 60);
            ctx.clip();
            ctx.drawImage(avatarImg, 20, 64, 60, 60);
            ctx.restore();
            ctx.fillStyle = '#333';
            ctx.font = 'bold 18px Arial';
            ctx.textAlign = 'left';
            ctx.fillText(truncateText(userInfo.nickname, 12), 95, 90);
            ctx.font = '12px Arial';
            ctx.fillStyle = '#666';
            ctx.fillText('B站数据统计报告', 95, 110);

            // 4. 总赞数卡片
            ctx.fillStyle = 'white';
            ctx.strokeStyle = '#eee';
            ctx.lineWidth = 1;
            ctx.strokeRect(20, 140, width * 0.35 - 40, 100);
            ctx.fillStyle = '#666';
            ctx.font = '14px Arial';
            ctx.fillText('总获赞数', 35, 165);
            ctx.fillStyle = '#fb7299';
            ctx.font = 'bold 32px Arial';
            ctx.fillText(formatLargeNumber(stats.total), 35, 200);
            ctx.fillStyle = '#999';
            ctx.font = '12px Arial';
            ctx.fillText(numberToChinese(stats.total), 35, 220);

            // 5. 账号评价 - 修改为带评分标准的显示
            ctx.fillStyle = '#333';
            ctx.font = 'bold 14px Arial';
            ctx.fillText('账号评价', 20, 260);
            ctx.strokeRect(20, 275, width * 0.35 - 40, 120);
            ctx.fillStyle = '#666';
            ctx.font = '12px Arial'; // 从13px改为12px
            let yPos = 295;

            // 定义评分标准映射
            const criteriaMap = {
                '✨ 动态区的小太阳': '≥ 三万',
                '✨ 动态创作达人': '≥ 一万',
                '✨ 动态小能手': '≥ 三千',
                '🎬 视频区的大佬喵': '≥ 十万',
                '🎬 优质视频阿婆主': '≥ 五万',
                '🎬 视频创作小阿婆': '≥ 一万',
                '💭 评论区的神仙楼主': '≥ 五万',
                '💭 热门评论小达人': '≥ 二万',
                '💭 活跃小话痨': '≥ 五千',
                '💫 弹幕区的气氛组组长': '≥ 五万',
                '💫 弹幕小能手': '≥ 二万',
                '💫 弹幕小可爱': '≥ 五千',
                '🔥 B站千万级顶流UP主': '≥ 千万',
                '👑 B站百万人气UP主': '≥ 百万',
                '🏆 B站三连收割机': '≥ 三十万',
                '⭐ B站三连收割星': '≥ 十五万',
                '🌟 B站活跃UP主': '≥ 五万',
                '👍 B站优质小咕咕': '≥ 二万',
                '🌱 初来乍到的小萌新,加油哦~': '< 二万'
            };

            titles.forEach(title => {
                if (yPos < 275 + 110) {
                    const criteria = criteriaMap[title] || '';
                    // 绘制称号
                    ctx.fillText(title, 35, yPos);
                    // 绘制评分标准(靠右对齐)
                    ctx.fillStyle = '#999';
                    ctx.font = '9px Arial'; // 从10px改为9px
                    ctx.textAlign = 'right';
                    ctx.fillText(criteria, width * 0.35 - 45, yPos);
                    // 恢复设置
                    ctx.fillStyle = '#666';
                    ctx.font = '12px Arial'; // 从13px改为12px
                    ctx.textAlign = 'left';
                    yPos += 20;
                }
            });

            // 6. 账号定义
            ctx.fillStyle = '#333';
            ctx.font = 'bold 14px Arial';
            ctx.fillText('账号定义', 20, 415);
            ctx.strokeRect(20, 430, width * 0.35 - 40, 80);
            ctx.fillStyle = '#666';
            ctx.font = '13px Arial';
            wrapText(ctx, accountDefinition, 35, 450, width * 0.35 - 80, 18);

            // 7. 饼图 - 保持原有位置和尺寸不变
            drawPieChartToCanvas(ctx, width * 0.35 + 115, 44 + 110, 70, stats);

            // 8. 图例 - 核心修复:调整保存图片时的图例位置,解决第一行错位
            const colors = ['#fb7299', '#00a1d6', '#ffb11b', '#23c16b'];
            const labels = ['动态', '视频', '评论', '弹幕'];
            const values = [stats.dynamic, stats.video, stats.comment, stats.danmaku];
            let legendY = 65;
            ctx.fillStyle = '#333';
            ctx.font = 'bold 14px Arial';
            ctx.fillText('数据分布', width * 0.35 + 210, legendY);
            legendY += 25;
            values.forEach((value, index) => {
                if (value > 0 && legendY < 65 + 180) {
                    const percentage = ((value / stats.total) * 100).toFixed(1);
                    ctx.fillStyle = colors[index];
                    ctx.fillRect(width * 0.35 + 210, legendY - 8, 14, 14);
                    ctx.fillStyle = '#333';
                    ctx.font = '13px Arial';
                    // 关键修复:为第一行图例增加13px的左边距,解决错位
                    const labelX = width * 0.35 + 240 + (index === 0 ? 13 : 0);
                    ctx.fillText(labels[index], labelX, legendY);
                    ctx.fillStyle = '#666';
                    ctx.font = '13px Arial';
                    ctx.textAlign = 'right';
                    ctx.fillText(`${formatLargeNumber(value)} (${percentage}%)`, width - 40, legendY);
                    ctx.textAlign = 'left';
                    legendY += 20;
                }
            });

            // 9. 数据卡片 - 保持原有位置和样式
            const cardWidth = (width * 0.65 - 50) / 2;
            const cardY = 44 + 240;
            values.forEach((value, index) => {
                const x = width * 0.35 + 20 + (index % 2) * (cardWidth + 15);
                const y = cardY + Math.floor(index / 2) * 100;
                ctx.strokeRect(x, y, cardWidth, 90);
                ctx.fillStyle = '#666';
                ctx.font = '14px Arial';
                ctx.fillText(labels[index] + '赞数', x + 15, y + 30);
                ctx.fillStyle = colors[index];
                ctx.font = 'bold 22px Arial';
                ctx.fillText(formatLargeNumber(value), x + 15, y + 60);
            });

            // 10. 绘制装饰图片 - 调整图层顺序
            // 先绘制横向素材图片(底层)
            ctx.globalAlpha = 0.6;
            ctx.drawImage(horizontalDecorationImg, 0, height - 100, width, 100);
            ctx.globalAlpha = 1;

            // 再绘制左右装饰图片(上层)
            const leftDecorationWidth = 151.5;
            const leftDecorationHeight = 114.5;
            ctx.drawImage(leftDecorationImg, 0, height - leftDecorationHeight, leftDecorationWidth, leftDecorationHeight);

            const rightDecorationWidth = 134.5;
            const rightDecorationHeight = 101.5;
            ctx.drawImage(rightDecorationImg, width - rightDecorationWidth, height - rightDecorationHeight, rightDecorationWidth, rightDecorationHeight);

            // 11. 作者信息 - 改为白色并居中
            ctx.fillStyle = 'white';
            ctx.font = '10px Arial';
            ctx.textAlign = 'center';
            ctx.fillText('B站赞数统计器·小小电子xxdz制作', width / 2, height - 10);

            // 下载
            canvas.toBlob(blob => {
                try {
                    const link = document.createElement('a');
                    const date = new Date().toLocaleDateString().replace(/\//g, '-');
                    link.download = `B站数据报告_${userInfo.nickname}_${date}.png`;
                    link.href = URL.createObjectURL(blob);
                    document.body.appendChild(link);
                    link.click();
                    document.body.removeChild(link);
                    URL.revokeObjectURL(link.href);
                } catch (e) {
                    console.error('保存失败:', e);
                    alert('保存图片失败,请重试');
                } finally {
                    // 恢复状态
                    isGeneratingReport = false;
                    if (wasPerformanceMode) {
                        // 恢复性能模式设置
                        window.Image = window.originalImage || Image;
                        EventTarget.prototype.addEventListener = window.originalAddEventListener || EventTarget.prototype.addEventListener;
                        blockAllExistingImages();
                        startImageBlockingObserver();
                    }
                    saveBtn.innerHTML = originalContent;
                    saveBtn.disabled = false;
                    document.body.removeChild(modal);
                }
            }, 'image/png');
        } catch (e) {
            console.error('生成失败:', e);
            alert('生成图片失败,请重试');
            // 恢复状态
            isGeneratingReport = false;
            if (wasPerformanceMode) {
                // 恢复性能模式设置
                window.Image = window.originalImage || Image;
                EventTarget.prototype.addEventListener = window.originalAddEventListener || EventTarget.prototype.addEventListener;
                blockAllExistingImages();
                startImageBlockingObserver();
            }
            saveBtn.innerHTML = originalContent;
            saveBtn.disabled = false;
            document.body.removeChild(modal);
        }
    });
}
    // 截断文本
    function truncateText(text, maxLength) {
        return text.length <= maxLength ? text : text.substring(0, maxLength) + '...';
    }

    // 格式化大数字
    function formatLargeNumber(num) {
        return num >= 10000 ? (num / 10000).toFixed(1) + '万' : num.toLocaleString();
    }

    // 绘制饼图到Canvas
    function drawPieChartToCanvas(ctx, centerX, centerY, radius, stats) {
        const data = [
            { value: stats.dynamic, color: '#fb7299', label: '动态' },
            { value: stats.video, color: '#00a1d6', label: '视频' },
            { value: stats.comment, color: '#ffb11b', label: '评论' },
            { value: stats.danmaku, color: '#23c16b', label: '弹幕' }
        ].filter(item => item.value > 0);
        const total = data.reduce((sum, item) => sum + item.value, 0);
        if (total === 0) return;
        let startAngle = 0;
        data.forEach(item => {
            const sliceAngle = (2 * Math.PI * item.value) / total;
            const endAngle = startAngle + sliceAngle;
            ctx.beginPath();
            ctx.moveTo(centerX, centerY);
            ctx.arc(centerX, centerY, radius, startAngle, endAngle);
            ctx.closePath();
            ctx.fillStyle = item.color;
            ctx.fill();
            startAngle = endAngle;
        });
        ctx.beginPath();
        ctx.arc(centerX, centerY, radius * 0.6, 0, 2 * Math.PI);
        ctx.fillStyle = 'white';
        ctx.fill();
        ctx.fillStyle = '#fb7299';
        ctx.font = 'bold 14px Arial';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        ctx.fillText('总赞数', centerX, centerY - 8);
        ctx.font = 'bold 12px Arial';
        ctx.fillText(formatLargeNumber(stats.total), centerX, centerY + 8);
    }

    // 文本换行
    function wrapText(ctx, text, x, y, maxWidth, lineHeight) {
        const words = text.split(' ');
        let line = '';
        for (let n = 0; n < words.length; n++) {
            const testLine = line + words[n] + ' ';
            const testWidth = ctx.measureText(testLine).width;
            if (testWidth > maxWidth && n > 0) {
                ctx.fillText(line, x, y);
                line = words[n] + ' ';
                y += lineHeight;
            } else line = testLine;
        }
        ctx.fillText(line, x, y);
    }

    // 账号定义
    function getAccountDefinition(stats) {
        const total = stats.total;
        if (total === 0) return '🌱 刚刚起步的B站萌新';
        const percentages = {
            dynamic: (stats.dynamic / total) * 100,
            video: (stats.video / total) * 100,
            comment: (stats.comment / total) * 100,
            danmaku: (stats.danmaku / total) * 100
        };
        let maxType = '', maxPercentage = 0;
        for (const [type, p] of Object.entries(percentages)) {
            if (p > maxPercentage) {
                maxPercentage = p;
                maxType = type;
            }
        }
const definitions = {
    dynamic: '💫 动态区的活跃小能手~',
    video: '🎬 努力产粮的咕咕咕',
    comment: '💭 评论区的话痨小天使',
    danmaku: '✨ 弹幕区的气氛组担当'
};
let definition = definitions[maxType] || '🌟 全面发展的B站小可爱';
if (maxPercentage >= 60) {
    const precise = {
        dynamic: '💫 动态区的超活跃小太阳',
        video: '🎬 超用心的视频UP主',
        comment: '💭 评论区的神仙小话痨',
        danmaku: '✨ 弹幕区的超活跃小能手'
    };
    definition = precise[maxType] || definition;
}
const isBalanced = Object.values(percentages).every(p => p < 40) &&
                  Math.max(...Object.values(percentages)) - Math.min(...Object.values(percentages)) < 30;
if (isBalanced) definition = '🎯 样样通的B站六边形战士';
return definition;
    }

// 账号称号
function getAccountTitles(stats) {
    const titles = [];

    // 动态相关称号
    if (stats.dynamic >= 30000) titles.push('✨ 动态区的小太阳'); // 如果动态赞数大于等于3万,则被评为✨ 动态区的小太阳
    else if (stats.dynamic >= 10000) titles.push('✨ 动态创作达人'); // 如果动态赞数大于等于1万,则被评为✨ 动态创作达人
    else if (stats.dynamic >= 3000) titles.push('✨ 动态小能手'); // 如果动态赞数大于等于3千,则被评为✨ 动态小能手

    // 视频相关称号
    if (stats.video >= 100000) titles.push('🎬 视频区的大佬喵'); // 如果视频赞数大于等于10万,则被评为🎬 视频区的大佬喵
    else if (stats.video >= 50000) titles.push('🎬 优质视频阿婆主'); // 如果视频赞数大于等于5万,则被评为🎬 优质视频制作家
    else if (stats.video >= 10000) titles.push('🎬 视频创作小阿婆'); // 如果视频赞数大于等于1万,则被评为🎬 视频创作小能手

    // 评论相关称号
    if (stats.comment >= 50000) titles.push('💭 评论区的神仙楼主'); // 如果评论赞数大于等于5万,则被评为💭 评论区的神仙楼主
    else if (stats.comment >= 20000) titles.push('💭 热门评论小达人'); // 如果评论赞数大于等于2万,则被评为💭 热门评论小达人
    else if (stats.comment >= 5000) titles.push('💭 活跃小话痨'); // 如果评论赞数大于等于5千,则被评为💭 活跃小话痨

    // 弹幕相关称号
    if (stats.danmaku >= 50000) titles.push('💫 弹幕区的气氛组组长'); // 如果弹幕赞数大于等于5万,则被评为💫 弹幕区的气氛组组长
    else if (stats.danmaku >= 20000) titles.push('💫 弹幕小能手'); // 如果弹幕赞数大于等于2万,则被评为💫 弹幕小能手
    else if (stats.danmaku >= 5000) titles.push('💫 弹幕小可爱'); // 如果弹幕赞数大于等于5千,则被评为💫 弹幕小可爱

// 总赞数相关称号
if (stats.total >= 10000000) titles.push('🔥 B站千万级顶流UP主'); // 如果总赞数大于等于1000万,则被评为🔥 B站千万级顶流UP主
else if (stats.total >= 1000000) titles.push('👑 B站百万人气UP主'); // 如果总赞数大于等于100万,则被评为👑 B站百万人气UP主
else if (stats.total >= 300000) titles.push('🏆 B站三连收割机'); // 如果总赞数大于等于30万,则被评为🏆 B站三连收割机
else if (stats.total >= 150000) titles.push('⭐ B站三连收割星'); // 如果总赞数大于等于15万,则被评为⭐ B站三连收割星
else if (stats.total >= 50000) titles.push('🌟 B站活跃UP主'); // 如果总赞数大于等于5万,则被评为🌟 B站活跃UP主
else if (stats.total >= 20000) titles.push('👍 B站优质小咕咕'); // 如果总赞数大于等于2万,则被评为👍 B站优质小咕咕

    // 默认称号
    if (titles.length === 0) titles.push('🌱 初来乍到的小萌新,加油哦~'); // 如果没有达到任何称号标准,则被评为🌱 初来乍到的小萌新

    return titles;
}
    // 图表图例
    function getChartLegend(stats) {
        const colors = ['#fb7299', '#00a1d6', '#ffb11b', '#23c16b'];
        const labels = ['动态', '视频', '评论', '弹幕'];
        const values = [stats.dynamic, stats.video, stats.comment, stats.danmaku];
        let legendHTML = '';
        labels.forEach((label, index) => {
            if (values[index] > 0) {
                const percentage = ((values[index] / stats.total) * 100).toFixed(1);
                legendHTML += `
                    <div style="display: flex; align-items: center; margin-bottom: 10px; padding: 0 5px;">
                        <div style="width: 14px; height: 14px; background: ${colors[index]}; border-radius: 2px; margin-right: 15px; flex-shrink: 0;"></div>
                        <div style="font-size: 13px; color: #333; width: 60px; flex-shrink: 0;">${label}</div>
                        <div style="font-size: 13px; font-weight: bold; color: #666; flex: 1; text-align: right; margin-left: 10px;">${formatLargeNumber(values[index])} (${percentage}%)</div>
                    </div>
                `;
            }
        });
        return legendHTML;
    }

// 绘制饼图 - 放大版本
function drawPieChart(stats, reportWindow) {
    const canvas = document.getElementById('likesChart');
    const ctx = canvas.getContext('2d');

    // 放大canvas尺寸
    canvas.width = 180;
    canvas.height = 180;

    const centerX = canvas.width / 2;
    const centerY = canvas.height / 2;
    const radius = Math.min(centerX, centerY) - 10; // 增大半径

    const data = [
        { value: stats.dynamic, color: '#fb7299', label: '动态' },
        { value: stats.video, color: '#00a1d6', label: '视频' },
        { value: stats.comment, color: '#ffb11b', label: '评论' },
        { value: stats.danmaku, color: '#23c16b', label: '弹幕' }
    ].filter(item => item.value > 0);

    const total = data.reduce((sum, item) => sum + item.value, 0);
    if (total === 0) return;

    let hoveredIndex = -1;
    let animationId = null;
    let animationProgress = 0;
    const animationDuration = 300;

// 绘制饼图函数
function drawPie() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    let startAngle = 0;

    data.forEach((item, index) => {
        const sliceAngle = (2 * Math.PI * item.value) / total;
        const endAngle = startAngle + sliceAngle;

        // 计算当前扇形的半径(悬停效果)
        let currentRadius = radius;
        if (hoveredIndex === index) {
            const progress = Math.min(animationProgress / animationDuration, 1);
            const easeOut = 1 - Math.pow(1 - progress, 3);
            currentRadius = radius + 7 * easeOut; // 从12减小到7
        }

        // 绘制扇形
        ctx.beginPath();
        ctx.moveTo(centerX, centerY);
        ctx.arc(centerX, centerY, currentRadius, startAngle, endAngle);
        ctx.closePath();
        ctx.fillStyle = item.color;
        ctx.fill();

        // 绘制扇形边框
        ctx.strokeStyle = 'white';
        ctx.lineWidth = 2;
        ctx.stroke();

        startAngle = endAngle;
    });

    // 绘制中心圆
    ctx.beginPath();
    ctx.arc(centerX, centerY, radius * 0.5, 0, 2 * Math.PI);
    ctx.fillStyle = 'white';
    ctx.fill();

    // 绘制中心文字
    ctx.fillStyle = '#fb7299';
    ctx.font = 'bold 14px Arial';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText('总赞数', centerX, centerY - 8);
    ctx.font = 'bold 12px Arial';
    ctx.fillText(formatLargeNumber(stats.total), centerX, centerY + 8);
}

    // 动画循环
    function animate() {
        animationProgress += 16; // 约60fps
        drawPie();

        if (animationProgress < animationDuration) {
            animationId = requestAnimationFrame(animate);
        } else {
            animationProgress = animationDuration;
            animationId = null;
        }
    }

    // 初始绘制
    drawPie();

    // 鼠标交互
    canvas.addEventListener('mousemove', (e) => {
        const rect = canvas.getBoundingClientRect();
        const x = e.clientX - rect.left;
        const y = e.clientY - rect.top;

        // 计算鼠标位置相对于圆心的角度
        const dx = x - centerX;
        const dy = y - centerY;
        const distance = Math.sqrt(dx * dx + dy * dy);

        if (distance <= radius) {
            // 计算角度(0到2π)
            let angle = Math.atan2(dy, dx);
            if (angle < 0) angle += 2 * Math.PI;

            // 找到对应的扇形
            let currentAngle = 0;
            let newHoveredIndex = -1;

            data.forEach((item, index) => {
                const sliceAngle = (2 * Math.PI * item.value) / total;
                if (angle >= currentAngle && angle < currentAngle + sliceAngle) {
                    newHoveredIndex = index;
                }
                currentAngle += sliceAngle;
            });

            // 如果悬停的扇形发生变化,启动动画
            if (newHoveredIndex !== hoveredIndex) {
                hoveredIndex = newHoveredIndex;
                animationProgress = 0;

                if (animationId) {
                    cancelAnimationFrame(animationId);
                }
                animationId = requestAnimationFrame(animate);

                // 显示提示
                if (hoveredIndex !== -1) {
                    showChartTooltip(e, data[hoveredIndex]);
                } else {
                    hideChartTooltip();
                }
            } else if (hoveredIndex !== -1) {
                showChartTooltip(e, data[hoveredIndex]);
            }
        } else {
            if (hoveredIndex !== -1) {
                hoveredIndex = -1;
                animationProgress = 0;

                if (animationId) {
                    cancelAnimationFrame(animationId);
                }
                animationId = requestAnimationFrame(animate);
                hideChartTooltip();
            }
        }
    });

    canvas.addEventListener('mouseleave', () => {
        if (hoveredIndex !== -1) {
            hoveredIndex = -1;
            animationProgress = 0;

            if (animationId) {
                cancelAnimationFrame(animationId);
            }
            animationId = requestAnimationFrame(animate);
            hideChartTooltip();
        }
    });

    // 点击事件(可选)
    canvas.addEventListener('click', (e) => {
        if (hoveredIndex !== -1) {
            const item = data[hoveredIndex];
            console.log(`点击了${item.label}: ${item.value}赞 (${((item.value / total) * 100).toFixed(1)}%)`);
        }
    });
}

// 图表提示工具函数
function showChartTooltip(event, slice) {
    let tooltip = document.getElementById('chartTooltip');
    if (!tooltip) {
        tooltip = document.createElement('div');
        tooltip.id = 'chartTooltip';
        tooltip.style.cssText = `
            position: fixed;
            background: rgba(0, 0, 0, 0.85);
            color: white;
            padding: 8px 12px;
            border-radius: 4px;
            font-size: 12px;
            pointer-events: none;
            z-index: 10005;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
            backdrop-filter: blur(4px);
            transition: opacity 0.2s;
        `;
        document.body.appendChild(tooltip);
    }

    const percentage = ((slice.value / countAllLikes().total) * 100).toFixed(1);
    tooltip.innerHTML = `
        <div style="font-weight: bold; margin-bottom: 2px;">${slice.label}</div>
        <div style="font-size: 11px; opacity: 0.9;">
            有 ${formatLargeNumber(slice.value)} 个赞啦,也就是占${percentage}%~
        </div>
    `;

    // 定位提示框
    const x = event.clientX + 15;
    const y = event.clientY + 15;

    // 确保提示框不会超出屏幕
    const tooltipRect = tooltip.getBoundingClientRect();
    const windowWidth = window.innerWidth;
    const windowHeight = window.innerHeight;

    let finalX = x;
    let finalY = y;

    if (x + tooltipRect.width > windowWidth - 10) {
        finalX = event.clientX - tooltipRect.width - 15;
    }
    if (y + tooltipRect.height > windowHeight - 10) {
        finalY = event.clientY - tooltipRect.height - 15;
    }

    tooltip.style.left = finalX + 'px';
    tooltip.style.top = finalY + 'px';
    tooltip.style.opacity = '1';
}

function hideChartTooltip() {
    const tooltip = document.getElementById('chartTooltip');
    if (tooltip) {
        tooltip.style.opacity = '0';
    }
}
// 检查新数据
function checkForNewItems() {
    const currentCount = document.querySelectorAll('.interaction-item').length;
    if (currentCount > lastItemCount) {
        lastItemCount = currentCount;
        if (noNewItemsTimer) clearTimeout(noNewItemsTimer);
        if (realTimeStats) updateDisplay(countAllLikes());
        updateScrollStatus(`加载中... 当前项目数: ${currentCount}`);

        // 只有在自动滚动过程中才重新设置6秒完成检测
        if (isScrolling) {
            noNewItemsTimer = setTimeout(() => {
                stopAutoScroll();
                showCompletionMessage(currentCount);
            }, 6000);
        }
        return true;
    }
    return false;
}
            // 自动滚动
function startAutoScroll() {
    if (isScrolling) {
        stopAutoScroll();
        return;
    }
    const loveList = document.querySelector('.love-list');
    if (!loveList) {
        updateScrollStatus('未找到点赞列表嗷');
        return;
    }
    isScrolling = true;
    lastItemCount = document.querySelectorAll('.interaction-item').length;
    updateScrollStatus(`开始自动滚动... 速度: ${scrollSpeed}ms, 当前项目数: ${lastItemCount}`);
document.getElementById('autoScrollBtn').textContent = '停止滚动';
document.getElementById('autoScrollBtn').style.background = '#ff6b6b';
document.getElementById('autoScrollBtn').style.backgroundImage = 'linear-gradient(90deg, #ff3742 0%, #ff4757 30%, #ff6b6b 70%, #ff6b6b 100%)';
document.getElementById('autoScrollBtn').style.backgroundSize = '300% 100%';
document.getElementById('autoScrollBtn').style.animation = 'scrollProgress 3s ease-in-out infinite';

    // 只有在自动滚动过程中才设置6秒完成检测
    noNewItemsTimer = setTimeout(() => {
        if (isScrolling) { // 确保只有在仍在滚动时才执行完成
            stopAutoScroll();
            showCompletionMessage(lastItemCount);
        }
    }, 6000);

    scrollInterval = setInterval(() => {
        if (!isScrolling) return;
        scrollAttempts++;
        updateScrollStatus(`滚动中... 尝试: ${scrollAttempts}, 项目: ${lastItemCount}, 速度: ${scrollSpeed}ms`);
        const scrollContainer = getScrollContainer();
        if (!scrollContainer) {
            updateScrollStatus('未找到滚动容器!嗷');
            stopAutoScroll();
            return;
        }
        scrollToBottomFast(scrollContainer);
        setTimeout(checkForNewItems, 500);
    }, scrollSpeed);
}

            // 获取滚动容器
            function getScrollContainer() {
                const containers = [
                    document.querySelector('.message-content__wrapper'),
                    document.querySelector('.love-list')?.parentElement,
                    document.querySelector('.m-infinite-scroll'),
                    document.documentElement
                ];
                for (let container of containers) {
                    if (container) return container;
                }
                return document.documentElement;
            }

            // 快速滚动到底部
            function scrollToBottomFast(container) {
                container.scrollTop = container.scrollHeight - container.clientHeight;
            }

// 停止自动滚动
function stopAutoScroll() {
    if (scrollInterval) clearInterval(scrollInterval);
    if (noNewItemsTimer) clearTimeout(noNewItemsTimer);
    isScrolling = false;
document.getElementById('autoScrollBtn').textContent = '继续自动滚动加载';
document.getElementById('autoScrollBtn').style.background = '#ff6b6b';
document.getElementById('autoScrollBtn').style.backgroundImage = 'none';
document.getElementById('autoScrollBtn').style.animation = 'none';

    // 清除6秒无新元素的定时器,避免了用户手动停止后还傻执行完成检测
    if (noNewItemsTimer) {
        clearTimeout(noNewItemsTimer);
        noNewItemsTimer = null;
    }
}

            // 更新滚动状态
            function updateScrollStatus(message) {
                const elem = document.getElementById('scrollStatus');
                if (elem) elem.textContent = message;
            }

            // 解析点赞数
            function parseLikeCount(text) {
                const match = text.match(/总计?(\d+)人赞/);
                return match ? parseInt(match[1]) : (text.includes('赞了我的') ? 1 : 0);
            }

            // 统计所有点赞
            function countAllLikes() {
                const items = document.querySelectorAll('.interaction-item');
                let total = 0, dynamic = 0, video = 0, comment = 0, danmaku = 0;
                items.forEach(item => {
                    const action = item.querySelector('.interaction-item__action');
                    if (action) {
                        const text = action.textContent.trim();
                        const count = parseLikeCount(text);
                        total += count;
                        if (text.includes('动态')) dynamic += count;
                        else if (text.includes('视频')) video += count;
                        else if (text.includes('评论')) comment += count;
                        else if (text.includes('弹幕')) danmaku += count;
                    }
                });
                return { total, dynamic, video, comment, danmaku };
            }

            // 更新显示
            function updateDisplay(stats) {
                document.getElementById('totalLikesCount').textContent = stats.total.toLocaleString();
                document.getElementById('dynamicLikes').textContent = stats.dynamic.toLocaleString();
                document.getElementById('videoLikes').textContent = stats.video.toLocaleString();
                document.getElementById('commentLikes').textContent = stats.comment.toLocaleString();
                document.getElementById('danmakuLikes').textContent = stats.danmaku.toLocaleString();
                updateChineseNumber(stats.total);
            }

            // 初始化
function init() {
    // 创建打开脚本的小按钮
    createOpenScriptButton();

    console.log('脚本初始化完成,小按钮也已显示');
}

// 切换到"收到的赞"页面的函数
function switchToLovePage() {
    // 使用XPath选择器定位"收到的赞"菜单项
    const xpathResult = document.evaluate(
        '/html/body/div[1]/div[3]/aside/div/ul[1]/li[4]',
        document,
        null,
        XPathResult.FIRST_ORDERED_NODE_TYPE,
        null
    );

    const loveSidebarItem = xpathResult.singleNodeValue;

    if (loveSidebarItem) {
        loveSidebarItem.click();
        const status = document.getElementById('status');
        if (status) {
            status.textContent = '正在切换到"收到的赞"页面捏...';
            status.style.color = '#1890ff';
        }

        // 等待页面切换后检查是否成功
        setTimeout(() => {
            if (document.querySelector('.love-list')) {
                if (status) {
                    status.textContent = '已切换到"收到的赞"页面辣,请重新点击统计按钮';
                    status.style.color = '#52c41a';
                }
            } else {
                // 如果XPath选择器不行,那就尝试备用选择器
                tryBackupSelectors();
            }
        }, 1500);
    } else {
        // 如果XPath选择器找不到,尝试备用选择器(应该不会吧,XPath可是最准的了)
        tryBackupSelectors();
    }
}

// 备用选择器函数
function tryBackupSelectors() {
    const status = document.getElementById('status');

    // 备用选择器1: 通过文本内容查找
    const sidebarItems = document.querySelectorAll('.message-sidebar__item');
    let foundItem = null;

    for (let item of sidebarItems) {
        const itemName = item.querySelector('.message-sidebar__item-name');
        if (itemName && itemName.textContent.includes('收到的赞')) {
            foundItem = item;
            break;
        }
    }

    if (foundItem) {
        foundItem.click();
        if (status) {
            status.textContent = '正在切换到"收到的赞"页面...';
            status.style.color = '#1890ff';
        }

        setTimeout(() => {
            if (document.querySelector('.love-list')) {
                if (status) {
                    status.textContent = '已切换到"收到的赞"页面辣,请重新点击统计按钮';
                    status.style.color = '#52c41a';
                }
            } else {
                if (status) {
                    status.textContent = '切换失败嘤,请手动点击左侧"收到的赞"菜单';
                    status.style.color = '#ff6b6b';
                }
            }
        }, 1500);
} else {
    if (status) {
        status.textContent = '额未找到"收到的赞"菜单项,请手动点击';
        status.style.color = '#ff6b6b';
    }
}
}

// 显示切换提示的函数
function showSwitchToLovePagePrompt() {
    const status = document.getElementById('status');
    if (status) {
        status.innerHTML = `
            <div style="color: #ff6b6b; font-weight: bold; margin-bottom: 5px;">
                当前不在"收到的赞"网页
            </div>
            <button id="switchToLovePage" style="
                background: #00a1d6;
                color: white;
                border: none;
                padding: 5px 10px;
                border-radius: 3px;
                cursor: pointer;
                font-size: 12px;
            ">点击切换!</button>
        `;

        document.getElementById('switchToLovePage').addEventListener('click', switchToLovePage);
    }
}

// 确保一定会创建小按钮
if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', init);
} else {
    init();
}

// 添加按钮点击事件监听
document.addEventListener('click', function(e) {
    if (e.target.id === 'countLikesBtn') {
        if (!document.querySelector('.love-list')) {
            showSwitchToLovePagePrompt();
            return;
        }
        const status = document.getElementById('status');
        if (status) {
            status.textContent = '正在统计中...';
            status.style.color = '#1890ff';
        }
        setTimeout(() => {
            const stats = countAllLikes();
            updateDisplay(stats);
            const count = document.querySelectorAll('.interaction-item').length;
            showCompletionMessage(count);
            if (status) {
                status.textContent = `统计完成!共找到 ${count} 条点赞记录`;
                status.style.color = '#52c41a';
            }
        }, 100);
    } else if (e.target.id === 'autoScrollBtn') {
        if (!document.querySelector('.love-list')) {
            showSwitchToLovePagePrompt();
            return;
        }
        startAutoScroll();
    }
});
})();