Greasy Fork

Greasy Fork is available in English.

特别好用的搜索引擎跳转脚本

搜索引擎相互跳转,对页面入侵性最小,置顶显示;并且还有复制后可以选择多种搜索引擎进行搜索的功能。(已完美修复 Cloudflare 盾卡死问题 & 增加高级选词弹窗配置)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         特别好用的搜索引擎跳转脚本
// @namespace    http://tampermonkey.net/
// @license MIT
// @version      1.5.0
// @description  搜索引擎相互跳转,对页面入侵性最小,置顶显示;并且还有复制后可以选择多种搜索引擎进行搜索的功能。(已完美修复 Cloudflare 盾卡死问题 & 增加高级选词弹窗配置)
// @author       Gemini
// @match        *://*/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_registerMenuCommand
// @run-at       document-start
// ==/UserScript==

(function() {
    'use strict';

    // =====================================================================
    // 0. 安全防御突破:构建 Trusted Types Policy (免疫 YouTube 拦截)
    // =====================================================================
    const gmPolicy = (function() {
        if (typeof window.trustedTypes !== 'undefined' && window.trustedTypes.createPolicy) {
            try { return window.trustedTypes.createPolicy('gm_search_policy', { createHTML: (s) => s }); }
            catch (e) { return { createHTML: (s) => s }; }
        }
        return { createHTML: (s) => s };
    })();

    // =====================================================================
    // 1. 核心配置与引擎数据库 (Base64 源码修改区)
    // =====================================================================
    const PLACEHOLDER_BASE64 = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iIzllOWU5ZSI+PHBhdGggZD0iTTEyIDJDNi40OCAyIDIgNi40OCAyIDEyczQuNDggMTAgMTAgMTAgMTAtNC40OCAxMC0xMFMxNy41MiAyIDEyIDJ6bS0xIDE3LjkzYy0zLjk1LS40OS03LTMuODUtNy03LjkzIDAtLjYyLjA4LTEuMjEuMjMtMS43OUw5IDE1djFjMCAxLjEgLjkgMiAyIDJ2MS45M3ptNi45LTEuNTRjLS41NC0xLjE3LTEuNjQtMi0yLjktMnYtMmMwLS41NS0uNDUtMS0xLTFoLTJ2LTIuNWMwLS4yOC4yMi0uNS41LS41aDRjLjU1IDAgMS0uNDUgMS0xVjhjMC0uNTUtLjQ1LTEtMS0xaC00Yy0uNTUgMC0xIC40NS0xIDF2My41aC0xdi0xLjVjMC0uNTUtLjQ1LTEtMS0xaC0xYy0uNTUgMC0xLS40NS0xLTFWNmgyYy41NSAwIDEtLjQ1IDEtMXYtLjQ2YzEuMDUtLjM0IDIuMTgtLjU0IDMuNC0uNTQgNS41MSAwIDEwIDQuNDkgMTAgMTB6Ii8+PC9zdmc+";

    const DEFAULT_ENGINES = [
        { id: 'baidu', name: '百度', domain: 'baidu.com', url: 'https://www.baidu.com/s?wd=%s', icon: '<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><path d="M345.706 297.423c15.35 12.792 35.817 20.467 53.726 17.908 20.467 0 38.375-10.233 53.725-23.025 17.91-15.35 30.7-35.817 40.934-58.842C512 189.97 512 136.245 496.65 90.194c-10.234-30.7-28.142-58.842-53.726-76.75C427.574 3.21 404.548-1.906 384.081 0.652c-12.791 2.558-25.583 7.675-38.375 15.35-23.025 15.35-38.376 40.934-48.61 66.518-12.791 46.05-15.35 92.101-2.557 138.152 10.233 28.142 25.583 56.284 51.167 76.75z m255.837 2.558c17.909 15.35 40.934 25.584 63.96 25.584 20.466 2.558 38.375-2.558 56.283-12.792 17.909-10.233 33.26-25.584 43.493-43.492 12.792-20.467 23.025-40.934 30.7-63.96 5.117-17.908 7.675-38.375 5.117-58.842-2.559-28.142-15.35-53.726-33.259-76.751-12.792-15.35-28.142-30.7-46.05-38.376-12.792-5.116-28.143-10.233-40.935-7.675-17.908 2.559-33.258 12.792-46.05 23.026-17.909 15.35-33.259 33.258-43.493 53.725-10.233 17.909-20.466 38.376-23.025 61.401-2.558 25.584-2.558 51.168 2.559 74.193 5.116 23.025 12.791 46.05 30.7 63.96zM245.929 509.768c17.91-15.35 28.143-35.818 35.818-56.285 10.233-33.258 10.233-66.517 7.675-99.776 0-12.792-5.117-25.584-10.234-38.376-12.792-28.142-35.817-53.725-63.959-69.076-23.025-10.233-46.05-15.35-66.518-10.233-25.583 2.558-46.05 20.467-61.4 40.934-20.467 28.142-30.7 63.96-35.818 97.218-2.558 20.467 0 40.934 5.117 61.4 7.675 30.701 23.025 58.843 46.05 79.31 17.91 15.35 40.935 23.026 63.96 23.026 28.142 0 56.284-7.675 79.31-28.142z m736.811-76.752c-2.558-20.467-7.675-38.375-17.908-56.284-10.234-20.467-28.143-40.934-48.61-51.167-23.025-12.792-51.167-15.35-76.75-12.792-12.792 2.558-28.143 5.117-40.935 12.792-17.908 10.233-30.7 28.142-40.933 48.609-10.234 25.584-15.35 53.726-15.35 81.868 0 25.583 0 53.726 7.674 79.31 5.117 17.908 15.35 38.375 33.26 48.608 17.908 15.35 40.933 20.467 63.959 23.026 17.908 2.558 38.375 2.558 56.284-2.559 17.908-5.116 35.817-15.35 46.05-30.7 12.792-15.35 20.467-35.817 23.026-53.726 12.792-30.7 10.233-58.842 10.233-86.985zM911.106 819.33c-2.559-35.817-20.467-71.634-46.05-99.776-5.118-5.117-10.234-10.234-17.91-15.35-33.258-28.142-66.517-58.843-99.776-89.543-33.259-33.26-63.96-69.076-92.101-107.452-20.467-33.259-48.61-63.96-86.985-81.868-23.025-10.233-51.167-15.35-76.751-12.792-46.05 5.117-86.985 30.7-115.127 66.518-7.675 7.675-12.791 17.909-17.908 28.142-20.467 30.7-46.05 61.401-74.193 86.985-15.35 15.35-30.7 28.142-46.05 40.934-7.676 7.675-17.91 15.35-25.584 23.025-30.7 23.025-61.401 53.726-79.31 86.985-12.792 23.025-20.467 48.609-23.025 76.75 0 23.026 2.558 46.051 10.233 66.518 7.675 23.026 17.909 46.051 33.26 63.96 25.583 30.7 63.958 51.167 102.334 53.725 48.609 2.559 97.218 0 143.269-7.675 20.467-2.558 40.934-10.233 63.959-12.792 46.05-5.116 92.101-2.558 135.594 10.234 35.817 12.792 74.192 17.909 112.568 20.467 38.375 2.558 79.31-2.558 115.127-23.025 25.583-12.792 46.05-35.818 58.842-61.401 20.467-33.26 30.7-71.635 25.584-112.569zM481.3 924.224H363.615c-12.792 0-25.584 0-38.376-2.559-25.584-5.117-48.61-20.467-63.96-43.492-12.791-15.35-20.466-33.259-23.025-53.726a246.563 246.563 0 0 1 0-61.4c5.117-23.026 17.909-43.493 33.26-58.843 12.791-12.792 30.7-23.026 48.608-30.7 7.675-2.56 15.35-5.117 23.026-5.117h69.076v-97.219h66.517c2.559 120.244 2.559 237.929 2.559 353.056z m263.512 0H583.634c-17.908-2.559-33.258-7.676-46.05-17.909-15.35-12.792-23.026-33.259-23.026-51.167v-173.97h66.518v161.178c0 7.675 2.558 12.792 7.675 17.908 5.117 5.117 12.792 7.675 20.467 7.675h69.076V678.62h66.518v245.604z" fill="#2932E1"></path><path d="M340.59 734.904c-12.793 5.117-25.585 15.35-33.26 30.7-5.116 12.792-7.675 25.584-7.675 38.376 0 15.35 5.117 30.7 12.792 43.492 10.234 15.35 28.142 25.584 46.05 23.026h53.727V732.346H353.38c-2.558-2.559-7.675 0-12.792 2.558z" fill="#2932E1"></path></svg>', enabled: true },
        { id: 'google', name: 'Google', domain: 'google.com', url: 'https://www.google.com/search?q=%s', icon: '<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><path d="M222.087529 515.915294c0-32.527059 5.481412-63.698824 15.179295-92.973176l-170.285177-128.90353A496.941176 496.941176 0 0 0 15.058824 515.945412c0 79.721412 18.672941 154.955294 51.802352 221.726117l170.255059-129.114353a293.767529 293.767529 0 0 1-15.028706-92.611764" fill="#FBBC05"></path><path d="M521.246118 219.979294a294.460235 294.460235 0 0 1 186.337882 65.957647l147.245176-145.648941C765.108706 62.885647 650.089412 15.058824 521.246118 15.058824 321.204706 15.058824 149.293176 128.421647 66.981647 294.038588l170.405647 128.90353c39.243294-118.061176 151.100235-202.992941 283.919059-202.992942" fill="#EA4335"></path><path d="M523.414588 805.315765c-133.511529 0-245.940706-84.359529-285.394823-201.728l-171.188706 128.12047C149.564235 896.301176 322.349176 1008.941176 523.444706 1008.941176c124.024471 0 242.447059-43.128471 331.38447-124.054588l-162.514823-123.090823c-45.808941 28.310588-103.574588 43.550118-168.929882 43.550117" fill="#34A853"></path><path d="M1008.941176 511.216941c0-29.394824-4.638118-61.108706-11.565176-90.503529H523.354353v192.301176h272.835765c-13.613176 65.596235-50.718118 115.983059-103.875765 148.781177l162.484706 123.090823c93.394824-84.901647 154.142118-211.425882 154.142117-373.669647" fill="#4285F4"></path></svg>', enabled: true },
        { id: 'bing', name: '必应', domain: 'bing.com', url: 'https://www.bing.com/search?q=%s', icon: '<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><path d="M340.5824 70.109867L102.536533 0.682667v851.217066L340.650667 643.345067V70.109867zM102.536533 851.7632l238.045867 171.6224 580.881067-340.923733V411.784533L102.536533 851.831467z" fill="#0078D4"></path><path d="M409.463467 255.3856l113.732266 238.933333 138.8544 56.866134 259.413334-139.400534-506.0608-156.330666z" fill="#0078D4"></path></svg>', enabled: true },
        { id: 'bilibili', name: 'B站', domain: 'bilibili.com', url: 'https://search.bilibili.com/all?keyword=%s', icon: '<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><path d="M210.22552317 41.01176535c18.55850066-10.60485751 42.220589-12.12930579 61.90585578-3.44657869 14.71423981 6.03151271 25.84934021 17.89569707 37.77980492 27.97031171 49.37886783 42.61827117 98.36005351 85.83306557 147.93776242 128.18621528h104.12644477c49.57770891-42.41943008 98.49261422-85.50166377 147.87148206-128.11993493 11.99674507-10.07461465 23.13184546-21.87251863 37.91236565-28.03659206 19.08874354-8.41760565 42.02174793-7.29083955 60.31512715 2.65121437 21.47483648 11.06882003 36.38791737 34.00182443 37.3158424 58.19415565 1.3256072 17.56429527-4.97102697 35.32743163-15.97356665 48.91490531-9.74321285 10.80369859-21.40855613 19.68526677-32.21225472 29.36219927-6.89315739 5.70011091-13.12351118 12.32814687-20.74575252 17.10033275 30.62152609 0 61.17677182-0.33140179 91.79829792 0.19884108 40.29845858 1.06048575 79.53643141 18.88990245 107.30790203 48.119541 29.2959189 28.76567603 45.99856949 69.32925605 45.93228914 110.29051822 0.13256073 140.38180144 0 280.82988322 0.06628037 421.21168466-0.13256073 21.20971504 1.06048575 42.75083188-3.64541978 63.62914514-8.61644674 42.68455152-37.3158424 79.73527248-73.77004013 102.73455722a157.08445203 157.08445203 0 0 1-83.77837441 22.99928475H190.01001353c-22.00507936-0.13256073-44.34156051 1.12676611-66.01523808-3.71170014-41.55778541-8.3513253-77.68058134-35.79139413-100.74614645-70.72114358a156.75305023 156.75305023 0 0 1-24.92141517-86.69471023v-416.24065771c0.13256073-21.40855613-1.19304647-42.94967296 3.18145726-63.96054692 13.2560719-68.53389173 76.28869379-124.40823479 146.28075342-127.45713133 31.88085293-0.99420539 63.82798621-0.26512144 95.70883914-0.39768216-15.04564161-10.86997897-28.23543315-23.99349014-42.4194301-35.92395485a71.25138647 71.25138647 0 0 1-26.57842415-59.45348248c0.92792503-23.59580798 15.11192197-46.06484987 35.79139413-57.39879133m-16.90149167 287.12651737c-27.17494739 4.83846624-50.37307323 26.31330272-57.92903422 52.75916619a99.0228571 99.0228571 0 0 0-3.04889653 28.10287242c0.13256073 115.26154518-0.06628035 230.52309037 0.06628035 345.8509159-0.53024288 31.35061005 21.14343469 61.0442111 50.63819467 71.05254539 10.53857716 3.84426085 21.87251863 3.91054121 32.87505831 3.97682157 198.31083565-0.13256073 396.68795165 0.06628035 594.9987873-0.06628036 29.09707781 1.12676611 57.06738954-16.96777203 69.32925604-43.08223368 7.48968062-14.97936125 7.3571199-32.01341364 7.09199847-48.38466244v-322.1225472c0-11.79790399 0.39768215-23.92720978-2.98261619-35.3274316a76.08985271 76.08985271 0 0 0-47.72185883-50.04167144c-12.65954867-4.63962516-26.44586345-3.91054121-39.70193536-3.97682158H227.85609879c-11.4665022 0-23.06556511-0.39768215-34.46578693 1.25932683z" fill="#00AEEC"></path><path d="M313.55660364 438.89276347c18.95618282-1.92213043 38.64144959 4.24194301 53.09056797 16.57008987 16.10612736 13.2560719 25.31909733 33.80298335 25.58421877 54.54873588 0.46396251 25.12025625 0.13256073 50.30679286 0.13256071 75.42704911 0 16.57008987-4.37450373 33.40530119-14.64795944 46.52881237a71.18510611 71.18510611 0 0 1-62.76750046 28.1691528 71.11882576 71.11882576 0 0 1-57.00110918-36.58675845c-8.81528781-15.11192197-9.54437177-33.00761904-9.27925033-49.97539107 0.53024288-24.3911723-1.3256072-48.91490531 1.12676611-73.23979725a71.58278827 71.58278827 0 0 1 63.76170585-61.44189326z m378.5934135 0a71.51650791 71.51650791 0 0 1 78.60850637 68.66645244c1.06048575 23.59580798 0.13256073 47.19161597 0.53024288 70.78742396 0.13256073 16.57008987-1.85585006 33.80298335-11.00253967 48.05326063-13.2560719 22.07135971-39.23797282 35.65883341-64.95475232 33.80298336a71.25138647 71.25138647 0 0 1-56.1394645-32.34481543c-10.27345573-15.24448269-12.26186651-34.00182443-11.797904-51.8975215 0.46396251-24.25861157-0.86164467-48.51722316 0.79536431-72.70955439 2.38609294-33.14017975 30.95292789-61.50817362 63.96054693-64.29194872z" fill="#00AEEC"></path></svg>', enabled: true },
        { id: 'youtube', name: 'YouTube', domain: 'youtube.com', url: 'https://www.youtube.com/results?search_query=%s', icon: '<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><path d="M426.666667 682.666667V384l256 149.845333L426.666667 682.666667z m587.093333-355.541334s-10.026667-71.04-40.704-102.357333c-38.954667-41.088-82.602667-41.258667-102.613333-43.648C727.168 170.666667 512.213333 170.666667 512.213333 170.666667h-0.426666s-214.954667 0-358.229334 10.453333c-20.053333 2.389333-63.658667 2.56-102.656 43.648-30.677333 31.317333-40.661333 102.4-40.661333 102.4S0 410.538667 0 493.952v78.293333c0 83.456 10.24 166.912 10.24 166.912s9.984 71.04 40.661333 102.357334c38.997333 41.088 90.154667 39.765333 112.938667 44.074666C245.76 893.568 512 896 512 896s215.168-0.341333 358.442667-10.752c20.053333-2.432 63.658667-2.602667 102.613333-43.690667 30.72-31.317333 40.704-102.4 40.704-102.4s10.24-83.413333 10.24-166.869333v-78.250667c0-83.456-10.24-166.912-10.24-166.912z" fill="#FF0000"></path></svg>', enabled: true },
        { id: 'xiaohongshu', name: '小红书', domain: 'xiaohongshu.com', url: 'https://www.xiaohongshu.com/search_result?keyword=%s', icon: "data:image/svg+xml;charset=utf-8;base64,PHN2ZyB0PSIxNzczMjQwMjk4MDQ1IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjM4OTEiIHdpZHRoPSIxMjgiIGhlaWdodD0iMTI4Ij48cGF0aCBkPSJNMCAwbTI1NiAwbDUxMiAwcTI1NiAwIDI1NiAyNTZsMCA1MTJxMCAyNTYtMjU2IDI1NmwtNTEyIDBxLTI1NiAwLTI1Ni0yNTZsMC01MTJxMC0yNTYgMjU2LTI1NloiIGZpbGw9IiNGQTJDMTkiIHAtaWQ9IjM4OTIiPjwvcGF0aD48cGF0aCBkPSJNNDQ1LjgyNCA3NjYuMjkzMzMzYzQuMTgxMzMzLTkuMTMwNjY3IDcuNjgtMTcuMDY2NjY3IDExLjQ3NzMzMy0yNC43ODkzMzNhNTEyIDUxMiAwIDAgMCAyMy4yNTMzMzQtNDkuMjM3MzMzIDI5LjE0MTMzMyAyOS4xNDEzMzMgMCAwIDEgMzQuNzczMzMzLTIxLjcxNzMzNGMyMS45NzMzMzMgMS41Nzg2NjcgNDQuMDMyIDAuNDI2NjY3IDY2Ljk4NjY2NyAwLjQyNjY2N1YzODQuODUzMzMzYy0xNS40NDUzMzMgMC0zMC42NzczMzMtMC41NTQ2NjctNDUuNzgxMzM0IDAtMTAuNTM4NjY3IDAuNTU0NjY3LTE0LjI1MDY2Ny0yLjkwMTMzMy0xMy45MDkzMzMtMTQuMTY1MzMzIDAuNzI1MzMzLTI3LjA5MzMzMyAwLTU0LjI3MiAwLTgyLjYwMjY2N2gyMTQuMjI5MzMzdjY1LjcwNjY2N2MwIDMwLjg5MDY2NyAwIDMwLjg5MDY2Ny0yOS45NTIgMzAuODkwNjY3aC0zMC4xMjI2NjZ2Mjg1Ljk1Mmg2NS4wMjRjMjYuMTk3MzMzIDAgMjYuMTk3MzMzIDAgMjYuMTk3MzMzIDI3LjUydjU3LjY0MjY2NmMwIDcuOTc4NjY3LTEuOTYyNjY3IDEyLjAzMi0xMC42MjQgMTIuMDMyLTEwMS42NzQ2NjctMC4xNzA2NjctMjAzLjM5Mi0wLjI5ODY2Ny0zMDUuMDY2NjY3LTAuMjEzMzMzYTM3LjcxNzMzMyAzNy43MTczMzMgMCAwIDEtNi40ODUzMzMtMS4zNjUzMzMiIGZpbGw9IiNGRkZGRkYiIHAtaWQ9IjM4OTMiPjwvcGF0aD48cGF0aCBkPSJNNDg2LjM1NzMzMyA1NTkuMTQ2NjY3Yy0xMy4zOTczMzMgMjcuNjA1MzMzLTI1LjE3MzMzMyA1Mi4yNjY2NjctMzcuNTQ2NjY2IDc2LjUwMTMzM2ExMS42MDUzMzMgMTEuNjA1MzMzIDAgMCAxLTguOTYgNC41MjI2NjdjLTI5Ljc4MTMzMyAwLTU5LjczMzMzMyAxLjE1Mi04OS40MjkzMzQtMS4wNjY2NjctMjkuNzM4NjY3LTIuMjE4NjY3LTQxLjY0MjY2Ny0yMS4zMzMzMzMtMjkuNzgxMzMzLTUwLjUxNzMzMyAxMy40ODI2NjctMzMuNjY0IDI5LjczODY2Ny00NC44LTk5LjJsMy40MTMzMzMtOC44MzJjLTEyLjAzMiAwLTIyLjU3MDY2NyAwLjI5ODY2Ny0zMy4xMDkzMzMgMC04LjU3NiAwLjEyOC0xNy4xNTItMC42ODI2NjctMjUuNTE0NjY3LTIuMzQ2NjY3YTMwLjAzNzczMzMgMzAuMDM3MzMzIDAgMCAxLTI1LjcyOC0zMy41MzYgMzAuNzIgMzAuNzIgMCAwIDEgMi45MDEzMzQtMTAuMTEyYzE4LjA0OC00My4zNDkzMzMgMzguMjcyLTg1Ljg0NTMzMyA1Ny43NzA2NjYtMTI4LjU1NDY2NyA2LjM1NzMzMy0xMy45OTQ2NjcgMTMuMDEzMzMzLTI3Ljc3NiAyMC4xODEzMzQtNDEuMzg2NjY2IDEuODM0NjY3LTMuNTQxMzMzIDYuMTAxMzMzLTguMDY0IDkuMzg2NjY2LTguMTkyIDI3Ljg2MTMzMy0wLjY4MjY2NyA1NS44MDgtMC4zNDEzMzMgODYuMTg2NjY3LTAuMzQxMzM0LTIuNjQ1MzMzIDYuNzg0LTQuMTM4NjY3IDExLjM5Mi02LjE0NCAxNS43MDEzMzQtMTcuMDY2NjY3IDM1LjcxMi0zNC4xNzYgNzEuMzgxMzMzLTUxLjM3MDY2NyAxMDYuOTY1MzMzLTMuNDU2IDcuMjEwNjY3LTcuNjggMTQuNzIgNS4yOTA2NjcgMjAuMjI0IDMuNDEzMzMzLTE4LjU2IDE3LjQwOC0xNS4xODkzMzMgMjkuNjEwNjY3LTE1LjE4OTMzM2g3MC40Yy0yLjk0NCA3LjA0LTQuODY0IDExLjk0NjY2Ny02Ljk5NzMzNCAxNi41OTczMzMtMjEuNzYgNDUuNDQtNDMuODYxMzMzIDkwLjUzODY2Ny02NS4yOCAxMzUuOTM2LTguNzg5MzMzIDE4LjQ3NDY2Ny01Ljg0NTMzMyAyMi45OTczMzMgMTQuNjM0NjY3IDIzLjE2OCAxMC41Mzg2NjctMC4yOTg2NjcgMjEuMjA1MzMzLTAuMzQxMzMzIDM1LjI4NTMzMy0wLjM0MTMzM20tMzguMzE0NjY2IDExMS44NzJjLTE2LjUxMiAzMy4xMDkzMzMtMzEuMjc0NjY3IDYyLjg5MDY2Ny00Ni4zNzg2NjcgOTIuNTAxMzMzYTEwLjI0IDEwLjI0IDAgMCAxLTcuNjggNC4yNjY2NjdjLTQwLjQ5MDY2Ny0wLjQyNjY2Ny04MS4wNjY2NjctMS4xOTQ2NjctMTIxLjY4NTMzMy0yLjI2MTMzNGE3OS4zMTczMzMgNzkuMzE3MzMzIDAgMCAxLTE2LjI5ODY2Ny00LjI2NjY2NmwyMi42OTg2NjctNDUuOTA5MzM0YzcuMzgxMzMzLTE1LjE4OTMzMyAxNC41OTItMzAuMjkzMzMzIDIyLjU3MDY2Ni00NC43MTQ2NjZhMTMuNjUzMzMzIDEzLjY1MzMzMyAwIDAgMSA5LjcyOC02LjRjMzcuMjA1MzMzIDEuODM0NjY3IDc0LjQxMDY2NyA0LjQzNzMzMyAxMTEuNjU4NjY3IDYuNjk4NjY2IDcuNDI0IDAuMzg0IDE0LjUwNjY2NyAwLjA4NTMzMyAyNS4zODY2NjcgMC4wODUzMzQiIGZpbGw9IiNGRkZGRkYiIHAtaWQ9IjM4OTQiPjwvcGF0aD48L3N2Zz4=", enabled: true },
        { id: 'douyin', name: '抖音', domain: 'douyin.com', url: 'https://www.douyin.com/search/%s', icon: '<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><path d="M0 0m184.32 0l655.36 0q184.32 0 184.32 184.32l0 655.36q0 184.32-184.32 184.32l-655.36 0q-184.32 0-184.32-184.32l0-655.36q0-184.32 184.32-184.32Z" fill="#111111"></path><path d="M204.27776 670.59712a246.25152 246.25152 0 0 1 245.97504-245.97504v147.57888a98.49856 98.49856 0 0 0-98.38592 98.38592c0 48.34304 26.14272 100.352 83.54816 100.352 3.81952 0 93.55264-0.88064 93.55264-77.19936V134.35904h157.26592a133.31456 133.31456 0 0 0 133.12 132.99712l-0.13312 147.31264a273.152 273.152 0 0 1-142.62272-38.912l-0.06144 317.98272c0 146.00192-124.24192 224.77824-241.14176 224.77824-131.74784 0.03072-231.1168-106.56768-231.1168-247.92064z" fill="#FF4040"></path><path d="M164.92544 631.23456a246.25152 246.25152 0 0 1 245.97504-245.97504v147.57888a98.49856 98.49856 0 0 0-98.38592 98.38592c0 48.34304 26.14272 100.352 83.54816 100.352 3.81952 0 93.55264-0.88064 93.55264-77.19936V94.99648h157.26592a133.31456 133.31456 0 0 0 133.12 132.99712l-0.13312 147.31264a273.152 273.152 0 0 1-142.62272-38.912l-0.06144 317.98272c0 146.00192-124.24192 224.77824-241.14176 224.77824-131.74784 0.03072-231.1168-106.56768-231.1168-247.92064z" fill="#00F5FF"></path><path d="M410.91072 427.58144c-158.8224 20.15232-284.44672 222.72-154.112 405.00224 120.40192 98.47808 373.68832 41.20576 380.70272-171.85792l-0.17408-324.1472a280.7296 280.7296 0 0 0 142.88896 38.62528V261.2224a144.98816 144.98816 0 0 1-72.8064-54.82496 135.23968 135.23968 0 0 1-54.70208-72.45824h-123.66848l-0.08192 561.41824c-0.11264 78.46912-130.9696 106.41408-164.18816 30.2592-83.18976-39.77216-64.37888-190.9248 46.31552-192.57344z" fill="#FFFFFF"></path></svg>', enabled: true },
        { id: 'weibo', name: '微博', domain: 'weibo.com', url: 'https://s.weibo.com/weibo?q=%s', icon: '<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><path d="M851.4 590.193c-22.196-66.233-90.385-90.422-105.912-91.863-15.523-1.442-29.593-9.94-19.295-27.505 10.302-17.566 29.304-68.684-7.248-104.681-36.564-36.14-116.512-22.462-173.094 0.866-56.434 23.327-53.39 7.055-51.65-8.925 1.89-16.848 32.355-111.02-60.791-122.395C311.395 220.86 154.85 370.754 99.572 457.15 16 587.607 29.208 675.873 29.208 675.873h0.58c10.009 121.819 190.787 218.869 412.328 218.869 190.5 0 350.961-71.853 398.402-169.478 0 0 0.143-0.433 0.575-1.156 4.938-10.506 8.71-21.168 11.035-32.254 6.668-26.205 11.755-64.215-0.728-101.66z m-436.7 251.27c-157.71 0-285.674-84.095-285.674-187.768 0-103.671 127.82-187.76 285.674-187.76 157.705 0 285.673 84.089 285.673 187.76 0 103.815-127.968 187.768-285.673 187.768z" fill="#E6162D"></path><path d="M803.096 425.327c2.896 1.298 5.945 1.869 8.994 1.869 8.993 0 17.7-5.328 21.323-14.112 5.95-13.964 8.993-28.793 8.993-44.205 0-62.488-51.208-113.321-114.181-113.321-15.379 0-30.32 3.022-44.396 8.926-11.755 4.896-17.263 18.432-12.335 30.24 4.933 11.662 18.572 17.134 30.465 12.238 8.419-3.46 17.268-5.33 26.41-5.33 37.431 0 67.752 30.241 67.752 67.247 0 9.068-1.735 17.857-5.369 26.202a22.832 22.832 0 0 0 12.335 30.236l0.01 0.01z" fill="#F5AA15"></path><path d="M726.922 114.157c-25.969 0-51.65 3.744-76.315 10.942-18.423 5.472-28.868 24.622-23.5 42.91 5.509 18.29 24.804 28.657 43.237 23.329a201.888 201.888 0 0 1 56.578-8.064c109.253 0 198.189 88.271 198.189 196.696 0 19.436-2.905 38.729-8.419 57.16-5.508 18.289 4.79 37.588 23.212 43.053 3.342 1.014 6.817 1.442 10.159 1.442 14.943 0 28.725-9.648 33.37-24.48 7.547-24.906 11.462-50.826 11.462-77.175-0.143-146.588-120.278-265.813-267.973-265.813z" fill="#F5AA15"></path><path d="M388.294 534.47c-84.151 0-152.34 59.178-152.34 132.334 0 73.141 68.189 132.328 152.34 132.328 84.148 0 152.337-59.182 152.337-132.328 0-73.15-68.19-132.334-152.337-132.334zM338.53 752.763c-29.454 0-53.39-23.755-53.39-52.987 0-29.228 23.941-52.989 53.39-52.989 29.453 0 53.39 23.76 53.39 52.989 0 29.227-23.937 52.987-53.39 52.987z m99.82-95.465c-6.382 11.086-19.296 15.696-28.726 10.219-9.43-5.323-11.75-18.717-5.37-29.803 6.386-11.09 19.297-15.7 28.725-10.224 9.43 5.472 11.755 18.864 5.37 29.808z" fill="#000000"></path></svg>', enabled: true }
    ];

    const DEFAULT_CONFIG = {
        height: 56, fontSize: 15, gap: 20, theme: 'auto', alwaysPin: false,
        showSelectionPreview: true, popupTrigger: 'auto',
        engines: DEFAULT_ENGINES
    };

    let userConfig = GM_getValue('gm_search_config', DEFAULT_CONFIG);
    if (!userConfig.engines || userConfig.engines.length === 0) userConfig.engines = DEFAULT_ENGINES;

    userConfig.engines.forEach(eng => {
        const defEng = DEFAULT_ENGINES.find(d => d.id === eng.id);
        if (defEng) eng.icon = defEng.icon;
    });
    userConfig = { ...DEFAULT_CONFIG, ...userConfig };

    // =====================================================================
    // 2. 纯净 DOM 构建函数
    // =====================================================================
    function el(tag, props, children) {
        const e = document.createElement(tag);
        if (props) {
            for (let k in props) {
                if (k === 'className') e.className = props[k];
                else if (k === 'dataset') { for (let d in props[k]) e.dataset[d] = props[k][d]; }
                else if (k === 'style') { for (let s in props[k]) e.style[s] = props[k][s]; }
                else e[k] = props[k];
            }
        }
        if (children) {
            for (let i = 0; i < children.length; i++) {
                const c = children[i];
                if (typeof c === 'string' || typeof c === 'number') e.appendChild(document.createTextNode(String(c)));
                else if (c instanceof Node) e.appendChild(c);
            }
        }
        return e;
    }

    // =====================================================================
    // 3. 动态场景嗅探 & 关键词提取
    // =====================================================================
    function checkIsSearchPage() {
        const host = window.location.hostname, path = window.location.pathname;
        if (host.includes('baidu.com') && path.includes('/s')) return true;
        if (host.includes('google.com') && path.includes('/search')) return true;
        if (host.includes('bing.com') && path.includes('/search')) return true;
        if (host.includes('search.bilibili.com')) return true;
        if (host.includes('youtube.com') && path.includes('/results')) return true;
        if (host.includes('xiaohongshu.com') && path.includes('/search_result')) return true;
        if (host.includes('douyin.com') && path.includes('/search')) return true;
        if (host.includes('weibo.com') && path.includes('/weibo')) return true;
        for (let eng of userConfig.engines) {
            if (eng.enabled && host.includes(eng.domain) && window.location.search) {
                try {
                    const queryParams = new URLSearchParams(new URL(eng.url).search);
                    for (let [key, val] of queryParams.entries()) {
                        if (val.includes('%s') && new URLSearchParams(window.location.search).has(key)) return true;
                    }
                } catch(e) {}
            }
        }
        return false;
    }
    let isEngineSearchPage = checkIsSearchPage();

    function getOriginalKeyword() {
        const url = new URL(window.location.href), host = url.hostname;
        let kw = '';
        for (let eng of userConfig.engines) {
            if (host.includes(eng.domain)) {
                try {
                    const queryParams = new URLSearchParams(new URL(eng.url).search);
                    for (let [key, val] of queryParams.entries()) {
                        if (val.includes('%s')) { kw = url.searchParams.get(key); if (kw) break; }
                    }
                } catch(e) {}
            }
            if (kw) break;
        }
        if (!kw && host.includes('douyin.com')) {
            const pathParts = url.pathname.split('/');
            if (pathParts[1] === 'search' && pathParts[2]) kw = decodeURIComponent(pathParts[2]);
        }
        if (!kw) {
            const inputs = document.querySelectorAll('input[type="text"], input[type="search"]');
            for (let input of inputs) { if (input.value && input.value.trim() !== '') { kw = input.value.trim(); break; } }
        }
        return kw ? kw.trim() : '';
    }

    // =====================================================================
    // 4. 智能主题感知系统
    // =====================================================================
    function getPageLuminance() {
        const getBg = (elem) => {
            let bg = window.getComputedStyle(elem).backgroundColor;
            return (bg === 'rgba(0, 0, 0, 0)' || bg === 'transparent') ? null : bg;
        };
        let bg = getBg(document.body) || getBg(document.documentElement);
        if (!bg) return 'light';
        let match = bg.match(/\d+/g);
        if (match && match.length >= 3) {
            let r = parseInt(match[0]), g = parseInt(match[1]), b = parseInt(match[2]);
            return ((r * 299 + g * 587 + b * 114) / 1000) < 128 ? 'dark' : 'light';
        }
        return 'light';
    }

    function applySmartTheme() {
        let theme = userConfig.theme;
        if (theme === 'auto') theme = getPageLuminance();
        document.documentElement.setAttribute('data-gm-theme', theme);
    }

    // =====================================================================
    // 5. CSS 隔离与各大站基础适配
    // =====================================================================
    const SITE_RULES = {
        'baidu.com': `#head, #s_tab { top: var(--gm-offset) !important; transition: top 0.3s ease !important; }`,
        'google.com': `html.gm-search-page.gm-scrolled #searchform, html.gm-search-page.gm-scrolled .sfbg, html.gm-search-page.gm-scrolled #hdtb { margin-top: var(--gm-offset) !important; transition: margin-top 0.3s ease !important; }`,
        'bing.com': `#b_header { position: sticky !important; top: var(--gm-offset) !important; z-index: 10000 !important; transition: top 0.3s ease, padding 0.3s ease !important; background-color: var(--gm-bg) !important; } html.gm-scrolled #b_header nav, html.gm-scrolled #b_header .b_scopebar, html.gm-scrolled #b_header #b_header_nav { display: none !important; } html.gm-scrolled #b_header { padding-top: 12px !important; padding-bottom: 12px !important; height: auto !important; min-height: 0 !important; }`,
        'weibo.com': `
            html.gm-search-page #searchapps, html.gm-search-page [class*="Nav_wrap_"], html.gm-search-page [class*="Nav_panel_"], html.gm-search-page #weibo_top_public { top: var(--gm-offset) !important; transition: top 0.3s ease !important; }
            html.gm-search-page #searchapps { position: sticky !important; z-index: 9999 !important; }
        `,
        'xiaohongshu.com': `
            html.gm-search-page #global > .header-container { top: var(--gm-offset) !important; transition: top 0.3s ease !important; z-index: 9999 !important; }
            html.gm-search-page .side-bar { top: calc(var(--gm-offset) + 72px) !important; transition: top 0.3s ease !important; }
            html.gm-search-page .main-container { padding-top: var(--gm-offset) !important; transition: padding-top 0.3s ease !important; }
            html.gm-search-page .reds-sticky-box, html.gm-search-page .tag-search-page-sticky, html.gm-search-page .search-layout__middle { display: none !important; }
        `,
        'youtube.com': `
            html.gm-search-page #masthead-container { top: var(--gm-offset) !important; transform: none !important; transition: top 0.3s ease !important; }
            html.gm-search-page ytd-page-manager, html.gm-search-page #page-manager { margin-top: calc(56px + var(--gm-offset)) !important; transform: none !important; transition: margin-top 0.3s ease !important; }
            html.gm-search-page tp-yt-app-drawer { top: calc(56px + var(--gm-offset)) !important; transition: top 0.3s ease !important; }
            html.gm-search-page #chips-wrapper, html.gm-search-page ytd-feed-filter-chip-bar-renderer { top: calc(56px + var(--gm-offset)) !important; transition: top 0.3s ease !important; }
        `,
        'douyin.com': `
            html.gm-search-page #douyin-header { top: var(--gm-offset) !important; transition: top 0.3s ease !important; z-index: 9999 !important; }
            html.gm-search-page a[href="//www.douyin.com/"] { transform: translateY(var(--gm-offset)) !important; transition: transform 0.3s ease !important; z-index: 10000 !important; display: inline-block; }
            html.gm-search-page #search-toolbar-container { position: sticky !important; top: calc(56px + var(--gm-offset)) !important; transition: top 0.3s ease !important; z-index: 9998 !important; }
            html.gm-search-page .YDoaql1z { display: none !important; }
            html.gm-search-page .hDLEI3Iz { margin-top: 0 !important; padding-top: 0 !important; }
        `,
        'bilibili.com': `.bili-header__bar, #biliMainHeader { position: fixed !important; top: var(--gm-offset) !important; left: 0 !important; width: 100% !important; z-index: 10000 !important; background-color: var(--gm-bg) !important; box-shadow: 0 2px 4px rgba(0,0,0,0.08) !important; transition: top 0.3s ease !important; transform: none !important; animation: none !important; } .bili-header { min-height: 64px !important; } .search-sticky-header, [class*="sticky-header"] { display: none !important; } .bili-header__bar .center-search-container, #biliMainHeader .center-search-container { display: flex !important; opacity: 1 !important; visibility: visible !important; pointer-events: auto !important; flex: 1 1 auto !important; width: 100% !important; max-width: 500px !important; margin: 0 auto !important; } .bili-header__bar .center-search__bar, #biliMainHeader .center-search__bar { width: 100% !important; max-width: 500px !important; margin: 0 auto !important; } .center-search-container form, .center-search-container #nav-searchform { display: flex !important; flex: 1 !important; width: 100% !important; } .bili-header__bar .right-entry-text, #biliMainHeader .right-entry-text { display: inline-block !important; } .bili-header__bar .left-entry ~ div:not(.center-search-container):not(.right-entry), #biliMainHeader .left-entry ~ div:not(.center-search-container):not(.right-entry) { display: none !important; } .center-search-container .nav-search-keyword { display: none !important; } .center-search-container input::-webkit-input-placeholder, .center-search-container input::-moz-placeholder, .center-search-container input:-ms-input-placeholder, .center-search-container input::placeholder { color: transparent !important; text-shadow: none !important; } .center-search-container input { color: var(--gm-text) !important; opacity: 1 !important; -webkit-text-fill-color: var(--gm-text) !important; } .search-header .search-input { display: none !important; } .search-header { background: transparent !important; min-height: 0 !important; height: auto !important; padding-top: 20px !important; padding-bottom: 5px !important; } .bili-header__banner, .download-entry, .download-client-trigger, .bili-header .left-entry .v-popover-wrap:has(.download-client-trigger), .bili-header a[href*="//app.bilibili.com"] { display: none !important; }`
    };

    let isBlockVisible = isEngineSearchPage;
    let isSelectionMode = false;
    let lastScrollTop = 0;
    const currentDomain = window.location.hostname;

    let styleEl = null;
    let cssText = `
        :root {
            --gm-config-height: ${userConfig.height}px;
            --gm-config-fontsize: ${userConfig.fontSize}px;
            --gm-config-gap: ${userConfig.gap}px;
            --gm-offset: 0px;

            --gm-bg: #ffffff; --gm-text: #222222; --gm-hover: #f5f5f5; --gm-active: #e8e8e8; --gm-border: #f0f0f0; --gm-shadow: 0 1px 3px rgba(0,0,0,0.04);
            --gm-pill-bg: #e6f4ff; --gm-pill-text: #1677ff; --gm-pill-border: #91caff;
        }
        html[data-gm-theme="dark"], @media (prefers-color-scheme: dark) { html[data-gm-theme="auto"] {
            --gm-bg: #1e1e20; --gm-text: #e0e0e0; --gm-hover: #2b2b2d; --gm-active: #3a3a3c; --gm-border: #2c2c2e; --gm-shadow: 0 1px 3px rgba(0,0,0,0.5);
            --gm-pill-bg: rgba(22, 119, 255, 0.15); --gm-pill-text: #4096ff; --gm-pill-border: rgba(22, 119, 255, 0.3);
        }}

        html.gm-search-page { margin-top: var(--gm-offset) !important; box-sizing: border-box !important; transition: margin-top 0.3s ease !important; }

        #custom-fixed-top-block {
            position: fixed; top: -100px; left: 0; width: 100%; height: var(--gm-config-height);
            background-color: var(--gm-bg); border-bottom: 1px solid var(--gm-border);
            display: flex; align-items: center; justify-content: space-between; padding: 0 20px;
            z-index: 2147483647 !important; pointer-events: auto;
            transition: top 0.3s cubic-bezier(0.2, 0.8, 0.2, 1), background-color 0.3s, box-shadow 0.3s, border 0.3s;
            box-shadow: var(--gm-shadow); box-sizing: border-box; user-select: none;
        }

        .gm-left-zone, .gm-right-zone { flex: 1; display: flex; align-items: center; min-width: 0; }
        .gm-left-zone { justify-content: flex-start; }
        .gm-engines-wrapper { flex: 0 0 auto; display: flex; align-items: center; gap: var(--gm-config-gap); }

        #gm-selection-preview {
            display: flex; align-items: center; background: transparent; color: rgb(22, 119, 255); border: none;
            padding: 0; font-size: 13px; max-width: 100%; box-sizing: border-box;
            white-space: nowrap; overflow: hidden; text-overflow: ellipsis; opacity: 0; transform: translateX(-10px); pointer-events: none; transition: opacity 0.3s ease, transform 0.3s ease;
        }

        #custom-fixed-top-block.gm-selection-mode #gm-selection-preview { opacity: 1; transform: translateX(0); }

        .gm-engine-btn {
            display: flex; align-items: center; gap: 6px; padding: calc(var(--gm-config-height) * 0.1) 14px; border-radius: 6px;
            color: var(--gm-text); font-size: var(--gm-config-fontsize); font-weight: 500; cursor: pointer; transition: background 0.2s, transform 0.1s;
        }
        .gm-engine-btn:hover { background: var(--gm-hover); }
        #custom-fixed-top-block:not(.gm-selection-mode) .gm-engine-btn.gm-active { font-weight: bold; }
        .gm-engine-btn img { width: 1.1em !important; height: 1.1em !important; border-radius: 4px !important; object-fit: contain !important; display: inline-block !important; background-color: transparent !important; pointer-events: none; }

        /* GUI 绝对防污染隔离 */
        #gm-settings-panel { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 340px; background: var(--gm-bg); border-radius: 12px; box-shadow: 0 10px 40px rgba(0,0,0,0.2); z-index: 2147483648; display: none; flex-direction: column; border: 1px solid var(--gm-border); color: var(--gm-text); overflow: hidden; text-align: left !important; }
        #gm-settings-panel, #gm-settings-panel * { box-sizing: border-box !important; font-family: system-ui, -apple-system, sans-serif !important; letter-spacing: normal !important; word-spacing: normal !important; line-height: 1.5 !important; text-transform: none !important; text-shadow: none !important; white-space: normal !important; word-break: normal !important; }
        #gm-settings-panel .gm-settings-header { padding: 14px 18px; border-bottom: 1px solid var(--gm-border); display: flex; justify-content: space-between; align-items: center; cursor: grab; background: var(--gm-hover); }
        #gm-settings-panel .gm-settings-header:active { cursor: grabbing; }
        #gm-settings-panel .gm-settings-header span:first-child { font-size: 16px !important; font-weight: bold !important; color: var(--gm-text) !important; }
        #gm-settings-panel .gm-settings-close { cursor: pointer; font-size: 20px !important; font-weight: normal !important; color: #999 !important; }
        #gm-settings-panel .gm-settings-close:hover { color: #ff4d4f !important; }
        #gm-settings-panel .gm-tabs { display: flex; border-bottom: 1px solid var(--gm-border); }
        #gm-settings-panel .gm-tab { flex: 1; text-align: center !important; padding: 12px 0; cursor: pointer; font-size: 14px !important; color: var(--gm-text); opacity: 0.6; transition: 0.2s; font-weight: normal !important; }
        #gm-settings-panel .gm-tab.active { opacity: 1; font-weight: bold !important; color: #1677ff !important; border-bottom: 2px solid #1677ff !important; }
        #gm-settings-panel .gm-tab-content { display: none; flex-direction: column; gap: 16px; padding: 18px; max-height: 400px; overflow-y: auto; }
        #gm-settings-panel .gm-tab-content.active { display: flex; }
        #gm-settings-panel .gm-setting-item { display: flex; flex-direction: column; gap: 8px; }
        #gm-settings-panel .gm-setting-item-row { display: flex; flex-direction: row; justify-content: space-between; align-items: center; }
        #gm-settings-panel .gm-setting-label { display: flex; justify-content: space-between; align-items: center; width: 100%; }
        #gm-settings-panel .gm-setting-label span { font-size: 14px !important; color: var(--gm-text) !important; font-weight: normal !important;}
        #gm-settings-panel .gm-setting-value { color: #1677ff !important; font-weight: bold !important; font-size: 14px !important; }
        #gm-settings-panel input[type=range] { -webkit-appearance: none; width: 100%; height: 6px !important; background: #e5e5e5 !important; border-radius: 3px !important; outline: none; margin: 0 !important; }
        #gm-settings-panel input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 16px !important; height: 16px !important; border-radius: 50% !important; background: #1677ff !important; cursor: pointer; border: 2px solid #fff !important; box-shadow: 0 1px 3px rgba(0,0,0,0.3) !important; }
        #gm-settings-panel select, #gm-settings-panel input[type=text], #gm-settings-panel textarea { width: 100%; padding: 8px !important; border-radius: 6px !important; border: 1px solid var(--gm-border) !important; background: var(--gm-bg) !important; color: var(--gm-text) !important; font-size: 13px !important; outline: none; box-sizing: border-box; }
        #gm-settings-panel input[type=text]:focus, #gm-settings-panel textarea:focus { border-color: #1677ff !important; }
        #gm-settings-panel textarea { resize: vertical; min-height: 60px; }
        #gm-settings-panel .gm-switch { position: relative; display: inline-block; width: 40px !important; height: 22px !important; flex-shrink: 0; }
        #gm-settings-panel .gm-switch input { opacity: 0; width: 0; height: 0; margin: 0; }
        #gm-settings-panel .gm-slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; transition: .3s; border-radius: 22px !important; }
        #gm-settings-panel .gm-slider:before { position: absolute; content: ""; height: 18px !important; width: 18px !important; left: 2px !important; bottom: 2px !important; background-color: white; transition: .3s; border-radius: 50% !important; box-shadow: 0 1px 2px rgba(0,0,0,0.2) !important; }
        #gm-settings-panel input:checked + .gm-slider { background-color: #1677ff !important; }
        #gm-settings-panel input:checked + .gm-slider:before { transform: translateX(18px) !important; }
        #gm-settings-panel .gm-engine-list-item { display: flex; align-items: center; justify-content: space-between; padding: 8px 10px; background: var(--gm-hover); border-radius: 8px; margin-bottom: 8px; }
        #gm-settings-panel .gm-engine-list-item.disabled { opacity: 0.5; filter: grayscale(100%); }
        #gm-settings-panel .gm-engine-info { display: flex; align-items: center; gap: 8px; flex: 1; overflow: hidden; }
        #gm-settings-panel .gm-engine-info img { width: 18px !important; height: 18px !important; border-radius: 4px !important; flex-shrink: 0; }
        #gm-settings-panel .gm-engine-info span { font-size: 14px !important; font-weight: 500 !important; white-space: nowrap !important; overflow: hidden !important; text-overflow: ellipsis !important; }
        #gm-settings-panel .gm-engine-actions { display: flex; gap: 4px; }
        #gm-settings-panel .gm-action-btn { padding: 4px; cursor: pointer; font-size: 14px !important; opacity: 0.7; transition: 0.2s; border-radius: 4px; user-select: none; }
        #gm-settings-panel .gm-action-btn:hover { opacity: 1; background: rgba(0,0,0,0.05); }
        #gm-settings-panel .gm-primary-btn { padding: 10px; background: #1677ff; color: #fff !important; border: none; border-radius: 8px; cursor: pointer; font-weight: bold !important; font-size: 14px !important; text-align: center; }
        #gm-settings-panel .gm-primary-btn:hover { background: #4096ff; }
        #gm-settings-panel .gm-secondary-btn { padding: 10px; background: var(--gm-hover); color: var(--gm-text) !important; border: none; border-radius: 8px; cursor: pointer; font-size: 14px !important; text-align: center; }
    `;

    function injectDynamicCSS() {
        let dynamicRules = '';
        if (isEngineSearchPage) {
            document.documentElement.classList.add('gm-search-page');
            document.documentElement.style.setProperty('--gm-offset', userConfig.height + 'px');
            for (const [domain, ruleCSS] of Object.entries(SITE_RULES)) {
                if (currentDomain.includes(domain)) { dynamicRules += `\n${ruleCSS}`; break; }
            }
        } else {
            document.documentElement.classList.remove('gm-search-page');
            document.documentElement.style.setProperty('--gm-offset', '0px');
        }
        if(styleEl) styleEl.textContent = cssText + dynamicRules;
    }

    // =====================================================================
    // 🚀 安全路由系统:精准特征cloudflare识别 (融合底层网络指纹,绝对防卡死)
    // =====================================================================
    let __gm_is_shield_locked = false;

    function isShieldPage() {
        // 1. 白名单免疫
        if (isEngineSearchPage) return false;
        if (__gm_is_shield_locked) return true;

        // 2. 高危标题嗅探
        const t = document.title || '';
        if (/^(Just a moment|Checking your browser|Attention Required|请稍候|安全验证)/i.test(t.trim())) {
            __gm_is_shield_locked = true;
            return true;
        }

        // 🌟 3. 最致命的网络特征底层嗅探 (核心修复)
        // 真正的 CF 拦截页必定会加载 challenge-platform 脚本。
        // 用这个路径判断,既能 100% 抓出伪装的 CF 盾,又绝对不会误杀带验证码的普通网页!
        if (document.querySelector('script[src*="/cdn-cgi/challenge-platform/"]')) {
            __gm_is_shield_locked = true;
            return true;
        }

        // 4. 专属防御容器 DOM 特征
        const shieldSelectors = '#challenge-running, #cf-wrapper, .cf-browser-verification, #challenge-stage';
        if (document.querySelector(shieldSelectors)) {
            __gm_is_shield_locked = true;
            return true;
        }

        // 5. 极简 DOM + 底部水印兜底
        if (document.body && document.querySelectorAll('*').length < 150) {
            const text = document.body.innerText || '';
            if (text.includes('Ray ID:') && text.includes('Cloudflare')) {
                __gm_is_shield_locked = true;
                return true;
            }
        }

        return false;
    }

    function bootScript() {
        if (!styleEl && (document.head || document.documentElement)) {
            styleEl = document.createElement('style');
            styleEl.id = 'gm-search-style';
            (document.head || document.documentElement).appendChild(styleEl);
            injectDynamicCSS();
        }
    }

    if (isEngineSearchPage) {
        bootScript();
    } else {
        document.addEventListener('DOMContentLoaded', () => {
            if (isShieldPage()) return;
            bootScript();
        });
    }

    function updateBarVisibility() {
        const topBlock = document.getElementById('custom-fixed-top-block');
        if (!topBlock) return;

        if (isSelectionMode) {
            topBlock.style.top = '0px';
            topBlock.classList.add('gm-selection-mode');
            if (isEngineSearchPage) document.documentElement.style.setProperty('--gm-offset', userConfig.height + 'px');
            return;
        } else {
            topBlock.style.top = `-${userConfig.height + 20}px`;
            topBlock.classList.remove('gm-selection-mode');
        }

        if (!isEngineSearchPage) return;

        if (userConfig.alwaysPin) {
            isBlockVisible = true;
            topBlock.style.top = '0px';
            document.documentElement.style.setProperty('--gm-offset', userConfig.height + 'px');
            return;
        }

        if (isBlockVisible) {
            topBlock.style.top = '0px';
            document.documentElement.style.setProperty('--gm-offset', userConfig.height + 'px');
        } else {
            topBlock.style.top = `-${userConfig.height + 20}px`;
            document.documentElement.style.setProperty('--gm-offset', '0px');
        }
    }

    function renderTopBarEngines() {
        const wrapper = document.querySelector('.gm-engines-wrapper');
        if (!wrapper) return;
        wrapper.textContent = '';

        const activeEngines = userConfig.engines.filter(e => e.enabled !== false);
        activeEngines.forEach(engine => {
            let finalIcon = engine.icon ? engine.icon.trim() : '';
            if (finalIcon.startsWith('<svg')) {
                finalIcon = `data:image/svg+xml,${encodeURIComponent(finalIcon)}`;
            } else if (finalIcon.length > 100 && !finalIcon.startsWith('http') && !finalIcon.startsWith('data:')) {
                finalIcon = `data:image/svg+xml;base64,${finalIcon}`;
            }

            const img = el('img', { src: finalIcon });
            img.onerror = function() { this.src = PLACEHOLDER_BASE64; };
            const span = el('span', {}, [engine.name]);

            const isActive = isEngineSearchPage && currentDomain.includes(engine.domain);
            const btn = el('div', { className: 'gm-engine-btn' + (isActive ? ' gm-active' : '') }, [img, span]);

            btn.addEventListener('mousedown', (e) => e.preventDefault());
            btn.addEventListener('click', () => {
                const selText = window.getSelection().toString().trim();
                const kw = selText || getOriginalKeyword();

                if (kw) {
                    const targetUrl = engine.url.replace('%s', encodeURIComponent(kw));
                    if (selText) {
                        window.open(targetUrl, '_blank');
                        window.getSelection().removeAllRanges();
                    } else {
                        window.location.href = targetUrl;
                    }
                } else {
                    window.location.href = `https://www.${engine.domain}`;
                }
            });
            wrapper.appendChild(btn);
        });
    }

    // =====================================================================
    // 6. GUI 设置面板构建与逻辑 (安全延迟挂载)
    // =====================================================================
    document.addEventListener('DOMContentLoaded', () => {
        if (typeof isShieldPage === 'function' && isShieldPage()) return;

        applySmartTheme();

        const selectionPreview = el('div', { id: 'gm-selection-preview' });
        const leftZone = el('div', { className: 'gm-left-zone' }, [selectionPreview]);
        const enginesWrapper = el('div', { className: 'gm-engines-wrapper' });
        const rightZone = el('div', { className: 'gm-right-zone' });
        const topBlock = el('div', { id: 'custom-fixed-top-block' }, [leftZone, enginesWrapper, rightZone]);
        document.documentElement.appendChild(topBlock);

        renderTopBarEngines();
        updateBarVisibility();

        // =====================================================================
        // 🚀 核心逻辑升级:保持选区高亮,精准判断点击范围
        // =====================================================================
        let selectionTimeout;
        let pendingSelectionText = '';
        let lastSelectionTime = 0;
        let savedRange = null; // 保存选区对象,用于获取高亮文本的精确物理坐标

        const triggerSelectionPopup = (text) => {
            if (!text) {
                isSelectionMode = false;
                updateBarVisibility();
                return;
            }
            if (userConfig.popupTrigger !== 'none') {
                isSelectionMode = true;
                if (userConfig.showSelectionPreview) {
                    selectionPreview.textContent = `🔍 搜索: "${text}"`;
                    selectionPreview.style.display = 'flex';
                } else {
                    selectionPreview.style.display = 'none';
                }
                updateBarVisibility();
            }
        };

        // 判断鼠标点击的坐标是否在“蓝色的高亮矩形”范围内
        const isClickInRects = (e, rects) => {
            for (let i = 0; i < rects.length; i++) {
                const r = rects[i];
                // 加 2px 的容错边缘,提升点击手感
                if (e.clientX >= r.left - 2 && e.clientX <= r.right + 2 &&
                    e.clientY >= r.top - 2 && e.clientY <= r.bottom + 2) {
                    return true;
                }
            }
            return false;
        };

        document.addEventListener('selectionchange', () => {
            clearTimeout(selectionTimeout);
            selectionTimeout = setTimeout(() => {
                const sel = window.getSelection();
                const text = sel.toString().trim();

                pendingSelectionText = text;
                lastSelectionTime = Date.now();

                if (!text) {
                    savedRange = null;
                    triggerSelectionPopup('');
                    return;
                }

                if (sel.rangeCount > 0) {
                    savedRange = sel.getRangeAt(0).cloneRange(); // 备份选区
                }

                if (userConfig.popupTrigger === 'auto') {
                    triggerSelectionPopup(text);
                }
            }, 80);
        });

        // 🌟 魔法步骤 1:拦截 mousedown,防止浏览器清除蓝色高亮
        document.addEventListener('mousedown', (e) => {
            if (e.button !== 0 || userConfig.popupTrigger !== 'click' || !savedRange) return;
            if (e.target.closest('#custom-fixed-top-block') || e.target.closest('#gm-settings-panel')) return;

            // 如果鼠标正好点在蓝色高亮区域内
            if (isClickInRects(e, savedRange.getClientRects())) {
                e.preventDefault(); // 强行阻止浏览器清除选中状态!
            }
        });

        // 🌟 魔法步骤 2:在鼠标抬起时,执行弹窗
        document.addEventListener('mouseup', (e) => {
            if (e.button !== 0 || userConfig.popupTrigger !== 'click' || !pendingSelectionText || !savedRange) return;
            if (e.target.closest('#custom-fixed-top-block') || e.target.closest('#gm-settings-panel')) return;

            if (Date.now() - lastSelectionTime > 150) {
                // 判断:只有点在文字上了才触发面板,点在其他空白处则立刻收起面板
                if (isClickInRects(e, savedRange.getClientRects())) {
                    triggerSelectionPopup(pendingSelectionText);
                } else {
                    triggerSelectionPopup('');
                }
            }
        });
        document.addEventListener('mouseup', (e) => {
            if (e.button !== 0) return;
            if (userConfig.popupTrigger !== 'click' || !pendingSelectionText) return;

            if (e.target.closest('#custom-fixed-top-block') || e.target.closest('#gm-settings-panel')) return;

            if (Date.now() - lastSelectionTime > 150) {
                // 🌟 触发面板前,先开启 300 毫秒的“免疫护盾”
                // 防止因为本次点击导致浏览器取消文字选中,从而触发 selectionchange 清空面板
                ignoreClearEventUntil = Date.now() + 300;
                triggerSelectionPopup(pendingSelectionText);
            }
        });

        let lastUrl = location.href;
        setInterval(() => {
            if (styleEl && typeof styleEl !== 'undefined' && !document.contains(styleEl)) {
                (document.head || document.documentElement).appendChild(styleEl);
            }

            if (typeof topBlock !== 'undefined' && !document.getElementById('custom-fixed-top-block')) {
                document.documentElement.appendChild(topBlock);
            }
            if (typeof panel !== 'undefined' && !document.getElementById('gm-settings-panel')) {
                document.documentElement.appendChild(panel);
            }

            if (isEngineSearchPage && !document.documentElement.classList.contains('gm-search-page')) {
                document.documentElement.classList.add('gm-search-page');
                document.documentElement.style.setProperty('--gm-offset', userConfig.height + 'px');
            }

            if (location.href !== lastUrl) {
                lastUrl = location.href;
                const newIsSearchPage = checkIsSearchPage();
                if (newIsSearchPage !== isEngineSearchPage) {
                    isEngineSearchPage = newIsSearchPage;
                    injectDynamicCSS();
                }
                updateBarVisibility();
                renderTopBarEngines();
            }
        }, 500);

        window.addEventListener('scroll', () => {
            if (!isEngineSearchPage) return;
            let currentScroll = window.pageYOffset || document.documentElement.scrollTop;
            if (currentScroll > 10) document.documentElement.classList.add('gm-scrolled');
            else document.documentElement.classList.remove('gm-scrolled');

            if (userConfig.alwaysPin || isSelectionMode) { lastScrollTop = currentScroll <= 0 ? 0 : currentScroll; return; }
            if (currentScroll > lastScrollTop && currentScroll > 50) { isBlockVisible = false; }
            else if (currentScroll < lastScrollTop) { isBlockVisible = true; }
            updateBarVisibility();
            lastScrollTop = currentScroll <= 0 ? 0 : currentScroll;
        }, { passive: true });

        const themeObserver = new MutationObserver(() => { if (userConfig.theme === 'auto') applySmartTheme(); });
        themeObserver.observe(document.documentElement, { attributes: true, attributeFilter: ['style', 'class', 'theme'] });
        themeObserver.observe(document.body, { attributes: true, attributeFilter: ['style', 'class', 'theme'] });

        const panel = el('div', { id: 'gm-settings-panel' });
        const closeBtn = el('span', { className: 'gm-settings-close' }, ['×']);
        closeBtn.onclick = () => { panel.style.display = 'none'; };
        const header = el('div', { className: 'gm-settings-header' }, [ el('span', {}, ['⚙️ 搜索枢纽设置']), closeBtn ]);

        const tabBasic = el('div', { className: 'gm-tab active', dataset: { target: 'tab-basic' } }, ['基础设置']);
        const tabEngines = el('div', { className: 'gm-tab', dataset: { target: 'tab-engines' } }, ['引擎管理']);
        const tabs = el('div', { className: 'gm-tabs' }, [tabBasic, tabEngines]);

        const cbPin = el('input', { type: 'checkbox', id: 'cb-always-pin', checked: userConfig.alwaysPin });
        cbPin.onchange = (e) => { updateBasicConfig('alwaysPin', e.target.checked); };
        const switchPin = el('label', { className: 'gm-switch' }, [cbPin, el('span', { className: 'gm-slider' })]);
        const itemPin = el('div', { className: 'gm-setting-item gm-setting-item-row' }, [
            el('div', { className: 'gm-setting-label' }, [el('span', { style: { fontWeight: 'bold' } }, ['📌 始终钉在顶部 (仅搜索页)'])]), switchPin
        ]);

        const cbPreview = el('input', { type: 'checkbox', id: 'cb-show-preview', checked: userConfig.showSelectionPreview });
        cbPreview.onchange = (e) => { updateBasicConfig('showSelectionPreview', e.target.checked); };
        const switchPreview = el('label', { className: 'gm-switch' }, [cbPreview, el('span', { className: 'gm-slider' })]);
        const itemPreview = el('div', { className: 'gm-setting-item gm-setting-item-row' }, [
            el('div', { className: 'gm-setting-label' }, [el('span', {}, ['💬 显示左上角选中文本提示'])]), switchPreview
        ]);

        const selectTrigger = el('select', { id: 'select-trigger' }, [
            el('option', { value: 'auto', selected: userConfig.popupTrigger === 'auto' }, ['默认:选中文字后自动弹出']),
            el('option', { value: 'click', selected: userConfig.popupTrigger === 'click' }, ['单击:选中文字后,再次左键单击才弹出']),
            el('option', { value: 'none', selected: userConfig.popupTrigger === 'none' }, ['关闭:禁止选词弹出'])
        ]);
        selectTrigger.onchange = (e) => { updateBasicConfig('popupTrigger', e.target.value); };
        const itemTrigger = el('div', { className: 'gm-setting-item' }, [ el('div', { className: 'gm-setting-label' }, [el('span', {}, ['🚀 划词面板弹出时机'])]), selectTrigger ]);

        const createSlider = (id, label, min, max, val, key) => {
            const range = el('input', { type: 'range', id: id, min: min, max: max, value: val });
            const valSpan = el('span', { className: 'gm-setting-value', id: `val-${key}` }, [`${val}px`]);
            range.oninput = (e) => { valSpan.textContent = `${e.target.value}px`; updateBasicConfig(key, e.target.value); };
            return el('div', { className: 'gm-setting-item' }, [ el('div', { className: 'gm-setting-label' }, [el('span', {}, [label]), valSpan]), range ]);
        };

        const itemHeight = createSlider('range-height', '方块高度', '30', '80', userConfig.height, 'height');
        const itemFont = createSlider('range-font', '字体大小', '12', '24', userConfig.fontSize, 'fontSize');
        const itemGap = createSlider('range-gap', '按钮间距', '0', '40', userConfig.gap, 'gap');

        const selectTheme = el('select', { id: 'select-theme' }, [
            el('option', { value: 'light', selected: userConfig.theme === 'light' }, ['浅色模式 (Light)']),
            el('option', { value: 'dark', selected: userConfig.theme === 'dark' }, ['深色模式 (Dark)']),
            el('option', { value: 'auto', selected: userConfig.theme === 'auto' }, ['跟随网页背景亮度 (Auto)'])
        ]);
        selectTheme.onchange = (e) => { updateBasicConfig('theme', e.target.value); };
        const itemTheme = el('div', { className: 'gm-setting-item' }, [ el('div', { className: 'gm-setting-label' }, [el('span', {}, ['智能主题配色'])]), selectTheme ]);

        const contentBasic = el('div', { id: 'tab-basic', className: 'gm-tab-content active' }, [itemPin, itemTrigger, itemPreview, itemHeight, itemFont, itemGap, itemTheme]);

        const listContainer = el('div', { id: 'gm-engine-list-container' });
        const btnAddEngine = el('div', { className: 'gm-primary-btn', id: 'btn-add-engine' }, ['+ 添加自定义引擎']);
        btnAddEngine.onclick = () => {
            document.getElementById('edit-idx').value = '-1'; document.getElementById('edit-name').value = '';
            document.getElementById('edit-url').value = ''; document.getElementById('edit-icon').value = '';
            switchTab('tab-edit');
        };
        const contentEngines = el('div', { id: 'tab-engines', className: 'gm-tab-content', style: { paddingTop: '5px' } }, [listContainer, btnAddEngine]);

        const editIdx = el('input', { type: 'hidden', id: 'edit-idx' });
        const editName = el('input', { type: 'text', id: 'edit-name', placeholder: '如: 豆瓣' });
        const editUrl = el('input', { type: 'text', id: 'edit-url', placeholder: '如: https://search.douban.com/?q=%s' });
        const editIcon = el('textarea', { id: 'edit-icon', placeholder: '输入图片网址,或者直接粘贴超长的 Base64 图片代码' });

        const btnSaveEngine = el('div', { className: 'gm-primary-btn', style: { flex: '1' } }, ['保存']);
        btnSaveEngine.onclick = () => {
            const idx = parseInt(editIdx.value), name = editName.value.trim(), url = editUrl.value.trim(); let icon = editIcon.value.trim();
            if(!name || !url.includes('%s')) return alert('请正确填写名称和包含 %s 的 URL!');
            let domain = ''; try { const urlObj = new URL(url.replace('%s', 'test')); domain = urlObj.hostname.replace('www.', ''); if (!icon) icon = `https://s2.googleusercontent.com/s2/favicons?domain=${domain}&sz=64`; } catch(e) { return alert('URL 格式不合法!'); }
            const newEng = { id: 'custom_' + Date.now(), name, domain, url, icon, enabled: true };
            if (idx === -1) userConfig.engines.push(newEng); else { newEng.id = userConfig.engines[idx].id; newEng.enabled = userConfig.engines[idx].enabled; userConfig.engines[idx] = newEng; }
            saveAndRender(); switchTab('tab-engines');
        };

        const btnCancelEngine = el('div', { className: 'gm-secondary-btn', style: { flex: '1' } }, ['取消']);
        btnCancelEngine.onclick = () => switchTab('tab-engines');
        const actionRow = el('div', { style: { display: 'flex', gap: '10px', marginTop: '10px' } }, [btnSaveEngine, btnCancelEngine]);

        const contentEdit = el('div', { id: 'tab-edit', className: 'gm-tab-content' }, [
            editIdx, el('div', { className: 'gm-setting-item' }, [el('div', { className: 'gm-setting-label' }, [el('span', {}, ['名称'])]), editName]),
            el('div', { className: 'gm-setting-item' }, [el('div', { className: 'gm-setting-label' }, [el('span', {}, ['搜索 URL (用 %s 占位)'])]), editUrl]),
            el('div', { className: 'gm-setting-item' }, [el('div', { className: 'gm-setting-label' }, [el('span', {}, ['图标 (支持 URL 或 Base64)'])]), editIcon]),
            actionRow
        ]);

        panel.appendChild(header); panel.appendChild(tabs); panel.appendChild(contentBasic); panel.appendChild(contentEngines); panel.appendChild(contentEdit);
        document.documentElement.appendChild(panel);

        const saveAndRender = () => { GM_setValue('gm_search_config', userConfig); renderTopBarEngines(); renderSettingsEngineList(); };

        function renderSettingsEngineList() {
            listContainer.textContent = '';
            userConfig.engines.forEach((eng, idx) => {
                let finalIcon = eng.icon ? eng.icon.trim() : '';
                if (finalIcon.startsWith('<svg')) {
                    finalIcon = `data:image/svg+xml,${encodeURIComponent(finalIcon)}`;
                } else if (finalIcon.length > 100 && !finalIcon.startsWith('http') && !finalIcon.startsWith('data:')) {
                    finalIcon = `data:image/svg+xml;base64,${finalIcon}`;
                }

                const img = el('img', { src: finalIcon });
                img.onerror = function() { this.src = PLACEHOLDER_BASE64; };
                const span = el('span', {}, [eng.name]);
                const info = el('div', { className: 'gm-engine-info' }, [img, span]);

                const btnUp = el('span', { className: 'gm-action-btn', title: '上移' }, ['▲']);
                btnUp.onclick = () => { if (idx > 0) { [userConfig.engines[idx-1], userConfig.engines[idx]] = [userConfig.engines[idx], userConfig.engines[idx-1]]; saveAndRender(); } };
                const btnDown = el('span', { className: 'gm-action-btn', title: '下移' }, ['▼']);
                btnDown.onclick = () => { if (idx < userConfig.engines.length - 1) { [userConfig.engines[idx+1], userConfig.engines[idx]] = [userConfig.engines[idx], userConfig.engines[idx+1]]; saveAndRender(); } };
                const btnToggle = el('span', { className: 'gm-action-btn', title: '显隐' }, [eng.enabled ? '👁️' : '🙈']);
                btnToggle.onclick = () => { userConfig.engines[idx].enabled = !eng.enabled; saveAndRender(); };
                const btnEdit = el('span', { className: 'gm-action-btn', title: '编辑' }, ['✏️']);
                btnEdit.onclick = () => {
                    document.getElementById('edit-idx').value = idx; document.getElementById('edit-name').value = eng.name;
                    document.getElementById('edit-url').value = eng.url; document.getElementById('edit-icon').value = eng.icon;
                    switchTab('tab-edit');
                };
                const btnDelete = el('span', { className: 'gm-action-btn', title: '删除', style: { color: '#ff4d4f' } }, ['✖']);
                btnDelete.onclick = () => { if (confirm(`确定删除 ${eng.name} 吗?`)) { userConfig.engines.splice(idx, 1); saveAndRender(); } };

                const actions = el('div', { className: 'gm-engine-actions' }, [btnUp, btnDown, btnToggle, btnEdit, btnDelete]);
                const item = el('div', { className: `gm-engine-list-item ${eng.enabled ? '' : 'disabled'}` }, [info, actions]);
                listContainer.appendChild(item);
            });
        }
        renderSettingsEngineList();

        function switchTab(targetId) {
            tabBasic.classList.remove('active'); tabEngines.classList.remove('active');
            contentBasic.classList.remove('active'); contentEngines.classList.remove('active'); contentEdit.classList.remove('active');
            if (targetId === 'tab-basic') { tabBasic.classList.add('active'); contentBasic.classList.add('active'); }
            else if (targetId === 'tab-engines') { tabEngines.classList.add('active'); contentEngines.classList.add('active'); }
            else if (targetId === 'tab-edit') { contentEdit.classList.add('active'); }
        }
        tabBasic.onclick = () => switchTab('tab-basic'); tabEngines.onclick = () => switchTab('tab-engines');

        GM_registerMenuCommand('⚙️ 搜索引擎顶栏设置', () => { panel.style.top = '50%'; panel.style.left = '50%'; panel.style.transform = 'translate(-50%, -50%)'; panel.style.display = 'flex'; });

        const updateBasicConfig = (key, val) => {
            if (key === 'theme' || key === 'popupTrigger' || key === 'alwaysPin' || key === 'showSelectionPreview') userConfig[key] = val; else userConfig[key] = parseInt(val);
            GM_setValue('gm_search_config', userConfig);
            if (key === 'theme') applySmartTheme(); else if (key !== 'alwaysPin') { document.documentElement.style.setProperty(`--gm-config-${key.toLowerCase()}`, val + 'px'); }
            updateBarVisibility();
        };

        let isDragging = false, startX, startY, initialLeft, initialTop;
        header.onmousedown = (e) => { isDragging = true; const rect = panel.getBoundingClientRect(); panel.style.transform = 'none'; panel.style.left = rect.left + 'px'; panel.style.top = rect.top + 'px'; startX = e.clientX; startY = e.clientY; initialLeft = rect.left; initialTop = rect.top; document.body.style.userSelect = 'none'; };
        window.addEventListener('mousemove', (e) => { if (isDragging) { panel.style.left = (initialLeft + e.clientX - startX) + 'px'; panel.style.top = (initialTop + e.clientY - startY) + 'px'; } });
        window.addEventListener('mouseup', () => { if(isDragging) { isDragging = false; document.body.style.userSelect = ''; }});
    });

    // =====================================================================
    // 7. B站 / 微博 全局劫持 (防止回车新开网页)
    // =====================================================================
    document.addEventListener('DOMContentLoaded', () => {
        if (typeof isShieldPage === 'function' && isShieldPage()) return;

        if (currentDomain.includes('search.bilibili.com')) {
            const urlParams = new URLSearchParams(window.location.search);
            const currentKeyword = urlParams.get('keyword');
            const originalOpen = window.open;
            window.open = function(url, name, specs) { if (typeof url === 'string' && (url.includes('search.bilibili.com') || url.startsWith('//search.bilibili.com'))) { window.location.href = url; return null; } return originalOpen.apply(this, arguments); };
            const observer = new MutationObserver(() => {
                const containers = document.querySelectorAll('.center-search-container');
                if (containers.length > 0) {
                    containers.forEach(container => {
                        const input = container.querySelector('input');
                        if (input) {
                            if (input.hasAttribute('placeholder')) input.removeAttribute('placeholder'); if (input.placeholder) input.placeholder = ''; if (input.hasAttribute('title')) input.removeAttribute('title');
                            if (currentKeyword && !input.dataset.echoed) { input.value = currentKeyword; input.setAttribute('value', currentKeyword); input.dispatchEvent(new Event('input', { bubbles: true })); input.dataset.echoed = 'true'; }
                        }
                        const links = container.querySelectorAll('a[target="_blank"]'); links.forEach(a => { a.target = '_self'; });
                    });
                }
            });
            observer.observe(document.body, { childList: true, subtree: true });
            window.addEventListener('keydown', (e) => { if (e.key === 'Enter') { const input = e.target.closest('.center-search-container input'); if (input) { e.preventDefault(); e.stopImmediatePropagation(); const kw = input.value.trim(); if (kw) window.location.href = `https://search.bilibili.com/all?keyword=${encodeURIComponent(kw)}`; } } }, true);
            window.addEventListener('click', (e) => { const isBtn = e.target.closest('.nav-search-btn') || e.target.closest('.search-btn') || e.target.closest('.center-search__search-btn') || e.target.closest('.search-button'); const container = e.target.closest('.center-search-container'); if (isBtn && container) { e.preventDefault(); e.stopImmediatePropagation(); const input = container.querySelector('input'); const kw = input ? input.value.trim() : ''; if (kw) window.location.href = `https://search.bilibili.com/all?keyword=${encodeURIComponent(kw)}`; } }, true);
        }

        if (currentDomain.includes('weibo.com') && window.location.pathname.includes('/weibo')) {
            const originalWeiboOpen = window.open;
            window.open = function(url, name, specs) {
                if (typeof url === 'string' && (url.includes('s.weibo.com/weibo') || url.startsWith('/weibo'))) { window.location.href = url; return null; }
                return originalWeiboOpen.apply(this, arguments);
            };
            const weiboObserver = new MutationObserver(() => {
                const forms = document.querySelectorAll('form[target="_blank"]'); forms.forEach(form => { form.target = '_self'; });
                const links = document.querySelectorAll('a[target="_blank"]'); links.forEach(a => { if (a.href && a.href.includes('s.weibo.com/weibo')) { a.target = '_self'; } });
            });
            weiboObserver.observe(document.body, { childList: true, subtree: true });
            window.addEventListener('keydown', (e) => { if (e.key === 'Enter' && e.target.tagName === 'INPUT' && (e.target.name === 'q' || e.target.closest('[class*="search"]'))) { const kw = e.target.value.trim(); if (kw) { e.preventDefault(); e.stopImmediatePropagation(); window.location.href = `https://s.weibo.com/weibo?q=${encodeURIComponent(kw)}`; } } }, true);
            window.addEventListener('click', (e) => { const btn = e.target.closest('button') || e.target.closest('[class*="searchBtn"]') || e.target.closest('.s-btn-b'); const container = btn ? (btn.closest('form') || btn.closest('[class*="search"]')) : null; if (btn && container) { const input = container.querySelector('input[type="text"], input[name="q"]'); if (input && input.value.trim()) { e.preventDefault(); e.stopImmediatePropagation(); window.location.href = `https://s.weibo.com/weibo?q=${encodeURIComponent(input.value.trim())}`; } } }, true);
        }
    });

})();