POE2 Trade ST工具箱

自动转换简繁中文(页面转简体,输入转繁体)- stomtian

// ==UserScript==
// @name         POE2 Trade ST工具箱
// @namespace    http://tampermonkey.net/
// @version      2.3.2
// @description  自动转换简繁中文(页面转简体,输入转繁体)- stomtian
// @author       stomtian
// @match        https://www.pathofexile.com/trade*
// @match        https://pathofexile.com/trade*
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        unsafeWindow
// @license      MIT
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/full.min.js
// @run-at       document-end
// @noframes     true
// ==/UserScript==
    
(function() {
    'use strict';
    
    console.log('POE2 Trade ST工具箱已加载');
    
    const STATE = {
        pageSimplified: GM_getValue('pageSimplified', true),
        inputTraditional: GM_getValue('inputTraditional', true),
        originalTexts: new WeakMap(),
        configs: GM_getValue('savedConfigs', {}),  // 保存的配置
        autoLoadEnabled: GM_getValue('autoLoadEnabled', false),  // 自动加载开关
        matchedCards: [], // 添加匹配的卡片列表
        currentMatchIndex: -1, // 添加当前匹配索引
        showOnlyMatched: GM_getValue('showOnlyMatched', false), // 添加新的状态
        searchPresets: GM_getValue('searchPresets', {}) // 添加预设关键词存储
    };
    
    const CUSTOM_DICT = [
        ['回覆', '回復'],
        ['恢覆', '恢復'],
    ];
    
    const CONFIG = {
        maxAttempts: 50,
        checkInterval: 100,
        inputSelector: 'input[type="text"]:not(#config-name):not(#config-category), textarea',
        textSelector: '.search-bar, .search-advanced-pane, .results-container, .resultset',
        excludeSelector: 'script, style, input, textarea, select, .converter-controls'
    };
    
    function waitForElement(selector) {
        /**
         * 等待指定选择器的元素出现在页面上
         * @param {string} selector - CSS选择器
         * @returns {Promise} - 当元素出现时解析的Promise
         */
        return new Promise(resolve => {
            // 如果元素已经存在,立即解析
            if (document.querySelector(selector)) {
                resolve();
                return;
            }
    
            // 创建观察器监听DOM变化
            const observer = new MutationObserver(() => {
                try {
                    if (document.querySelector(selector)) {
                        observer.disconnect();
                        resolve();
                    }
                } catch (error) {
                    console.debug('等待元素时出错:', error);
                }
            });
    
            // 开始观察DOM变化
            observer.observe(document.body, {
                childList: true,
                subtree: true
            });
        });
    }
    
    function waitForOpenCC() {
        /**
         * 等待OpenCC库加载完成
         * @returns {Promise} - 当OpenCC可用时解析的Promise
         */
        return new Promise((resolve, reject) => {
            // 如果OpenCC已经加载,立即解析
            if (typeof window.OpenCC !== 'undefined') {
                resolve(window.OpenCC);
                return;
            }
    
            let attempts = 0;
            const maxAttempts = CONFIG.maxAttempts;
            const checkInterval = CONFIG.checkInterval;

            // 定期检查OpenCC是否已加载
            const checkOpenCC = setInterval(() => {
                attempts++;

                if (typeof window.OpenCC !== 'undefined') {
                    clearInterval(checkOpenCC);
                    resolve(window.OpenCC);
                    return;
                }
    
                // 超过最大尝试次数后放弃
                if (attempts >= maxAttempts) {
                    clearInterval(checkOpenCC);
                    reject(new Error('加载OpenCC超时'));
                }
            }, checkInterval);
        });
    }
    
    function createConverters(OpenCC) {
        /**
         * 创建简繁转换器
         * @param {Object} OpenCC - OpenCC库对象
         * @returns {Object} - 包含简体到繁体和繁体到简体的转换器
         */
        try {
            // 创建简体到繁体的转换器(输入转换用)
        const toTraditional = OpenCC.ConverterFactory(
            OpenCC.Locale.from.cn,
            OpenCC.Locale.to.tw.concat([CUSTOM_DICT])
        );
    
            // 创建繁体到简体的转换器(页面转换用)
        const toSimplified = OpenCC.ConverterFactory(
            OpenCC.Locale.from.tw,
            OpenCC.Locale.to.cn
        );
    
        return { toTraditional, toSimplified };
        } catch (error) {
            console.error('创建转换器时出错:', error);
            // 返回空转换器,避免脚本崩溃
            return {
                toTraditional: text => text,
                toSimplified: text => text
            };
        }
    }
    
    function createInputHandler(converter) {
        /**
         * 创建输入处理函数,用于将输入文本转换为繁体中文
         * @param {Object} converter - 文本转换器对象
         * @returns {Function} - 处理输入事件的函数
         */
        return function handleInput(e) {
            try {
                // 检查是否需要进行转换
                if (!e?.target || !STATE.inputTraditional) return;

            // 如果输入框标记了不需要转换,则直接返回
                if (e.target.dataset?.noConvert === 'true') return;

                // 检查输入值是否存在
                const text = e.target.value;
                if (!text) return;
    
                // 保存当前光标位置
            const cursorPosition = e.target.selectionStart;
    
                // 使用requestAnimationFrame优化性能
            requestAnimationFrame(() => {
                try {
                        // 转换文本
                    const convertedText = converter.toTraditional(text);

                        // 如果转换前后文本相同,则不需要更新
                    if (text === convertedText) return;
    
                        // 更新输入框的值
                    e.target.value = convertedText;
    
                        // 恢复光标位置
                    if (typeof cursorPosition === 'number') {
                        e.target.setSelectionRange(cursorPosition, cursorPosition);
                    }
    
                        // 触发输入事件,确保其他监听器能够接收到更新
                    e.target.dispatchEvent(new Event('input', {
                        bubbles: true,
                        cancelable: true
                    }));
                    } catch (error) {
                        console.debug('转换输入文本时出错:', error);
                    }
            });
            } catch (error) {
                console.debug('处理输入事件时出错:', error);
            }
        };
    }
    
    function convertPageText(converter, forceRestore = false) {
        /**
         * 转换页面上的文本内容(简繁转换)
         * @param {Object} converter - 文本转换器对象
         * @param {boolean} forceRestore - 是否强制恢复原始文本
         */
        // 如果不需要简体化且不是强制恢复,则直接返回
        if (!STATE.pageSimplified && !forceRestore) return;
    
        try {
            // 查找需要处理的元素
            const elements = document.querySelectorAll(CONFIG.textSelector);
            if (!elements.length) return;
    
            // 处理每个根元素
            elements.forEach(root => {
                try {
                    // 创建TreeWalker遍历文本节点
                    const walker = document.createTreeWalker(
                        root,
                        NodeFilter.SHOW_TEXT,
                        {
                            acceptNode: function(node) {
                                // 过滤空文本节点
                                    if (!node.textContent.trim()) return NodeFilter.FILTER_REJECT;
    
                                // 检查父节点
                                    const parent = node.parentNode;
                                    if (!parent) return NodeFilter.FILTER_REJECT;
    
                                // 排除特定元素内的文本
                                    if (parent.closest?.(CONFIG.excludeSelector)) {
                                        return NodeFilter.FILTER_REJECT;
                                    }
    
                                    return NodeFilter.FILTER_ACCEPT;
                            }
                        }
                    );
    
                    // 遍历并处理每个文本节点
                    let node;
                    while (node = walker.nextNode()) {
                            const text = node.textContent.trim();
                            if (!text) continue;
    
                        // 保存原始文本(如果尚未保存)
                            if (!STATE.originalTexts.has(node)) {
                                STATE.originalTexts.set(node, text);
                            }
    
                        // 根据当前状态进行转换或恢复
                            if (STATE.pageSimplified) {
                                const convertedText = converter.toSimplified(text);
                                if (text !== convertedText) {
                                    node.textContent = convertedText;
                                }
                            } else {
                                const originalText = STATE.originalTexts.get(node);
                                if (originalText && node.textContent !== originalText) {
                                    node.textContent = originalText;
                                }
                            }
                    }
                } catch (error) {
                    console.debug('处理文本节点时出错:', error);
                }
            });
        } catch (error) {
            console.debug('转换页面文本时出错:', error);
        }
    }
    
    function attachInputListener(handleInput) {
        /**
         * 为页面上的输入元素添加转换事件监听器
         * @param {Function} handleInput - 输入处理函数
         */
        try {
            const inputElements = document.querySelectorAll(CONFIG.inputSelector);
            if (!inputElements.length) return;
    
            inputElements.forEach(element => {
                try {
                    // 排除已处理的元素和搜索框
                    if (element?.dataset?.hasConverter || element?.dataset?.isSearchInput) {
                        return;
                    }

                    // 添加输入事件监听器
                    element.addEventListener('input', handleInput);

                    // 标记元素已添加转换器
                    element.dataset.hasConverter = 'true';
                } catch (error) {
                    console.debug('为输入元素添加事件监听器时出错:', error);
                }
            });
        } catch (error) {
            console.debug('查找输入元素时出错:', error);
        }
    }
    
    function createObserver(handleInput, converter) {
        /**
         * 创建DOM变化观察器,监听页面变化并处理新添加的元素
         * @param {Function} handleInput - 输入处理函数
         * @param {Object} converter - 文本转换器对象
         * @returns {MutationObserver} - 配置好的观察器实例
         */
        return new MutationObserver(mutations => {
                let needsTextConversion = false;
    
                for (const mutation of mutations) {
                // 跳过没有新增节点的变化
                    if (!mutation.addedNodes.length) continue;
    
                // 检查是否有新的输入元素
                const hasNewInputs = Array.from(mutation.addedNodes)
                    .some(node => {
                        try {
                            // 检查节点是否包含输入元素
                            return node.nodeType === Node.ELEMENT_NODE &&
                                   node.querySelectorAll?.(CONFIG.inputSelector)?.length > 0;
                            } catch (error) {
                            console.debug('检查新节点时出错:', error);
                                return false;
                            }
                        });
    
                // 如果有新的输入元素,为它们添加事件监听器
                        if (hasNewInputs) {
                            attachInputListener(handleInput);
                        }
    
                // 标记需要进行文本转换
                        needsTextConversion = true;
                }
    
            // 如果需要文本转换,延迟执行以确保DOM已完全更新
                if (needsTextConversion) {
                    setTimeout(() => convertPageText(converter), 100);
                }
        });
    }
    
    function createConfigModal() {
        const modalHtml = `
            <div id="config-modal" style="display: none; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
                background: #1a1a1a; padding: 20px; border-radius: 8px; z-index: 10000; min-width: 600px; color: #fff;">
                <div style="display: flex; justify-content: space-between; margin-bottom: 15px;">
                    <h3 style="margin: 0;">ST工具箱</h3>
                    <button id="close-config-modal" style="background: none; border: none; color: #fff; cursor: pointer;">✕</button>
                </div>
    
                <!-- 标签栏 -->
                <div style="display: flex; gap: 10px; margin-bottom: 15px; border-bottom: 1px solid #444; padding-bottom: 10px;">
                    <button id="tab-configs" class="modal-tab active" style="padding: 8px 20px; background: #4a90e2; border: none; color: #fff; cursor: pointer; border-radius: 4px; transition: all 0.2s;">配置管理</button>
                    <button id="tab-presets" class="modal-tab" style="padding: 8px 20px; background: #3d3d3d; border: none; color: #fff; cursor: pointer; border-radius: 4px; transition: all 0.2s;">预设关键词</button>
                    <button id="tab-settings" class="modal-tab" style="padding: 8px 20px; background: #3d3d3d; border: none; color: #fff; cursor: pointer; border-radius: 4px; transition: all 0.2s;">设置</button>
                    <button id="tab-contact" class="modal-tab" style="padding: 8px 20px; background: #3d3d3d; border: none; color: #fff; cursor: pointer; border-radius: 4px; transition: all 0.2s;">联系我</button>
                </div>
    
                <!-- 配置管理面板 -->
                <div id="panel-configs" class="panel" style="display: block;">
                    <div style="padding: 15px; background: #2d2d2d; border-radius: 4px;">
                        <div style="margin-bottom: 15px;">
                            <input type="text" id="config-name" placeholder="配置名称"
                                style="padding: 5px; margin-right: 10px; background: #3d3d3d; border: 1px solid #444; color: #fff; width: 200px;">
                            <div class="custom-select" style="display: inline-block; position: relative; width: 150px; margin-right: 10px;">
                                <input type="text" id="config-category" placeholder="选择或输入分类"
                                    style="padding: 5px; background: #3d3d3d; border: 1px solid #444; color: #fff; width: 100%; cursor: pointer;">
                                <div id="category-dropdown" style="display: none; position: absolute; top: 100%; left: 0; width: 100%;
                                    background: #3d3d3d; border: 1px solid #444; border-top: none; max-height: 200px; overflow-y: auto; z-index: 1000;">
                                </div>
                            </div>
                            <button id="save-config" style="padding: 5px 10px; background: #4a90e2; border: none; color: #fff; cursor: pointer; border-radius: 3px;">
                                保存当前配置
                            </button>
                        </div>
                        <div id="category-tabs" style="margin-bottom: 15px; border-bottom: 1px solid #444; padding-bottom: 10px;"></div>
                        <div id="config-list" style="max-height: 300px; overflow-y: auto;">
                        </div>
                    </div>
                </div>
    
                <!-- 设置面板 -->
                <div id="panel-settings" class="panel" style="display: none;">
                    <div style="padding: 15px; background: #2d2d2d; border-radius: 4px;">
                        <!-- 功能开关 -->
                        <div style="margin-bottom: 20px;">
                            <div style="font-weight: bold; margin-bottom: 10px; color: #4a90e2;">功能开关</div>
                            <div style="display: flex; gap: 10px;">
                                <button id="toggle-page-simplified" style="flex: 1; padding: 8px 15px; background: ${STATE.pageSimplified ? '#4a90e2' : '#3d3d3d'}; border: none; color: #fff; cursor: pointer; border-radius: 3px; transition: background-color 0.2s; text-align: center;">
                                    ${STATE.pageSimplified ? '✓ 页面简体' : '✗ 页面简体'}
                                </button>
                                <button id="toggle-input-traditional" style="flex: 1; padding: 8px 15px; background: ${STATE.inputTraditional ? '#4a90e2' : '#3d3d3d'}; border: none; color: #fff; cursor: pointer; border-radius: 3px; transition: background-color 0.2s; text-align: center;">
                                    ${STATE.inputTraditional ? '✓ 输入繁体' : '✗ 输入繁体'}
                                </button>
                                <button id="toggle-auto-load" style="flex: 1; padding: 8px 15px; background: ${STATE.autoLoadEnabled ? '#4a90e2' : '#3d3d3d'}; border: none; color: #fff; cursor: pointer; border-radius: 3px; transition: background-color 0.2s; text-align: center;">
                                    ${STATE.autoLoadEnabled ? '✓ 自动加载' : '✗ 自动加载'}
                                </button>
                            </div>
                        </div>
    
                        <!-- 配置导入导出 -->
                        <div style="margin-top: 20px;">
                            <div style="font-weight: bold; margin-bottom: 10px; color: #4a90e2;">配置导入导出</div>
                            <div style="display: flex; gap: 10px;">
                                <button id="export-configs" style="flex: 1; padding: 8px 15px; background: #27ae60; border: none; color: #fff; cursor: pointer; border-radius: 3px;">导出配置</button>
                                <button id="import-configs" style="flex: 1; padding: 8px 15px; background: #e67e22; border: none; color: #fff; cursor: pointer; border-radius: 3px;">导入配置</button>
                                <input type="file" id="import-file" accept=".json" style="display: none;">
                            </div>
                        </div>
                    </div>
                </div>

                <!-- 预设关键词面板 -->
                <div id="panel-presets" class="panel" style="display: none;">
                    <div style="padding: 15px; background: #2d2d2d; border-radius: 4px;">
                        <div style="margin-bottom: 15px; display: flex; justify-content: flex-end;">
                            <button id="add-preset" style="padding: 8px 20px; background: #4a90e2; border: none; color: #fff; cursor: pointer; border-radius: 4px; transition: all 0.2s;">
                                添加预设
                            </button>
                        </div>
                        <div id="preset-list" style="max-height: 400px; overflow-y: auto;">
                        </div>
                    </div>
                </div>
                <!-- 联系我面板 -->
                <div id="panel-contact" class="panel" style="display: none;">
                    <div style="padding: 15px; background: #2d2d2d; border-radius: 4px;">
                        <div style="text-align: center; padding: 20px;">
                            <div style="font-size: 18px; color: #4a90e2; margin-bottom: 15px;">欢迎加入POE2 ST工具箱交流群</div>
                            <div style="font-size: 24px; color: #FFD700; margin-bottom: 15px;">QQ群:858024457</div>
                            <div style="color: #999; font-size: 14px;">
                                欢迎各位流亡者加入交流群,反馈使用问题,提出建议!
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <!-- 预设编辑弹窗 -->
            <div id="preset-edit-modal" style="display: none; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
                background: #1a1a1a; padding: 20px; border-radius: 8px; z-index: 10002; width: 800px; color: #fff; box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);">
                <div style="display: flex; justify-content: space-between; margin-bottom: 15px;">
                    <h3 style="margin: 0;" id="preset-edit-title">添加预设</h3>
                    <button id="close-preset-edit" style="background: none; border: none; color: #fff; cursor: pointer; font-size: 20px;">✕</button>
                </div>
                <div style="margin-bottom: 15px;">
                    <div style="margin-bottom: 10px;">
                        <label style="display: block; margin-bottom: 5px;">预设名称</label>
                        <input type="text" id="preset-name" style="width: 100%; padding: 8px; background: #2d2d2d; border: 1px solid #444; color: #fff; border-radius: 4px;">
                    </div>
                    <div>
                        <label style="display: block; margin-bottom: 5px;">关键词(用;分隔)</label>
                        <textarea id="preset-keywords" style="width: 100%; height: 200px; padding: 8px; background: #2d2d2d; border: 1px solid #444; color: #fff; border-radius: 4px; resize: vertical; font-family: monospace;"></textarea>
                    </div>
                </div>
                <div style="display: flex; justify-content: flex-end; gap: 10px;">
                    <button id="cancel-preset-edit" style="padding: 8px 20px; background: #3d3d3d; border: none; color: #fff; cursor: pointer; border-radius: 4px;">
                        取消
                    </button>
                    <button id="save-preset" style="padding: 8px 20px; background: #4a90e2; border: none; color: #fff; cursor: pointer; border-radius: 4px;">
                        保存
                    </button>
                </div>
            </div>

            <!-- 添加遮罩层 -->
            <div id="preset-edit-overlay" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.7); z-index: 10001;"></div>
        </div>
    `;
    
        document.body.insertAdjacentHTML('beforeend', modalHtml);
    
        // 添加遮罩
        const overlay = document.createElement('div');
        overlay.id = 'config-modal-overlay';
        overlay.style.cssText = `
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.5);
            z-index: 9999;
        `;
        document.body.appendChild(overlay);
    
        // 添加样式
        const style = document.createElement('style');
        style.textContent = `
            .modal-tab.active {
                background: #4a90e2 !important;
            }
            .modal-tab:hover {
                background: #357abd !important;
            }
            .panel {
                transition: opacity 0.3s ease;
            }
            #config-list::-webkit-scrollbar {
                width: 8px;
            }
            #config-list::-webkit-scrollbar-track {
                background: #1a1a1a;
            }
            #config-list::-webkit-scrollbar-thumb {
                background: #444;
                border-radius: 4px;
            }
            #config-list::-webkit-scrollbar-thumb:hover {
                background: #555;
            }
        `;
        document.head.appendChild(style);
    
        setupConfigModalEvents();
        updateConfigList();
        setupCategoryDropdown();
    }
    
    function setupCategoryDropdown() {
        const categoryInput = document.getElementById('config-category');
        const dropdown = document.getElementById('category-dropdown');
        let isDropdownVisible = false;
    
        function updateDropdown() {
            const categories = Object.keys(STATE.configs);
            const inputValue = categoryInput.value.toLowerCase();
    
            dropdown.innerHTML = '';
    
            categories
                .filter(category => category.toLowerCase().includes(inputValue))
                .forEach(category => {
                    const item = document.createElement('div');
                    item.className = 'dropdown-item';
                    item.textContent = category;
                    item.onclick = () => {
                        categoryInput.value = category;
                        hideDropdown();
                    };
                    dropdown.appendChild(item);
                });
    
            if (categories.length === 0) {
                const item = document.createElement('div');
                item.className = 'dropdown-item';
                item.textContent = '无已有分类';
                item.style.color = '#666';
                dropdown.appendChild(item);
            }
        }
    
        function showDropdown() {
            updateDropdown();
            dropdown.style.display = 'block';
            isDropdownVisible = true;
        }
    
        function hideDropdown() {
            dropdown.style.display = 'none';
            isDropdownVisible = false;
        }
    
        categoryInput.addEventListener('focus', showDropdown);
        categoryInput.addEventListener('input', updateDropdown);
    
        // 点击外部区域时隐藏下拉列表
        document.addEventListener('click', (e) => {
            const isClickInside = categoryInput.contains(e.target) || dropdown.contains(e.target);
            if (!isClickInside && isDropdownVisible) {
                hideDropdown();
            }
        });
    
        // 阻止事件冒泡,避免点击下拉列表时触发外部点击事件
        dropdown.addEventListener('click', (e) => {
            e.stopPropagation();
        });
    }
    
    function setupConfigModalEvents() {
        const modal = document.getElementById('config-modal');
        const overlay = document.getElementById('config-modal-overlay');
        const closeBtn = document.getElementById('close-config-modal');
        const saveBtn = document.getElementById('save-config');
        const togglePageBtn = document.getElementById('toggle-page-simplified');
        const toggleInputBtn = document.getElementById('toggle-input-traditional');
        const toggleAutoLoadBtn = document.getElementById('toggle-auto-load');
        const exportBtn = document.getElementById('export-configs');
        const importBtn = document.getElementById('import-configs');
        const importFile = document.getElementById('import-file');
        const tabConfigs = document.getElementById('tab-configs');
        const tabSettings = document.getElementById('tab-settings');
        const tabPresets = document.getElementById('tab-presets'); 
        const tabContact = document.getElementById('tab-contact');
        const panelConfigs = document.getElementById('panel-configs');
        const panelSettings = document.getElementById('panel-settings');
        const panelPresets = document.getElementById('panel-presets');
        const panelContact = document.getElementById('panel-contact');
        const savePresetBtn = document.getElementById('save-preset');

        const addPresetBtn = document.getElementById('add-preset');
        const presetEditModal = document.getElementById('preset-edit-modal');
        const presetEditOverlay = document.getElementById('preset-edit-overlay');
        const closePresetEdit = document.getElementById('close-preset-edit');
        const cancelPresetEdit = document.getElementById('cancel-preset-edit');
        const presetEditTitle = document.getElementById('preset-edit-title');

        // 标签切换函数
        function switchTab(activeTab) {
            // 重置所有标签和面板
            [tabConfigs, tabSettings, tabPresets, tabContact].forEach(tab => {
                tab.classList.remove('active');
                tab.style.background = '#3d3d3d';
            });
            [panelConfigs, panelSettings, panelPresets, panelContact].forEach(panel => {
                panel.style.display = 'none';
            });

            // 激活选中的标签和面板
            activeTab.classList.add('active');
            activeTab.style.background = '#4a90e2';
            
            // 显示对应的面板
            if (activeTab === tabConfigs) {
                panelConfigs.style.display = 'block';
            } else if (activeTab === tabSettings) {
                panelSettings.style.display = 'block';
            } else if (activeTab === tabPresets) {
                panelPresets.style.display = 'block';
                updatePresetList();
            } else if (activeTab === tabContact) {
                panelContact.style.display = 'block';
            }
        }

        // 标签切换事件
        tabConfigs.addEventListener('click', () => switchTab(tabConfigs));
        tabSettings.addEventListener('click', () => switchTab(tabSettings));
        tabPresets.addEventListener('click', () => switchTab(tabPresets));
        tabContact.addEventListener('click', () => switchTab(tabContact));
        
        // 初始化显示配置管理标签
        switchTab(tabConfigs);

        closeBtn.addEventListener('click', () => {
            modal.style.display = 'none';
            overlay.style.display = 'none';
        });
    
        overlay.addEventListener('click', () => {
            modal.style.display = 'none';
            overlay.style.display = 'none';
        });
    
        togglePageBtn.addEventListener('click', () => {
            STATE.pageSimplified = !STATE.pageSimplified;
            GM_setValue('pageSimplified', STATE.pageSimplified);
            togglePageBtn.textContent = STATE.pageSimplified ? '✓ 页面简体' : '✗ 页面简体';
            togglePageBtn.style.backgroundColor = STATE.pageSimplified ? '#4a90e2' : '#3d3d3d';
            convertPageText(window.converter, true);
        });
    
        toggleInputBtn.addEventListener('click', () => {
            STATE.inputTraditional = !STATE.inputTraditional;
            GM_setValue('inputTraditional', STATE.inputTraditional);
            toggleInputBtn.textContent = STATE.inputTraditional ? '✓ 输入繁体' : '✗ 输入繁体';
            toggleInputBtn.style.backgroundColor = STATE.inputTraditional ? '#4a90e2' : '#3d3d3d';
        });
    
        toggleAutoLoadBtn.addEventListener('click', () => {
            STATE.autoLoadEnabled = !STATE.autoLoadEnabled;
            GM_setValue('autoLoadEnabled', STATE.autoLoadEnabled);
            toggleAutoLoadBtn.textContent = STATE.autoLoadEnabled ? '✓ 自动加载' : '✗ 自动加载';
            toggleAutoLoadBtn.style.backgroundColor = STATE.autoLoadEnabled ? '#4a90e2' : '#3d3d3d';
        });
    
        saveBtn.addEventListener('click', saveCurrentConfig);
    
        // 修改导出配置
        exportBtn.addEventListener('click', () => {
            const configData = {
                version: '2.0.0',
                configs: {},
                searchPresets: STATE.searchPresets
            };

            // 复制配置,但不包含 timestamp
            Object.keys(STATE.configs).forEach(category => {
                configData.configs[category] = {};
                Object.keys(STATE.configs[category]).forEach(name => {
                    configData.configs[category][name] = {
                        url: STATE.configs[category][name].url
                    };
                });
            });
            
            const blob = new Blob([JSON.stringify(configData, null, 2)], { type: 'application/json' });
            const url = URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = `poe2_trade_configs_${new Date().toISOString().slice(0,10)}.json`;
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
            URL.revokeObjectURL(url);
        });
    
        // 导入配置按钮点击
        importBtn.addEventListener('click', () => {
            importFile.click();
        });
    
        // 处理文件导入
        importFile.addEventListener('change', (e) => {
            const file = e.target.files[0];
            if (!file) return;
    
            const reader = new FileReader();
            reader.onload = (event) => {
                try {
                    const importedData = JSON.parse(event.target.result);
                    
                    // 验证导入的数据
                    if (!importedData.version || (!importedData.configs && !importedData.searchPresets)) {
                        throw new Error('无效的配置文件格式');
                    }
    
                    // 确认导入
                    if (confirm(`确定要导入这些配置吗?\n这将会覆盖同名的现有配置和预设关键词。`)) {
                        // 合并配置
                        if (importedData.configs) {
                            Object.keys(importedData.configs).forEach(category => {
                                if (!STATE.configs[category]) {
                                    STATE.configs[category] = {};
                                }
                                Object.assign(STATE.configs[category], importedData.configs[category]);
                            });
                            GM_setValue('savedConfigs', STATE.configs);
                            updateConfigList();
                        }

                        // 合并预设关键词
                        if (importedData.searchPresets) {
                            Object.assign(STATE.searchPresets, importedData.searchPresets);
                            GM_setValue('searchPresets', STATE.searchPresets);
                            updatePresetList();
                        }

                        alert('配置导入成功!');
                    }
                } catch (error) {
                    alert('导入失败:' + error.message);
                }
                
                // 清除文件选择,允许重复导入同一个文件
                importFile.value = '';
            };
            reader.readAsText(file);
        });
    
        // 添加预设标签切换事件
        tabPresets.addEventListener('click', () => {
            tabPresets.classList.add('active');
            tabConfigs.classList.remove('active');
            tabSettings.classList.remove('active');
            tabConfigs.style.background = '#3d3d3d';
            tabSettings.style.background = '#3d3d3d';
            panelConfigs.style.display = 'none';
            panelSettings.style.display = 'none';
            panelPresets.style.display = 'block';
            updatePresetList();
        });
    
        // 添加保存预设事件
        savePresetBtn.addEventListener('click', saveSearchPreset);

        function closePresetEditModal() {
            presetEditModal.style.display = 'none';
            presetEditOverlay.style.display = 'none';
        }

        // 打开预设编辑弹窗
        addPresetBtn.addEventListener('click', () => {
            presetEditModal.style.display = 'block';
            presetEditOverlay.style.display = 'block';
            presetEditTitle.textContent = '添加预设';
            document.getElementById('preset-name').value = '';
            document.getElementById('preset-keywords').value = '';
            document.getElementById('preset-name').dataset.editMode = 'false';
        });

        // 关闭预设编辑弹窗
        [closePresetEdit, cancelPresetEdit, presetEditOverlay].forEach(btn => {
            btn.addEventListener('click', closePresetEditModal);
        });

        // 添加预设名称和关键词输入框的事件处理
        const presetNameInput = document.getElementById('preset-name');
        const presetKeywordsInput = document.getElementById('preset-keywords');

        // 标记这些输入框不需要转换
        presetNameInput.dataset.noConvert = 'true';
        presetKeywordsInput.dataset.noConvert = 'true';

        // 移除原有的输入转换处理
        [presetNameInput, presetKeywordsInput].forEach(input => {
            const oldInput = input.cloneNode(true);
            input.parentNode.replaceChild(oldInput, input);
        });
    }
    
    // 修改 saveCurrentConfig 函数
    function saveCurrentConfig() {
        const name = document.getElementById('config-name').value.trim();
        const category = document.getElementById('config-category').value.trim();

        if (!name) {
            alert('请输入配置名称');
            return;
        }

        if (!category) {
            alert('请输入分类名称');
            return;
        }

        if (!STATE.configs[category]) {
            STATE.configs[category] = {};
        }

        STATE.configs[category][name] = {
            url: window.location.href
        };

        GM_setValue('savedConfigs', STATE.configs);
        updateConfigList();

        document.getElementById('config-name').value = '';
        document.getElementById('config-category').value = '';
    }
    
    function updateConfigList() {
        const configList = document.getElementById('config-list');
        const categoryTabs = document.getElementById('category-tabs');
        configList.innerHTML = '';
        categoryTabs.innerHTML = '';
    
        // 获取所有分类
        const categories = Object.keys(STATE.configs);
    
        // 如果没有配置,显示提示信息
        if (categories.length === 0) {
            configList.innerHTML = '<div style="text-align: center; color: #666;">暂无保存的配置</div>';
            return;
        }
    
        // 创建标签
        categories.forEach((category, index) => {
            const tabButton = document.createElement('button');
            tabButton.textContent = category;
            tabButton.style.cssText = `
                background: ${index === 0 ? '#4a90e2' : '#3d3d3d'};
                border: none;
                color: #fff;
                padding: 5px 15px;
                cursor: pointer;
                border-radius: 3px;
                transition: background-color 0.2s;
                margin-right: 10px;
            `;
            tabButton.dataset.category = category;
            tabButton.title = '双击删除分类';
    
            tabButton.addEventListener('click', (e) => {
                document.querySelectorAll('#category-tabs button[data-category]').forEach(btn => {
                    btn.style.backgroundColor = '#3d3d3d';
                });
                tabButton.style.backgroundColor = '#4a90e2';
                showCategoryConfigs(category);
            });
    
            tabButton.addEventListener('dblclick', (e) => {
                e.stopPropagation();
                deleteCategory(category);
            });
    
            categoryTabs.appendChild(tabButton);
        });
    
        // 默认显示第一个分类的配置
        showCategoryConfigs(categories[0]);
    }
    
    function deleteCategory(category) {
        /**
         * 删除指定的配置类别及其所有配置
         * @param {string} category - 要删除的配置类别
         */
        try {
            // 检查类别是否存在
            if (!STATE.configs[category]) {
                console.warn(`类别不存在: ${category}`);
                return;
            }

            // 获取该类别下的配置数量
        const configCount = Object.keys(STATE.configs[category]).length;

            // 确认删除操作
        if (confirm(`确定要删除分类 "${category}" 及其包含的 ${configCount} 个配置吗?`)) {
                // 删除类别
            delete STATE.configs[category];

                // 保存更新后的配置
            GM_setValue('savedConfigs', STATE.configs);

                // 更新配置列表显示
            updateConfigList();

                console.log(`已删除类别: ${category} (包含 ${configCount} 个配置)`);
            }
        } catch (error) {
            console.error('删除类别时出错:', error);
        }
    }
    
    function showCategoryConfigs(category) {
        /**
         * 显示指定类别的所有配置
         * @param {string} category - 配置类别
         */
        try {
            // 获取配置列表容器
        const configList = document.getElementById('config-list');
            if (!configList) {
                console.warn('无法找到配置列表容器');
                return;
            }

            // 清空当前列表
        configList.innerHTML = '';

            // 获取指定类别的配置
        const configs = STATE.configs[category];
            if (!configs || Object.keys(configs).length === 0) {
                const emptyMessage = document.createElement('div');
                emptyMessage.textContent = '该分类下没有配置';
                emptyMessage.style.padding = '10px';
                emptyMessage.style.color = '#999';
                configList.appendChild(emptyMessage);
                return;
            }

            // 遍历并显示每个配置
        Object.entries(configs).forEach(([name, data]) => {
                // 创建配置项容器
            const configItem = document.createElement('div');
            configItem.style.cssText = `
                display: grid;
                grid-template-columns: 1fr auto auto auto;
                align-items: center;
                padding: 8px;
                margin: 5px 0;
                background: #3d3d3d;
                border-radius: 4px;
                gap: 10px;
            `;
    
                // 创建配置名称元素
            const nameSpan = document.createElement('span');
            nameSpan.textContent = name;
            nameSpan.style.cssText = `
                overflow: hidden;
                text-overflow: ellipsis;
                white-space: nowrap;
            `;
    
                // 创建读取按钮
            const loadBtn = document.createElement('button');
            loadBtn.textContent = '读取';
            loadBtn.style.cssText = `
                background: #4a90e2;
                border: none;
                color: #fff;
                padding: 3px 12px;
                cursor: pointer;
                border-radius: 3px;
                transition: background-color 0.2s;
            `;
                loadBtn.onclick = () => {
                    loadConfig(data.url);
                };
    
                // 创建更新按钮
            const updateBtn = document.createElement('button');
            updateBtn.textContent = '更新';
            updateBtn.style.cssText = `
                background: #27ae60;
                border: none;
                color: #fff;
                padding: 3px 12px;
                cursor: pointer;
                border-radius: 3px;
                transition: background-color 0.2s;
            `;
            updateBtn.onclick = (e) => {
                e.stopPropagation();
                updateConfig(category, name);
            };
    
                // 创建删除按钮
            const deleteBtn = document.createElement('button');
            deleteBtn.textContent = '删除';
            deleteBtn.style.cssText = `
                background: #e74c3c;
                border: none;
                color: #fff;
                padding: 3px 12px;
                cursor: pointer;
                border-radius: 3px;
                transition: background-color 0.2s;
            `;
            deleteBtn.onclick = (e) => {
                e.stopPropagation();
                deleteConfig(category, name);
            };
    
                // 添加所有元素到配置项
            configItem.appendChild(nameSpan);
            configItem.appendChild(loadBtn);
            configItem.appendChild(updateBtn);
            configItem.appendChild(deleteBtn);

                // 添加配置项到列表
            configList.appendChild(configItem);
        });
        } catch (error) {
            console.error('显示配置列表时出错:', error);
        }
    }
    
    function loadConfig(url) {
        /**
         * 加载指定URL的配置
         * @param {string} url - 要加载的配置URL
         */
        try {
            if (!url) {
                console.warn('加载配置失败: URL为空');
                return;
            }

            // 导航到指定URL
        window.location.href = url;
            console.log('正在加载配置:', url);
        } catch (error) {
            console.error('加载配置时出错:', error);
        }
    }
    
    function deleteConfig(category, name) {
        /**
         * 删除指定类别和名称的配置
         * @param {string} category - 配置类别
         * @param {string} name - 配置名称
         */
        try {
            // 确认删除操作
        if (confirm(`确定要删除配置 "${name}" 吗?`)) {
                // 删除指定配置
                if (STATE.configs[category] && STATE.configs[category][name]) {
            delete STATE.configs[category][name];

                    // 如果类别下没有配置了,删除整个类别
            if (Object.keys(STATE.configs[category]).length === 0) {
                delete STATE.configs[category];
            }

                    // 保存更新后的配置
            GM_setValue('savedConfigs', STATE.configs);

                    // 更新配置列表显示
            updateConfigList();

                    console.log(`已删除配置: ${category}/${name}`);
                } else {
                    console.warn(`配置不存在: ${category}/${name}`);
                }
            }
        } catch (error) {
            console.error('删除配置时出错:', error);
        }
    }
    
    function createConfigButton() {
        const floatingButton = document.createElement('div');
        floatingButton.style.cssText = `
            position: fixed;
            right: 20px;
            top: 50%;
            transform: translateY(-50%);
            width: 50px;
            height: 50px;
            background: linear-gradient(135deg, #3c3c28 0%, #2a2a1c 100%);
            border-radius: 25px;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            color: #ffd700;
            font-weight: bold;
            font-family: 'Fontin SmallCaps', Arial, sans-serif;
            font-size: 18px;
            box-shadow: 0 0 20px rgba(0,0,0,0.5),
                        inset 0 0 8px rgba(255, 215, 0, 0.3),
                        0 0 30px rgba(255, 215, 0, 0.2);
            border: 1px solid rgba(255, 215, 0, 0.4);
            z-index: 9998;
            transition: all 0.3s ease;
            user-select: none;
            touch-action: none;
            text-shadow: 0 0 10px rgba(255, 215, 0, 0.6);
            animation: normalGlowing 2s ease-in-out infinite;
        `;
        floatingButton.textContent = 'ST';
        floatingButton.title = 'ST工具箱 (按住可拖动)';
    
        // 添加悬停效果
        floatingButton.addEventListener('mouseenter', () => {
            if (!isDragging) {
                floatingButton.style.transform = 'scale(1.1)';
                floatingButton.style.boxShadow = `
                    0 0 25px rgba(0,0,0,0.5),
                    inset 0 0 12px rgba(255, 215, 0, 0.5),
                    0 0 40px rgba(255, 215, 0, 0.3)
                `;
                floatingButton.style.color = '#ffe44d';
                floatingButton.style.textShadow = '0 0 15px rgba(255, 215, 0, 0.8)';
                floatingButton.style.border = '1px solid rgba(255, 215, 0, 0.6)';
                floatingButton.style.animation = 'none';
    
                if (isHidden) {
                    showButton();
                }
            }
        });
    
        floatingButton.addEventListener('mouseleave', () => {
            if (!isDragging) {
                floatingButton.style.transform = 'scale(1)';
                floatingButton.style.boxShadow = `
                    0 0 20px rgba(0,0,0,0.5),
                    inset 0 0 8px rgba(255, 215, 0, 0.3),
                    0 0 30px rgba(255, 215, 0, 0.2)
                `;
                floatingButton.style.color = '#ffd700';
                floatingButton.style.textShadow = '0 0 10px rgba(255, 215, 0, 0.6)';
                floatingButton.style.border = '1px solid rgba(255, 215, 0, 0.4)';
                floatingButton.style.animation = 'normalGlowing 2s ease-in-out infinite';
    
                checkAndHideButton();
            }
        });
    
        // 添加拖拽功能
        let isDragging = false;
        let startX, startY;
        let lastX = GM_getValue('floatingButtonX', window.innerWidth - 70);
        let lastY = GM_getValue('floatingButtonY', window.innerHeight / 2);
        let dragDistance = 0;
        let mouseDownTime = 0;
        let isHidden = false;
    
        function dragStart(e) {
            isDragging = true;
            dragDistance = 0;
            mouseDownTime = Date.now();
            const rect = floatingButton.getBoundingClientRect();
            startX = e.clientX - rect.left;
            startY = e.clientY - rect.top;
            floatingButton.style.transition = 'none';
            floatingButton.style.transform = 'scale(1)';
        }
    
        function drag(e) {
            if (!isDragging) return;
            e.preventDefault();
    
            const x = e.clientX - startX;
            const y = e.clientY - startY;
    
            // 计算拖动距离
            const dx = x - lastX;
            const dy = y - lastY;
            dragDistance += Math.sqrt(dx * dx + dy * dy);
    
            // 限制拖动范围,添加边距防止完全贴边
            const margin = 20; // 边距
            const maxX = window.innerWidth - floatingButton.offsetWidth - margin;
            const maxY = window.innerHeight - floatingButton.offsetHeight - margin;
            const minX = margin;
            const minY = margin;
    
            lastX = Math.max(minX, Math.min(x, maxX));
            lastY = Math.max(minY, Math.min(y, maxY));
    
            floatingButton.style.left = lastX + 'px';
            floatingButton.style.top = lastY + 'px';
            floatingButton.style.right = 'auto';
        }
    
        function dragEnd(e) {
            if (!isDragging) return;
    
            const dragDuration = Date.now() - mouseDownTime;
            isDragging = false;
            floatingButton.style.transition = 'all 0.3s ease';
    
            // 保存位置
            GM_setValue('floatingButtonX', lastX);
            GM_setValue('floatingButtonY', lastY);
    
            // 如果拖动距离小于5像素且时间小于200ms,则认为是点击
            if (dragDistance < 5 && dragDuration < 200) {
                document.getElementById('config-modal').style.display = 'block';
                document.getElementById('config-modal-overlay').style.display = 'block';
            }
        }
    
        function checkAndHideButton() {
            const threshold = 20; // 距离边缘多少像素时触发隐藏
            const buttonWidth = floatingButton.offsetWidth;
            const buttonHeight = floatingButton.offsetHeight;
            const buttonRight = lastX + buttonWidth;
            const buttonBottom = lastY + buttonHeight;
            const windowWidth = window.innerWidth;
            const windowHeight = window.innerHeight;
    
            // 检查各个边缘
            if (buttonRight > windowWidth - threshold) {
                // 右边缘
                hideButton('right');
            } else if (lastX < threshold) {
                // 左边缘
                hideButton('left');
            } else if (lastY < threshold) {
                // 上边缘
                hideButton('top');
            } else if (buttonBottom > windowHeight - threshold) {
                // 下边缘
                hideButton('bottom');
            }
        }
    
        function hideButton(direction) {
            isHidden = true;
            floatingButton.style.transition = 'all 0.3s ease';
    
            // 添加金光动画
            floatingButton.style.animation = 'none';
            floatingButton.offsetHeight; // 触发重绘
            floatingButton.style.animation = 'glowing 1.5s ease-in-out infinite';
            floatingButton.style.background = 'linear-gradient(135deg, #5a5a42 0%, #3a3a2c 100%)';
    
            switch (direction) {
                case 'right':
                    floatingButton.style.transform = 'translateY(-50%) translateX(60%)';
                    floatingButton.style.borderRadius = '25px 0 0 25px';
                    break;
                case 'left':
                    floatingButton.style.transform = 'translateY(-50%) translateX(-60%)';
                    floatingButton.style.borderRadius = '0 25px 25px 0';
                    break;
                case 'top':
                    floatingButton.style.transform = 'translateX(-50%) translateY(-60%)';
                    floatingButton.style.borderRadius = '0 0 25px 25px';
                    break;
                case 'bottom':
                    floatingButton.style.transform = 'translateX(-50%) translateY(60%)';
                    floatingButton.style.borderRadius = '25px 25px 0 0';
                    break;
            }
        }
    
        function showButton() {
            isHidden = false;
            floatingButton.style.transition = 'all 0.3s ease';
            floatingButton.style.animation = 'normalGlowing 2s ease-in-out infinite';
            floatingButton.style.background = 'linear-gradient(135deg, #3c3c28 0%, #2a2a1c 100%)';
            floatingButton.style.transform = 'scale(1)';
            floatingButton.style.borderRadius = '25px';
        }
    
        // 添加金光动画样式
        const glowingStyle = document.createElement('style');
        glowingStyle.textContent = `
            @keyframes normalGlowing {
                0% {
                    box-shadow: 0 0 20px rgba(0,0,0,0.5),
                                inset 0 0 8px rgba(255, 215, 0, 0.3),
                                0 0 30px rgba(255, 215, 0, 0.2);
                    border-color: rgba(255, 215, 0, 0.4);
                    color: #ffd700;
                    text-shadow: 0 0 10px rgba(255, 215, 0, 0.6);
                }
                50% {
                    box-shadow: 0 0 25px rgba(0,0,0,0.5),
                                inset 0 0 12px rgba(255, 215, 0, 0.4),
                                0 0 40px rgba(255, 215, 0, 0.3),
                                0 0 60px rgba(255, 215, 0, 0.2);
                    border-color: rgba(255, 215, 0, 0.5);
                    color: #ffe44d;
                    text-shadow: 0 0 15px rgba(255, 215, 0, 0.7);
                }
                100% {
                    box-shadow: 0 0 20px rgba(0,0,0,0.5),
                                inset 0 0 8px rgba(255, 215, 0, 0.3),
                                0 0 30px rgba(255, 215, 0, 0.2);
                    border-color: rgba(255, 215, 0, 0.4);
                    color: #ffd700;
                    text-shadow: 0 0 10px rgba(255, 215, 0, 0.6);
                }
            }
    
            @keyframes glowing {
                0% {
                    box-shadow: 0 0 20px rgba(0,0,0,0.5),
                                inset 0 0 8px rgba(255, 215, 0, 0.5),
                                0 0 30px rgba(255, 215, 0, 0.4),
                                0 0 50px rgba(255, 215, 0, 0.2);
                    border-color: rgba(255, 215, 0, 0.6);
                    color: #ffd700;
                    text-shadow: 0 0 15px rgba(255, 215, 0, 0.8);
                }
                50% {
                    box-shadow: 0 0 30px rgba(0,0,0,0.6),
                                inset 0 0 20px rgba(255, 215, 0, 0.8),
                                0 0 60px rgba(255, 215, 0, 0.6),
                                0 0 100px rgba(255, 215, 0, 0.4),
                                0 0 150px rgba(255, 215, 0, 0.2);
                    border-color: rgba(255, 223, 0, 1);
                    color: #ffe44d;
                    text-shadow: 0 0 25px rgba(255, 215, 0, 1),
                                0 0 35px rgba(255, 215, 0, 0.7),
                                0 0 45px rgba(255, 215, 0, 0.4);
                }
                100% {
                    box-shadow: 0 0 20px rgba(0,0,0,0.5),
                                inset 0 0 8px rgba(255, 215, 0, 0.5),
                                0 0 30px rgba(255, 215, 0, 0.4),
                                0 0 50px rgba(255, 215, 0, 0.2);
                    border-color: rgba(255, 215, 0, 0.6);
                    color: #ffd700;
                    text-shadow: 0 0 15px rgba(255, 215, 0, 0.8);
                }
            }
        `;
        document.head.appendChild(glowingStyle);
    
        // 监听窗口大小变化
        window.addEventListener('resize', () => {
            if (!isDragging) {
                const margin = 20;
                const maxX = window.innerWidth - floatingButton.offsetWidth - margin;
                const maxY = window.innerHeight - floatingButton.offsetHeight - margin;
                const minX = margin;
                const minY = margin;
    
                lastX = Math.max(minX, Math.min(lastX, maxX));
                lastY = Math.max(minY, Math.min(lastY, maxY));
    
                floatingButton.style.left = lastX + 'px';
                floatingButton.style.top = lastY + 'px';
            }
        });
    
        floatingButton.addEventListener('mousedown', dragStart);
        document.addEventListener('mousemove', drag);
        document.addEventListener('mouseup', dragEnd);
    
        // 恢复上次保存的位置或使用默认位置
        const margin = 20;
        const maxX = window.innerWidth - 70 - margin;
        const maxY = window.innerHeight / 2;
        const minX = margin;
        const minY = margin;
    
        lastX = Math.max(minX, Math.min(GM_getValue('floatingButtonX', maxX), maxX));
        lastY = Math.max(minY, Math.min(GM_getValue('floatingButtonY', maxY), maxY));
    
        floatingButton.style.right = 'auto';
        floatingButton.style.top = lastY + 'px';
        floatingButton.style.left = lastX + 'px';
        floatingButton.style.transform = 'scale(1)';
        floatingButton.style.transform = 'scale(1)';
    
        return floatingButton;
    }
    
    function createControls() {
        const floatingButton = createConfigButton();
        document.body.appendChild(floatingButton);

        // 创建搜索框但不立即显示
        createSearchBox();

        // 添加快捷键监听
        document.addEventListener('keydown', (e) => {
            if (e.altKey && !e.ctrlKey && !e.shiftKey && e.key.toLowerCase() === 'f') {
                e.preventDefault(); // 阻止默认行为
                toggleSearchBox();
            }
        });
    }

    // 切换搜索框显示状态
    function toggleSearchBox() {
        const searchBox = document.querySelector('.search-box-container');
        if (searchBox) {
            searchBox.style.display = searchBox.style.display === 'none' ? 'flex' : 'none';
            if (searchBox.style.display === 'flex') {
                // 当显示搜索框时,自动聚焦到输入框
                const searchInput = searchBox.querySelector('input');
                if (searchInput) {
                    searchInput.focus();
                }
            }
        }
    }

    // 创建搜索框
    function createSearchBox(handleInput) {
        const searchBoxContainer = document.createElement('div');
        searchBoxContainer.className = 'search-box-container';
        searchBoxContainer.style.cssText = `
            position: fixed;
            top: 10px;
            left: 20px;
            z-index: 9999;
            background: rgba(28, 28, 28, 0.95);
            padding: 15px 10px 10px;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
            border: 1px solid #444;
            display: none;
            flex-direction: column;
            gap: 8px;
        `;

        const searchRow = document.createElement('div');
        searchRow.style.cssText = `
            display: flex;
            gap: 8px;
            align-items: center;
        `;

        const navigationRow = document.createElement('div');
        navigationRow.style.cssText = `
            display: flex;
            gap: 8px;
            align-items: center;
        `;

        // 创建搜索输入框
        const searchInput = document.createElement('input');
        searchInput.type = 'text';
        searchInput.placeholder = '输入关键词(用;分隔)';
        searchInput.dataset.isSearchInput = 'true';
        searchInput.style.cssText = `
            width: 250px;
            padding: 5px 10px;
            border: 1px solid #666;
            border-radius: 4px;
            background: #2d2d2d;
            color: #fff;
        `;

        // 添加搜索事件
        searchInput.addEventListener('input', (e) => {
            if (!e?.target?.value) return;

            // 如果页面是繁体模式,则将输入转换为繁体
            if (!STATE.pageSimplified) {
                const cursorPosition = e.target.selectionStart;
                const text = e.target.value;

                requestAnimationFrame(() => {
                    try {
                        const convertedText = window.converter.toTraditional(text);
                        if (text === convertedText) return;

                        e.target.value = convertedText;

                        if (typeof cursorPosition === 'number') {
                            e.target.setSelectionRange(cursorPosition, cursorPosition);
                        }
                    } catch (error) {}
                });
            }
        });

        const searchButton = document.createElement('button');
        searchButton.textContent = '搜索';
        searchButton.style.cssText = `
            padding: 5px 15px;
            background: #4a90e2;
            border: none;
            border-radius: 4px;
            color: #fff;
            cursor: pointer;
            transition: background 0.2s;
        `;

        // 添加预设下拉框
        const presetSelectContainer = document.createElement('div');
        presetSelectContainer.style.cssText = `
            position: relative;
            width: 120px;
        `;

        const presetInput = document.createElement('input');
        presetInput.readOnly = true;
        presetInput.placeholder = '选择预设';
        presetInput.style.cssText = `
            width: 100%;
            padding: 5px;
            background: #2d2d2d;
            border: 1px solid #666;
            border-radius: 4px;
            color: #fff;
            cursor: pointer;
        `;

        // 修改预设选择框的样式
        const presetDropdown = document.createElement('div');
        presetDropdown.style.cssText = `
            display: none;
            position: absolute;
            top: 100%;
            left: 0;
            width: 200px;
            max-height: 300px;
            overflow-y: auto;
            background: #2d2d2d;
            border: 1px solid #666;
            border-radius: 4px;
            z-index: 10000;
            margin-top: 4px;
            padding-top: 30px; // 为搜索框留出空间
            color: #fff; // 添加默认文字颜色
        `;

        // 添加预设搜索框
        const presetSearchInput = document.createElement('input');
        presetSearchInput.type = 'text';
        presetSearchInput.placeholder = '搜索预设...';
        presetSearchInput.style.cssText = `
            position: absolute;
            top: 0;
            left: 0;
            width: calc(100% - 16px);
            margin: 8px;
            padding: 4px 8px;
            background: #3d3d3d;
            border: 1px solid #666;
            border-radius: 3px;
            color: #fff;
            font-size: 12px;
        `;

        // 阻止搜索框的点击事件冒泡,避免关闭下拉框
        presetSearchInput.addEventListener('click', (e) => {
            e.stopPropagation();
        });

        // 添加搜索框的输入事件
        presetSearchInput.addEventListener('input', (e) => {
            const searchText = e.target.value.toLowerCase();
            const options = presetDropdown.querySelectorAll('.preset-option');
            options.forEach(option => {
                const name = option.querySelector('span').textContent.toLowerCase();
                if (name.includes(searchText)) {
                    option.style.display = '';
                } else {
                    option.style.display = 'none';
                }
            });
        });

        presetDropdown.appendChild(presetSearchInput);

        // 添加滚动条样式
        const styleSheet = document.createElement('style');
        styleSheet.textContent = `
            .preset-dropdown::-webkit-scrollbar {
                width: 8px;
            }
            .preset-dropdown::-webkit-scrollbar-track {
                background: #1a1a1a;
            }
            .preset-dropdown::-webkit-scrollbar-thumb {
                background: #444;
                border-radius: 4px;
            }
            .preset-dropdown::-webkit-scrollbar-thumb:hover {
                background: #555;
            }
        `;
        document.head.appendChild(styleSheet);

        let selectedPresets = new Set();

        // 修改预设选项的样式
        function updatePresetOptions() {
            // 保留搜索框
            presetDropdown.innerHTML = '';
            presetDropdown.appendChild(presetSearchInput);
            presetSearchInput.value = ''; // 清空搜索框

            // 创建分隔线
            const createDivider = () => {
                const divider = document.createElement('div');
                divider.style.cssText = `
                    height: 1px;
                    background: #666;
                    margin: 5px 0;
                `;
                return divider;
            };

            // 创建预设选项
            const createPresetOption = (name, keywords, isSelected) => {
                const option = document.createElement('div');
                option.className = 'preset-option'; // 添加类名以便搜索
                option.style.cssText = `
                    padding: 6px 10px;
                    cursor: pointer;
                    display: flex;
                    align-items: center;
                    gap: 8px;
                    transition: all 0.2s;
                    color: #fff;
                    ${isSelected ? 'background: #2a4a6d;' : ''}
                `;

                const checkbox = document.createElement('input');
                checkbox.type = 'checkbox';
                checkbox.checked = isSelected;
                checkbox.style.cssText = `
                    margin: 0;
                    cursor: pointer;
                `;

                const label = document.createElement('span');
                label.textContent = name;
                label.style.cssText = `
                    flex: 1;
                    overflow: hidden;
                    text-overflow: ellipsis;
                    white-space: nowrap;
                    color: #fff;
                `;

                option.appendChild(checkbox);
                option.appendChild(label);

                option.addEventListener('mouseover', () => {
                    option.style.backgroundColor = isSelected ? '#2a5a8d' : '#3d3d3d';
                });

                option.addEventListener('mouseout', () => {
                    option.style.backgroundColor = isSelected ? '#2a4a6d' : 'transparent';
                });

                option.addEventListener('click', (e) => {
                    e.stopPropagation();
                    checkbox.checked = !checkbox.checked;
                    if (checkbox.checked) {
                        selectedPresets.add(name);
                    } else {
                        selectedPresets.delete(name);
                    }
                    updateSelectedPresets();
                    // 重新渲染预设列表以更新顺序
                    updatePresetOptions();
                });

                return option;
            };

            // 获取所有预设并分类
            const selectedOptions = [];
            const unselectedOptions = [];
            
            Object.entries(STATE.searchPresets).forEach(([name, keywords]) => {
                const isSelected = selectedPresets.has(name);
                const option = createPresetOption(name, keywords, isSelected);
                
                if (isSelected) {
                    selectedOptions.push(option);
                } else {
                    unselectedOptions.push(option);
                }
            });

            // 添加已选择的预设
            if (selectedOptions.length > 0) {
                const selectedTitle = document.createElement('div');
                selectedTitle.style.cssText = `
                    padding: 5px 10px;
                    color: #999;
                    font-size: 12px;
                    background: #262626;
                `;
                selectedTitle.textContent = '已选择的预设';
                presetDropdown.appendChild(selectedTitle);
                
                selectedOptions.forEach(option => presetDropdown.appendChild(option));
            }

            // 添加未选择的预设
            if (selectedOptions.length > 0 && unselectedOptions.length > 0) {
                presetDropdown.appendChild(createDivider());
            }

            if (unselectedOptions.length > 0) {
                if (selectedOptions.length > 0) {
                    const unselectedTitle = document.createElement('div');
                    unselectedTitle.style.cssText = `
                        padding: 5px 10px;
                        color: #999;
                        font-size: 12px;
                        background: #262626;
                    `;
                    unselectedTitle.textContent = '未选择的预设';
                    presetDropdown.appendChild(unselectedTitle);
                }
                
                unselectedOptions.forEach(option => presetDropdown.appendChild(option));
            }
        }

        function updateSelectedPresets() {
            if (selectedPresets.size === 0) {
                presetInput.value = '';
                presetInput.placeholder = '选择预设';
            } else {
                const names = Array.from(selectedPresets).join(', ');
                presetInput.value = names;
                presetInput.placeholder = '';
            }
        }

        function applySelectedPresets() {
            if (selectedPresets.size === 0) return;

            const keywords = Array.from(selectedPresets)
                .map(name => STATE.searchPresets[name])
                .join(';');

            searchInput.value = keywords;

            // 手动触发输入转换
            if (!STATE.pageSimplified) {
                try {
                    const convertedText = window.converter.toTraditional(keywords);
                    if (keywords !== convertedText) {
                        searchInput.value = convertedText;
                    }
                } catch (error) {}
            }

            // 触发搜索
            performSearch();
            // 清空选择
            selectedPresets.clear();
            updateSelectedPresets();
        }

        // 点击输入框时显示/隐藏下拉框
        presetInput.addEventListener('click', (e) => {
            e.stopPropagation();
            const isVisible = presetDropdown.style.display === 'block';
            presetDropdown.style.display = isVisible ? 'none' : 'block';
            if (!isVisible) {
                updatePresetOptions();
                // 聚焦搜索框
                setTimeout(() => {
                    presetSearchInput.focus();
                }, 0);
            }
        });

        // 点击其他地方时隐藏下拉框
        document.addEventListener('click', () => {
            presetDropdown.style.display = 'none';
        });

        // 添加搜索事件
        const performSearch = () => {
            // 获取所有预设关键词
            const presetKeywords = Array.from(selectedPresets)
                .map(name => STATE.searchPresets[name])
                .join(';');

            // 获取输入框关键词
            const inputKeywords = searchInput.value.trim();

            // 合并关键词
            const combinedKeywords = [presetKeywords, inputKeywords]
                .filter(k => k) // 过滤掉空字符串
                .join(';');

            // 如果页面是繁体模式,则将关键词转换为繁体
            let searchKeywords = combinedKeywords;
            if (!STATE.pageSimplified) {
                try {
                    searchKeywords = window.converter.toTraditional(combinedKeywords);
                } catch (error) {
                    console.error('转换繁体失败:', error);
                }
            }

            // 使用;或;作为分隔符
            const keywords = searchKeywords.toLowerCase().split(/[;;]/);
            // 过滤掉空字符串
            const filteredKeywords = keywords.filter(k => k.trim());
            
            if (!filteredKeywords.length) {
                clearHighlights();
                matchCounter.textContent = '';
                return;
            }
            searchAndHighlight(filteredKeywords, matchCounter);
        };

        searchInput.addEventListener('keyup', (e) => {
            if (e.key === 'Enter') {
                performSearch();
            }
        });

        searchButton.addEventListener('click', performSearch);

        // 添加导航按钮
        const prevButton = document.createElement('button');
        prevButton.textContent = '上一个';
        prevButton.style.cssText = `
            padding: 5px 15px;
            background: #2d2d2d;
            border: 1px solid #666;
            border-radius: 4px;
            color: #fff;
            cursor: pointer;
            transition: background 0.2s;
            flex: 1;
        `;

        const nextButton = document.createElement('button');
        nextButton.textContent = '下一个';
        nextButton.style.cssText = `
            padding: 5px 15px;
            background: #2d2d2d;
            border: 1px solid #666;
            border-radius: 4px;
            color: #fff;
            cursor: pointer;
            transition: background 0.2s;
            flex: 1;
        `;

        const matchCounter = document.createElement('span');
        matchCounter.className = 'search-counter';
        matchCounter.style.cssText = `
            color: #fff;
            font-size: 12px;
            padding: 0 10px;
            min-width: 60px;
            text-align: center;
        `;

        // 添加导航事件
        prevButton.addEventListener('click', () => {
            navigateHighlight('prev');
        });

        nextButton.addEventListener('click', () => {
            navigateHighlight('next');
        });

        // 添加hover效果
        [searchButton, prevButton, nextButton].forEach(button => {
            button.addEventListener('mouseover', () => {
                button.style.background = button === searchButton ? '#357abd' : '#3d3d3d';
            });
            button.addEventListener('mouseout', () => {
                button.style.background = button === searchButton ? '#4a90e2' : '#2d2d2d';
            });
        });

        // 组装界面
        presetSelectContainer.appendChild(presetInput);
        presetSelectContainer.appendChild(presetDropdown);

        searchRow.appendChild(presetSelectContainer);
        searchRow.appendChild(searchInput);
        searchRow.appendChild(searchButton);

        navigationRow.appendChild(prevButton);
        navigationRow.appendChild(matchCounter);
        navigationRow.appendChild(nextButton);

        searchBoxContainer.appendChild(searchRow);
        searchBoxContainer.appendChild(navigationRow);

        // 添加选项行
        const optionsRow = document.createElement('div');
        optionsRow.style.cssText = `
            display: flex;
            gap: 8px;
            align-items: center;
            padding: 0 5px;
        `;

        const showOnlyMatchedLabel = document.createElement('label');
        showOnlyMatchedLabel.style.cssText = `
            display: flex;
            align-items: center;
            gap: 5px;
            color: #fff;
            font-size: 12px;
            cursor: pointer;
        `;

        const showOnlyMatchedCheckbox = document.createElement('input');
        showOnlyMatchedCheckbox.type = 'checkbox';
        showOnlyMatchedCheckbox.checked = STATE.showOnlyMatched;
        showOnlyMatchedCheckbox.style.cssText = `
            margin: 0;
            cursor: pointer;
        `;

        showOnlyMatchedLabel.appendChild(showOnlyMatchedCheckbox);
        showOnlyMatchedLabel.appendChild(document.createTextNode('只显示匹配项'));

        showOnlyMatchedCheckbox.addEventListener('change', (e) => {
            STATE.showOnlyMatched = e.target.checked;
            GM_setValue('showOnlyMatched', STATE.showOnlyMatched);
            if (STATE.matchedCards.length > 0) {
                updateCardVisibility();
            }
        });

        optionsRow.appendChild(showOnlyMatchedLabel);
        searchBoxContainer.insertBefore(optionsRow, navigationRow);

        document.body.appendChild(searchBoxContainer);

        // 添加关闭按钮
        const closeButton = document.createElement('button');
        closeButton.textContent = '×';
        closeButton.style.cssText = `
            position: absolute;
            top: -10px;
            right: -10px;
            width: 20px;
            height: 20px;
            line-height: 1;
            padding: 0;
            background: #2d2d2d;
            border: 1px solid #666;
            border-radius: 50%;
            color: #999;
            font-size: 16px;
            font-weight: bold;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: all 0.2s;
            z-index: 10000;
            box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
        `;

        closeButton.addEventListener('mouseover', () => {
            closeButton.style.color = '#fff';
            closeButton.style.background = '#3d3d3d';
            closeButton.style.borderColor = '#999';
        });

        closeButton.addEventListener('mouseout', () => {
            closeButton.style.color = '#999';
            closeButton.style.background = '#2d2d2d';
            closeButton.style.borderColor = '#666';
        });

        closeButton.addEventListener('click', () => {
            searchBoxContainer.style.display = 'none';
            clearHighlights();
            searchInput.value = '';
            matchCounter.textContent = '';
            // 不清除选择的预设
        });

        searchBoxContainer.insertBefore(closeButton, searchBoxContainer.firstChild);

        // 添加键盘快捷键
        document.addEventListener('keydown', (e) => {
            if (e.key === 'F3' || (e.ctrlKey && e.key === 'g')) {
                e.preventDefault();
                if (e.shiftKey) {
                    navigateHighlight('prev');
                } else {
                    navigateHighlight('next');
                }
            }
        });

        // 在搜索框显示时更新预设选项
        const originalToggleSearchBox = toggleSearchBox;
        toggleSearchBox = function() {
            const searchBox = document.querySelector('.search-box-container');
            if (searchBox) {
                const isCurrentlyHidden = searchBox.style.display === 'none';
                if (isCurrentlyHidden) {
                    updatePresetOptions();
                    // 不清除选择的预设
                    updateSelectedPresets();
                }
                searchBox.style.display = isCurrentlyHidden ? 'flex' : 'none';
                if (isCurrentlyHidden) {
                    const searchInput = searchBox.querySelector('input[type="text"]');
                    if (searchInput) {
                        searchInput.focus();
                    }
                }
            }
        };

        return updatePresetOptions;
    }

    // 清除所有高亮
    function clearHighlights() {
        const highlights = document.querySelectorAll('.st-highlight');
        highlights.forEach(highlight => {
            const parent = highlight.parentNode;
            parent.replaceChild(document.createTextNode(highlight.textContent), highlight);
        });

        // 清除所有高亮样式
        document.querySelectorAll('.current-highlight, .matched-card').forEach(card => {
            card.classList.remove('current-highlight', 'matched-card');
        });

        // 重置导航状态
        STATE.matchedCards = [];
        STATE.currentMatchIndex = -1;

        // 恢复所有卡片的可见性
        const allCards = document.querySelectorAll('.row[data-id]');
        allCards.forEach(card => {
            card.style.display = '';
        });
    }

    // 修改 searchAndHighlight 函数中的关键词处理部分
    function escapeRegExp(string) {
        return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
    }

    function searchAndHighlight(keywords, matchCounter) {
        clearHighlights();

        const itemCards = document.querySelectorAll('.row[data-id]');
        STATE.matchedCards = [];
        let hasMatch = false;

        // 预处理关键词,处理特殊字符和通配符
        const processedKeywords = keywords.map(keyword => {
            keyword = keyword.trim();
            
            // 处理带条件的通配符
            // 匹配模式:(&>2) 或 (&>=2) 或 (&<2) 或 (&<=2) 或 (&=2)
            // 或带加号的版本:+(&>2) 等
            const conditionalPattern = /(\(?&(>=|<=|>|<|=)(\d+)\)?)/;
            if (conditionalPattern.test(keyword)) {
                const match = keyword.match(conditionalPattern);
                const fullMatch = match[0];
                const operator = match[2];
                const targetNum = parseInt(match[3]);
                
                // 将关键词分成前后两部分
                const [before, after] = keyword.split(fullMatch);
                
                // 构建正则表达式和验证函数
                const numPattern = '(\\d+)';
                const beforePattern = before ? escapeRegExp(before) : '';
                const afterPattern = after ? escapeRegExp(after) : '';
                
                return {
                    pattern: beforePattern + numPattern + afterPattern,
                    validate: (foundNum) => {
                        const num = parseInt(foundNum);
                        switch(operator) {
                            case '>': return num > targetNum;
                            case '>=': return num >= targetNum;
                            case '<': return num < targetNum;
                            case '<=': return num <= targetNum;
                            case '=': return num === targetNum;
                            default: return false;
                        }
                    }
                };
            }
            
            // 处理简单通配符
            if (keyword.includes('&')) {
                // 处理带加号的通配符
                if (keyword.includes('+&')) {
                    keyword = escapeRegExp(keyword).replace(/\\\+&/g, '\\+[0-9]+');
                } else {
                    // 处理不带加号的通配符
                    keyword = escapeRegExp(keyword).replace(/&/g, '[0-9]+');
                }
            } else {
                // 处理其他特殊字符
                keyword = escapeRegExp(keyword).replace(/\\\+/g, '[++]');
            }
            
            return { pattern: keyword };
        }).filter(k => k);

        itemCards.forEach(card => {
            const cardText = card.textContent;
            const matches = processedKeywords.map(keyword => {
                if (!keyword.validate) {
                    // 简单模式匹配
                    const regex = new RegExp(keyword.pattern, 'i');
                    return regex.test(cardText);
                } else {
                    // 条件模式匹配
                    const regex = new RegExp(keyword.pattern, 'i');
                    const match = cardText.match(regex);
                    if (!match) return false;
                    
                    // 提取数字并验证条件
                    const foundNum = match[1];
                    return keyword.validate(foundNum);
                }
            });
            const allMatch = matches.every(match => match);

            if (allMatch) {
                hasMatch = true;
                STATE.matchedCards.push(card);
                highlightKeywords(card, processedKeywords.map(k => k.pattern));
            } else if (STATE.showOnlyMatched) {
                card.style.display = 'none';
            }
        });

        if (!hasMatch) {
            alert('未找到匹配的结果');
            if (matchCounter) {
                matchCounter.textContent = '0/0';
            }
        } else {
            STATE.currentMatchIndex = 0;
            updateHighlightNavigation();
            updateCardVisibility();
        }
    }

    // 修改 highlightKeywords 函数
    function highlightKeywords(element, patterns) {
        const walker = document.createTreeWalker(
            element,
            NodeFilter.SHOW_TEXT,
            {
                acceptNode: function(node) {
                    if (node.parentNode.nodeName === 'SCRIPT' ||
                        node.parentNode.nodeName === 'STYLE' ||
                        node.parentNode.classList.contains('st-highlight')) {
                        return NodeFilter.FILTER_REJECT;
                    }

                    const text = node.textContent;
                    const containsAnyKeyword = patterns.some(pattern => {
                        const regex = new RegExp(pattern, 'i');
                        return regex.test(text);
                    });

                    return containsAnyKeyword ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
                }
            }
        );

        const nodes = [];
        let node;
        while (node = walker.nextNode()) {
            nodes.push(node);
        }

        nodes.forEach(textNode => {
            let text = textNode.textContent;
            let tempText = text;

            patterns.forEach(pattern => {
                const regex = new RegExp(`(${pattern})`, 'gi');
                if (regex.test(text)) {
                    tempText = tempText.replace(regex, (match) => {
                        return `<span class="st-highlight">${match}</span>`;
                    });
                }
            });

            if (tempText !== text) {
                const tempDiv = document.createElement('div');
                tempDiv.innerHTML = tempText;
                const fragment = document.createDocumentFragment();
                while (tempDiv.firstChild) {
                    fragment.appendChild(tempDiv.firstChild);
                }
                textNode.parentNode.replaceChild(fragment, textNode);
            }
        });
    }

    // 更新高亮导航
    function updateHighlightNavigation() {
        const matchCounter = document.querySelector('.search-counter');
        if (!matchCounter) return;

        // 更新计数器
        matchCounter.textContent = `${STATE.currentMatchIndex + 1}/${STATE.matchedCards.length}`;

        // 移除之前的当前高亮
        document.querySelectorAll('.current-highlight, .matched-card').forEach(card => {
            card.classList.remove('current-highlight', 'matched-card');
        });

        // 添加新的当前高亮
        const currentCard = STATE.matchedCards[STATE.currentMatchIndex];
        if (currentCard) {
            currentCard.classList.add('current-highlight');
            // 滚动到当前卡片
            currentCard.scrollIntoView({
                behavior: 'smooth',
                block: 'center'
            });
        }
    }

    // 导航到上一个/下一个高亮
    function navigateHighlight(direction) {
        if (STATE.matchedCards.length === 0) return;

        if (direction === 'next') {
            STATE.currentMatchIndex = (STATE.currentMatchIndex + 1) % STATE.matchedCards.length;
        } else {
            STATE.currentMatchIndex = (STATE.currentMatchIndex - 1 + STATE.matchedCards.length) % STATE.matchedCards.length;
        }

        updateHighlightNavigation();
    }

    // 修改样式
    const style = document.createElement('style');
    style.textContent = `
        .current-highlight {
            background-color: rgba(255, 215, 0, 0.3) !important;
        }
        .matched-card {
            background-color: rgba(255, 215, 0, 0.1) !important;
        }
        .st-highlight {
            background-color: #ffd700;
            color: #000;
            border-radius: 2px;
            padding: 0 2px;
        }
    `;
    document.head.appendChild(style);
    
    function watchSearchResults(converter) {
        let lastUrl = location.href;
        const urlObserver = setInterval(() => {
            if (location.href !== lastUrl) {
                lastUrl = location.href;
                STATE.originalTexts = new WeakMap();
                setTimeout(() => {
                    convertPageText(converter);
                }, 500);
            }
        }, 100);
    
        // 监视搜索结果变化
        const resultObserver = new MutationObserver((mutations) => {
            let needsConversion = false;
            for (const mutation of mutations) {
                if (mutation.type === 'childList' || mutation.type === 'characterData') {
                    needsConversion = true;
                    break;
                }
            }
            if (needsConversion) {
                setTimeout(() => convertPageText(converter), 100);
            }
        });
    
        const resultsContainer = document.querySelector('.results-container');
        if (resultsContainer) {
            resultObserver.observe(resultsContainer, {
                childList: true,
                subtree: true,
                characterData: true
            });
        }
    }
    
    function findReactInstance(element) {
        const key = Object.keys(element).find(key => key.startsWith('__reactFiber$'));
        return key ? element[key] : null;
    }
    
    function findLoadMoreHandler() {
        const loadMoreBtn = document.querySelector('.load-more-btn');
        if (!loadMoreBtn) {
            console.log('未找到加载更多按钮');
            return null;
        }
    
        // 尝试获取React实例
        const instance = findReactInstance(loadMoreBtn);
        if (!instance) {
            console.log('未找到React实例');
            return null;
        }
    
        // 遍历查找onClick处理函数
        let current = instance;
        while (current) {
            if (current.memoizedProps && current.memoizedProps.onClick) {
                return current.memoizedProps.onClick;
            }
            current = current.return;
        }
    
        console.log('未找到onClick处理函数');
        return null;
    }
    
    function clickLoadMoreIfExists() {
        // 使用正确的选择器
        const loadMoreBtn = document.querySelector('.btn.load-more-btn');
        if (!loadMoreBtn) {
            console.log('未找到加载更多按钮');
            return false;
        }
    
        const results = document.querySelectorAll('.resultset, .trade-result, [class*="result-item"]');
        const currentResultCount = results.length;
    
        if (currentResultCount >= 100) {
            return false;
        }
    
        try {
            // 尝试多种方式触发点击
            // 1. 原生点击
            loadMoreBtn.click();
    
            // 2. 模拟鼠标事件序列
            ['mousedown', 'mouseup', 'click'].forEach(eventType => {
                const event = new MouseEvent(eventType, {
                    bubbles: true,
                    cancelable: true,
                    buttons: 1
                });
                loadMoreBtn.dispatchEvent(event);
            });
    
            // 3. 尝试点击内部的span
            const spanInButton = loadMoreBtn.querySelector('span');
            if (spanInButton) {
                spanInButton.click();
                ['mousedown', 'mouseup', 'click'].forEach(eventType => {
                    const event = new MouseEvent(eventType, {
                        bubbles: true,
                        cancelable: true,
                        buttons: 1
                    });
                    spanInButton.dispatchEvent(event);
                });
            }
    
            // 4. 使用 HTMLElement 的 click 方法
            HTMLElement.prototype.click.call(loadMoreBtn);
    
            return true;
        } catch (error) {
            console.log('触发加载更多时出错:', error);
            return false;
        }
    }
    
    function autoLoadAllResults() {
        let attempts = 0;
        const maxAttempts = 20;
        let lastResultCount = 0;
    
        function tryLoadMore() {
            const results = document.querySelectorAll('.resultset');
            const currentResultCount = results.length;
    
            if (currentResultCount >= 100 || attempts >= maxAttempts ||
                (currentResultCount === lastResultCount && attempts > 0)) {
                return;
            }
    
            if (clickLoadMoreIfExists()) {
                lastResultCount = currentResultCount;
                attempts++;
                // 修改加载更多的处理方式
                setTimeout(() => {
                    // 确保新内容加载后计算DPS
                    const newResults = document.querySelectorAll('.row[data-id]').length;
                    if (newResults > currentResultCount) {
                        calculateDPS();
                    }
                    tryLoadMore();
                }, 1000);
            }
        }
    
        setTimeout(tryLoadMore, 1000);
    }
    
    // 检查URL是否是搜索结果页面
    function isSearchResultPage() {
        const isPOE2Trade = window.location.href.includes('pathofexile.com/trade2/search/poe2');
        const hasResults = document.querySelector('.results-container, .trade-results, .search-results, [class*="results"]') !== null;
        return isPOE2Trade && hasResults;
    }
    
    // 将这些函数移到init函数外部
            function createDPSPanel() {
                const panel = document.createElement('div');
                panel.id = 'dps-sort-panel';
                panel.style.cssText = `
                    position: fixed;
                    right: 20px;
                    top: 50%;
                    transform: translateY(-50%);
                    background: rgba(28, 28, 28, 0.95);
                    padding: 8px;
                    border-radius: 6px;
                    box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
                    border: 1px solid #444;
                    width: 200px; // 增加宽度以适应价格显示
                    max-height: 60vh;
                    z-index: 9997;
                    display: none;
                `;

                // 添加标题
                const title = document.createElement('div');
                title.style.cssText = `
                    font-weight: bold;
                    color: #FFD700;
                    margin-bottom: 6px;
                    padding-bottom: 3px;
                    border-bottom: 1px solid #444;
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    cursor: pointer;
                    font-size: 14px;
                    user-select: none;
                    height: 18px;
                `;
                
                // 添加展开/收起指示器
                const indicator = document.createElement('span');
                indicator.textContent = '▼';
                indicator.style.marginRight = '3px';
                indicator.style.fontSize = '10px';
                indicator.id = 'integrated-panel-indicator';
                
                const titleText = document.createElement('span');
                titleText.textContent = 'DPS';
                
                const titleLeft = document.createElement('div');
                titleLeft.style.display = 'flex';
                titleLeft.style.alignItems = 'center';
                titleLeft.appendChild(indicator);
                titleLeft.appendChild(titleText);

                title.appendChild(titleLeft);

                // 添加关闭按钮
                const closeBtn = document.createElement('button');
                closeBtn.textContent = '×';
                closeBtn.style.cssText = `
                    background: none;
                    border: none;
                    color: #999;
                    font-size: 20px;
                    cursor: pointer;
                    padding: 0 5px;
                `;
                closeBtn.onclick = (e) => {
                    e.stopPropagation();
                    panel.style.display = 'none';
                };
                title.appendChild(closeBtn);

                // 添加内容容器
                const content = document.createElement('div');
                content.id = 'dps-sort-content';
                content.style.cssText = `
                    max-height: calc(60vh - 35px);
                    overflow-y: auto;
                    transition: max-height 0.3s ease-out;
                    padding-right: 2px;
                `;

                // 添加展开/收起功能
                let isExpanded = true;
                title.onclick = () => {
                    isExpanded = !isExpanded;
                    content.style.maxHeight = isExpanded ? 'calc(60vh - 35px)' : '0';
                    content.style.overflow = isExpanded ? 'auto' : 'hidden';
                    indicator.textContent = isExpanded ? '▼' : '▶';

            // 调整护盾面板位置
            const shieldPanel = document.getElementById('shield-sort-panel');
            if (shieldPanel) {
                if (isExpanded) {
                    shieldPanel.style.transform = 'translateY(calc(-50% + 200px))';
                } else {
                    shieldPanel.style.transform = 'translateY(calc(-50% + 50px))';
                }
            }
                };

                // 添加滚动条样式
                const style = document.createElement('style');
                style.textContent = `
                    #dps-sort-content::-webkit-scrollbar {
                        width: 6px;
                    }
                    #dps-sort-content::-webkit-scrollbar-track {
                        background: #1a1a1a;
                    }
                    #dps-sort-content::-webkit-scrollbar-thumb {
                        background: #444;
                        border-radius: 3px;
                    }
                    #dps-sort-content::-webkit-scrollbar-thumb:hover {
                        background: #555;
                    }
                    .dps-item {
                        padding: 4px 8px;
                        margin: 1px 0;
                        background: #2d2d2d;
                        border-radius: 3px;
                        cursor: pointer;
                        transition: background 0.2s;
                        display: flex;
                        justify-content: space-between;
                        align-items: center;
                        gap: 8px;
                        font-size: 13px;
                        white-space: nowrap;
                        user-select: none;
                        line-height: 1.2;
                    }
                    .dps-item:hover {
                        background: #3d3d3d;
                    }
                    .dps-item:last-child {
                        margin-bottom: 0;
                    }
                    .dps-value {
                        color: #FFD700;
                        font-weight: bold;
                    }
                    .price-value {
                        color: #8acdff;
                        font-size: 12px;
                        text-align: right;
                    }
                `;

                panel.appendChild(title);
                panel.appendChild(content);
                document.head.appendChild(style);
                document.body.appendChild(panel);

                return panel;
            }

    // 将convertCurrencyText函数移到全局作用域
                function convertCurrencyText(currencyText) {
        if (!currencyText) return '';
                    if (currencyText.includes('Exalted') || currencyText.includes('exalted')) return 'E';
                    if (currencyText.includes('Divine') || currencyText.includes('divine')) return 'D';
                    if (currencyText.includes('Chaos') || currencyText.includes('chaos')) return 'C';
                    if (currencyText.includes('崇高')) return 'E';
                    if (currencyText.includes('神圣')) return 'D';
                    if (currencyText.includes('混沌')) return 'C';
                    return currencyText; // 其他货币保持原样
                }

    function updateDPSPanel() {
        try {
            console.log('Updating DPS panel...');
            
            // 获取或创建面板
            const panel = document.getElementById('integrated-sort-panel') || createIntegratedPanel();
                const content = document.getElementById('dps-sort-content');
            if (!content) {
                console.error('DPS sort content not found');
                return;
            }

            // 清空现有内容
            content.innerHTML = '';
            
            // 清除可能存在的旧数据属性
            content.removeAttribute('data-shield-content');
            content.removeAttribute('data-evasion-content');
            content.removeAttribute('data-armour-content');
            content.removeAttribute('data-defence-content');

                const items = document.querySelectorAll('.row[data-id]');
                const dpsData = [];

                items.forEach(item => {
                    const dpsDisplay = item.querySelector('.dps-display');
                    if (dpsDisplay) {
                        const dps = parseInt(dpsDisplay.textContent.replace('DPS: ', ''));
                        // 修改价格获取逻辑
                        const priceElement = item.querySelector('.price [data-field="price"]');
                        let price = '未标价';
                        if (priceElement) {
                            const amount = priceElement.querySelector('span:not(.price-label):not(.currency-text)');
                            const currencyText = priceElement.querySelector('.currency-text');
                            if (amount && currencyText) {
                                // 获取数量和转换后的货币类型
                                const amountText = amount.textContent.trim();
                                const currency = currencyText.querySelector('span')?.textContent || currencyText.textContent;
                                const simpleCurrency = convertCurrencyText(currency);
                                price = `${amountText}${simpleCurrency}`;
                            }
                        }

                        dpsData.push({
                            dps,
                            price,
                            element: item
                        });
                    }
                });

            // 如果没有DPS数据,隐藏DPS选项卡
            const dpsTab = panel.querySelector('[data-tab="dps"]');
            if (dpsData.length === 0) {
                if (dpsTab) dpsTab.style.display = 'none';

                // 如果护盾选项卡也是隐藏的,则隐藏整个面板
                const shieldTab = panel.querySelector('[data-tab="shield"]');
                const evasionTab = panel.querySelector('[data-tab="evasion"]');
                const armourTab = panel.querySelector('[data-tab="armour"]');
                const defenceTab = panel.querySelector('[data-tab="defence"]');
                
                // 检查是否所有选项卡都隐藏了
                if ((shieldTab && shieldTab.style.display === 'none') &&
                    (evasionTab && evasionTab.style.display === 'none') &&
                    (armourTab && armourTab.style.display === 'none') &&
                    (defenceTab && defenceTab.style.display === 'none')) {
                    panel.style.display = 'none';
                }
                // 移除自动切换到护盾选项卡的代码,保留当前选项卡状态
                return;
            } else {
                // 有DPS数据,确保DPS选项卡可见
                if (dpsTab) dpsTab.style.display = '';
            }

                // 按DPS从高到低排序
                dpsData.sort((a, b) => b.dps - a.dps);

                // 更新面板内容
                dpsData.forEach(({dps, price, element}) => {
                    const dpsItem = document.createElement('div');
                    dpsItem.className = 'dps-item';
                    
                    // 创建DPS显示
                    const dpsText = document.createElement('span');
                    dpsText.className = 'dps-value';
                    dpsText.textContent = dps.toString();
                    
                    // 创建价格显示
                    const priceText = document.createElement('span');
                    priceText.className = 'price-value';
                    priceText.textContent = price;
                    
                    // 添加到DPS项
                    dpsItem.appendChild(dpsText);
                    dpsItem.appendChild(priceText);
                    
                    dpsItem.onclick = () => {
                        element.scrollIntoView({ behavior: 'smooth', block: 'center' });
                        // 添加高亮效果
                        element.style.transition = 'background-color 0.3s';
                        element.style.backgroundColor = 'rgba(255, 215, 0, 0.2)';
                        setTimeout(() => {
                            element.style.backgroundColor = '';
                        }, 1500);
                    };
                    content.appendChild(dpsItem);
                });

                panel.style.display = 'block';
        } catch (error) {
            console.error('Error updating DPS panel:', error);
        }
            }

            function calculateDPS() {
                console.log('Calculating DPS...'); // 添加调试日志
                const items = document.querySelectorAll('.row[data-id]');
                console.log('Found items:', items.length); // 添加调试日志
                
                items.forEach(item => {
                    // 查找已有的DPS显示,如果存在则跳过
                    if (item.querySelector('.dps-display')) return;

                    // 获取元素伤害
                    const edamageSpan = item.querySelector('span[data-field="edamage"]');
                    if (!edamageSpan) return;

                    // 初始化伤害值
                    let minTotal = 0;
                    let maxTotal = 0;

                    // 获取所有元素伤害值
                    const damages = {
                        fire: edamageSpan.querySelector('.colourFireDamage'),
                        lightning: edamageSpan.querySelector('.colourLightningDamage'),
                        cold: edamageSpan.querySelector('.colourColdDamage')
                    };

                    // 处理每种元素伤害
                    Object.values(damages).forEach(dmg => {
                        if (dmg) {
                            const [min, max] = dmg.textContent.split('-').map(Number);
                            if (!isNaN(min) && !isNaN(max)) {
                                minTotal += min;
                                maxTotal += max;
                            }
                        }
                    });

                    // 获取元素增伤
                    let elementInc = 1;
                    const elementIncSpan = item.querySelector('span[data-field="stat.explicit.stat_387439868"]');
                    if (elementIncSpan) {
                        const incMatch = elementIncSpan.textContent.match(/(\d+)%/);
                        if (incMatch) {
                            elementInc = 1 + (parseInt(incMatch[1]) / 100);
                        }
                    }

                    // 获取攻击速度
                    let aps = 1;
                    const apsSpan = item.querySelector('span[data-field="aps"]');
                    if (apsSpan) {
                        let apsValue = apsSpan.querySelector('.colourDefault');
                        if (!apsValue) {
                            apsValue = apsSpan.querySelector('.colourAugmented');
                        }
                        if (apsValue) {
                            aps = parseFloat(apsValue.textContent) || 1;
                        }
                    }

                    // 计算DPS
                    const dps = ((minTotal + maxTotal) / 2) * elementInc * aps;
                    console.log('minTotal:', minTotal);
                    console.log('maxTotal:', maxTotal);
                    console.log('elementInc:', elementInc);
                    console.log('aps:', aps);
                    console.log('dps:', dps);

                    // 创建DPS显示元素
                    const dpsDisplay = document.createElement('span');
                    dpsDisplay.className = 'dps-display';
                    dpsDisplay.style.cssText = `
                        color: #FFD700;
                        font-weight: bold;
                        margin-left: 10px;
                    `;
                    dpsDisplay.textContent = `DPS: ${Math.round(dps)}`;

                    // 将DPS显示添加到元素伤害后面
                    edamageSpan.appendChild(dpsDisplay);
                });

                // 更新DPS排序面板
                updateDPSPanel();
            }

            // 创建一个防抖函数来避免过于频繁的计算
            function debounce(func, wait) {
                let timeout;
                return function executedFunction(...args) {
                    const later = () => {
                        clearTimeout(timeout);
                        func(...args);
                    };
                    clearTimeout(timeout);
                    timeout = setTimeout(later, wait);
                };
            }

    async function init() {
        /**
         * 初始化脚本,设置转换器、观察器和UI元素
         */
        try {
            // 等待页面完全加载
            await new Promise(resolve => setTimeout(resolve, 100));

            // 等待OpenCC库加载
            const OpenCC = await waitForOpenCC();
            console.log('OpenCC已加载');

            // 创建转换器
            const converter = createConverters(OpenCC);
            window.converter = converter;

            // 创建输入处理函数
            const handleInput = createInputHandler(converter);

            // 为现有输入元素添加事件监听器
            attachInputListener(handleInput);

            // 创建观察器监听DOM变化
            const observer = createObserver(handleInput, converter);
            observer.observe(document.body, {
                childList: true,
                subtree: true
            });

            // 创建控制面板
            createControls();

            // 创建配置按钮
            createConfigButton();

            // 创建配置模态框
            createConfigModal();

            // 设置配置模态框事件
            setupConfigModalEvents();

            // 创建搜索框
            createSearchBox(handleInput);

            // 如果启用了页面简体化,转换页面文本
            if (STATE.pageSimplified) {
                convertPageText(converter);
            }

            // 监视搜索结果
            watchSearchResults(converter);

            // 定期转换页面文本
            setInterval(() => {
                if (STATE.pageSimplified) {
                    convertPageText(converter);
                }
            }, 1000);

            // 使用防抖包装calculateDPS和calculateShield
            const debouncedCalculateDPS = debounce(calculateDPS, 200);
            const debouncedCalculateShield = debounce(calculateShield, 200);
            const debouncedCalculateEvasion = debounce(calculateEvasion, 200);
            const debouncedCalculateArmour = debounce(calculateArmour, 200);
            const debouncedCalculateDefence = debounce(calculateDefence, 200);

            // 同时计算DPS、护盾、闪避、护甲和总防御的防抖函数
            const debouncedCalculate = debounce(() => {
                calculateDPS();
                calculateShield();
                calculateEvasion();
                calculateArmour();
                calculateDefence();
            }, 200);
            
            // 监听搜索按钮点击事件
            const setupSearchButtonListener = () => {
                // 使用MutationObserver监听搜索按钮的出现
                const searchBtnObserver = new MutationObserver((mutations, observer) => {
                    const searchBtn = document.querySelector('.controls-center .search-btn');
                    if (searchBtn) {
                        console.log('搜索按钮已找到,添加点击事件监听器');
                        searchBtn.addEventListener('click', () => {
                            console.log('搜索按钮被点击,触发计算...');
                            // 延迟执行计算,确保搜索结果已加载
                            setTimeout(() => {
                                debouncedCalculate();
                            }, 1000);
                        });
                        observer.disconnect(); // 找到按钮后停止观察
                    }
                });
                
                // 开始观察文档
                searchBtnObserver.observe(document.body, {
                    childList: true,
                    subtree: true
                });
                
                // 立即检查一次,以防按钮已经存在
                const searchBtn = document.querySelector('.controls-center .search-btn');
                if (searchBtn) {
                    console.log('搜索按钮已存在,添加点击事件监听器');
                    searchBtn.addEventListener('click', () => {
                        console.log('搜索按钮被点击,触发计算...');
                        // 延迟执行计算,确保搜索结果已加载
                        setTimeout(() => {
                            debouncedCalculate();
                        }, 1000);
                    });
                }
            };
            
            // 设置搜索按钮监听器
            setupSearchButtonListener();

            // 创建一个更强大的观察器来监视DOM变化
            const resultsObserver = new MutationObserver((mutations) => {
                let hasNewContent = false;
                mutations.forEach(mutation => {
                    // 检查是否有新的结果项被添加
                    if (mutation.type === 'childList' && 
                        mutation.addedNodes.length > 0 &&
                        Array.from(mutation.addedNodes).some(node => 
                            node.nodeType === 1 && // 元素节点
                            (node.classList?.contains('row') || node.querySelector?.('.row[data-id]'))
                        )) {
                        hasNewContent = true;
                    }
                });

                if (hasNewContent) {
                    console.log('New content detected, calculating DPS, Shield, Evasion and Armour...'); // 添加调试日志
                    // 使用延时确保DOM完全更新
                    setTimeout(() => {
                        debouncedCalculate();
                    }, 300);
                }
            });

            // 观察整个结果容器及其子元素
            const resultsContainer = document.querySelector('.results-container');
            if (resultsContainer) {
                resultsObserver.observe(resultsContainer, {
                    childList: true,
                    subtree: true,
                    attributes: true,
                    characterData: true
                });

                // 同时观察父元素,以防结果容器被替换
                if (resultsContainer.parentNode) {
                    resultsObserver.observe(resultsContainer.parentNode, {
                        childList: true
                    });
                }
            }

            // 添加滚动事件监听器
            window.addEventListener('scroll', () => {
                // 检查是否滚动到底部附近
                if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight - 1000) {
                    debouncedCalculate();
                }
            });

            // 将函数添加到window对象,以便其他地方可以调用
            window.calculateDPS = calculateDPS;
            window.calculateShield = calculateShield;
            window.calculateEvasion = calculateEvasion;
            window.calculateArmour = calculateArmour;
            window.calculateDefence = calculateDefence;
            window.debouncedCalculateDPS = debouncedCalculateDPS;
            window.debouncedCalculateShield = debouncedCalculateShield;
            window.debouncedCalculateEvasion = debouncedCalculateEvasion;
            window.debouncedCalculateArmour = debouncedCalculateArmour;
            window.debouncedCalculateDefence = debouncedCalculateDefence;
            window.debouncedCalculate = debouncedCalculate;

            // 监听URL变化
            let lastUrl = location.href;
            const urlCheckInterval = setInterval(() => {
                const currentUrl = location.href;
                if ((currentUrl !== lastUrl || currentUrl.includes('pathofexile.com/trade2/search/poe2')) && STATE.autoLoadEnabled) {
                    lastUrl = currentUrl;
                    setTimeout(() => {
                        if (isSearchResultPage()) {
                            autoLoadAllResults();
                        }
                    }, 100);
                }
            }, 100);
    
            // 初始检查
            setTimeout(() => {
                if (isSearchResultPage() && STATE.autoLoadEnabled) {
                    autoLoadAllResults();
                }
            }, 100);
    
            // 延迟初始计算,确保页面元素已加载
            setTimeout(() => {
                // 初始计算DPS和护盾
                calculateDPS();
            calculateShield();
                calculateEvasion();
                calculateArmour();
                calculateDefence();

                // 如果没有找到物品,设置重试
                const retryCalculation = () => {
                    const items = document.querySelectorAll('.row[data-id]');
                    if (items.length > 0) {
                        console.log('重试计算,找到物品数量:', items.length);
                calculateDPS();
                calculateShield();
                        calculateEvasion();
                        calculateArmour();
                        calculateDefence();
                    } else {
                        console.log('未找到物品,500ms后重试...');
                        setTimeout(retryCalculation, 500);
                    }
                };

                // 如果初始计算没有找到物品,启动重试机制
                const items = document.querySelectorAll('.row[data-id]');
                if (items.length === 0) {
                    console.log('初始计算未找到物品,启动重试机制');
                    setTimeout(retryCalculation, 500);
                }
            }, 500);

        } catch (error) {
            console.error('初始化时出错:', error);
        }
    }
    
    // 修改 updateConfig 函数
    function updateConfig(category, name) {
        if (confirm(`确定要用当前页面更新配置 "${name}" 吗?`)) {
            STATE.configs[category][name] = {
                url: window.location.href
            };
            GM_setValue('savedConfigs', STATE.configs);
            updateConfigList();
        }
    }
    
    // 添加预设关键词相关函数
    function saveSearchPreset() {
        const nameInput = document.getElementById('preset-name');
        const keywordsInput = document.getElementById('preset-keywords');
        const name = nameInput.value.trim();
        const keywords = keywordsInput.value.trim();
        const saveBtn = document.getElementById('save-preset');

        if (!name || !keywords) {
            alert('请输入预设名称和关键词');
            return;
        }

        // 检查是否在编辑模式
        if (nameInput.dataset.editMode === 'true') {
            const originalName = nameInput.dataset.originalName;
            // 如果名称改变了,删除旧的预设
            if (originalName !== name) {
                delete STATE.searchPresets[originalName];
            }
            // 清除编辑模式标记
            delete nameInput.dataset.editMode;
            delete nameInput.dataset.originalName;
            saveBtn.textContent = '保存预设';
        } else if (STATE.searchPresets[name] && !confirm(`预设 "${name}" 已存在,是否覆盖?`)) {
            return;
        }

        STATE.searchPresets[name] = keywords;
        GM_setValue('searchPresets', STATE.searchPresets);
        updatePresetList();

        nameInput.value = '';
        keywordsInput.value = '';
    }

    function updatePresetList() {
        const presetList = document.getElementById('preset-list');
        presetList.innerHTML = '';

        Object.entries(STATE.searchPresets).forEach(([name, keywords]) => {
            const presetItem = document.createElement('div');
            presetItem.style.cssText = `
                display: grid;
                grid-template-columns: 1fr auto auto;
                align-items: center;
                padding: 8px;
                margin: 5px 0;
                background: #3d3d3d;
                border-radius: 4px;
                gap: 10px;
            `;

            const nameSpan = document.createElement('span');
            nameSpan.textContent = name;  // 只显示预设名称
            nameSpan.title = keywords;    // 将关键词设置为提示文本
            nameSpan.style.cssText = `
                overflow: hidden;
                text-overflow: ellipsis;
                white-space: nowrap;
                cursor: help;  // 添加提示光标
            `;

            const editBtn = document.createElement('button');
            editBtn.textContent = '编辑';
            editBtn.style.cssText = `
                background: #27ae60;
                border: none;
                color: #fff;
                padding: 3px 12px;
                cursor: pointer;
                border-radius: 3px;
            `;
            editBtn.onclick = () => {
                const presetEditModal = document.getElementById('preset-edit-modal');
                const presetEditOverlay = document.getElementById('preset-edit-overlay');
                const presetEditTitle = document.getElementById('preset-edit-title');
                const nameInput = document.getElementById('preset-name');
                const keywordsInput = document.getElementById('preset-keywords');

                presetEditTitle.textContent = '编辑预设';
                nameInput.value = name;
                keywordsInput.value = keywords;
                nameInput.dataset.editMode = 'true';
                nameInput.dataset.originalName = name;

                presetEditModal.style.display = 'block';
                presetEditOverlay.style.display = 'block';
            };

            const deleteBtn = document.createElement('button');
            deleteBtn.textContent = '删除';
            deleteBtn.style.cssText = `
                background: #e74c3c;
                border: none;
                color: #fff;
                padding: 3px 12px;
                cursor: pointer;
                border-radius: 3px;
            `;
            deleteBtn.onclick = () => {
                if (confirm(`确定要删除预设 "${name}" 吗?`)) {
                    delete STATE.searchPresets[name];
                    GM_setValue('searchPresets', STATE.searchPresets);
                    updatePresetList();
                }
            };

            presetItem.appendChild(nameSpan);
            presetItem.appendChild(editBtn);
            presetItem.appendChild(deleteBtn);
            presetList.appendChild(presetItem);
        });
    }
    
    setTimeout(init, 2000);

    // 在clearHighlights函数后添加
    function updateCardVisibility() {
        const allCards = document.querySelectorAll('.row[data-id]');
        
        if (STATE.showOnlyMatched) {
            // 如果启用了"只显示匹配项",隐藏所有非匹配卡片
            allCards.forEach(card => {
                if (STATE.matchedCards.includes(card)) {
                    card.style.display = '';
                } else {
                    card.style.display = 'none';
                }
            });
        } else {
            // 如果禁用了"只显示匹配项",显示所有卡片
            allCards.forEach(card => {
                card.style.display = '';
            });
        }
    }

    // 计算护盾值
    function calculateShield() {
        console.log('Calculating Shield...');
        const items = document.querySelectorAll('.row[data-id]');
        console.log('Found items:', items.length);
        
        let processedCount = 0;
        let successCount = 0;

        items.forEach((item, index) => {
            try {
            // 如果已经计算过护盾值,则跳过
                if (item.querySelector('.shield-display')) {
                    processedCount++;
                    return;
                }

            // 1. 获取符文孔数量
            const socketsDiv = item.querySelector('.sockets');
                if (!socketsDiv) {
                    console.debug(`Item ${index}: No sockets div found`);
                    return;
                }
            
            // 修改符文孔数量的获取逻辑
            let numSockets = 0;
            for (let i = 1; i <= 6; i++) { // 假设最多6个符文孔
                if (socketsDiv.classList.contains(`numSockets${i}`)) {
                    numSockets = i;
                    break;
                }
            }
                if (numSockets === 0) {
                    // 尝试其他方式获取符文孔数量
                    const socketText = socketsDiv.textContent.trim();
                    if (socketText) {
                        numSockets = socketText.length;
                    } else {
                        numSockets = 1; // 默认值
                    }
                    console.debug(`Item ${index}: Using alternative socket count: ${numSockets}`);
                }

            // 2. 获取能量护盾值
            const esSpan = item.querySelector('span[data-field="es"]');
                if (!esSpan) {
                    console.debug(`Item ${index}: No ES span found`);
                    return;
                }

                const esValue = esSpan.querySelector('.colourAugmented, .colourDefault');
                if (!esValue) {
                    console.debug(`Item ${index}: No ES value found`);
                    return;
                }
            
            const totalES = parseInt(esValue.textContent);
                if (isNaN(totalES)) {
                    console.debug(`Item ${index}: Invalid ES value: ${esValue.textContent}`);
                    return;
                }

            // 3. 获取当前品质
            let currentQuality = 0;
            const qualitySpan = item.querySelector('span[data-field="quality"]');
            if (qualitySpan) {
                const qualityMatch = qualitySpan.textContent.match(/\+(\d+)%/);
                if (qualityMatch) {
                    currentQuality = parseInt(qualityMatch[1]);
                }
            }
            // 计算品质差值
            const qualityDiff = 20 - currentQuality;

            // 4. 获取护盾增加百分比
            let esInc = 0;

                // 定义可能包含护盾增加的词缀ID列表
                const possibleESIncIds = [
                    'stat.explicit.stat_4015621042',  // 原有ID
                    'stat.explicit.stat_1999113824',  // 增加闪避与能量护盾
                    'stat.explicit.stat_2866361420',  // 增加能量护盾
                    'stat.explicit.stat_2511217560',  // 增加最大能量护盾
                    'stat.explicit.stat_3489782002',  // 增加能量护盾和魔力
                    'stat.explicit.stat_3321629045'   // 增加护甲与能量护盾
                ];

                // 遍历所有可能的词缀ID
                for (const statId of possibleESIncIds) {
                    const statSpan = item.querySelector(`span[data-field="${statId}"]`);
                    if (statSpan) {
                        // 检查词缀文本是否包含"能量护盾"或"Energy Shield"
                        const statText = statSpan.textContent;
                        if (statText.includes('能量护盾') || statText.includes('Energy Shield')) {
                            // 提取百分比数值
                            const incMatch = statText.match(/(\d+)%/);
                if (incMatch) {
                                esInc += parseInt(incMatch[1]);
                                console.debug(`Found ES increase: ${incMatch[1]}% from stat ${statId}`);
                            }
                        }
                    }
                }

                // 通用方法:查找所有包含"能量护盾"或"Energy Shield"的显式词缀
                const allExplicitStats = item.querySelectorAll('span[data-field^="stat.explicit.stat_"]');
                allExplicitStats.forEach(statSpan => {
                    // 检查是否已经在上面的特定ID列表中处理过
                    const statId = statSpan.getAttribute('data-field');
                    if (!possibleESIncIds.includes(statId)) {
                        const statText = statSpan.textContent;
                        // 检查是否包含能量护盾相关文本和百分比增加
                        if ((statText.includes('能量护盾') || statText.includes('Energy Shield')) &&
                            statText.includes('%') &&
                            (statText.includes('增加') || statText.includes('increased'))) {
                            const incMatch = statText.match(/(\d+)%/);
                            if (incMatch) {
                                esInc += parseInt(incMatch[1]);
                                console.debug(`Found additional ES increase: ${incMatch[1]}% from stat ${statId}`);
                                // 将新发现的ID添加到列表中,以便将来使用
                                possibleESIncIds.push(statId);
                            }
                        }
                    }
                });

            // 5. 获取已插入的符文提供的增益和数量
            let insertedRuneBonus = 0;
            let insertedRuneCount = 0;
            let esRuneInc = 0; // 新增:专门用于记录护盾符文的增益

            // 获取符文增益 - 能量护盾增加
            const esRuneStatSpan = item.querySelector('span[data-field="stat.rune.stat_3523867985"]');
            if (esRuneStatSpan) {
                const runeMatch = esRuneStatSpan.textContent.match(/(\d+)%/);
                if (runeMatch) {
                    insertedRuneBonus = parseInt(runeMatch[1]);
                    insertedRuneCount = insertedRuneBonus / 20;
                }
            }

            // 获取符文增益 - 能量护盾百分比增加
            const esIncRuneStatSpan = item.querySelector('span[data-field="stat.rune.stat_2866361420"]');
            if (esIncRuneStatSpan) {
                const esIncRuneMatch = esIncRuneStatSpan.textContent.match(/(\d+)%/);
                if (esIncRuneMatch) {
                    esRuneInc = parseInt(esIncRuneMatch[1]);
                }
            }

            // 6. 计算可用的符文孔位增益
            let availableRuneBonus = 0;
            // 计算剩余可用的孔数
            const remainingSlots = numSockets - insertedRuneCount;
            availableRuneBonus = remainingSlots * 20;

            // 7. 计算基础护盾
            // 当前护盾 = 基础护盾 * (1 + 当前品质/100) * (1 + (已插入符文增益 + 装备增益 + 护盾符文增益)/100)
            const baseES = Math.round(totalES / (1 + currentQuality/100) / (1 + (insertedRuneBonus + esInc + esRuneInc)/100));

            // 8. 计算最大可能护盾(考虑品质提升和剩余符文孔)
            // 最大护盾 = 基础护盾 * (1 + (当前品质 + 品质差值)/100) * (1 + (装备增益 + 已插入符文增益 + 可用符文增益)/100)
            const maxES = Math.round(baseES * (1 + (currentQuality + qualityDiff)/100) * (1 + (esInc + insertedRuneBonus + availableRuneBonus)/100));

            // 创建护盾显示元素
            const shieldDisplay = document.createElement('span');
            shieldDisplay.className = 'shield-display';
            shieldDisplay.style.cssText = `
                color: #6495ED;
                font-weight: bold;
                margin-left: 10px;
            `;
            shieldDisplay.textContent = `总护盾: ${maxES}`;

            // 将护盾显示添加到能量护盾后面
            esSpan.appendChild(shieldDisplay);

                successCount++;
                processedCount++;

            // 添加调试信息
                console.debug(`Item ${index} Shield calculation:`, {
                totalES,
                currentQuality,
                qualityDiff,
                esInc,
                insertedRuneBonus,
                insertedRuneCount,
                numSockets,
                availableRuneBonus,
                baseES,
                maxES
            });
            } catch (error) {
                console.error(`Error calculating shield for item ${index}:`, error);
            }
        });

        console.log(`Shield calculation completed: ${successCount} successful, ${processedCount} processed out of ${items.length} items`);

        // 更新护盾排序面板
        updateShieldPanel();
    }

    // 创建护盾排序面板
    function createShieldPanel() {
        const panel = document.createElement('div');
        panel.id = 'shield-sort-panel';
        panel.style.cssText = `
            position: fixed;
            right: 20px;
            top: 50%;
            transform: translateY(calc(-50% + 200px));
            background: rgba(28, 28, 28, 0.95);
            padding: 8px;
            border-radius: 6px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
            border: 1px solid #444;
            width: 180px;
            max-height: 60vh;
            z-index: 9997;
            display: none;
        `;

        // 添加标题
        const title = document.createElement('div');
        title.style.cssText = `
            font-weight: bold;
            color: #8acdff;
            margin-bottom: 6px;
            padding-bottom: 3px;
            border-bottom: 1px solid #444;
            display: flex;
            justify-content: space-between;
            align-items: center;
            cursor: pointer;
            font-size: 14px;
            user-select: none;
            height: 18px;
        `;
        
        // 添加展开/收起指示器
        const indicator = document.createElement('span');
        indicator.textContent = '▼';
        indicator.style.marginRight = '3px';
        indicator.style.fontSize = '10px';
        indicator.id = 'integrated-panel-indicator';
        
        const titleText = document.createElement('span');
        titleText.textContent = 'ES';
        
        const titleLeft = document.createElement('div');
        titleLeft.style.display = 'flex';
        titleLeft.style.alignItems = 'center';
        titleLeft.appendChild(indicator);
        titleLeft.appendChild(titleText);

        title.appendChild(titleLeft);

        // 添加关闭按钮
        const closeBtn = document.createElement('button');
        closeBtn.textContent = '×';
        closeBtn.style.cssText = `
            background: none;
            border: none;
            color: #999;
            font-size: 20px;
            cursor: pointer;
            padding: 0 5px;
        `;
        closeBtn.onclick = (e) => {
            e.stopPropagation();
            panel.style.display = 'none';
        };
        title.appendChild(closeBtn);

        // 添加内容容器
        const content = document.createElement('div');
        content.id = 'shield-sort-content';
        content.style.cssText = `
            max-height: calc(60vh - 35px);
            overflow-y: auto;
            transition: max-height 0.3s ease-out;
            padding-right: 2px;
        `;

        // 添加展开/收起功能
        let isExpanded = true;
        title.onclick = () => {
            isExpanded = !isExpanded;
            content.style.maxHeight = isExpanded ? 'calc(60vh - 35px)' : '0';
            content.style.overflow = isExpanded ? 'auto' : 'hidden';
            indicator.textContent = isExpanded ? '▼' : '▶';
        };

        // 添加组件到面板
        panel.appendChild(title);
        panel.appendChild(content);

        // 添加到文档
        document.body.appendChild(panel);

        console.log('Shield panel created successfully');
        return panel;
    }

    // 更新护盾排序面板
    function updateShieldPanel() {
        try {
            console.log('Updating shield panel...');

            // 获取或创建面板
            const panel = document.getElementById('integrated-sort-panel') || createIntegratedPanel();
            const content = document.getElementById('shield-sort-content');
            if (!content) {
                console.error('Shield sort content not found');
                return;
            }

            // 清空现有内容
            content.innerHTML = '';

            // 清除可能存在的旧数据属性
            content.removeAttribute('data-armour-content');
            content.removeAttribute('data-evasion-content');
            content.removeAttribute('data-dps-content');
            content.removeAttribute('data-defence-content');

            // 获取所有物品
            const items = document.querySelectorAll('.row[data-id]');
            const shieldData = [];

            // 收集护盾数据
            items.forEach(item => {
                const shieldDisplay = item.querySelector('.shield-display');
                if (shieldDisplay) {
                    const shield = parseInt(shieldDisplay.textContent.replace('总护盾: ', ''));
                    
                    // 获取价格
                    const priceElement = item.querySelector('.price [data-field="price"]');
                    let price = '未标价';
                    if (priceElement) {
                        const amount = priceElement.querySelector('span:not(.price-label):not(.currency-text)');
                        const currencyText = priceElement.querySelector('.currency-text');
                        if (amount && currencyText) {
                            const amountText = amount.textContent.trim();
                            const currency = currencyText.querySelector('span')?.textContent || currencyText.textContent;
                            // 使用全局的convertCurrencyText函数
                            const simpleCurrency = convertCurrencyText(currency);
                            price = `${amountText}${simpleCurrency}`;
                        }
                    }

                    shieldData.push({
                        shield,
                        price,
                        element: item
                    });
                }
            });

            console.log(`Found ${shieldData.length} items with shield data`);

            // 如果没有护盾数据,隐藏护盾选项卡
            const shieldTab = panel.querySelector('[data-tab="shield"]');
            if (shieldData.length === 0) {
                if (shieldTab) shieldTab.style.display = 'none';

                // 如果DPS选项卡也是隐藏的,则隐藏整个面板
                const dpsTab = panel.querySelector('[data-tab="dps"]');
                const evasionTab = panel.querySelector('[data-tab="evasion"]');
                const armourTab = panel.querySelector('[data-tab="armour"]');
                const defenceTab = panel.querySelector('[data-tab="defence"]');
                
                // 检查是否所有选项卡都隐藏了
                if ((dpsTab && dpsTab.style.display === 'none') &&
                    (evasionTab && evasionTab.style.display === 'none') &&
                    (armourTab && armourTab.style.display === 'none') &&
                    (defenceTab && defenceTab.style.display === 'none')) {
                    panel.style.display = 'none';
                }
                // 移除自动切换到护盾选项卡的代码,保留当前选项卡状态
                return;
            } else {
                // 有护盾数据,确保护盾选项卡可见
                if (shieldTab) shieldTab.style.display = '';
            }

            // 按护盾值从高到低排序
            shieldData.sort((a, b) => b.shield - a.shield);

            // 更新面板内容
            shieldData.forEach(({shield, price, element}) => {
                const shieldItem = document.createElement('div');
                shieldItem.className = 'dps-item'; // 复用DPS项的样式

                // 创建护盾显示
                const shieldText = document.createElement('span');
                shieldText.className = 'shield-value'; // 使用护盾专用的样式
                shieldText.textContent = shield.toString();

                // 创建价格显示
                const priceText = document.createElement('span');
                priceText.className = 'price-value';
                priceText.textContent = price;

                // 添加到护盾项
                shieldItem.appendChild(shieldText);
                shieldItem.appendChild(priceText);

                // 添加点击事件
                shieldItem.onclick = () => {
                    element.scrollIntoView({ behavior: 'smooth', block: 'center' });
                    // 添加高亮效果
                    element.style.transition = 'background-color 0.3s';
                    element.style.backgroundColor = 'rgba(138, 205, 255, 0.2)';
                    setTimeout(() => {
                        element.style.backgroundColor = '';
                    }, 1500);
                };

                content.appendChild(shieldItem);
            });

            // 显示面板
            panel.style.display = 'block';
            console.log('Shield panel updated successfully');
        } catch (error) {
            console.error('Error updating shield panel:', error);
        }
    }

    // 辅助函数:安全地查询选择器
    function safeQuerySelector(element, selector) {
        try {
            return element.querySelector(selector);
        } catch (error) {
            console.error(`Error querying selector "${selector}":`, error);
            return null;
        }
    }

    // 创建整合面板,包含总防御、DPS、护盾、闪避和护甲五个选项卡
    function createIntegratedPanel() {
        // 检查是否已存在面板
        let panel = document.getElementById('integrated-sort-panel');
        if (panel) return panel;
        
        panel = document.createElement('div');
        panel.id = 'integrated-sort-panel';
        panel.style.cssText = `
            position: fixed;
            right: 20px;
            top: 50%;
            transform: translateY(-50%);
            background: rgba(28, 28, 28, 0.95);
            padding: 8px;
            border-radius: 6px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
            border: 1px solid #444;
            width: 180px;
            max-height: 60vh;
            z-index: 9997;
            display: none;
        `;

        // 创建标题栏
        const titleBar = document.createElement('div');
        titleBar.style.cssText = `
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 6px;
            padding-bottom: 3px;
            border-bottom: 1px solid #444;
            font-size: 13px;
            user-select: none;
            height: 18px;
        `;
        
        // 创建选项卡容器
        const tabsContainer = document.createElement('div');
        tabsContainer.style.cssText = `
            display: flex;
            gap: 4px;
            flex-wrap: nowrap;
        `;
        
        // 创建总防御选项卡(默认激活)
        const defenceTab = document.createElement('div');
        defenceTab.textContent = 'DEF';
        defenceTab.className = 'sort-tab active';
        defenceTab.dataset.tab = 'defence';
        defenceTab.style.cssText = `
            color: #9370DB;
            font-weight: bold;
            cursor: pointer;
            padding: 0 3px;
            font-size: 12px;
        `;
        
        // 创建DPS选项卡
        const dpsTab = document.createElement('div');
        dpsTab.textContent = 'DPS';
        dpsTab.className = 'sort-tab';
        dpsTab.dataset.tab = 'dps';
        dpsTab.style.cssText = `
            color: #FFD700;
            font-weight: bold;
            cursor: pointer;
            padding: 0 3px;
            opacity: 0.6;
            font-size: 12px;
        `;
        
        // 创建护盾选项卡
        const shieldTab = document.createElement('div');
        shieldTab.textContent = 'ES';
        shieldTab.className = 'sort-tab';
        shieldTab.dataset.tab = 'shield';
        shieldTab.style.cssText = `
            color: #8acdff;
            font-weight: bold;
            cursor: pointer;
            padding: 0 3px;
            opacity: 0.6;
            font-size: 12px;
        `;
        
        // 创建闪避选项卡
        const evasionTab = document.createElement('div');
        evasionTab.textContent = 'EV';
        evasionTab.className = 'sort-tab';
        evasionTab.dataset.tab = 'evasion';
        evasionTab.style.cssText = `
            color: #7FFF00;
            font-weight: bold;
            cursor: pointer;
            padding: 0 3px;
            opacity: 0.6;
            font-size: 12px;
        `;
        
        // 创建护甲选项卡
        const armourTab = document.createElement('div');
        armourTab.textContent = 'AR';
        armourTab.className = 'sort-tab';
        armourTab.dataset.tab = 'armour';
        armourTab.style.cssText = `
            color: #FF6347;
            font-weight: bold;
            cursor: pointer;
            padding: 0 3px;
            opacity: 0.6;
            font-size: 12px;
        `;
        
        // 添加选项卡到容器
        tabsContainer.appendChild(defenceTab);
        tabsContainer.appendChild(dpsTab);
        tabsContainer.appendChild(shieldTab);
        tabsContainer.appendChild(evasionTab);
        tabsContainer.appendChild(armourTab);
        
        // 创建展开/收起指示器
        const indicator = document.createElement('span');
        indicator.textContent = '▼';
        indicator.style.marginRight = '3px';
        indicator.style.fontSize = '10px';
        indicator.id = 'integrated-panel-indicator';
        
        // 创建左侧容器
        const titleLeft = document.createElement('div');
        titleLeft.style.cssText = `
            display: flex;
            align-items: center;
        `;
        titleLeft.appendChild(indicator);
        titleLeft.appendChild(tabsContainer);
        
        // 添加关闭按钮
        const closeBtn = document.createElement('button');
        closeBtn.textContent = '×';
        closeBtn.style.cssText = `
            background: none;
            border: none;
            color: #999;
            font-size: 20px;
            cursor: pointer;
            padding: 0 5px;
        `;
        closeBtn.onclick = (e) => {
            e.stopPropagation();
            panel.style.display = 'none';
        };
        
        // 组装标题栏
        titleBar.appendChild(titleLeft);
        titleBar.appendChild(closeBtn);
        
        // 创建内容容器
        const contentContainer = document.createElement('div');
        contentContainer.style.cssText = `
            position: relative;
        `;
        
        // 创建总防御内容
        const defenceContent = document.createElement('div');
        defenceContent.id = 'defence-sort-content';
        defenceContent.className = 'sort-content active';
        defenceContent.style.cssText = `
            max-height: calc(60vh - 35px);
            overflow-y: auto;
            transition: max-height 0.3s ease-out, opacity 0.3s ease-out;
            padding-right: 2px;
        `;
        
        // 创建DPS内容
        const dpsContent = document.createElement('div');
        dpsContent.id = 'dps-sort-content';
        dpsContent.className = 'sort-content';
        dpsContent.style.cssText = `
            max-height: calc(60vh - 35px);
            overflow-y: auto;
            transition: max-height 0.3s ease-out, opacity 0.3s ease-out;
            padding-right: 2px;
            display: none;
        `;
        
        // 创建护盾内容
        const shieldContent = document.createElement('div');
        shieldContent.id = 'shield-sort-content';
        shieldContent.className = 'sort-content';
        shieldContent.style.cssText = `
            max-height: calc(60vh - 35px);
            overflow-y: auto;
            transition: max-height 0.3s ease-out, opacity 0.3s ease-out;
            padding-right: 2px;
            display: none;
        `;
        
        // 创建闪避内容
        const evasionContent = document.createElement('div');
        evasionContent.id = 'evasion-sort-content';
        evasionContent.className = 'sort-content';
        evasionContent.style.cssText = `
            max-height: calc(60vh - 35px);
            overflow-y: auto;
            transition: max-height 0.3s ease-out, opacity 0.3s ease-out;
            padding-right: 2px;
            display: none;
        `;
        
        // 创建护甲内容
        const armourContent = document.createElement('div');
        armourContent.id = 'armour-sort-content';
        armourContent.className = 'sort-content';
        armourContent.style.cssText = `
            max-height: calc(60vh - 35px);
            overflow-y: auto;
            transition: max-height 0.3s ease-out, opacity 0.3s ease-out;
            padding-right: 2px;
            display: none;
        `;
        
        // 添加内容到容器
        contentContainer.appendChild(defenceContent);
        contentContainer.appendChild(dpsContent);
        contentContainer.appendChild(shieldContent);
        contentContainer.appendChild(evasionContent);
        contentContainer.appendChild(armourContent);
        
        // 添加展开/收起功能
        let isExpanded = true;
        indicator.onclick = (e) => {
            e.stopPropagation();
            isExpanded = !isExpanded;
            defenceContent.style.maxHeight = isExpanded ? 'calc(60vh - 35px)' : '0';
            dpsContent.style.maxHeight = isExpanded ? 'calc(60vh - 35px)' : '0';
            shieldContent.style.maxHeight = isExpanded ? 'calc(60vh - 35px)' : '0';
            evasionContent.style.maxHeight = isExpanded ? 'calc(60vh - 35px)' : '0';
            armourContent.style.maxHeight = isExpanded ? 'calc(60vh - 35px)' : '0';
            defenceContent.style.overflow = isExpanded ? 'auto' : 'hidden';
            dpsContent.style.overflow = isExpanded ? 'auto' : 'hidden';
            shieldContent.style.overflow = isExpanded ? 'auto' : 'hidden';
            evasionContent.style.overflow = isExpanded ? 'auto' : 'hidden';
            armourContent.style.overflow = isExpanded ? 'auto' : 'hidden';
            indicator.textContent = isExpanded ? '▼' : '▶';
        };

        // 添加选项卡切换功能
        defenceTab.onclick = () => {
            defenceTab.classList.add('active');
            dpsTab.classList.remove('active');
            shieldTab.classList.remove('active');
            evasionTab.classList.remove('active');
            armourTab.classList.remove('active');
            defenceContent.style.display = 'block';
            dpsContent.style.display = 'none';
            shieldContent.style.display = 'none';
            evasionContent.style.display = 'none';
            armourContent.style.display = 'none';
            defenceTab.style.opacity = '1';
            dpsTab.style.opacity = '0.6';
            shieldTab.style.opacity = '0.6';
            evasionTab.style.opacity = '0.6';
            armourTab.style.opacity = '0.6';
        };
        
        dpsTab.onclick = () => {
            dpsTab.classList.add('active');
            defenceTab.classList.remove('active');
            shieldTab.classList.remove('active');
            evasionTab.classList.remove('active');
            armourTab.classList.remove('active');
            dpsContent.style.display = 'block';
            defenceContent.style.display = 'none';
            shieldContent.style.display = 'none';
            evasionContent.style.display = 'none';
            armourContent.style.display = 'none';
            dpsTab.style.opacity = '1';
            defenceTab.style.opacity = '0.6';
            shieldTab.style.opacity = '0.6';
            evasionTab.style.opacity = '0.6';
            armourTab.style.opacity = '0.6';
        };
        
        shieldTab.onclick = () => {
            shieldTab.classList.add('active');
            defenceTab.classList.remove('active');
            dpsTab.classList.remove('active');
            evasionTab.classList.remove('active');
            armourTab.classList.remove('active');
            shieldContent.style.display = 'block';
            defenceContent.style.display = 'none';
            dpsContent.style.display = 'none';
            evasionContent.style.display = 'none';
            armourContent.style.display = 'none';
            shieldTab.style.opacity = '1';
            defenceTab.style.opacity = '0.6';
            dpsTab.style.opacity = '0.6';
            evasionTab.style.opacity = '0.6';
            armourTab.style.opacity = '0.6';
        };
        
        evasionTab.onclick = () => {
            evasionTab.classList.add('active');
            defenceTab.classList.remove('active');
            dpsTab.classList.remove('active');
            shieldTab.classList.remove('active');
            armourTab.classList.remove('active');
            evasionContent.style.display = 'block';
            defenceContent.style.display = 'none';
            dpsContent.style.display = 'none';
            shieldContent.style.display = 'none';
            armourContent.style.display = 'none';
            evasionTab.style.opacity = '1';
            defenceTab.style.opacity = '0.6';
            dpsTab.style.opacity = '0.6';
            shieldTab.style.opacity = '0.6';
            armourTab.style.opacity = '0.6';
        };
        
        armourTab.onclick = () => {
            armourTab.classList.add('active');
            defenceTab.classList.remove('active');
            dpsTab.classList.remove('active');
            shieldTab.classList.remove('active');
            evasionTab.classList.remove('active');
            armourContent.style.display = 'block';
            defenceContent.style.display = 'none';
            dpsContent.style.display = 'none';
            shieldContent.style.display = 'none';
            evasionContent.style.display = 'none';
            armourTab.style.opacity = '1';
            defenceTab.style.opacity = '0.6';
            dpsTab.style.opacity = '0.6';
            shieldTab.style.opacity = '0.6';
            evasionTab.style.opacity = '0.6';
        };

        // 添加滚动条样式
        const style = document.createElement('style');
        style.textContent = `
            #dps-sort-content::-webkit-scrollbar,
            #shield-sort-content::-webkit-scrollbar,
            #evasion-sort-content::-webkit-scrollbar,
            #armour-sort-content::-webkit-scrollbar {
                width: 6px;
            }
            #dps-sort-content::-webkit-scrollbar-track,
            #shield-sort-content::-webkit-scrollbar-track,
            #evasion-sort-content::-webkit-scrollbar-track {
                background: #1a1a1a;
            }
            #dps-sort-content::-webkit-scrollbar-thumb,
            #shield-sort-content::-webkit-scrollbar-thumb,
            #evasion-sort-content::-webkit-scrollbar-thumb {
                background: #444;
                border-radius: 3px;
            }
            #dps-sort-content::-webkit-scrollbar-thumb:hover,
            #shield-sort-content::-webkit-scrollbar-thumb:hover,
            #evasion-sort-content::-webkit-scrollbar-thumb:hover {
                background: #555;
            }
            .dps-item {
                    padding: 4px 8px;
                    margin: 1px 0;
                    background: #2d2d2d;
                    border-radius: 3px;
                    cursor: pointer;
                    transition: background 0.2s;
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    gap: 8px;
                    font-size: 13px;
                    white-space: nowrap;
                    user-select: none;
                    line-height: 1.2;
            }
            .dps-item:hover {
                background: #3d3d3d;
            }
            .dps-item:last-child {
                margin-bottom: 0;
            }
            .dps-value {
                color: #FFD700;
                font-weight: bold;
            }
            .shield-value {
                color: #8acdff;
                font-weight: bold;
            }
            .evasion-value {
                color: #7FFF00;
                font-weight: bold;
            }
            .price-value {
                color: #8acdff;
                font-size: 12px;
                text-align: right;
            }
        `;

        // 组装面板
        panel.appendChild(titleBar);
        panel.appendChild(contentContainer);
        document.head.appendChild(style);
        document.body.appendChild(panel);

        console.log('Integrated panel created successfully');
        return panel;
    }

    // 计算闪避值
    function calculateEvasion() {
        console.log('Calculating Evasion...');
        const items = document.querySelectorAll('.row[data-id]');
        console.log('Found items:', items.length);

        let processedCount = 0;
        let successCount = 0;

        items.forEach((item, index) => {
            try {
                // 如果已经计算过闪避值,则跳过
                if (item.querySelector('.evasion-display')) {
                    processedCount++;
                    return;
                }

                // 1. 获取符文孔数量
                const socketsDiv = item.querySelector('.sockets');
                if (!socketsDiv) {
                    console.debug(`Item ${index}: No sockets div found`);
                    return;
                }

                // 修改符文孔数量的获取逻辑
                let numSockets = 0;
                for (let i = 1; i <= 6; i++) { // 假设最多6个符文孔
                    if (socketsDiv.classList.contains(`numSockets${i}`)) {
                        numSockets = i;
                        break;
                    }
                }
                if (numSockets === 0) {
                    // 尝试其他方式获取符文孔数量
                    const socketText = socketsDiv.textContent.trim();
                    if (socketText) {
                        numSockets = socketText.length;
                    } else {
                        numSockets = 1; // 默认值
                    }
                    console.debug(`Item ${index}: Using alternative socket count: ${numSockets}`);
                }

                // 2. 获取闪避值
                const evasionSpan = item.querySelector('span[data-field="ev"]');
                if (!evasionSpan) {
                    console.debug(`Item ${index}: No Evasion span found`);
                    return;
                }

                const evasionValue = evasionSpan.querySelector('.colourAugmented, .colourDefault');
                if (!evasionValue) {
                    console.debug(`Item ${index}: No Evasion value found`);
                    return;
                }

                const totalEvasion = parseInt(evasionValue.textContent);
                if (isNaN(totalEvasion)) {
                    console.debug(`Item ${index}: Invalid Evasion value: ${evasionValue.textContent}`);
                    return;
                }

                // 3. 获取当前品质
                let currentQuality = 0;
                const qualitySpan = item.querySelector('span[data-field="quality"]');
                if (qualitySpan) {
                    const qualityMatch = qualitySpan.textContent.match(/\+(\d+)%/);
                    if (qualityMatch) {
                        currentQuality = parseInt(qualityMatch[1]);
                    }
                }
                // 计算品质差值
                const qualityDiff = 20 - currentQuality;

                // 4. 获取闪避增加百分比
                let evasionInc = 0;

                // 定义可能包含闪避增加的词缀ID列表
                const possibleEvasionIncIds = [
                    'stat.explicit.stat_1999113824',  // 增加闪避与能量护盾
                    'stat.explicit.stat_2144192051',  // 增加闪避
                    'stat.explicit.stat_3489782002',  // 增加闪避和生命
                    'stat.explicit.stat_3321629045'   // 增加护甲与闪避
                ];

                // 遍历所有可能的词缀ID
                for (const statId of possibleEvasionIncIds) {
                    const statSpan = item.querySelector(`span[data-field="${statId}"]`);
                    if (statSpan) {
                        // 检查词缀文本是否包含"闪避"或"Evasion"
                        const statText = statSpan.textContent;
                        if (statText.includes('闪避') || statText.includes('Evasion')) {
                            // 提取百分比数值
                            const incMatch = statText.match(/(\d+)%/);
                            if (incMatch) {
                                evasionInc += parseInt(incMatch[1]);
                                console.debug(`Found Evasion increase: ${incMatch[1]}% from stat ${statId}`);
                            }
                        }
                    }
                }

                // 通用方法:查找所有包含"闪避"或"Evasion"的显式词缀
                const allExplicitStats = item.querySelectorAll('span[data-field^="stat.explicit.stat_"]');
                allExplicitStats.forEach(statSpan => {
                    // 检查是否已经在上面的特定ID列表中处理过
                    const statId = statSpan.getAttribute('data-field');
                    if (!possibleEvasionIncIds.includes(statId)) {
                        const statText = statSpan.textContent;
                        // 检查是否包含闪避相关文本和百分比增加
                        if ((statText.includes('闪避') || statText.includes('Evasion')) &&
                            statText.includes('%') &&
                            (statText.includes('增加') || statText.includes('increased'))) {
                            const incMatch = statText.match(/(\d+)%/);
                            if (incMatch) {
                                evasionInc += parseInt(incMatch[1]);
                                console.debug(`Found additional Evasion increase: ${incMatch[1]}% from stat ${statId}`);
                                // 将新发现的ID添加到列表中,以便将来使用
                                possibleEvasionIncIds.push(statId);
                            }
                        }
                    }
                });

                // 5. 获取已插入的符文提供的增益和数量
                let insertedRuneBonus = 0;
                let insertedRuneCount = 0;
                let evasionRuneInc = 0; // 专门用于记录闪避符文的增益

                // 获取符文增益 - 闪避增加
                const evasionRuneStatSpan = item.querySelector('span[data-field="stat.rune.stat_3523867985"]');
                if (evasionRuneStatSpan) {
                    const runeMatch = evasionRuneStatSpan.textContent.match(/(\d+)%/);
                    if (runeMatch) {
                        insertedRuneBonus = parseInt(runeMatch[1]);
                        insertedRuneCount = insertedRuneBonus / 20;
                    }
                }

                // 获取符文增益 - 闪避百分比增加
                const evasionIncRuneStatSpan = item.querySelector('span[data-field="stat.rune.stat_2866361420"]');
                if (evasionIncRuneStatSpan) {
                    const evasionIncRuneMatch = evasionIncRuneStatSpan.textContent.match(/(\d+)%/);
                    if (evasionIncRuneMatch) {
                        evasionRuneInc = parseInt(evasionIncRuneMatch[1]);
                    }
                }

                // 6. 计算可用的符文孔位增益
                let availableRuneBonus = 0;
                // 计算剩余可用的孔数
                const remainingSlots = numSockets - insertedRuneCount;
                availableRuneBonus = remainingSlots * 20;

                // 7. 计算基础闪避
                // 当前闪避 = 基础闪避 * (1 + 当前品质/100) * (1 + (已插入符文增益 + 装备增益 + 闪避符文增益)/100)
                const baseEvasion = Math.round(totalEvasion / (1 + currentQuality/100) / (1 + (insertedRuneBonus + evasionInc + evasionRuneInc)/100));

                // 8. 计算最大可能闪避(考虑品质提升和剩余符文孔)
                // 最大闪避 = 基础闪避 * (1 + (当前品质 + 品质差值)/100) * (1 + (装备增益 + 已插入符文增益 + 可用符文增益)/100)
                const maxEvasion = Math.round(baseEvasion * (1 + (currentQuality + qualityDiff)/100) * (1 + (evasionInc + insertedRuneBonus + availableRuneBonus)/100));

                // 创建闪避显示元素
                const evasionDisplay = document.createElement('span');
                evasionDisplay.className = 'evasion-display';
                evasionDisplay.style.cssText = `
                    color: #32CD32;
                    font-weight: bold;
                    margin-left: 10px;
                `;
                evasionDisplay.textContent = `总闪避: ${maxEvasion}`;

                // 将闪避显示添加到闪避后面
                evasionSpan.appendChild(evasionDisplay);

                successCount++;
                processedCount++;

                // 添加调试信息
                console.debug(`Item ${index} Evasion calculation:`, {
                    totalEvasion,
                    currentQuality,
                    qualityDiff,
                    evasionInc,
                    insertedRuneBonus,
                    insertedRuneCount,
                    numSockets,
                    availableRuneBonus,
                    baseEvasion,
                    maxEvasion
                });
            } catch (error) {
                console.error(`Error calculating evasion for item ${index}:`, error);
            }
        });

        console.log(`Evasion calculation completed: ${successCount} successful, ${processedCount} processed out of ${items.length} items`);

        // 更新闪避排序面板
        updateEvasionPanel();
    }

    // 创建闪避排序面板
    function createEvasionPanel() {
        const panel = document.createElement('div');
        panel.id = 'evasion-sort-panel';
        panel.style.cssText = `
            position: fixed;
            right: 20px;
            top: 50%;
            transform: translateY(calc(-50% + 400px));
            background: rgba(28, 28, 28, 0.95);
            padding: 8px;
            border-radius: 6px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
            border: 1px solid #444;
            width: 180px;
            max-height: 60vh;
            z-index: 9997;
            display: none;
        `;

        // 添加标题
        const title = document.createElement('div');
        title.style.cssText = `
            font-weight: bold;
            color: #7FFF00;
            margin-bottom: 6px;
            padding-bottom: 3px;
            border-bottom: 1px solid #444;
            display: flex;
            justify-content: space-between;
            align-items: center;
            cursor: pointer;
            font-size: 14px;
            user-select: none;
            height: 18px;
        `;

        // 添加展开/收起指示器
        const indicator = document.createElement('span');
        indicator.textContent = '▼';
        indicator.style.marginRight = '3px';
        indicator.style.fontSize = '10px';
        indicator.id = 'integrated-panel-indicator';

        const titleText = document.createElement('span');
        titleText.textContent = 'EV';

        const titleLeft = document.createElement('div');
        titleLeft.style.display = 'flex';
        titleLeft.style.alignItems = 'center';
        titleLeft.appendChild(indicator);
        titleLeft.appendChild(titleText);

        title.appendChild(titleLeft);

        // 添加关闭按钮
        const closeBtn = document.createElement('button');
        closeBtn.textContent = '×';
        closeBtn.style.cssText = `
            background: none;
            border: none;
            color: #999;
            font-size: 20px;
            cursor: pointer;
            padding: 0 5px;
        `;
        closeBtn.onclick = (e) => {
            e.stopPropagation();
            panel.style.display = 'none';
        };
        title.appendChild(closeBtn);

        // 添加内容容器
        const content = document.createElement('div');
        content.id = 'evasion-sort-content';
        content.style.cssText = `
            max-height: calc(60vh - 35px);
            overflow-y: auto;
            transition: max-height 0.3s ease-out;
            padding-right: 2px;
        `;

        // 添加展开/收起功能
        let isExpanded = true;
        title.onclick = () => {
            isExpanded = !isExpanded;
            content.style.maxHeight = isExpanded ? 'calc(60vh - 35px)' : '0';
            content.style.overflow = isExpanded ? 'auto' : 'hidden';
            indicator.textContent = isExpanded ? '▼' : '▶';
        };

        // 添加组件到面板
        panel.appendChild(title);
        panel.appendChild(content);

        // 添加到文档
        document.body.appendChild(panel);

        console.log('Evasion panel created successfully');
        return panel;
    }

    // 更新闪避排序面板
    function updateEvasionPanel() {
        try {
            console.log('Updating evasion panel...');

            // 获取或创建面板
            const panel = document.getElementById('integrated-sort-panel') || createIntegratedPanel();
            const content = document.getElementById('evasion-sort-content');
            if (!content) {
                console.error('Evasion sort content not found');
                return;
            }

            // 清空现有内容
            content.innerHTML = '';

            // 清除可能存在的旧数据属性
            content.removeAttribute('data-armour-content');
            content.removeAttribute('data-shield-content');
            content.removeAttribute('data-dps-content');
            content.removeAttribute('data-defence-content');

            // 获取所有物品
            const items = document.querySelectorAll('.row[data-id]');
            const evasionData = [];

            // 收集闪避数据
            items.forEach(item => {
                const evasionDisplay = item.querySelector('.evasion-display');
                if (evasionDisplay) {
                    const evasion = parseInt(evasionDisplay.textContent.replace('总闪避: ', ''));

                    // 获取价格
                    const priceElement = item.querySelector('.price [data-field="price"]');
                    let price = '未标价';
                    if (priceElement) {
                        const amount = priceElement.querySelector('span:not(.price-label):not(.currency-text)');
                        const currencyText = priceElement.querySelector('.currency-text');
                        if (amount && currencyText) {
                            const amountText = amount.textContent.trim();
                            const currency = currencyText.querySelector('span')?.textContent || currencyText.textContent;
                            // 使用全局的convertCurrencyText函数
                            const simpleCurrency = convertCurrencyText(currency);
                            price = `${amountText}${simpleCurrency}`;
                        }
                    }

                    evasionData.push({
                        evasion,
                        price,
                        element: item
                    });
                }
            });

            console.log(`Found ${evasionData.length} items with evasion data`);

            // 如果没有闪避数据,隐藏闪避选项卡
            const evasionTab = panel.querySelector('[data-tab="evasion"]');
            if (evasionData.length === 0) {
                if (evasionTab) evasionTab.style.display = 'none';

                // 如果其他选项卡也是隐藏的,则隐藏整个面板
                const dpsTab = panel.querySelector('[data-tab="dps"]');
                const shieldTab = panel.querySelector('[data-tab="shield"]');
                const armourTab = panel.querySelector('[data-tab="armour"]');
                const defenceTab = panel.querySelector('[data-tab="defence"]');
                
                // 检查是否所有选项卡都隐藏了
                if ((dpsTab && dpsTab.style.display === 'none') &&
                    (shieldTab && shieldTab.style.display === 'none') &&
                    (armourTab && armourTab.style.display === 'none') &&
                    (defenceTab && defenceTab.style.display === 'none')) {
                    panel.style.display = 'none';
                }
                // 移除自动切换到其他选项卡的代码,保留当前选项卡状态
                return;
            } else {
                // 有闪避数据,确保闪避选项卡可见
                if (evasionTab) evasionTab.style.display = '';
            }

            // 按闪避值从高到低排序
            evasionData.sort((a, b) => b.evasion - a.evasion);

            // 更新面板内容
            evasionData.forEach(({evasion, price, element}) => {
                const evasionItem = document.createElement('div');
                evasionItem.className = 'dps-item'; // 复用DPS项的样式

                // 创建闪避显示
                const evasionText = document.createElement('span');
                evasionText.className = 'evasion-value'; // 使用闪避专用的样式
                evasionText.textContent = evasion.toString();

                // 创建价格显示
                const priceText = document.createElement('span');
                priceText.className = 'price-value';
                priceText.textContent = price;
                
                // 添加到闪避项
                evasionItem.appendChild(evasionText);
                evasionItem.appendChild(priceText);
                
                // 添加点击事件
                evasionItem.onclick = () => {
                    element.scrollIntoView({ behavior: 'smooth', block: 'center' });
                    // 添加高亮效果
                    element.style.transition = 'background-color 0.3s';
                    element.style.backgroundColor = 'rgba(127, 255, 0, 0.2)';
                    setTimeout(() => {
                        element.style.backgroundColor = '';
                    }, 1500);
                };

                content.appendChild(evasionItem);
            });

            // 显示面板
            panel.style.display = 'block';
            console.log('Evasion panel updated successfully');
        } catch (error) {
            console.error('Error updating evasion panel:', error);
        }
    }

    // 计算护甲值
    function calculateArmour() {
        console.log('Calculating Armour...');
        const items = document.querySelectorAll('.row[data-id]');
        console.log('Found items:', items.length);

        let processedCount = 0;
        let successCount = 0;

        items.forEach((item, index) => {
            try {
                // 如果已经计算过护甲值,则跳过
                if (item.querySelector('.armour-display')) {
                    processedCount++;
                    return;
                }

                // 1. 获取符文孔数量
                const socketsDiv = item.querySelector('.sockets');
                if (!socketsDiv) {
                    console.debug(`Item ${index}: No sockets div found`);
                    return;
                }

                // 修改符文孔数量的获取逻辑
                let numSockets = 0;
                for (let i = 1; i <= 6; i++) { // 假设最多6个符文孔
                    if (socketsDiv.classList.contains(`numSockets${i}`)) {
                        numSockets = i;
                        break;
                    }
                }
                if (numSockets === 0) {
                    // 尝试其他方式获取符文孔数量
                    const socketText = socketsDiv.textContent.trim();
                    if (socketText) {
                        numSockets = socketText.length;
                    } else {
                        numSockets = 1; // 默认值
                    }
                    console.debug(`Item ${index}: Using alternative socket count: ${numSockets}`);
                }

                // 2. 获取护甲值
                const armourSpan = item.querySelector('span[data-field="ar"]');
                if (!armourSpan) {
                    console.debug(`Item ${index}: No Armour span found`);
                    return;
                }

                const armourValue = armourSpan.querySelector('.colourAugmented, .colourDefault');
                if (!armourValue) {
                    console.debug(`Item ${index}: No Armour value found`);
                    return;
                }

                const totalArmour = parseInt(armourValue.textContent);
                if (isNaN(totalArmour)) {
                    console.debug(`Item ${index}: Invalid Armour value: ${armourValue.textContent}`);
                    return;
                }

                // 3. 获取当前品质
                let currentQuality = 0;
                const qualitySpan = item.querySelector('span[data-field="quality"]');
                if (qualitySpan) {
                    const qualityMatch = qualitySpan.textContent.match(/\+(\d+)%/);
                    if (qualityMatch) {
                        currentQuality = parseInt(qualityMatch[1]);
                    }
                }
                // 计算品质差值
                const qualityDiff = 20 - currentQuality;

                // 4. 获取护甲增加百分比
                let armourInc = 0;

                // 定义可能包含护甲增加的词缀ID列表
                const possibleArmourIncIds = [
                    'stat.explicit.stat_3321629045',  // 增加护甲与能量护盾
                    'stat.explicit.stat_2866361420',  // 增加护甲
                    'stat.explicit.stat_2511217560',  // 增加最大护甲
                    'stat.explicit.stat_3489782002'   // 增加护甲和生命
                ];

                // 遍历所有可能的词缀ID
                for (const statId of possibleArmourIncIds) {
                    const statSpan = item.querySelector(`span[data-field="${statId}"]`);
                    if (statSpan) {
                        // 检查词缀文本是否包含"护甲"或"Armour"
                        const statText = statSpan.textContent;
                        if (statText.includes('护甲') || statText.includes('Armour')) {
                            // 提取百分比数值
                            const incMatch = statText.match(/(\d+)%/);
                            if (incMatch) {
                                armourInc += parseInt(incMatch[1]);
                                console.debug(`Found Armour increase: ${incMatch[1]}% from stat ${statId}`);
                            }
                        }
                    }
                }

                // 通用方法:查找所有包含"护甲"或"Armour"的显式词缀
                const allExplicitStats = item.querySelectorAll('span[data-field^="stat.explicit.stat_"]');
                allExplicitStats.forEach(statSpan => {
                    // 检查是否已经在上面的特定ID列表中处理过
                    const statId = statSpan.getAttribute('data-field');
                    if (!possibleArmourIncIds.includes(statId)) {
                        const statText = statSpan.textContent;
                        // 检查是否包含护甲相关文本和百分比增加
                        if ((statText.includes('护甲') || statText.includes('Armour')) &&
                            statText.includes('%') &&
                            (statText.includes('增加') || statText.includes('increased'))) {
                            const incMatch = statText.match(/(\d+)%/);
                            if (incMatch) {
                                armourInc += parseInt(incMatch[1]);
                                console.debug(`Found additional Armour increase: ${incMatch[1]}% from stat ${statId}`);
                                // 将新发现的ID添加到列表中,以便将来使用
                                possibleArmourIncIds.push(statId);
                            }
                        }
                    }
                });

                // 5. 获取已插入的符文提供的增益和数量
                let insertedRuneBonus = 0;
                let insertedRuneCount = 0;
                let armourRuneInc = 0; // 专门用于记录护甲符文的增益

                // 获取符文增益 - 护甲增加
                const armourRuneStatSpan = item.querySelector('span[data-field="stat.rune.stat_3523867985"]');
                if (armourRuneStatSpan) {
                    const runeMatch = armourRuneStatSpan.textContent.match(/(\d+)%/);
                    if (runeMatch) {
                        insertedRuneBonus = parseInt(runeMatch[1]);
                        insertedRuneCount = insertedRuneBonus / 20;
                    }
                }

                // 获取符文增益 - 护甲百分比增加
                const armourIncRuneStatSpan = item.querySelector('span[data-field="stat.rune.stat_2866361420"]');
                if (armourIncRuneStatSpan) {
                    const armourIncRuneMatch = armourIncRuneStatSpan.textContent.match(/(\d+)%/);
                    if (armourIncRuneMatch) {
                        armourRuneInc = parseInt(armourIncRuneMatch[1]);
                    }
                }

                // 6. 计算可用的符文孔位增益
                let availableRuneBonus = 0;
                // 计算剩余可用的孔数
                const remainingSlots = numSockets - insertedRuneCount;
                availableRuneBonus = remainingSlots * 20;

                // 7. 计算基础护甲
                // 当前护甲 = 基础护甲 * (1 + 当前品质/100) * (1 + (已插入符文增益 + 装备增益 + 护甲符文增益)/100)
                const baseArmour = Math.round(totalArmour / (1 + currentQuality/100) / (1 + (insertedRuneBonus + armourInc + armourRuneInc)/100));

                // 8. 计算最大可能护甲(考虑品质提升和剩余符文孔)
                // 最大护甲 = 基础护甲 * (1 + (当前品质 + 品质差值)/100) * (1 + (装备增益 + 已插入符文增益 + 可用符文增益)/100)
                const maxArmour = Math.round(baseArmour * (1 + (currentQuality + qualityDiff)/100) * (1 + (armourInc + insertedRuneBonus + availableRuneBonus)/100));

                // 创建护甲显示元素
                const armourDisplay = document.createElement('span');
                armourDisplay.className = 'armour-display';
                armourDisplay.style.cssText = `
                    color: #CD853F;
                    font-weight: bold;
                    margin-left: 10px;
                `;
                armourDisplay.textContent = `总护甲: ${maxArmour}`;

                // 将护甲显示添加到护甲后面
                armourSpan.appendChild(armourDisplay);

                successCount++;
                processedCount++;

                // 添加调试信息
                console.debug(`Item ${index} Armour calculation:`, {
                    totalArmour,
                    currentQuality,
                    qualityDiff,
                    armourInc,
                    insertedRuneBonus,
                    insertedRuneCount,
                    numSockets,
                    availableRuneBonus,
                    baseArmour,
                    maxArmour
                });
            } catch (error) {
                console.error(`Error calculating armour for item ${index}:`, error);
            }
        });

        console.log(`Armour calculation completed: ${successCount} successful, ${processedCount} processed out of ${items.length} items`);

        // 更新护甲排序面板
        updateArmourPanel();
    }

    // 创建护甲排序面板
    function createArmourPanel() {
        const panel = document.createElement('div');
        panel.id = 'armour-sort-panel';
        panel.style.cssText = `
            position: fixed;
            right: 20px;
            top: 50%;
            transform: translateY(calc(-50% + 600px));
            background: rgba(28, 28, 28, 0.95);
            padding: 8px;
            border-radius: 6px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
            border: 1px solid #444;
            width: 180px;
            max-height: 60vh;
            z-index: 9997;
            display: none;
        `;

        // 添加标题
        const title = document.createElement('div');
        title.style.cssText = `
            font-weight: bold;
            color: #FF6347;
            margin-bottom: 6px;
            padding-bottom: 3px;
            border-bottom: 1px solid #444;
            display: flex;
            justify-content: space-between;
            align-items: center;
            cursor: pointer;
            font-size: 14px;
            user-select: none;
            height: 18px;
        `;

        // 添加展开/收起指示器
        const indicator = document.createElement('span');
        indicator.textContent = '▼';
        indicator.style.marginRight = '3px';
        indicator.style.fontSize = '10px';
        indicator.id = 'integrated-panel-indicator';

        const titleText = document.createElement('span');
        titleText.textContent = 'AR';

        const titleLeft = document.createElement('div');
        titleLeft.style.display = 'flex';
        titleLeft.style.alignItems = 'center';
        titleLeft.appendChild(indicator);
        titleLeft.appendChild(titleText);

        title.appendChild(titleLeft);

        // 添加关闭按钮
        const closeBtn = document.createElement('button');
        closeBtn.textContent = '×';
        closeBtn.style.cssText = `
            background: none;
            border: none;
            color: #999;
            font-size: 20px;
            cursor: pointer;
            padding: 0 5px;
        `;
        closeBtn.onclick = (e) => {
            e.stopPropagation();
            panel.style.display = 'none';
        };
        title.appendChild(closeBtn);

        // 添加内容容器
        const content = document.createElement('div');
        content.id = 'armour-sort-content';
        content.style.cssText = `
            max-height: calc(60vh - 35px);
            overflow-y: auto;
            transition: max-height 0.3s ease-out;
            padding-right: 2px;
        `;

        // 添加展开/收起功能
        let isExpanded = true;
        title.onclick = () => {
            isExpanded = !isExpanded;
            content.style.maxHeight = isExpanded ? 'calc(60vh - 35px)' : '0';
            content.style.overflow = isExpanded ? 'auto' : 'hidden';
            indicator.textContent = isExpanded ? '▼' : '▶';
        };

        // 添加组件到面板
        panel.appendChild(title);
        panel.appendChild(content);

        // 添加到文档
        document.body.appendChild(panel);

        console.log('Armour panel created successfully');
        return panel;
    }

    // 更新护甲排序面板
    function updateArmourPanel() {
        try {
            console.log('Updating armour panel...');

            // 获取或创建面板
            const panel = document.getElementById('integrated-sort-panel') || createIntegratedPanel();
            const content = document.getElementById('armour-sort-content');
            if (!content) {
                console.error('Armour sort content not found');
                return;
            }

            // 清空现有内容
            content.innerHTML = '';

            // 获取所有物品
            const items = document.querySelectorAll('.row[data-id]');
            const armourData = [];

            // 收集护甲数据
            items.forEach(item => {
                const armourDisplay = item.querySelector('.armour-display');
                if (armourDisplay) {
                    const armour = parseInt(armourDisplay.textContent.replace('总护甲: ', ''));

                    // 获取价格
                    const priceElement = item.querySelector('.price [data-field="price"]');
                    let price = '未标价';
                    if (priceElement) {
                        const amount = priceElement.querySelector('span:not(.price-label):not(.currency-text)');
                        const currencyText = priceElement.querySelector('.currency-text');
                        if (amount && currencyText) {
                            const amountText = amount.textContent.trim();
                            const currency = currencyText.querySelector('span')?.textContent || currencyText.textContent;
                            // 使用全局的convertCurrencyText函数
                            const simpleCurrency = convertCurrencyText(currency);
                            price = `${amountText}${simpleCurrency}`;
                        }
                    }

                    armourData.push({
                        armour,
                        price,
                        element: item
                    });
                }
            });

            console.log(`Found ${armourData.length} items with armour data`);

            // 如果没有护甲数据,隐藏护甲选项卡
            const armourTab = panel.querySelector('[data-tab="armour"]');
            if (armourData.length === 0) {
                if (armourTab) armourTab.style.display = 'none';

                // 如果其他选项卡也是隐藏的,则隐藏整个面板
                const dpsTab = panel.querySelector('[data-tab="dps"]');
                const shieldTab = panel.querySelector('[data-tab="shield"]');
                const evasionTab = panel.querySelector('[data-tab="evasion"]');
                const defenceTab = panel.querySelector('[data-tab="defence"]');
                
                // 检查是否所有选项卡都隐藏了
                if ((dpsTab && dpsTab.style.display === 'none') &&
                    (shieldTab && shieldTab.style.display === 'none') &&
                    (evasionTab && evasionTab.style.display === 'none') &&
                    (defenceTab && defenceTab.style.display === 'none')) {
                    panel.style.display = 'none';
                }
                // 移除自动切换到其他选项卡的代码,保留当前选项卡状态
                return;
            } else {
                // 有护甲数据,确保护甲选项卡可见
                if (armourTab) armourTab.style.display = '';
            }

            // 按护甲值从高到低排序
            armourData.sort((a, b) => b.armour - a.armour);

            // 更新面板内容
            armourData.forEach(({armour, price, element}) => {
                const armourItem = document.createElement('div');
                armourItem.className = 'dps-item'; // 复用DPS项的样式

                // 创建护甲显示
                const armourText = document.createElement('span');
                armourText.className = 'armour-value'; // 使用护甲专用的样式
                armourText.textContent = armour.toString();

                // 创建价格显示
                const priceText = document.createElement('span');
                priceText.className = 'price-value';
                priceText.textContent = price;

                // 添加到护甲项
                armourItem.appendChild(armourText);
                armourItem.appendChild(priceText);

                // 添加点击事件
                armourItem.onclick = () => {
                    element.scrollIntoView({ behavior: 'smooth', block: 'center' });
                    // 添加高亮效果
                    element.style.transition = 'background-color 0.3s';
                    element.style.backgroundColor = 'rgba(255, 99, 71, 0.2)';
                    setTimeout(() => {
                        element.style.backgroundColor = '';
                    }, 1500);
                };

                content.appendChild(armourItem);
            });

            // 显示面板
            panel.style.display = 'block';
            console.log('Armour panel updated successfully');
        } catch (error) {
            console.error('Error updating armour panel:', error);
        }
    }

    // 计算总防御值(护盾+闪避+护甲)
    function calculateDefence() {
        console.log('Calculating Defence...');
        const items = document.querySelectorAll('.row[data-id]');
        console.log('Found items:', items.length);
        
        let processedCount = 0;
        let successCount = 0;
        
        items.forEach((item, index) => {
            try {
                // 如果已经计算过总防御值,则跳过
                if (item.querySelector('.defence-display')) {
                    processedCount++;
                    return;
                }

                // 获取护盾、闪避和护甲值
                let totalDefence = 0;
                
                // 获取护盾值
                const shieldDisplay = item.querySelector('.shield-display');
                if (shieldDisplay) {
                    const shield = parseInt(shieldDisplay.textContent.replace('总护盾: ', ''));
                    if (!isNaN(shield)) {
                        totalDefence += shield;
                    }
                }
                
                // 获取闪避值
                const evasionDisplay = item.querySelector('.evasion-display');
                if (evasionDisplay) {
                    const evasion = parseInt(evasionDisplay.textContent.replace('总闪避: ', ''));
                    if (!isNaN(evasion)) {
                        totalDefence += evasion;
                    }
                }
                
                // 获取护甲值
                const armourDisplay = item.querySelector('.armour-display');
                if (armourDisplay) {
                    const armour = parseInt(armourDisplay.textContent.replace('总护甲: ', ''));
                    if (!isNaN(armour)) {
                        totalDefence += armour;
                    }
                }

                // 创建总防御显示元素
                const defenceDisplay = document.createElement('span');
                defenceDisplay.className = 'defence-display';
                defenceDisplay.style.cssText = `
                    color: #9370DB;
                    font-weight: bold;
                    margin-left: 5px;
                    font-size: 14px;
                    background-color: rgba(147, 112, 219, 0.1);
                    padding: 1px 4px;
                    border-radius: 3px;
                `;
                defenceDisplay.textContent = `DEF: ${totalDefence}`;

                // 将总防御显示添加到装备名称旁边
                const itemHeader = item.querySelector('.itemHeader');
                if (itemHeader) {
                    // 找到装备名称元素
                    const itemName = itemHeader.querySelector('.itemName');
                    if (itemName) {
                        // 添加到装备名称后面
                        itemName.appendChild(defenceDisplay);
                    } else {
                        // 如果找不到装备名称,直接添加到itemHeader
                        itemHeader.appendChild(defenceDisplay);
                    }
                } else {
                    // 如果找不到itemHeader,尝试添加到其他位置
                    const esSpan = item.querySelector('span[data-field="es"]');
                    const evSpan = item.querySelector('span[data-field="ev"]');
                    const arSpan = item.querySelector('span[data-field="ar"]');
                    
                    if (esSpan) {
                        esSpan.appendChild(defenceDisplay);
                    } else if (evSpan) {
                        evSpan.appendChild(defenceDisplay);
                    } else if (arSpan) {
                        arSpan.appendChild(defenceDisplay);
                    }
                }
                
                successCount++;
                processedCount++;

                // 添加调试信息
                console.debug(`Item ${index} Defence calculation: ${totalDefence}`);
            } catch (error) {
                console.error(`Error calculating defence for item ${index}:`, error);
            }
        });

        console.log(`Defence calculation completed: ${successCount} successful, ${processedCount} processed out of ${items.length} items`);

        // 更新总防御排序面板
        updateDefencePanel();
    }

    // 更新总防御排序面板
    function updateDefencePanel() {
        try {
            console.log('Updating defence panel...');
            
            // 获取或创建面板
            const panel = document.getElementById('integrated-sort-panel') || createIntegratedPanel();
            const content = document.getElementById('defence-sort-content');
            if (!content) {
                console.error('Defence sort content not found');
                return;
            }

            // 清空现有内容
            content.innerHTML = '';
            
            // 清除可能存在的旧数据属性
            content.removeAttribute('data-shield-content');
            content.removeAttribute('data-evasion-content');
            content.removeAttribute('data-armour-content');
            content.removeAttribute('data-dps-content');

            // 获取所有物品
            const items = document.querySelectorAll('.row[data-id]');
            const defenceData = [];

            // 收集总防御数据
            items.forEach(item => {
                const defenceDisplay = item.querySelector('.defence-display');
                if (defenceDisplay) {
                    const defence = parseInt(defenceDisplay.textContent.replace('DEF: ', ''));
                    
                    // 获取价格
                    const priceElement = item.querySelector('.price [data-field="price"]');
                    let price = '未标价';
                    if (priceElement) {
                        const amount = priceElement.querySelector('span:not(.price-label):not(.currency-text)');
                        const currencyText = priceElement.querySelector('.currency-text');
                        if (amount && currencyText) {
                            const amountText = amount.textContent.trim();
                            const currency = currencyText.querySelector('span')?.textContent || currencyText.textContent;
                            // 使用全局的convertCurrencyText函数
                            const simpleCurrency = convertCurrencyText(currency);
                            price = `${amountText}${simpleCurrency}`;
                        }
                    }

                    defenceData.push({
                        defence,
                        price,
                        element: item
                    });
                }
            });

            console.log(`Found ${defenceData.length} items with defence data`);

            // 如果没有总防御数据,隐藏总防御选项卡
            const defenceTab = panel.querySelector('[data-tab="defence"]');
            if (defenceData.length === 0) {
                if (defenceTab) defenceTab.style.display = 'none';
                
                // 如果其他选项卡也是隐藏的,则隐藏整个面板
                const dpsTab = panel.querySelector('[data-tab="dps"]');
                const shieldTab = panel.querySelector('[data-tab="shield"]');
                const evasionTab = panel.querySelector('[data-tab="evasion"]');
                const armourTab = panel.querySelector('[data-tab="armour"]');
                
                // 检查是否所有选项卡都隐藏了
                if ((dpsTab && dpsTab.style.display === 'none') && 
                    (shieldTab && shieldTab.style.display === 'none') &&
                    (evasionTab && evasionTab.style.display === 'none') &&
                    (armourTab && armourTab.style.display === 'none')) {
                    panel.style.display = 'none';
                }
                // 移除自动切换到其他选项卡的代码,保留当前选项卡状态
                return;
            } else {
                // 有总防御数据,确保总防御选项卡可见
                if (defenceTab) defenceTab.style.display = '';
            }

            // 按总防御值从高到低排序
            defenceData.sort((a, b) => b.defence - a.defence);

            // 更新面板内容
            defenceData.forEach(({defence, price, element}) => {
                const defenceItem = document.createElement('div');
                defenceItem.className = 'dps-item'; // 复用DPS项的样式
                
                // 创建总防御显示
                const defenceText = document.createElement('span');
                defenceText.className = 'defence-value';
                defenceText.textContent = defence.toString();
                
                // 创建价格显示
                const priceText = document.createElement('span');
                priceText.className = 'price-value';
                priceText.textContent = price;
                
                // 添加到总防御项
                defenceItem.appendChild(defenceText);
                defenceItem.appendChild(priceText);
                
                // 添加点击事件
                defenceItem.onclick = () => {
                    element.scrollIntoView({ behavior: 'smooth', block: 'center' });
                    // 添加高亮效果
                    element.style.transition = 'background-color 0.3s';
                    element.style.backgroundColor = 'rgba(147, 112, 219, 0.2)';
                    setTimeout(() => {
                        element.style.backgroundColor = '';
                    }, 1500);
                };

                content.appendChild(defenceItem);
            });

            // 显示面板
            panel.style.display = 'block';
            console.log('Defence panel updated successfully');
        } catch (error) {
            console.error('Error updating defence panel:', error);
        }
    }
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址