Greasy Fork

Greasy Fork is available in English.

反诈中心

所有网站-反诈中心

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         反诈中心
// @namespace    none
// @version      0.0.2
// @description  所有网站-反诈中心
// @author       yangrenrui & _s_z_y_ & Murasame
// @match        *://*/*
// @match        *://*
// @icon         https://t2.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url=http://llong.tech&size=64
// @license      MIT
// @grant        none
// ==/UserScript==
(function() {
    'use strict';

    // 获取目标关键词列表和正则表达式列表
    let targetStrings = JSON.parse(localStorage.getItem('targetStrings')) || ['florr','bilibili','mihoyo','hornex'];
    let targetRegexes = JSON.parse(localStorage.getItem('targetRegexes')) || ['/^https?:\/\/([a-zA-Z0-9-]+\.)?bilibili\.(com|cn)\/.*/','/^https?:\/\/([a-zA-Z0-9-]+\.)?mihoyo\.(com|cn)\/.*/', '/^https?:\\/\\/malicious\\.site\\//','/^https?:\/\/([a-zA-Z0-9-]+\.)?florr\.io\/.*/','/^https?:\/\/([a-zA-Z0-9-]+\.)?hornex\.pro\/.*/'];

    // 解析关键词列表,支持正则表达式
    let targetPatterns = [];
    function updatePatterns() {
        targetPatterns = targetStrings.map(str => str).concat(targetRegexes.map(str => {
            if (str.startsWith('/') && str.endsWith('/')) {
                try {
                    let patternBody = str.slice(1, -1);
                    return new RegExp(patternBody);
                } catch (e) {
                    console.error(`无效的正则表达式: ${str}`);
                    return null;
                }
            } else {
                console.warn(`正则表达式模式中的项应以斜杠包裹: ${str}`);
                return null;
            }
        }).filter(item => item !== null));
    }
    updatePatterns();

    // 创建提示弹窗
    function createPopup(message, type = 'info') {
        const popup = document.createElement('div');
        popup.className = `custom-popup ${type}`;
        popup.innerText = message;
        document.body.appendChild(popup);

        // 显示动画
        setTimeout(() => {
            popup.classList.add('show');
        }, 10);

        // 自动隐藏
        setTimeout(() => {
            popup.classList.remove('show');
            // 移除元素
            setTimeout(() => {
                document.body.removeChild(popup);
            }, 300);
        }, 500);
    }

    // 注入自定义CSS
    const style = document.createElement('style');
    style.innerHTML = `
    /* 提示弹窗样式 */
    .custom-popup {
        position: fixed;
        top: 20px;
        right: 20px;
        background-color: rgba(50, 50, 50, 0.9);
        color: #fff;
        padding: 10px 20px;
        border-radius: 5px;
        opacity: 0;
        transition: opacity 0.3s, transform 0.3s;
        z-index: 10005;
        font-family: Arial, sans-serif;
        pointer-events: none;
    }
    .custom-popup.show {
        opacity: 1;
        transform: translateY(0);
    }
    .custom-popup.info {
        background-color: #e74c3c;
    }
    .custom-popup.success {
        background-color: rgba(76, 175, 80, 0.9);
    }
    .custom-popup.error {
        background-color: rgba(244, 67, 54, 0.9);
    }
    .custom-popup.warning {
        background-color: rgba(255, 152, 0, 0.9);
    }

    /* 编辑界面样式 */
    #editUI {
        position: fixed;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        z-index: 10002;
        background-color: #fff;
        border: 2px solid #333;
        padding: 25px;
        border-radius: 10px;
        box-shadow: 0 4px 16px rgba(0,0,0,0.3);
        width: 700px;
        max-height: 80vh;
        overflow-y: auto;
        font-family: Arial, sans-serif;
    }
    #editUI h2 {
        text-align: center;
        margin-top: 0;
    }
    #editUI h3 {
        margin-bottom: 10px;
    }
    #editUI button {
        font-size: 14px;
    }
    #editUI .section {
        margin-bottom: 30px;
    }
    #editUI .item-block {
        border: 1px solid #ccc;
        padding: 10px;
        border-radius: 5px;
        background-color: #f5f5f5;
        display: flex;
        align-items: center;
        justify-content: space-between;
        position: relative;
    }
    #editUI .item-block code {
        font-family: Consolas, monospace;
    }
    #editUI .item-buttons {
        display: flex;
        gap: 5px;
    }
    #editUI .item-buttons button {
        background: none;
        border: none;
        cursor: pointer;
        font-size: 18px;
    }
    #editUI .add-button {
        padding: 8px 16px;
        background-color: #2196F3;
        color: #fff;
        border: none;
        border-radius: 4px;
        cursor: pointer;
        font-size: 14px;
    }
    #editUI .save-cancel-buttons {
        display: flex;
        justify-content: flex-end;
        gap: 10px;
        margin-top: 15px;
    }
    #editUI .save-cancel-buttons button {
        padding: 10px 20px;
        border: none;
        border-radius: 4px;
        cursor: pointer;
        font-size: 14px;
    }
    #editUI .save-button {
        background-color: #4CAF50;
        color: #fff;
    }
    #editUI .cancel-button {
        background-color: #f44336;
        color: #fff;
    }

    /* 提示框样式 */
    .tooltip-custom {
        position: absolute;
        background-color: rgba(0, 0, 0, 0.8);
        color: #fff;
        padding: 8px 12px;
        border-radius: 6px;
        display: none;
        font-size: 14px;
        box-shadow: 0 2px 8px rgba(0,0,0,0.3);
        z-index: 10000;
        pointer-events: none;
        transition: opacity 0.3s;
    }
    .tooltip-custom.show {
        display: block;
        opacity: 1;
    }
    `;
    document.head.appendChild(style);

    // 创建提示框
    const tooltip = document.createElement('div');
    tooltip.className = 'tooltip-custom';
    document.body.appendChild(tooltip);

    // 创建确认窗口
    const confirmDialog = document.createElement('div');
    confirmDialog.style.position = 'absolute';
    confirmDialog.style.backgroundColor = '#fff';
    confirmDialog.style.color = '#000';
    confirmDialog.style.padding = '15px 20px';
    confirmDialog.style.borderRadius = '8px';
    confirmDialog.style.display = 'none';
    confirmDialog.style.fontSize = '14px';
    confirmDialog.style.boxShadow = '0 4px 12px rgba(0,0,0,0.4)';
    confirmDialog.style.zIndex = '10001';
    confirmDialog.style.width = '300px';
    confirmDialog.style.boxSizing = 'border-box';
    document.body.appendChild(confirmDialog);

    // 确认内容
    const confirmText = document.createElement('p');
    confirmText.innerText = '您即将打开一个疑似诈骗链接:';
    confirmText.style.margin = '0 0 10px 0';
    confirmDialog.appendChild(confirmText);

    const urlText = document.createElement('p');
    urlText.style.wordBreak = 'break-all';
    urlText.style.margin = '0 0 10px 0';
    confirmDialog.appendChild(urlText);

    // 按钮容器
    const buttonContainer = document.createElement('div');
    buttonContainer.style.textAlign = 'right';
    buttonContainer.style.display = 'flex';
    buttonContainer.style.justifyContent = 'flex-end';
    buttonContainer.style.gap = '10px';
    confirmDialog.appendChild(buttonContainer);

    const confirmButton = document.createElement('button');
    confirmButton.innerText = '确定 (Enter)';
    confirmButton.style.padding = '6px 12px';
    confirmButton.style.backgroundColor = '#4CAF50';
    confirmButton.style.color = '#fff';
    confirmButton.style.border = 'none';
    confirmButton.style.borderRadius = '4px';
    confirmButton.style.cursor = 'pointer';
    confirmButton.style.fontSize = '14px';
    confirmButton.onclick = () => {
        window.open(confirmButton.linkHref, '_blank');
        hideConfirmDialog();
        createPopup('已打开链接', 'success');
    };
    buttonContainer.appendChild(confirmButton);

    const cancelButton = document.createElement('button');
    cancelButton.innerText = '取消 (Esc)';
    cancelButton.style.padding = '6px 12px';
    cancelButton.style.backgroundColor = '#f44336';
    cancelButton.style.color = '#fff';
    cancelButton.style.border = 'none';
    cancelButton.style.borderRadius = '4px';
    cancelButton.style.cursor = 'pointer';
    cancelButton.style.fontSize = '14px';
    cancelButton.onclick = () => {
        hideConfirmDialog();
        createPopup('已取消', 'info');
    };
    buttonContainer.appendChild(cancelButton);

    let currentLinkHref = '';
    let mouseX = 0;
    let mouseY = 0;

    // 显示确认窗口
    function showConfirmDialog(x, y, href) {
        currentLinkHref = href;
        urlText.innerText = href;
        confirmDialog.style.left = `${x + 10}px`;
        confirmDialog.style.top = `${y + 10}px`;
        confirmDialog.style.display = 'block';
        confirmButton.linkHref = href;
        confirmButton.focus();
    }

    // 隐藏确认窗口
    function hideConfirmDialog() {
        confirmDialog.style.display = 'none';
        currentLinkHref = '';
    }

    // 监听鼠标移动以记录位置
    document.addEventListener('mousemove', function(event) {
        mouseX = event.pageX;
        mouseY = event.pageY;
    });

    // 处理鼠标点击事件
    document.addEventListener('click', function(event) {
        const link = event.target.closest('a');
        if (link && link.href) {
            for (let pattern of targetPatterns) {
                if (typeof pattern === 'string') {
                    if (link.href.includes(pattern)) {
                        event.preventDefault();
                        showConfirmDialog(mouseX, mouseY, link.href);
                        return;
                    }
                } else if (pattern instanceof RegExp) {
                    if (pattern.test(link.href)) {
                        event.preventDefault();
                        showConfirmDialog(mouseX, mouseY, link.href);
                        return;
                    }
                }
            }
        }
    });

    // 处理键盘事件
    document.addEventListener('keydown', function(e) {
        if (confirmDialog.style.display === 'block') {
            if (e.key === 'Enter') {
                e.preventDefault();
                window.open(confirmButton.linkHref, '_blank');
                hideConfirmDialog();
                createPopup('已打开链接', 'success');
            } else if (e.key === 'Escape') {
                e.preventDefault();
                hideConfirmDialog();
                createPopup('已取消', 'info');
            }
        }

        // Ctrl + M 打开编辑界面
        if (e.ctrlKey && (e.key === 'm' || e.key === 'M')) {
            e.preventDefault();
            showEditUI();
        }
    });

    // 监听鼠标悬停显示提示框
    function handleMouseOver(event) {
        const link = event.target.closest('a');
        if (link && link.href) {
            for (let pattern of targetPatterns) {
                if (typeof pattern === 'string') {
                    if (link.href.includes(pattern)) {
                        tooltip.innerText = `疑似诈骗链接 (关键字匹配): ${pattern}`;
                        tooltip.style.left = `${event.pageX + 10}px`;
                        tooltip.style.top = `${event.pageY + 10}px`;
                        tooltip.classList.add('show');
                        return;
                    }
                } else if (pattern instanceof RegExp) {
                    if (pattern.test(link.href)) {
                        tooltip.innerText = `疑似诈骗链接 (正则匹配): ${pattern}`;
                        tooltip.style.left = `${event.pageX + 10}px`;
                        tooltip.style.top = `${event.pageY + 10}px`;
                        tooltip.classList.add('show');
                        return;
                    }
                }
            }
            tooltip.classList.remove('show');
        }
    }

    // 监听鼠标移出隐藏提示框
    function handleMouseOut() {
        tooltip.classList.remove('show');
    }

    document.addEventListener('mousemove', handleMouseOver);
    document.addEventListener('mouseout', handleMouseOut);

    // 创建编辑关键词和正则表达式的UI
    function showEditUI() {
        if (document.getElementById('editUI')) return;
        const editUI = document.createElement('div');
        editUI.id = 'editUI';

        // 匹配关键字模式部分
        const keywordSection = document.createElement('div');
        keywordSection.className = 'section';

        const keywordTitle = document.createElement('h3');
        keywordTitle.innerText = '匹配关键字模式';
        keywordSection.appendChild(keywordTitle);

        const keywordList = document.createElement('div');
        keywordList.id = 'keywordList';
        keywordSection.appendChild(keywordList);

        // 渲染关键词列表
        function renderKeywordList() {
            keywordList.innerHTML = '';
            targetStrings.forEach((keyword, index) => {
                const keywordBlock = document.createElement('div');
                keywordBlock.className = 'item-block';

                const keywordDisplay = document.createElement('div');
                keywordDisplay.innerHTML = `<code>${keyword}</code>`;
                keywordBlock.appendChild(keywordDisplay);

                const buttonGroup = document.createElement('div');
                buttonGroup.className = 'item-buttons';

                const editButton = document.createElement('button');
                editButton.innerHTML = '🖊';
                editButton.title = '编辑';
                editButton.onclick = () => {
                    enterEditMode(keywordBlock, 'keyword', index, keyword);
                };
                buttonGroup.appendChild(editButton);

                const deleteButton = document.createElement('button');
                deleteButton.innerHTML = '×';
                deleteButton.title = '删除';
                deleteButton.onclick = () => {
                    createCustomConfirm(`确定要删除关键词 "${keyword}" 吗?`, () => {
                        targetStrings.splice(index, 1);
                        updatePatterns();
                        renderKeywordList();
                        renderRegexList();
                        createPopup('已删除', 'success');
                    });
                };
                buttonGroup.appendChild(deleteButton);

                keywordBlock.appendChild(buttonGroup);
                keywordList.appendChild(keywordBlock);
            });
        }

        renderKeywordList();

        const addKeywordButton = document.createElement('button');
        addKeywordButton.innerText = '+ 添加关键词';
        addKeywordButton.className = 'add-button';
        addKeywordButton.onclick = () => {
            enterAddMode('keyword');
        };
        keywordSection.appendChild(addKeywordButton);

        editUI.appendChild(keywordSection);

        // 高级模式部分
        const regexSection = document.createElement('div');
        regexSection.className = 'section';

        const regexTitle = document.createElement('h3');
        regexTitle.innerText = '高级模式(正则表达式)';
        regexSection.appendChild(regexTitle);

        const regexList = document.createElement('div');
        regexList.id = 'regexList';
        regexSection.appendChild(regexList);

        // 渲染正则表达式列表
        function renderRegexList() {
            regexList.innerHTML = '';
            targetRegexes.forEach((regex, index) => {
                const regexBlock = document.createElement('div');
                regexBlock.className = 'item-block';

                const regexDisplay = document.createElement('div');
                regexDisplay.innerHTML = `<code>${regex}</code>`;
                regexBlock.appendChild(regexDisplay);

                const buttonGroup = document.createElement('div');
                buttonGroup.className = 'item-buttons';

                const editButton = document.createElement('button');
                editButton.innerHTML = '🖊';
                editButton.title = '编辑';
                editButton.onclick = () => {
                    enterEditMode(regexBlock, 'regex', index, regex);
                };
                buttonGroup.appendChild(editButton);

                const deleteButton = document.createElement('button');
                deleteButton.innerHTML = '×';
                deleteButton.title = '删除';
                deleteButton.onclick = () => {
                    createCustomConfirm(`确定要删除正则表达式 "${regex}" 吗?`, () => {
                        targetRegexes.splice(index, 1);
                        updatePatterns();
                        renderKeywordList();
                        renderRegexList();
                        createPopup('已删除', 'success');
                    });
                };
                buttonGroup.appendChild(deleteButton);

                regexBlock.appendChild(buttonGroup);
                regexList.appendChild(regexBlock);
            });
        }

        renderRegexList();

        const addRegexButton = document.createElement('button');
        addRegexButton.innerText = '+ 添加正则表达式';
        addRegexButton.className = 'add-button';
        addRegexButton.onclick = () => {
            enterAddMode('regex');
        };
        regexSection.appendChild(addRegexButton);

        editUI.appendChild(regexSection);

        // 按钮容器
        const buttonContainerEdit = document.createElement('div');
        buttonContainerEdit.className = 'save-cancel-buttons';

        const saveButtonEdit = document.createElement('button');
        saveButtonEdit.innerText = '保存';
        saveButtonEdit.className = 'save-button';
        saveButtonEdit.onclick = () => {
            try {
                // 验证所有正则表达式
                targetRegexes.forEach(regex => {
                    if (regex.startsWith('/') && regex.endsWith('/')) {
                        new RegExp(regex.slice(1, -1));
                    } else {
                        throw new Error(`正则表达式必须以斜杠 "/" 包裹: ${regex}`);
                    }
                });

                // 更新存储
                localStorage.setItem('targetStrings', JSON.stringify(targetStrings));
                localStorage.setItem('targetRegexes', JSON.stringify(targetRegexes));

                createPopup('已自动保存', 'success');
                document.body.removeChild(editUI);
            } catch (error) {
                createPopup(`保存失败: ${error.message}`, 'error');
            }
        };
        buttonContainerEdit.appendChild(saveButtonEdit);

        const cancelButtonEdit = document.createElement('button');
        cancelButtonEdit.innerText = '取消';
        cancelButtonEdit.className = 'cancel-button';
        cancelButtonEdit.onclick = () => {
            createPopup('已取消', 'info');
            document.body.removeChild(editUI);
        };
        buttonContainerEdit.appendChild(cancelButtonEdit);

        editUI.appendChild(buttonContainerEdit);
        document.body.appendChild(editUI);
    }

    // 进入编辑模式
    function enterEditMode(block, type, index, currentValue) {
        block.innerHTML = '';

        const inputContainer = document.createElement('div');
        inputContainer.style.display = 'flex';
        inputContainer.style.alignItems = 'center';
        inputContainer.style.gap = '10px';
        inputContainer.style.width = '100%';

        const input = document.createElement('input');
        input.type = 'text';
        input.value = currentValue;
        input.style.flexGrow = '1';
        input.style.fontFamily = 'Consolas, monospace';
        input.style.padding = '5px';
        input.style.border = '1px solid #ccc';
        input.style.borderRadius = '4px';
        inputContainer.appendChild(input);

        const okButton = document.createElement('button');
        okButton.innerText = 'OK (请在编辑后到最下方保存)';
        okButton.style.padding = '5px 10px';
        okButton.style.backgroundColor = '#4CAF50';
        okButton.style.color = '#fff';
        okButton.style.border = 'none';
        okButton.style.borderRadius = '4px';
        okButton.style.cursor = 'pointer';
        okButton.style.fontSize = '14px';
        okButton.onclick = () => {
            saveEdit(block, type, index, input.value.trim());
        };
        inputContainer.appendChild(okButton);

        block.appendChild(inputContainer);

        // 监听 Enter 键
        input.addEventListener('keydown', function(e) {
            if (e.key === 'Enter') {
                e.preventDefault();
                saveEdit(block, type, index, input.value.trim());
            }
        });

        // 自动聚焦输入框
        input.focus();
    }

    // 进入添加模式
    function enterAddMode(type) {
        let sectionId = type === 'keyword' ? 'keywordList' : 'regexList';
        let list = document.getElementById(sectionId);

        const addBlock = document.createElement('div');
        addBlock.className = 'item-block';

        const inputContainer = document.createElement('div');
        inputContainer.style.display = 'flex';
        inputContainer.style.alignItems = 'center';
        inputContainer.style.gap = '10px';
        inputContainer.style.width = '100%';

        const input = document.createElement('input');
        input.type = 'text';
        input.placeholder = type === 'keyword' ? '输入新的关键词' : '输入新的正则表达式(需用斜杠包裹)';
        input.style.flexGrow = '1';
        input.style.fontFamily = 'Consolas, monospace';
        input.style.padding = '5px';
        input.style.border = '1px solid #ccc';
        input.style.borderRadius = '4px';
        inputContainer.appendChild(input);

        const okButton = document.createElement('button');
        okButton.innerText = 'OK';
        okButton.style.padding = '5px 10px';
        okButton.style.backgroundColor = '#4CAF50';
        okButton.style.color = '#fff';
        okButton.style.border = 'none';
        okButton.style.borderRadius = '4px';
        okButton.style.cursor = 'pointer';
        okButton.style.fontSize = '14px';
        okButton.onclick = () => {
            const newValue = input.value.trim();
            if (newValue === '') {
                createPopup('输入不能为空', 'error');
                return;
            }
            if (type === 'regex') {
                if (!newValue.startsWith('/') || !newValue.endsWith('/')) {
                    createPopup('正则表达式必须以斜杠 "/" 包裹。', 'error');
                    return;
                }
                try {
                    new RegExp(newValue.slice(1, -1));
                } catch (e) {
                    createPopup('无效的正则表达式。', 'error');
                    return;
                }
                targetRegexes.push(newValue);
            } else {
                targetStrings.push(newValue);
            }
            updatePatterns();
            renderEditUI();
            createPopup('已自动保存', 'success');
        };
        inputContainer.appendChild(okButton);

        // 监听 Enter 键
        input.addEventListener('keydown', function(e) {
            if (e.key === 'Enter') {
                e.preventDefault();
                okButton.click();
            }
        });

        addBlock.appendChild(inputContainer);
        list.appendChild(addBlock);

        // 自动聚焦输入框
        input.focus();
    }

    // 保存编辑
    function saveEdit(block, type, index, newValue) {
        if (type === 'keyword') {
            if (newValue === '') {
                createPopup('关键词不能为空。', 'error');
                return;
            }
            targetStrings[index] = newValue;
        } else if (type === 'regex') {
            if (!newValue.startsWith('/') || !newValue.endsWith('/')) {
                createPopup('正则表达式必须以斜杠 "/" 包裹。', 'error');
                return;
            }
            try {
                new RegExp(newValue.slice(1, -1));
                targetRegexes[index] = newValue;
            } catch (e) {
                createPopup('无效的正则表达式。', 'error');
                return;
            }
        }

        updatePatterns();
        renderEditUI();
        createPopup('已自动保存', 'success');
    }

    // 重新渲染编辑界面
    function renderEditUI() {
        const editUI = document.getElementById('editUI');
        if (editUI) {
            document.body.removeChild(editUI);
            showEditUI();
        }
    }

    // 自定义确认弹窗
    function createCustomConfirm(message, onConfirm) {
        // 创建遮罩
        const overlay = document.createElement('div');
        overlay.className = 'custom-confirm-overlay';
        document.body.appendChild(overlay);

        // 创建弹窗
        const confirmBox = document.createElement('div');
        confirmBox.className = 'custom-confirm-box';

        const msg = document.createElement('p');
        msg.innerText = message;
        confirmBox.appendChild(msg);

        const buttons = document.createElement('div');
        buttons.style.display = 'flex';
        buttons.style.justifyContent = 'flex-end';
        buttons.style.gap = '10px';

        const yesButton = document.createElement('button');
        yesButton.innerText = '确定';
        yesButton.style.padding = '6px 12px';
        yesButton.style.backgroundColor = '#4CAF50';
        yesButton.style.color = '#fff';
        yesButton.style.border = 'none';
        yesButton.style.borderRadius = '4px';
        yesButton.style.cursor = 'pointer';
        yesButton.onclick = () => {
            onConfirm();
            document.body.removeChild(overlay);
            document.body.removeChild(confirmBox);
        };
        buttons.appendChild(yesButton);

        const noButton = document.createElement('button');
        noButton.innerText = '取消';
        noButton.style.padding = '6px 12px';
        noButton.style.backgroundColor = '#f44336';
        noButton.style.color = '#fff';
        noButton.style.border = 'none';
        noButton.style.borderRadius = '4px';
        noButton.style.cursor = 'pointer';
        noButton.onclick = () => {
            document.body.removeChild(overlay);
            document.body.removeChild(confirmBox);
        };
        buttons.appendChild(noButton);

        confirmBox.appendChild(buttons);
        document.body.appendChild(confirmBox);

        // CSS for custom confirm
        const confirmStyle = document.createElement('style');
        confirmStyle.innerHTML = `
        .custom-confirm-overlay {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0,0,0,0.5);
            z-index: 10003;
        }
        .custom-confirm-box {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background-color: #fff;
            padding: 20px 30px;
            border-radius: 8px;
            box-shadow: 0 4px 16px rgba(0,0,0,0.3);
            z-index: 10004;
            font-family: Arial, sans-serif;
            width: 300px;
        }
        .custom-confirm-box p {
            margin-bottom: 20px;
            font-size: 14px;
        }
        .custom-confirm-box button {
            font-size: 14px;
        }
        `;
        document.head.appendChild(confirmStyle);
    }
})();