跳转到内容

User:Heihaheihaha-test/test.js

维基百科,自由的百科全书
注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google ChromeFirefoxMicrosoft EdgeSafari:按住⇧ Shift键并单击工具栏的“刷新”按钮。参阅Help:绕过浏览器缓存以获取更多帮助。
(function() {
    'use strict';

    const SCRIPT_ID_PREFIX = 'wpAiSumChkGemini_';
    const WIKIPEDIA_ARTICLE_URL_REGEX = /^https:\/\/zh\.wikipedia\.org\/wiki\/[^:]+$/;
    const MAIN_CONTENT_SELECTOR = '#mw-content-text .mw-parser-output';
    const SELECTORS_TO_REMOVE_FROM_CONTENT = [
        '.toc', '.mw-editsection', '.navbox', '#catlinks', '.noprint',
        '#coordinates', 'table.ambox', '.gallery', 'figure.mw-halign-right',
        'figure.mw-halign-left', 'figure.mw-halign-center', 'div.thumb',
        'table.infobox', '.wikitable.plainlinks.metadata.ambox.ambox-style',
        '.mw-stack.selflink', 'div.printfooter', 'div.mw-hidden-catlinks'
    ];
    const MAX_ARTICLE_TEXT_LENGTH = 30000;

    let actionButton = null;
    let resultDialog = null;
    let isLoading = false;
    let aiConfig = null;

    const SCRIPT_CSS = `
        #${SCRIPT_ID_PREFIX}actionButton {
            padding: 5px 10px; font-size: 0.85em; background-color: #008080; color: white;
            border: 1px solid #006666; border-radius: 4px; cursor: pointer; margin-left: 8px;
            line-height: normal;
        }
        #${SCRIPT_ID_PREFIX}actionButton:hover { background-color: #006666; }
        #${SCRIPT_ID_PREFIX}actionButton:disabled { background-color: #cccccc; cursor: not-allowed; }

        #${SCRIPT_ID_PREFIX}resultDialog {
            position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
            width: 750px; max-width: 95vw; max-height: 85vh;
            background-color: #fdfdfd; border: 1px solid #bdc3c7;
            box-shadow: 0 5px 15px rgba(0,0,0,0.3); z-index: 2000;
            display: none; border-radius: 6px; overflow: hidden;
            flex-direction: column; font-size: 14px;
        }
        #${SCRIPT_ID_PREFIX}resultDialog .dialog-header {
            padding: 12px 18px; background-color: #e0e7e7; border-bottom: 1px solid #c8d0d0;
            display: flex; justify-content: space-between; align-items: center; cursor: grab;
        }
        #${SCRIPT_ID_PREFIX}resultDialog .dialog-header h3 {
            margin: 0; font-size: 1.3em; color: #205050;
        }
        #${SCRIPT_ID_PREFIX}resultDialog .dialog-close-btn {
            background: none; border: none; font-size: 2em; font-weight: bold;
            color: #507070; cursor: pointer; padding: 0 8px; line-height: 1;
        }
        #${SCRIPT_ID_PREFIX}resultDialog .dialog-close-btn:hover { color: #205050; }
        #${SCRIPT_ID_PREFIX}resultDialog .dialog-content {
            padding: 15px 20px; overflow-y: auto; line-height: 1.65; color: #333;
            flex-grow: 1; background-color: #fff;
        }
        #${SCRIPT_ID_PREFIX}resultDialog .dialog-content pre {
            white-space: pre-wrap; word-wrap: break-word; background-color: #f0f0f0;
            border: 1px solid #e0e0e0; padding: 10px 12px; border-radius: 4px;
            font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
            font-size: 0.9em; max-height: 400px; overflow-y: auto;
        }
        #${SCRIPT_ID_PREFIX}resultDialog .dialog-content code {
            font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
            background-color: #f0f0f0; padding: 0.15em 0.4em; border-radius: 3px; font-size: 0.9em;
        }
        #${SCRIPT_ID_PREFIX}resultDialog .dialog-content pre code {
            background-color: transparent; padding: 0; font-size: inherit;
        }
        #${SCRIPT_ID_PREFIX}resultDialog .dialog-content h1, #${SCRIPT_ID_PREFIX}resultDialog .dialog-content h2,
        #${SCRIPT_ID_PREFIX}resultDialog .dialog-content h3, #${SCRIPT_ID_PREFIX}resultDialog .dialog-content h4,
        #${SCRIPT_ID_PREFIX}resultDialog .dialog-content h5, #${SCRIPT_ID_PREFIX}resultDialog .dialog-content h6 {
             margin-top: 1.2em; margin-bottom: 0.6em; color: #1a4040; line-height: 1.3;
        }
        #${SCRIPT_ID_PREFIX}resultDialog .dialog-content h1 { font-size: 1.8em; }
        #${SCRIPT_ID_PREFIX}resultDialog .dialog-content h2 { font-size: 1.6em; }
        #${SCRIPT_ID_PREFIX}resultDialog .dialog-content h3 { font-size: 1.4em; }
        #${SCRIPT_ID_PREFIX}resultDialog .dialog-content h4 { font-size: 1.2em; }
        #${SCRIPT_ID_PREFIX}resultDialog .dialog-content ul, #${SCRIPT_ID_PREFIX}resultDialog .dialog-content ol {
            padding-left: 25px; margin-bottom: 1em;
        }
        #${SCRIPT_ID_PREFIX}resultDialog .dialog-content li { margin-bottom: 0.4em; }
        #${SCRIPT_ID_PREFIX}resultDialog .dialog-content p { margin-bottom: 1em; }
        #${SCRIPT_ID_PREFIX}resultDialog .dialog-content strong { font-weight: bold; }
        #${SCRIPT_ID_PREFIX}resultDialog .dialog-content em { font-style: italic; }
        #${SCRIPT_ID_PREFIX}resultDialog .dialog-content hr {
            border: 0; border-top: 1px solid #ccc; margin: 1.5em 0;
        }
        #${SCRIPT_ID_PREFIX}resultDialog .dialog-content a {
            color: #0645ad; text-decoration: none;
        }
        #${SCRIPT_ID_PREFIX}resultDialog .dialog-content a:hover {
            text-decoration: underline;
        }
        #${SCRIPT_ID_PREFIX}resultDialog .dialog-content table {
            border-collapse: collapse; margin: 1.2em 0; width: auto;
            border: 1px solid #c8d0d0; box-shadow: 0 1px 2px rgba(0,0,0,0.05);
            font-size: 0.95em;
        }
        #${SCRIPT_ID_PREFIX}resultDialog .dialog-content th,
        #${SCRIPT_ID_PREFIX}resultDialog .dialog-content td {
            border: 1px solid #d8e0e0; padding: 8px 12px; text-align: left;
        }
        #${SCRIPT_ID_PREFIX}resultDialog .dialog-content th {
            background-color: #e0e7e7; font-weight: bold; color: #205050;
        }
        #${SCRIPT_ID_PREFIX}resultDialog .dialog-content tr:nth-child(even) td {
            background-color: #f7f9f9;
        }
        #${SCRIPT_ID_PREFIX}configWarning {
            background-color: #fff3cd; color: #856404; padding: 10px;
            border: 1px solid #ffeeba; border-radius: 4px; margin: 10px 0;
            text-align: center; font-size: 0.9em;
        }
    `;

    function injectStyles() {
        if (typeof GM_addStyle !== 'undefined') {
            GM_addStyle(SCRIPT_CSS);
        } else {
            const styleElement = document.createElement('style');
            styleElement.id = `${SCRIPT_ID_PREFIX}styles`;
            styleElement.textContent = SCRIPT_CSS;
            document.head.appendChild(styleElement);
        }
    }

    function loadAiConfig() {
        try {
            const storedConfig = localStorage.getItem('wpAiSumChkGeminiConfig');
            if (storedConfig) {
                aiConfig = JSON.parse(storedConfig);
            } else if (typeof GM_getValue !== 'undefined') {
                const gmStoredConfig = GM_getValue('wpAiSumChkGeminiConfig');
                if (gmStoredConfig) aiConfig = JSON.parse(gmStoredConfig);
            }

            if (!aiConfig || !aiConfig.apiKey || !aiConfig.modelName) {
                displayConfigWarning();
                return false;
            }
            const warningDiv = document.getElementById(`${SCRIPT_ID_PREFIX}configWarning`);
            if (warningDiv) warningDiv.style.display = 'none';
            return true;
        } catch (e) {
            displayConfigWarning('加载Gemini AI配置时出错。');
            return false;
        }
    }

    function displayConfigWarning(specificMessage = '') {
        let warningDiv = document.getElementById(`${SCRIPT_ID_PREFIX}configWarning`);
        if (!warningDiv) {
            warningDiv = document.createElement('div');
            warningDiv.id = `${SCRIPT_ID_PREFIX}configWarning`;
            const firstHeading = document.getElementById('firstHeading');
            if (firstHeading) {
                firstHeading.parentNode.insertBefore(warningDiv, firstHeading.nextSibling);
            } else {
                const contentDiv = document.getElementById('content');
                if (contentDiv) contentDiv.prepend(warningDiv);
            }
        }
        const generalMessage = 'AI总结与事实核查助手(Gemini)配置不完整或缺失。请在浏览器开发者控制台 (F12) 中运行指令来设置API密钥及模型名称。详情请参考脚本的安装说明。';
        warningDiv.textContent = generalMessage + (specificMessage ? ` (${specificMessage})` : '');
        warningDiv.style.display = 'block';

        console.info("To configure AI Summary & Fact-Check Helper (Gemini Only), run the following in your browser's developer console on zh.wikipedia.org:\n" +
        "localStorage.setItem('wpAiSumChkGeminiConfig', JSON.stringify({\n" +
        "  apiKey: 'YOUR_GEMINI_API_KEY_HERE',\n" +
        "  modelName: 'gemini-1.5-flash-latest' \n" +
        "}));\n" +
        "Then refresh the page.");
    }


    function isChineseWikipediaArticlePage() {
        return WIKIPEDIA_ARTICLE_URL_REGEX.test(window.location.href) &&
               document.querySelector(MAIN_CONTENT_SELECTOR) &&
               !document.getElementById('noarticletext');
    }

    function getArticleContentText() {
        const contentElement = document.querySelector(MAIN_CONTENT_SELECTOR);
        if (!contentElement) {
            return null;
        }
        const clonedContent = contentElement.cloneNode(true);
        SELECTORS_TO_REMOVE_FROM_CONTENT.forEach(selector => {
            clonedContent.querySelectorAll(selector).forEach(el => el.remove());
        });

        let text = "";
        clonedContent.querySelectorAll('p, h1, h2, h3, h4, h5, h6, li, pre, blockquote, dl, dd, dt').forEach(el => {
            const trimmedText = (el.innerText || el.textContent || "").trim();
            if (trimmedText) {
                if (el.tagName.startsWith('H') || el.tagName === 'BLOCKQUOTE' || el.tagName === 'PRE') {
                    text += trimmedText + "\n\n";
                } else {
                    text += trimmedText + "\n";
                }
            }
        });

        if (!text.trim()) {
            text = (clonedContent.innerText || clonedContent.textContent || "").trim();
        }

        text = text.replace(/\[编辑\]/g, '').replace(/\[\d+\]/g, '').replace(/\s\s+/g, ' ').trim();
        return text.length > MAX_ARTICLE_TEXT_LENGTH ? text.substring(0, MAX_ARTICLE_TEXT_LENGTH) + "\n\n[条目内容过长,已截断]" : text;
    }

    function showLoadingState(show) {
        isLoading = show;
        if (actionButton) {
            actionButton.textContent = show ? '处理中...' : 'AI总结与事实核查 (Gemini)';
            actionButton.disabled = show;
        }
        if (show && !resultDialog) {
            createResultDialog();
        }
        if (resultDialog) {
            const contentDiv = resultDialog.querySelector(`#${SCRIPT_ID_PREFIX}resultDialog .dialog-content`);
            contentDiv.innerHTML = show ? '<p style="text-align:center; padding: 20px;"><i>AI分析中,请稍候...</i></p>' : '';
            if (show) resultDialog.style.display = 'flex';
        }
    }

    function escapeHtml(unsafeStr) {
        if (typeof unsafeStr !== 'string') return '';
        return unsafeStr.replace(/[&<>"']/g, function (match) {
            switch (match) {
                case '&': return '&amp;';
                case '<': return '&lt;';
                case '>': return '&gt;';
                case '"': return '&quot;';
                case "'": return '&#039;';
                default: return match;
            }
        });
    }

    function processInlineMarkdown(text) {
        text = escapeHtml(text);
        text = text.replace(/\*\*(.*?)\*\*|__(.*?)__/g, '<strong>$1$2</strong>');
        text = text.replace(/(?<!\*)\*(?!\s)(.*?[^\s])\*(?!\*)|(?<!_)_{_}(?!\s)(.*?)\s|\s\*([^*]+)\*(?=\s)/g, '<em>$1$2$3</em>');
        text = text.replace(/(?<!\w)_(\w(?:[^_]*\w)?)_(?!\w)/g, '<em>$1</em>');
        text = text.replace(/`([^`]+)`/g, '<code>$1</code>');
        text = text.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (match, linkText, url) => {
            const BANNED_PROTOCOLS_REGEX = /^(?:javascript|data|vbscript):/i;
            let safeUrl = '#';
            try {
                const currentBase = new URL(window.location.href);
                const resolvedUrl = new URL(url, currentBase);
                if (!BANNED_PROTOCOLS_REGEX.test(resolvedUrl.protocol)) {
                    safeUrl = resolvedUrl.href;
                }
            } catch (e) {
                if (!BANNED_PROTOCOLS_REGEX.test(url) && (url.startsWith('/') || url.startsWith('./') || url.startsWith('../') || url.startsWith('#') || (typeof URL !== 'undefined' && URL.canParse && URL.canParse(url)) ) ) {
                     safeUrl = url;
                }
            }
            return `<a href="${escapeHtml(safeUrl)}" target="_blank" rel="noopener noreferrer">${escapeHtml(linkText)}</a>`;
        });
        return text;
    }

    function parseMarkdownTableRow(rowLine) {
        const trimmed = rowLine.trim();
        if (trimmed.startsWith('|')) {
            if (trimmed.endsWith('|')) {
                return trimmed.slice(1, -1).split('|').map(cell => cell.trim());
            }
            return trimmed.slice(1).split('|').map(cell => cell.trim());
        }
        return rowLine.split('|').map(cell => cell.trim());
    }

    function basicMarkdownToHtml(md) {
        let html = '';
        const lines = md.split('\n');
        let inListType = null;
        let inCodeBlock = false;
        let codeBlockLang = '';
        let codeBlockContent = [];
        let paragraphBuffer = [];

        function flushParagraph() {
            if (paragraphBuffer.length > 0) {
                html += "<p>" + processInlineMarkdown(paragraphBuffer.join(' ')) + "</p>\n";
                paragraphBuffer = [];
            }
        }
        function flushList() {
            if (inListType) {
                html += (inListType === 'ul' ? "</ul>\n" : "</ol>\n");
                inListType = null;
            }
        }
        function flushCodeBlock() {
            if (codeBlockContent.length > 0) {
                 html += "<pre><code" + (codeBlockLang ? ` class="language-${escapeHtml(codeBlockLang)}"` : "") + ">" + escapeHtml(codeBlockContent.join('\n')) + "</code></pre>\n";
            }
            codeBlockContent = [];
            codeBlockLang = '';
        }

        for (let i = 0; i < lines.length; i++) {
            const line = lines[i];

            if (line.startsWith("```")) {
                flushParagraph();
                flushList();
                if (inCodeBlock) {
                    flushCodeBlock();
                    inCodeBlock = false;
                } else {
                    inCodeBlock = true;
                    codeBlockLang = line.substring(3).trim();
                }
                continue;
            }

            if (inCodeBlock) {
                codeBlockContent.push(line);
                continue;
            }

            const trimmedLine = line.trim();
            if (trimmedLine.includes('|') && i + 1 < lines.length) {
                const nextLineTrimmed = lines[i+1].trim();
                if (nextLineTrimmed.includes('|') && nextLineTrimmed.replace(/[-:|\s]/g, '').length === 0 && nextLineTrimmed.includes('-')) {
                    flushParagraph();
                    flushList();
                    let tableLines = [line];
                    let j = i + 1;
                    while(j < lines.length && lines[j].trim().includes('|')) {
                        tableLines.push(lines[j]);
                        j++;
                    }
                    if (tableLines.length > 1) {
                        const headerCellsRaw = parseMarkdownTableRow(tableLines[0]);
                        const separatorLine = tableLines[1];
                        const alignParts = parseMarkdownTableRow(separatorLine).map(part => {
                            const trimmedPart = part.trim();
                            if (trimmedPart.startsWith(':') && trimmedPart.endsWith(':')) return 'center';
                            if (trimmedPart.startsWith(':')) return 'left';
                            if (trimmedPart.endsWith(':')) return 'right';
                            return 'left';
                        });

                        html += '<table>\n<thead>\n<tr>\n';
                        headerCellsRaw.forEach((cell, index) => {
                            html += `<th${alignParts[index] ? ` style="text-align:${alignParts[index]}"` : ''}>${processInlineMarkdown(cell)}</th>\n`;
                        });
                        html += '</tr>\n</thead>\n<tbody>\n';

                        for (let k = 2; k < tableLines.length; k++) {
                            const rowCellsRaw = parseMarkdownTableRow(tableLines[k]);
                            html += '<tr>\n';
                            rowCellsRaw.forEach((cell, index) => {
                                html += `<td${alignParts[index] ? ` style="text-align:${alignParts[index]}"` : ''}>${processInlineMarkdown(cell)}</td>\n`;
                            });
                            html += '</tr>\n';
                        }
                        html += '</tbody>\n</table>\n';
                        i = j - 1;
                        continue;
                    }
                }
            }


            const headingMatch = line.match(/^(#{1,6})\s+(.*)/);
            if (headingMatch) {
                flushParagraph();
                flushList();
                const level = headingMatch[1].length;
                html += `<h${level}>${processInlineMarkdown(headingMatch[2])}</h${level}>\n`;
                continue;
            }

            const hrMatch = line.match(/^(\*\*\*|---|___)\s*$/);
            if (hrMatch) {
                flushParagraph();
                flushList();
                html += "<hr>\n";
                continue;
            }

            const listItemUL = line.match(/^(\s*)[-*+]\s+(.*)/);
            const listItemOL = line.match(/^(\s*)\d+\.\s+(.*)/);

            if (listItemUL) {
                flushParagraph();
                if (inListType !== 'ul') {
                    flushList();
                    html += "<ul>\n";
                    inListType = 'ul';
                }
                html += "<li>" + processInlineMarkdown(listItemUL[2]) + "</li>\n";
                continue;
            }

            if (listItemOL) {
                flushParagraph();
                if (inListType !== 'ol') {
                    flushList();
                    html += "<ol>\n";
                    inListType = 'ol';
                }
                html += "<li>" + processInlineMarkdown(listItemOL[2]) + "</li>\n";
                continue;
            }

            if (line.trim() === "") {
                flushParagraph();
                flushList();
            } else {
                if (inListType) {
                     const continuationMatch = line.match(/^(\s{2,}|\t)(.*)/);
                     if(continuationMatch && html.endsWith("</li>\n")){
                        html = html.substring(0, html.length - "</li>\n".length) + " " + processInlineMarkdown(continuationMatch[2]) + "</li>\n";
                     } else {
                        flushList();
                        paragraphBuffer.push(line);
                     }
                } else {
                    paragraphBuffer.push(line);
                }
            }
        }

        flushParagraph();
        flushList();
        if (inCodeBlock) flushCodeBlock();

        return html;
    }


    function displayAnalysisResult(analysisText, isError = false) {
        showLoadingState(false);
        if (!resultDialog) createResultDialog();

        const contentDiv = resultDialog.querySelector(`#${SCRIPT_ID_PREFIX}resultDialog .dialog-content`);
        if (isError) {
            contentDiv.innerHTML = `<p style="color: red; font-weight: bold;">处理出错:</p><pre>${escapeHtml(analysisText)}</pre>`;
        } else {
            contentDiv.innerHTML = basicMarkdownToHtml(analysisText);
        }
        resultDialog.style.display = 'flex';
    }

    async function makeAiApiCall(prompt) {
        if (!aiConfig) {
            throw new Error("Gemini AI配置未加载。");
        }

        const endpointUrl = `https://generativelanguage.googleapis.com/v1beta/models/${aiConfig.modelName}:generateContent?key=${aiConfig.apiKey}`;
        const requestBody = {
            contents: [{ role: "user", parts: [{ text: prompt }] }],
            generationConfig: {
                "maxOutputTokens": 8192,
                "temperature": 0.5,
            },
        };
        const headers = { 'Content-Type': 'application/json' };

        try {
            const response = await fetch(endpointUrl, {
                method: 'POST',
                headers: headers,
                body: JSON.stringify(requestBody)
            });

            if (!response.ok) {
                const errorData = await response.json().catch(() => ({}));
                const errorMsg = errorData?.error?.message || response.statusText || `HTTP Error ${response.status}`;
                throw new Error(`Gemini API调用失败: ${errorMsg}`);
            }

            const data = await response.json();
            let aiResponseText = '';

            if (data.candidates && data.candidates[0]?.content?.parts) {
                aiResponseText = data.candidates[0].content.parts.map(part => part.text).join("\n");
            } else if (data.promptFeedback?.blockReason) {
                aiResponseText = `请求被安全设置阻止 (Gemini): ${data.promptFeedback.blockReason}. ${data.promptFeedback.blockReasonMessage || ''}`;
            } else {
                aiResponseText = '未能从Gemini API获取有效回复。请检查控制台的API响应详情。';
            }
            return aiResponseText;
        } catch (error) {
            throw error;
        }
    }


    async function handleSummaryFactCheckAction() {
        if (isLoading) return;
        if (!loadAiConfig()) {
            displayAnalysisResult("无法执行操作:Gemini AI配置不正确或缺失。请检查浏览器控制台中的设置说明。", true);
            return;
        }

        const articleText = getArticleContentText();
        const articleTitle = (document.querySelector('#firstHeading .mw-page-title-main') || document.querySelector('#firstHeading') || {}).innerText || document.title.replace(' - 维基百科,自由的百科全书', '');

        if (!articleText) {
            displayAnalysisResult("无法提取条目内容进行分析。", true);
            return;
        }

        showLoadingState(true);

        const summaryFactCheckPrompt = `你是一位信息分析专家。请针对以下中文维基百科条目(标题:“${articleTitle}”)执行以下两项任务:

1.  **内容总结**:请提供一个关于该条目主题的简洁摘要(目标200-300字左右),清晰地概括其核心内容和主要方面。
2.  **事实核查辅助**:
    * 请从条目中挑选出 3-5 个关键的、可供查证的 factual claims (事实性论述)。
    * 对于每一个挑选出的论述:
        * 评估其当前在文内是否得到了明确的参考文献支持(可以基于上下文判断,例如是否有紧随其后的引用标记,或者论述本身是否像是常识性总结而非特定细节)。
        * 如果当前明显缺乏有效引用或论述本身非常具体且重要但未见引用,请指出。
        * 建议用户可以如何去查证该论述的真实性(例如,可以搜索哪些关键词?需要查找哪种类型的文献或资料?)。
    * 请指出条目中是否有任何其他看起来特别需要查证但目前可能缺乏支持的论述。

请确保你的回答清晰、有条理,以Markdown格式输出(例如使用标题、列表、表格等),便于用户理解和进一步操作。

条目内容(可能已截断)如下:
\`\`\`
${articleText}
\`\`\`
`;

        try {
            const analysis = await makeAiApiCall(summaryFactCheckPrompt);
            displayAnalysisResult(analysis);
        } catch (error) {
            displayAnalysisResult(error.message, true);
        }
    }

    function createActionButton() {
        if (document.getElementById(`${SCRIPT_ID_PREFIX}actionButton`)) return;

        actionButton = document.createElement('button');
        actionButton.textContent = 'AI总结与事实核查 (Gemini)';
        actionButton.id = `${SCRIPT_ID_PREFIX}actionButton`;
        actionButton.title = '使用Gemini AI总结条目内容并辅助事实核查';
        actionButton.addEventListener('click', handleSummaryFactCheckAction);

        let targetToolbar;
        if (mw.config.get('skin') === 'vector-2022') {
            targetToolbar = document.querySelector('.vector-feature-page-tools .vector-menu-content ul');
            if (targetToolbar) {
                 const newListItem = document.createElement('li');
                 newListItem.classList.add('vector-tab-limón');
                 newListItem.appendChild(actionButton);
                 targetToolbar.appendChild(newListItem);
            } else {
                 targetToolbar = document.querySelector('#p-views ul');
                 if (targetToolbar) {
                    const newListItem = document.createElement('li');
                    newListItem.appendChild(actionButton);
                    targetToolbar.appendChild(newListItem);
                 }
            }
        } else {
            targetToolbar = document.querySelector('#p-cactions .vector-menu-content ul') || document.querySelector('#p-views ul');
             if (targetToolbar) {
                const newListItem = document.createElement('li');
                newListItem.appendChild(actionButton);
                targetToolbar.appendChild(newListItem);
             }
        }


        if (!targetToolbar) {
            actionButton.style.position = 'fixed';
            actionButton.style.top = '100px';
            actionButton.style.right = '20px';
            actionButton.style.zIndex = '1500';
            document.body.appendChild(actionButton);
        }
    }

    function createResultDialog() {
        if (document.getElementById(`${SCRIPT_ID_PREFIX}resultDialog`)) return;

        resultDialog = document.createElement('div');
        resultDialog.id = `${SCRIPT_ID_PREFIX}resultDialog`;
        resultDialog.style.display = 'flex';
        resultDialog.innerHTML = `
            <div class="dialog-header">
                <h3>AI总结与事实核查 (Gemini)</h3>
                <button class="dialog-close-btn" title="关闭">&times;</button>
            </div>
            <div class="dialog-content"></div>
        `;
        document.body.appendChild(resultDialog);

        resultDialog.querySelector('.dialog-close-btn').addEventListener('click', () => {
            resultDialog.style.display = 'none';
        });

        const header = resultDialog.querySelector('.dialog-header');
        let isDragging = false;
        let currentX, currentY, initialX, initialY, xOffset = 0, yOffset = 0;

        header.addEventListener('mousedown', (e) => {
            if (e.target.classList.contains('dialog-close-btn')) return;
            initialX = e.clientX - xOffset;
            initialY = e.clientY - yOffset;
            isDragging = true;
            header.style.cursor = 'grabbing';
        });

        document.addEventListener('mousemove', (e) => {
            if (isDragging) {
                e.preventDefault();
                currentX = e.clientX - initialX;
                currentY = e.clientY - initialY;
                xOffset = currentX;
                yOffset = currentY;
                resultDialog.style.transform = `translate(-50%, -50%) translate(${currentX}px, ${currentY}px)`;
            }
        });

        document.addEventListener('mouseup', () => {
            if (isDragging) {
                initialX = currentX;
                initialY = currentY;
                isDragging = false;
                header.style.cursor = 'grab';
            }
        });
    }

    function initializeScript() {
        if (mw && mw.config && mw.config.get('wgIsProbablyEditable') && isChineseWikipediaArticlePage()) {
            injectStyles();
            createActionButton();
        }
    }

    mw.loader.using(['mediawiki.util', 'mediawiki.jqueryMsg']).then(initializeScript);

})();