网页调试

内置多种网页调试工具,包括:Eruda、vConsole、PageSpy、Chii,可在设置菜单中进行详细配置

// ==UserScript==
// @name            网页调试
// @namespace       https://greasyfork.org/zh-CN/scripts/475228
// @supportURL      https://github.com/WhiteSevs/TamperMonkeyScript/issues
// @version         2024.5.25
// @author          WhiteSevs
// @description     内置多种网页调试工具,包括:Eruda、vConsole、PageSpy、Chii,可在设置菜单中进行详细配置
// @icon            data:image/png;base64,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
// @license         MIT
// @match           *://*/*
// @run-at          document-start
// @grant           unsafeWindow
// @grant           GM_registerMenuCommand
// @grant           GM_unregisterMenuCommand
// @grant           GM_info
// @grant           GM_getValue
// @grant           GM_setValue
// @grant           GM_deleteValue
// @grant           GM_setClipboard
// @grant           GM_getResourceText
// @resource        Resource_erudaMonitor             https://fastly.jsdelivr.net/npm/eruda-monitor
// @resource        Resource_erudaFeatures            https://fastly.jsdelivr.net/npm/eruda-features
// @resource        Resource_erudaTiming              https://fastly.jsdelivr.net/npm/eruda-timing
// @resource        Resource_erudaCode                https://fastly.jsdelivr.net/npm/eruda-code
// @resource        Resource_erudaBenchmark           https://fastly.jsdelivr.net/npm/eruda-benchmark
// @resource        Resource_Leaflet                  https://update.greasyfork.org/scripts/483765/1360579/Leaflet.js
// @resource        Resource_erudaGeolocation         https://fastly.jsdelivr.net/gh/WhiteSevs/eruda-geolocation/eruda-geolocation.js
// @resource        Resource_erudaOrientation         https://fastly.jsdelivr.net/gh/WhiteSevs/eruda-orientation/eruda-orientation.js
// @resource        Resource_erudaTouches             https://fastly.jsdelivr.net/npm/eruda-touches
// @resource        Resource_erudaOutlinePlugin       https://fastly.jsdelivr.net/npm/eruda-outline-plugin
// @resource        Resource_erudaPixel               https://fastly.jsdelivr.net/npm/eruda-pixel
// @resource        Resource_vConsoleVueDevtools      https://fastly.jsdelivr.net/npm/vue-vconsole-devtools@1.0.9/dist/vue_plugin.min.js
// @require         https://update.greasyfork.org/scripts/456485/1360571/pops.js
// @require         https://update.greasyfork.org/scripts/483694/1360576/Eruda-2.js
// @require         https://update.greasyfork.org/scripts/483695/1360577/vConsole-2.js
// @require         https://update.greasyfork.org/scripts/483696/1382916/PageSpy-2.js
// @require         https://update.greasyfork.org/scripts/455186/1365298/WhiteSevsUtils.js
// ==/UserScript==

(function () {
  if (typeof unsafeWindow === "undefined") {
    unsafeWindow = globalThis || window || self;
  }
  /**
   * @type {import("../库/pops")}
   */
  const pops = window.pops;
  /**
   * @type {import("../库/Utils")}
   */
  const utils = window.Utils.noConflict();
  /**
   * 菜单对象
   */
  const GM_Menu = new utils.GM_Menu({
    GM_getValue,
    GM_setValue,
    GM_registerMenuCommand,
    GM_unregisterMenuCommand,
  });
  /**
   * @type {Window & typeof globalThis}
   */
  let currentWin = unsafeWindow;
  let console = currentWin.console;
  /**
   * 配置面板
   */
  const PopsPanel = {
    /**
     * 本地存储的总键名
     */
    key: "GM_Panel",
    /**
     * 属性attributes的data-key
     */
    attributeDataKey_Name: "data-key",
    /**
     * 属性attributes的data-default-value
     */
    attributeDataDefaultValue_Name: "data-default-value",
    /**
     * 初始化菜单
     */
    initMenu() {
      this.initLocalDefaultValue();
      if (!this.isTopWindow()) {
        return;
      }
      GM_Menu.add([
        {
          key: "show_pops_panel_setting",
          text: "⚙ 设置",
          autoReload: false,
          isStoreValue: false,
          showText(text) {
            return text;
          },
          callback() {
            PopsPanel.showPanel();
          },
        },
      ]);
    },
    isTopWindow() {
      return unsafeWindow.window.self === unsafeWindow.window.top;
    },
    /**
     * 初始化本地设置默认的值
     */
    initLocalDefaultValue() {
      let content = this.getContent();
      content.forEach((item) => {
        if (!item["forms"]) {
          return;
        }
        item.forms.forEach((__item__) => {
          if (__item__.forms) {
            __item__.forms.forEach((containerItem) => {
              if (!containerItem.attributes) {
                return;
              }
              let key = containerItem.attributes[this.attributeDataKey_Name];
              let defaultValue =
                containerItem.attributes[this.attributeDataDefaultValue_Name];
              if (this.getValue(key) == null) {
                this.setValue(key, defaultValue);
              }
            });
          } else {
          }
        });
      });
    },
    /**
     * 设置值
     * @param {string} key 键
     * @param {any} value 值
     */
    setValue(key, value) {
      let localValue = GM_getValue(this.key, {});
      localValue[key] = value;
      GM_setValue(this.key, localValue);
    },
    /**
     * 获取值
     * @param {string} key 键
     * @param {any} defaultValue 默认值
     * @returns {any}
     */
    getValue(key, defaultValue) {
      let localValue = GM_getValue(this.key, {});
      return localValue[key] ?? defaultValue;
    },
    /**
     * 删除值
     * @param {string} key 键
     */
    deleteValue(key) {
      let localValue = GM_getValue(this.key, {});
      delete localValue[key];
      GM_setValue(this.key, localValue);
    },
    /**
     * 显示设置面板
     */
    showPanel() {
      pops.panel({
        title: {
          text: `${GM_info?.script?.name || "网页调试"}`,
          position: "center",
        },
        content: this.getContent(),
        mask: {
          enable: true,
          clickEvent: {
            toClose: true,
          },
        },
        width: utils.isPhone() ? "92vw" : "650px",
        height: utils.isPhone() ? "80vh" : "500px",
        drag: true,
        only: true,
        zIndex: 200000000,
        style: `
        aside.pops-panel-aside{
          width: 20%;
        }
        `,
      });
    },
    /**
     * 获取按钮配置
     * @param {string} text 文字
     * @param {string} key 键
     * @param {boolean} defaultValue 默认值
     * @param {?(event:Event,value: boolean)=>boolean} _callback_ 点击回调
     * @param {string|undefined} description 描述
     */
    getSwtichDetail(text, key, defaultValue, _callback_, description) {
      /**
       * @type {PopsPanelSwitchDetails}
       */
      let result = {
        text: text,
        type: "switch",
        description: description,
        attributes: {},
        getValue() {
          return Boolean(PopsPanel.getValue(key, defaultValue));
        },
        callback(event, value) {
          console.log(`${value ? "开启" : "关闭"} ${text}`);
          if (typeof _callback_ === "function") {
            if (_callback_(event, value)) {
              return;
            }
          }
          PopsPanel.setValue(key, Boolean(value));
        },
      };
      result.attributes[this.attributeDataKey_Name] = key;
      result.attributes[this.attributeDataDefaultValue_Name] =
        Boolean(defaultValue);
      return result;
    },
    /**
     * 获取输入框配置
     * @param {string} text 文字
     * @param {string} key 键
     * @param {boolean} defaultValue 默认值
     * @param {string} [placeholder=""] 提示
     * @param {?(event:Event,value: string)=>boolean} _callback_ 输入回调
     * @param {string|undefined} description 描述
     * @returns {PopsPanelInputDetails}
     */
    getInputDetail(
      text,
      key,
      defaultValue,
      placeholder = "",
      _callback_,
      description
    ) {
      return {
        text: text,
        type: "input",
        attributes: {
          "data-key": key,
          "data-default-value": defaultValue,
        },
        description: description,
        getValue() {
          let localValue = PopsPanel.getValue(key, defaultValue);
          return localValue;
        },
        callback(event, value) {
          if (typeof _callback_ === "function") {
            if (_callback_(event, value)) {
              return;
            }
          }
          PopsPanel.setValue(key, value);
        },
        placeholder: placeholder,
      };
    },
    /**
     * 获取数字输入框配置
     * @param {string} text 文字
     * @param {string} key 键
     * @param {boolean} defaultValue 默认值
     * @param {string} [placeholder=""] 提示
     * @param {?(event:Event,value: string)=>boolean} _callback_ 输入回调
     * @param {string|undefined} description 描述
     * @returns {PopsPanelInputDetails}
     */
    getNumberInputDetail(
      text,
      key,
      defaultValue,
      placeholder = "",
      _callback_,
      description
    ) {
      let config = this.getInputDetail(
        text,
        key,
        defaultValue,
        (placeholder = ""),
        _callback_,
        description
      );
      config.isNumber = true;
      config.getValue = function () {
        let localValue = PopsPanel.getValue(key, defaultValue);
        localValue = parseInt(localValue);
        if (isNaN(localValue)) {
          return defaultValue;
        } else {
          return localValue;
        }
      };
      config.callback = function (event, value, valueAsNumber) {
        if (typeof _callback_ === "function") {
          if (_callback_(event, value)) {
            return;
          }
        }
        if (value === "") {
          PopsPanel.deleteValue(key);
          return;
        }
        if (isNaN(valueAsNumber)) {
          return;
        }
        PopsPanel.setValue(key, valueAsNumber);
      };
      return config;
    },
    /**
     * 获取下拉列表配置
     * @param {string} text 文字
     * @param {string} key 键
     * @param {any} defaultValue 默认值
     * @param {{
     * value: any,
     * text: string,
     * disable?(value: any): boolean,
     * }[]} data 数据
     * @param {string} description (可选)描述
     * @param {(event:PointerEvent, isSelectedValue: any, isSelectedText:string)=>void} selectCallBack(可选)选择的回调
     * @returns {PopsPanelSelectDetails}
     */
    getSelectDetail(
      text,
      key,
      defaultValue,
      data,
      description,
      selectCallBack
    ) {
      return {
        text: text,
        type: "select",
        description: description,
        attributes: {
          "data-key": key,
          "data-default-value": defaultValue,
        },
        getValue() {
          return PopsPanel.getValue(key, defaultValue);
        },
        callback(event, isSelectedValue, isSelectedText) {
          PopsPanel.setValue(key, isSelectedValue);
          if (typeof selectCallBack === "function") {
            selectCallBack(event, isSelectedValue, isSelectedText);
          }
        },
        data: data,
      };
    },
    /**
     * 获取配置内容
     */
    getContent() {
      /**
       * @type {PopsPanelContentConfig[]}
       */
      let content = [
        {
          id: "debug-panel-config-all",
          title: "总设置",
          headerTitle: "总设置",
          forms: [
            {
              text: "功能",
              type: "forms",
              forms: [
                this.getSelectDetail(
                  "调试工具",
                  "currentDebug",
                  "eruda",
                  [
                    {
                      value: "eruda",
                      text: "Eruda",
                    },
                    {
                      value: "vconsole",
                      text: "VConsole",
                    },
                    {
                      value: "pagespy",
                      text: "PageSpy",
                    },
                    {
                      value: "chii",
                      text: "Chii",
                    },
                  ],
                  void 0,
                  void 0
                ),
                this.getSwtichDetail(
                  "允许在iframe内加载",
                  "allowRunInIframe",
                  false,
                  void 0,
                  "如果指定本脚本的容器并没有在iframe内执行本脚本,那么该功能将不会生效"
                ),
                this.getSwtichDetail(
                  "主动加载调试工具",
                  "autoLoadDebugTool",
                  true,
                  void 0,
                  "关闭后将会在脚本菜单注册按钮,有3种状态【加载并显示调试工具】、【隐藏调试工具】、【显示调试工具】"
                ),
              ],
            },
          ],
        },
        {
          id: "debug-panel-config-eruda",
          title: "Eruda",
          headerTitle:
            "<a href='https://github.com/liriliri/eruda/blob/master/README_CN.md' target='_blank'>Eruda设置</a>",
          forms: [
            {
              text: "功能",
              type: "forms",
              forms: [
                {
                  text: "版本",
                  type: "button",
                  attributes: {
                    "data-key": "eruda-version",
                    "data-default-value": GlobalDebug.erudaVersion,
                  },
                  buttonType: "primary",
                  buttonText: GlobalDebug.erudaVersion,
                  callback(event) {
                    window.open("https://github.com/liriliri/eruda", "_blank");
                  },
                },
                this.getSwtichDetail(
                  "自动打开面板",
                  "eruda-auto-open-panel",
                  false,
                  void 0,
                  "加载完毕后自动显示面板内容"
                ),

                this.getSelectDetail(
                  "默认展示的面板元素",
                  "eruda-default-show-panel-name",
                  "console",
                  [
                    {
                      text: "Console",
                      value: "console",
                      disable() {
                        return !PopsPanel.getValue("eruda-panel-console");
                      },
                    },
                    {
                      text: "Elements",
                      value: "elements",
                      disable() {
                        return !PopsPanel.getValue("eruda-panel-elements");
                      },
                    },
                    {
                      text: "Network",
                      value: "network",
                      disable() {
                        return !PopsPanel.getValue("eruda-panel-network");
                      },
                    },
                    {
                      text: "Resources",
                      value: "resources",
                      disable() {
                        return !PopsPanel.getValue("eruda-panel-resources");
                      },
                    },
                    {
                      text: "Sources",
                      value: "sources",
                      disable() {
                        return !PopsPanel.getValue("eruda-panel-sources");
                      },
                    },
                    {
                      text: "Info",
                      value: "info",
                      disable() {
                        return !PopsPanel.getValue("eruda-panel-info");
                      },
                    },
                    {
                      text: "Snippets",
                      value: "snippets",
                      disable() {
                        return !PopsPanel.getValue("eruda-panel-snippets");
                      },
                    },
                    {
                      text: "Monitor",
                      value: "monitor",
                      disable() {
                        return !PopsPanel.getValue(
                          "eruda_plugin_Resource_erudaMonitor"
                        );
                      },
                    },
                    {
                      text: "Features",
                      value: "features",
                      disable() {
                        return !PopsPanel.getValue(
                          "eruda_plugin_Resource_erudaFeatures"
                        );
                      },
                    },
                    {
                      text: "Timing",
                      value: "timing",
                      disable() {
                        return !PopsPanel.getValue(
                          "eruda_plugin_Resource_erudaTiming"
                        );
                      },
                    },
                    {
                      text: "Code",
                      value: "code",
                      disable() {
                        return !PopsPanel.getValue(
                          "eruda_plugin_Resource_erudaCode"
                        );
                      },
                    },
                    {
                      text: "Benchmark",
                      value: "benchmark",
                      disable() {
                        return !PopsPanel.getValue(
                          "eruda_plugin_Resource_erudaBenchmark"
                        );
                      },
                    },
                    {
                      text: "Geolocation",
                      value: "geolocation",
                      disable() {
                        return !PopsPanel.getValue(
                          "eruda_plugin_Resource_erudaGeolocation"
                        );
                      },
                    },
                    {
                      text: "Orientation",
                      value: "orientation",
                      disable() {
                        return !PopsPanel.getValue(
                          "eruda_plugin_Resource_erudaOrientation"
                        );
                      },
                    },
                    {
                      text: "Touches",
                      value: "touches",
                      disable() {
                        return !PopsPanel.getValue(
                          "eruda_plugin_Resource_erudaTouches"
                        );
                      },
                    },
                    {
                      text: "Outline",
                      value: "outline",
                      disable() {
                        return !PopsPanel.getValue(
                          "eruda_plugin_Resource_erudaOutlinePlugin"
                        );
                      },
                    },
                    {
                      text: "Pixel",
                      value: "ixel",
                      disable() {
                        return !PopsPanel.getValue(
                          "eruda_plugin_Resource_erudaPixel"
                        );
                      },
                    },
                    {
                      text: "Settings",
                      value: "settings",
                    },
                  ],
                  "开启【自动打开面板】才会生效",
                  void 0
                ),
              ],
            },
            {
              text: "面板",
              type: "forms",
              forms: [
                this.getSwtichDetail(
                  "Console",
                  "eruda-panel-console",
                  true,
                  void 0,
                  "控制台"
                ),
                this.getSwtichDetail(
                  "Elements",
                  "eruda-panel-elements",
                  true,
                  void 0,
                  "元素"
                ),
                this.getSwtichDetail(
                  "Network",
                  "eruda-panel-network",
                  true,
                  void 0,
                  "网络"
                ),
                this.getSwtichDetail(
                  "Resources",
                  "eruda-panel-resources",
                  true,
                  void 0,
                  "资源"
                ),
                this.getSwtichDetail(
                  "Sources",
                  "eruda-panel-sources",
                  true,
                  void 0,
                  "源代码"
                ),
                this.getSwtichDetail(
                  "Info",
                  "eruda-panel-info",
                  true,
                  void 0,
                  "信息"
                ),
                this.getSwtichDetail(
                  "Snippets",
                  "eruda-panel-snippets",
                  true,
                  void 0,
                  "拓展"
                ),
              ],
            },
            {
              text: "插件",
              type: "forms",
              forms: [
                this.getSwtichDetail(
                  "eruda-monitor",
                  "eruda_plugin_Resource_erudaMonitor",
                  false,
                  void 0,
                  "展示页面的 fps 和内存信息"
                ),
                this.getSwtichDetail(
                  "eruda-features",
                  "eruda_plugin_Resource_erudaFeatures",
                  false,
                  void 0,
                  "浏览器特性检测"
                ),
                this.getSwtichDetail(
                  "eruda-timing",
                  "eruda_plugin_Resource_erudaTiming",
                  false,
                  void 0,
                  "展示性能资源数据"
                ),
                this.getSwtichDetail(
                  "eruda-code",
                  "eruda_plugin_Resource_erudaCode",
                  false,
                  void 0,
                  "运行 JavaScript 代码"
                ),
                this.getSwtichDetail(
                  "eruda-benchmark",
                  "eruda_plugin_Resource_erudaBenchmark",
                  false,
                  void 0,
                  "运行 JavaScript 性能测试"
                ),
                this.getSwtichDetail(
                  "eruda-geolocation",
                  "eruda_plugin_Resource_erudaGeolocation",
                  false,
                  void 0,
                  "测试地理位置接口"
                ),
                this.getSwtichDetail(
                  "eruda-orientation",
                  "eruda_plugin_Resource_erudaOrientation",
                  false,
                  void 0,
                  "测试重力感应接口"
                ),
                this.getSwtichDetail(
                  "eruda-touches",
                  "eruda_plugin_Resource_erudaTouches",
                  false,
                  void 0,
                  "(暂时无效)可视化屏幕 Touch 事件触发"
                ),
                this.getSwtichDetail(
                  "eruda-outline-plugin",
                  "eruda_plugin_Resource_erudaOutlinePlugin",
                  false,
                  void 0,
                  "给页面的元素添加边框"
                ),
                this.getSwtichDetail(
                  "eruda-pixel",
                  "eruda_plugin_Resource_erudaPixel",
                  false,
                  void 0,
                  "高精度的UI恢复辅助工具"
                ),
              ],
            },
          ],
        },
        {
          id: "debug-panel-config-vconsole",
          title: "vConsole",
          headerTitle:
            "<a href='https://github.com/Tencent/vConsole/blob/dev/README_CN.md' target='_blank'>vConsole设置</a>",
          forms: [
            {
              text: "功能",
              type: "forms",
              forms: [
                {
                  text: "版本",
                  type: "button",
                  attributes: {
                    "data-key": "vconsole-version",
                    "data-default-value": GlobalDebug.vConsoleVersion,
                  },
                  buttonType: "primary",
                  buttonText: GlobalDebug.vConsoleVersion,
                  callback(event) {
                    window.open(
                      "https://github.com/Tencent/vConsole",
                      "_blank"
                    );
                  },
                },
                this.getSwtichDetail(
                  "自动打开面板",
                  "vconsole-auto-open-panel",
                  false,
                  void 0,
                  "加载完毕后自动显示面板内容"
                ),
                this.getSelectDetail(
                  "默认展示的面板元素",
                  "vconsole-default-show-panel-name",
                  "default",
                  [
                    {
                      text: "Log",
                      value: "default",
                    },
                    {
                      text: "System",
                      value: "system",
                      disable() {
                        return !PopsPanel.getValue("vConsole-panel-system");
                      },
                    },
                    {
                      text: "Network",
                      value: "network",
                      disable() {
                        return !PopsPanel.getValue("vConsole-panel-network");
                      },
                    },
                    {
                      text: "Element",
                      value: "element",
                      disable() {
                        return !PopsPanel.getValue("vConsole-panel-element");
                      },
                    },
                    {
                      text: "Storage",
                      value: "storage",
                      disable() {
                        return !PopsPanel.getValue("vConsole-panel-storage");
                      },
                    },
                    {
                      text: "Stats",
                      value: "stats",
                      disable() {
                        return !PopsPanel.getValue(
                          "vConsole_plugin_Resource_vConsole_Stats"
                        );
                      },
                    },
                    {
                      text: "exportLog",
                      value: "exportlog",
                      disable() {
                        return !PopsPanel.getValue(
                          "vConsole_plugin_Resource_vConsole_ExportLog"
                        );
                      },
                    },
                    {
                      text: "Vue",
                      value: "vue",
                      disable() {
                        return !PopsPanel.getValue(
                          "vConsole_plugin_Resource_vConsoleVueDevtools"
                        );
                      },
                    },
                  ],
                  "开启【自动打开面板】才会生效",
                  void 0
                ),
              ],
            },

            {
              text: "面板",
              type: "forms",
              forms: [
                this.getSwtichDetail(
                  "System",
                  "vConsole-panel-system",
                  true,
                  void 0,
                  "控制台"
                ),
                this.getSwtichDetail(
                  "Network",
                  "vConsole-panel-network",
                  true,
                  void 0,
                  "元素"
                ),
                this.getSwtichDetail(
                  "Element",
                  "vConsole-panel-element",
                  true,
                  void 0,
                  "网络"
                ),
                this.getSwtichDetail(
                  "Storage",
                  "vConsole-panel-storage",
                  true,
                  void 0,
                  "资源"
                ),
              ],
            },
            {
              text: "配置",
              type: "forms",
              forms: [
                this.getSelectDetail(
                  "主题",
                  "vConsole-theme",
                  "light",
                  [
                    {
                      value: "auto",
                      text: "自动",
                    },
                    {
                      value: "light",
                      text: "浅色主题",
                    },
                    {
                      value: "dark",
                      text: "深色主题",
                    },
                  ],
                  void 0,
                  void 0
                ),
                this.getSwtichDetail(
                  "禁止Log自动滚动",
                  "vconsole-disableLogScrolling",
                  false
                ),
                this.getSwtichDetail(
                  "显示日志的输出时间",
                  "vconsole-showTimestamps",
                  false
                ),
                this.getNumberInputDetail(
                  "日志的上限数量",
                  "vconsole-maxLogNumber",
                  1000,
                  "请输入数字"
                ),
                this.getNumberInputDetail(
                  "请求记录的上限数量",
                  "vconsole-maxNetworkNumber",
                  1000,
                  "请输入数字"
                ),
              ],
            },
            {
              text: "Storage配置",
              type: "forms",
              forms: [
                this.getSwtichDetail(
                  "Cookies",
                  "vConsole-storage-defaultStorages-cookies",
                  true,
                  void 0,
                  "显示Cookies"
                ),
                this.getSwtichDetail(
                  "LocalStorage",
                  "vConsole-storage-defaultStorages-localStorage",
                  true,
                  void 0,
                  "显示LocalStorage"
                ),
                this.getSwtichDetail(
                  "SessionStorage",
                  "vConsole-storage-defaultStorages-sessionStorage",
                  true,
                  void 0,
                  "显示SessionStorage"
                ),
              ],
            },
            {
              text: "插件",
              type: "forms",
              forms: [
                this.getSwtichDetail(
                  "vconsole-stats-plugin",
                  "vConsole_plugin_Resource_vConsole_Stats",
                  false,
                  void 0,
                  "A vConsole plugin which can show Stats in front-end."
                ),
                this.getSwtichDetail(
                  "vconsole-outputlog-plugin",
                  "vConsole_plugin_Resource_vConsole_ExportLog",
                  false,
                  void 0,
                  "使用该插件可以复制或下载console中打印的log"
                ),
                this.getSwtichDetail(
                  "vconsole-vue-devtools-plugin",
                  "vConsole_plugin_Resource_vConsoleVueDevtools",
                  false,
                  void 0,
                  "Vue-vConsole-devtools 是一款vConsole插件,把Vue.js官方调试工具vue-devtools移植到移动端,可以直接在移动端查看调试Vue.js应用"
                ),
              ],
            },
          ],
        },
        {
          id: "debug-panel-config-pagespy",
          title: "PageSpy",
          headerTitle:
            "<a href='https://github.com/HuolalaTech/page-spy-web/blob/main/README_ZH.md' target='_blank'>PageSpy设置</a>",
          forms: [
            {
              text: "功能",
              type: "forms",
              forms: [
                {
                  text: "注意!隐私保护!",
                  type: "button",
                  buttonType: "danger",
                  buttonText: "了解详情",
                  callback(event) {
                    pops.confirm({
                      title: {
                        text: "提示",
                      },
                      content: {
                        text: `下面默认配置的${GlobalDebug.pageSpyDefaultApi}是仅供测试使用的,其他人也可以看到你的调试信息,包括Cookie等信息,如果想用,请自己搭建一个调试端`,
                      },
                      btn: {
                        reverse: true,
                        position: "end",
                        ok: {
                          text: "前往了解更多",
                          callback() {
                            window.open(
                              "https://github.com/HuolalaTech/page-spy-web/wiki/%F0%9F%90%9E-%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E8%A7%A3%E7%AD%94#user-content-testjikejishucom-%E6%98%AF%E5%AE%98%E6%96%B9%E6%8F%90%E4%BE%9B%E7%9A%84%E5%9F%9F%E5%90%8D%E5%90%97%E4%B8%80%E7%9B%B4%E5%8F%AF%E4%BB%A5%E7%94%A8%E5%90%97",
                              "_blank"
                            );
                          },
                        },
                      },
                      mask: {
                        enable: true,
                      },
                    });
                  },
                },
                {
                  text: "版本",
                  type: "button",
                  attributes: {
                    "data-key": "pagespy-version",
                    "data-default-value": GlobalDebug.pageSpyVersion,
                  },
                  buttonType: "primary",
                  buttonText: GlobalDebug.pageSpyVersion,
                  callback(event) {
                    window.open(
                      "https://github.com/HuolalaTech/page-spy-web",
                      "_blank"
                    );
                  },
                },
                this.getSwtichDetail(
                  "禁止在调试端运行",
                  "pagespy-disable-run-in-debug-client",
                  true,
                  void 0,
                  "调试端是下面配置的api/clientOrigin地址"
                ),
              ],
            },
            {
              text: "配置",
              type: "forms",
              forms: [
                this.getInputDetail(
                  "api",
                  "pagespy-api",
                  GlobalDebug.pageSpyDefaultApi,
                  "",
                  function (event, value) {
                    PopsPanel.setValue("pagespy-api", value.trim());
                  },
                  "服务器地址的 Host"
                ),
                this.getInputDetail(
                  "clientOrigin",
                  "pagespy-clientOrigin",
                  GlobalDebug.pageSpyDefaultCliennOrigin,
                  "",
                  function (event, value) {
                    PopsPanel.setValue("pagespy-clientOrigin", value.trim());
                  },
                  "服务器地址的 Origin"
                ),
                this.getInputDetail(
                  "project",
                  "pagespy-project",
                  "default",
                  void 0,
                  void 0,
                  "项目名称"
                ),
                this.getInputDetail(
                  "title",
                  "pagespy-title",
                  "--",
                  void 0,
                  void 0,
                  "自定义标题"
                ),
                this.getSwtichDetail(
                  "autoRender",
                  "pagespy-autoRender",
                  true,
                  void 0,
                  "自动渲染「圆形白底带 Logo」"
                ),
                {
                  text: "enableSSL",
                  description: "是否https",
                  type: "select",
                  attributes: {
                    "data-key": "pagespy-enableSSL",
                    "data-default-value": true,
                  },
                  getValue() {
                    return PopsPanel.getValue(
                      this.attributes["data-key"],
                      this.attributes["data-default-value"]
                    );
                  },
                  callback(event, isSelectedValue, isSelectedText) {
                    PopsPanel.setValue(
                      this.attributes["data-key"],
                      isSelectedValue
                    );
                  },
                  data: [
                    {
                      value: null,
                      text: "默认(自动分析)",
                    },
                    {
                      value: true,
                      text: "开启",
                    },
                    {
                      value: false,
                      text: "关闭",
                    },
                  ],
                },
              ],
            },
          ],
        },
        {
          id: "debug-panel-config-chii",
          title: "Chii",
          headerTitle:
            "<a href='https://github.com/liriliri/chii/blob/master/README_CN.md' target='_blank'>Chii设置</a>",
          forms: [
            {
              text: "功能",
              type: "forms",
              forms: [
                {
                  text: "调试页面",
                  type: "button",
                  buttonType: "primary",
                  buttonText: "前往",
                  disable: Boolean(
                    PopsPanel.getValue("chii-script-embedded", true)
                  ),
                  callback(event) {
                    let url = PopsPanel.getValue(
                      "chii-debug-url",
                      GlobalDebug.chiiUrl
                    );
                    window.open(url, "_blank");
                  },
                },
              ],
            },
            {
              text: "配置",
              type: "forms",
              forms: [
                this.getSwtichDetail(
                  "本页展示",
                  "chii-script-embedded",
                  true,
                  (event, value) => {
                    let $shadowRoot = event.target.getRootNode();
                    let button = $shadowRoot.querySelector(
                      "li.pops-panel-forms-container-item ul > li > .pops-panel-button button"
                    );
                    if (value) {
                      button.setAttribute("disabled", true);
                    } else {
                      button.removeAttribute("disabled");
                    }
                  },
                  "将调试器展示在同一页面中"
                ),
                this.getSwtichDetail(
                  "禁止在调试端运行",
                  "chii-disable-run-in-debug-url",
                  true,
                  void 0,
                  "调试端是下面配置的【调试页面Url】"
                ),
                this.getSwtichDetail(
                  "检测script加载",
                  "chii-check-script-load",
                  true,
                  void 0,
                  "失败会有alert提示弹出"
                ),
                this.getInputDetail(
                  "调试页面Url",
                  "chii-debug-url",
                  GlobalDebug.chiiUrl,
                  "请输入链接Url",
                  void 0,
                  "配置【调试页面】的Url"
                ),
                this.getInputDetail(
                  "来源js",
                  "chii-target-js",
                  GlobalDebug.chiiDetaultScriptJs,
                  "请输入目标js文件",
                  void 0,
                  "用于注入页面来进行调试"
                ),
              ],
            },
            {
              text: "本页展示的配置",
              type: "forms",
              forms: [
                {
                  text: "高度",
                  type: "slider",
                  description: "移动端不好拖拽,使用这个配置高度",
                  attributes: {
                    "data-key": ChiiHeight.$data.key,
                    "data-default-value": ChiiHeight.$data.winHalfHeight,
                  },
                  getValue() {
                    return ChiiHeight.getLocalHeight();
                  },
                  callback(event, value) {
                    ChiiHeight.setGMLocalHeight(value);
                    ChiiHeight.setLocalHeight(value);
                    let chiiContainer = Array.from(
                      document.querySelectorAll(".__chobitsu-hide__")
                    ).find((ele) => ele.querySelector("iframe"));
                    if (chiiContainer) {
                      chiiContainer.style.height = value + "px";
                    }
                  },
                  getToolTipContent(value) {
                    return value + "px";
                  },
                  min: 0,
                  max: ChiiHeight.$data.winHeight,
                  step: 1,
                },
              ],
            },
          ],
        },
      ];
      return content;
    },
  };

  const ChiiHeight = {
    $data: {
      key: "chii-embedded-height",
      winHeight: parseInt(globalThis.innerHeight),
      winHalfHeight: parseInt(globalThis.innerHeight / 2),
    },
    init() {
      let height = this.$data.winHalfHeight;
      if (!this.isExistGMLocalHeight()) {
        /* GM未创建或不是数字,设置值到油猴数据管理器中 */
        this.setGMLocalHeight(height);
      } else {
        height = this.getGMLocalHeight();
      }
      this.setLocalHeight(height);
    },
    isExistLocalHeight() {
      return typeof this.getLocalHeight() === "number";
    },
    /**
     *
     * @returns {number}
     */
    getLocalHeight() {
      return globalThis.localStorage.getItem(this.$data.key);
    },
    /**
     *
     * @param {number} value
     */
    setLocalHeight(value) {
      if (typeof value !== "number") {
        console.log(value);
        throw new TypeError(`${this.$data.key}的值必须是number`);
      }
      globalThis.localStorage.setItem(this.$data.key, value);
      if (this.getLocalHeight() !== value) {
        globalThis.localStorage[this.$data.key] = value;
      }
    },
    isExistGMLocalHeight() {
      return typeof this.getGMLocalHeight() === "number";
    },
    /**
     *
     * @returns {number}
     */
    getGMLocalHeight() {
      return PopsPanel.getValue(this.$data.key);
    },
    /**
     *
     * @param {number} value
     */
    setGMLocalHeight(value) {
      if (typeof value !== "number") {
        console.log(value);
        throw new TypeError(`${this.$data.key}的值必须是number`);
      }
      PopsPanel.setValue(this.$data.key, value);
    },
  };

  const vConsolePlugin = {
    State(vConsole, VConsole) {
      const Stats = function () {
        var mode = 0;
        var localPositionStorageKey = "vConsole-Plugin-Stats-Position";
        function getLocalPositionStorage() {
          return GM_getValue(localPositionStorageKey, {
            top: 0,
            left: 0,
          });
        }
        function setLocalPositionStorage(left, top) {
          GM_setValue(localPositionStorageKey, {
            left: left,
            top: top,
          });
        }
        var container = document.createElement("div");
        let oldPosition = getLocalPositionStorage();
        container.style.cssText = `position:fixed;top:${oldPosition.top}px;left:${oldPosition.left}px;cursor:pointer;opacity:0.9;z-index:10000`;
        container.addEventListener(
          "click",
          function (event) {
            event.preventDefault();
            showPanel(++mode % container.children.length);
          },
          {
            capture: true,
          }
        );
        function addPanel(panel) {
          container.appendChild(panel.dom);
          return panel;
        }

        function showPanel(id) {
          for (var i = 0; i < container.children.length; i++) {
            container.children[i].style.display = i === id ? "block" : "none";
          }

          mode = id;
        }

        function drag() {
          pops.config.Utils.drag(container, {
            dragElement: container,
            limit: true,
            extraDistance: 2,
            moveCallBack(moveElement, left, top) {
              setLocalPositionStorage(left, top);
            },
          });
        }

        var beginTime = (performance || Date).now(),
          prevTime = beginTime,
          frames = 0;

        var fpsPanel = addPanel(new Stats.Panel("FPS", "#0ff", "#002"));
        var msPanel = addPanel(new Stats.Panel("MS", "#0f0", "#020"));

        if (self.performance && self.performance.memory) {
          var memPanel = addPanel(new Stats.Panel("MB", "#f08", "#201"));
        }

        showPanel(0);
        drag();
        return {
          REVISION: 16,

          dom: container,

          addPanel: addPanel,
          showPanel: showPanel,

          begin: function () {
            beginTime = (performance || Date).now();
          },

          end: function () {
            frames++;

            var time = (performance || Date).now();

            msPanel.update(time - beginTime, 200);

            if (time >= prevTime + 1000) {
              fpsPanel.update((frames * 1000) / (time - prevTime), 100);

              prevTime = time;
              frames = 0;

              if (memPanel) {
                var memory = performance.memory;
                memPanel.update(
                  memory.usedJSHeapSize / 1048576,
                  memory.jsHeapSizeLimit / 1048576
                );
              }
            }

            return time;
          },

          update: function () {
            beginTime = this.end();
          },

          // Backwards Compatibility

          domElement: container,
          setMode: showPanel,
        };
      };

      Stats.Panel = function (name, fg, bg) {
        var min = Infinity,
          max = 0,
          round = Math.round;
        var PR = round(window.devicePixelRatio || 1);

        var WIDTH = 80 * PR,
          HEIGHT = 48 * PR,
          TEXT_X = 3 * PR,
          TEXT_Y = 2 * PR,
          GRAPH_X = 3 * PR,
          GRAPH_Y = 15 * PR,
          GRAPH_WIDTH = 74 * PR,
          GRAPH_HEIGHT = 30 * PR;

        var canvas = document.createElement("canvas");
        canvas.width = WIDTH;
        canvas.height = HEIGHT;
        canvas.style.cssText = "width:80px;height:48px";

        var context = canvas.getContext("2d");
        context.font = "bold " + 9 * PR + "px Helvetica,Arial,sans-serif";
        context.textBaseline = "top";

        context.fillStyle = bg;
        context.fillRect(0, 0, WIDTH, HEIGHT);

        context.fillStyle = fg;
        context.fillText(name, TEXT_X, TEXT_Y);
        context.fillRect(GRAPH_X, GRAPH_Y, GRAPH_WIDTH, GRAPH_HEIGHT);

        context.fillStyle = bg;
        context.globalAlpha = 0.9;
        context.fillRect(GRAPH_X, GRAPH_Y, GRAPH_WIDTH, GRAPH_HEIGHT);

        return {
          dom: canvas,

          update: function (value, maxValue) {
            min = Math.min(min, value);
            max = Math.max(max, value);

            context.fillStyle = bg;
            context.globalAlpha = 1;
            context.fillRect(0, 0, WIDTH, GRAPH_Y);
            context.fillStyle = fg;
            context.fillText(
              round(value) +
                " " +
                name +
                " (" +
                round(min) +
                "-" +
                round(max) +
                ")",
              TEXT_X,
              TEXT_Y
            );

            context.drawImage(
              canvas,
              GRAPH_X + PR,
              GRAPH_Y,
              GRAPH_WIDTH - PR,
              GRAPH_HEIGHT,
              GRAPH_X,
              GRAPH_Y,
              GRAPH_WIDTH - PR,
              GRAPH_HEIGHT
            );

            context.fillRect(
              GRAPH_X + GRAPH_WIDTH - PR,
              GRAPH_Y,
              PR,
              GRAPH_HEIGHT
            );

            context.fillStyle = bg;
            context.globalAlpha = 0.9;
            context.fillRect(
              GRAPH_X + GRAPH_WIDTH - PR,
              GRAPH_Y,
              PR,
              round((1 - value / maxValue) * GRAPH_HEIGHT)
            );
          },
        };
      };

      class VConsoleStatsPlugin {
        constructor(vConsole, VConsole) {
          this.vConsole = vConsole;
          this.VConsole = VConsole;
          this.dom = null;
          this.requestID = null;
          this.stats = null;
          return this.init();
        }
        init() {
          this.addStyle();
          const vConsoleStats = new this.VConsole.VConsolePlugin(
            "Stats",
            "Stats"
          );
          vConsoleStats.on("ready", () => {
            document
              .querySelectorAll(".vc-stats-buttons")
              .forEach((statusButton) => {
                statusButton.addEventListener("click", (event) => {
                  const currentType = event.target.dataset.type;
                  if (
                    currentType.toString() === "2" &&
                    !(self.performance && self.performance.memory)
                  ) {
                    console.error(
                      "浏览器不支持window.performance或者window.performance.memory"
                    );
                    return;
                  }
                  this.changePanel(currentType);
                });
              });
          });

          vConsoleStats.on("renderTab", (callback) => {
            const statsHTML = `
            <div class="vc-stats-buttons">
              <div class="vc-button-container">
                <button class="vc-stats-button" data-type="0">show FPS</button>
                <div class="vc-description">
                  <span>最后一秒渲染的帧。数字越高越好</span>
                </div>
              </div>
              <div class="vc-button-container">
                <button class="vc-stats-button" data-type="1">show MS</button>
                <div class="vc-description">
                  <span>渲染帧所需的毫秒数。数字越低越好</span>
                </div>
              </div>
              <div class="vc-button-container">
                <button class="vc-stats-button" data-type="2">show MB</button>
                <div class="vc-description">
                  <span>内存分配(MB)</span>
                  <a class="vc-link" href="https://caniuse.com/mdn-api_performance_memory" target="_blank">performance.memory兼容性查看</a>
                  <span>Chrome启用方式: --enable-precise-memory-info</span>
                </div>
              </div>
            </div>`;
            callback(statsHTML);
          });

          vConsoleStats.on("addTool", (callback) => {
            const buttons = [
              {
                name: "Show Stats",
                onClick: this.show,
              },
              {
                name: "Close Stats",
                onClick: this.close,
              },
            ];
            callback(buttons);
          });
          this.vConsole.addPlugin(vConsoleStats);
          return vConsoleStats;
        }

        addStyle = (target) => {
          if (target == null) {
            target = document.head || document.body || document.documentElement;
          }
          const cssNode = document.createElement("style");
          cssNode.setAttribute("type", "text/css");
          cssNode.innerHTML = `
          .vc-stats-button{
              margin: 10px 10px;
              background-color: #fbf9fe;
              padding: 2px 4px;
              cursor: pointer;
              border-radius: 4px;
              border: 1px solid;
          }
          .vc-button-container{
            display: flex;
            align-items: center;
          }
          .vc-description{
            display: flex;
            flex-direction: column;
          }
          .vc-description a.vc-link{
            color: blue;
          }`;
          target.appendChild(cssNode);
        };
        show = () => {
          if (!this.stats) {
            this.stats = new Stats();
            this.stats.showPanel(1); // 0: fps, 1: ms, 2: mb, 3+: custom
            this.dom = this.stats.dom;
            document.body.appendChild(this.dom);
            this.requestID = requestAnimationFrame(this.loop);
          }
        };

        changePanel = (type) => {
          if (!this.stats) {
            this.show();
          }
          this.stats.setMode(Number(type));
        };

        loop = () => {
          this.stats.update();
          this.requestID = requestAnimationFrame(this.loop);
        };

        close = () => {
          if (this.requestID) {
            cancelAnimationFrame(this.requestID);
          }
          if (this.dom) {
            document.body.removeChild(this.dom);
          }

          this.stats = null;
          this.requestID = null;
          this.dom = null;
        };
      }

      return new VConsoleStatsPlugin(vConsole, VConsole);
    },
    exportLog(vConsole, VConsole) {
      class VConsoleOutputLogsPlugin {
        constructor(vConsole, VConsole, logItemSelector) {
          this.vConsole = vConsole;
          this.VConsole = VConsole;
          this.$ = vConsole.$;
          this.dom = null;
          this.logItemSelector =
            logItemSelector || ".vc-content #__vc_plug_default .vc-log-row";
          return this.init();
        }

        init() {
          const vConsoleExportLogs = new this.VConsole.VConsolePlugin(
            "exportLog",
            "exportLog"
          );

          vConsoleExportLogs.on("ready", () => {
            console.log("[vConsole-exportlog-plugin] -- load");
          });
          vConsoleExportLogs.on("renderTab", (callback) => {
            const html = `<div class="vconsole-exportlog">
            </div>`;
            callback(html);
          });
          vConsoleExportLogs.on("addTool", (callback) => {
            const buttons = [
              {
                name: "exportLogs",
                onClick: this.export,
              },
              {
                name: "copyLogs",
                onClick: this.copyText,
              },
            ];
            callback(buttons);
          });
          this.vConsole.addPlugin(vConsoleExportLogs);
          return vConsoleExportLogs;
        }
        funDownload = (content, filename) => {
          var eleLink = document.createElement("a");
          eleLink.download = filename;
          eleLink.style.display = "none";
          var blob = new Blob([content]);
          eleLink.href = URL.createObjectURL(blob);
          document.body.appendChild(eleLink);
          eleLink.click();
          document.body.removeChild(eleLink);
        };
        getAllLogContent = () => {
          let logRowsElement = document.querySelectorAll(this.logItemSelector);
          let logText = "";
          for (let index = 0; index < logRowsElement.length; index++) {
            const ele = logRowsElement[index];
            logText += `${ele.textContent}\n`;
          }
          return logText;
        };
        export = () => {
          let logText = this.getAllLogContent();
          this.funDownload(
            logText,
            `${
              new Date().toLocaleDateString() +
              " " +
              new Date().toLocaleTimeString()
            }.log`
          );
        };
        copyText = () => {
          let logText = this.getAllLogContent();
          utils.setClip(logText);
        };
      }
      return new VConsoleOutputLogsPlugin(vConsole, VConsole);
    },
  };
  /**
   * 全局调试
   */
  const GlobalDebug = {
    $data: {
      /** 当前的调试工具是否已执行 */
      isLoadDebugTool: false,
      /** 当前已执行的调试工具名 */
      loadDebugToolName: void 0,
    },
    $ele: {
      /** 隐藏调试工具的style元素 */
      hideDebugToolCSSNode: void 0,
    },
    erudaVersion: "3.0.1",
    vConsoleVersion: "3.15.1",
    pageSpyVersion: "1.8.9",
    pageSpyDefaultApi: "test.jikejishu.com",
    pageSpyDefaultCliennOrigin: "https://test.jikejishu.com",
    chiiUrl: "https://chii.liriliri.io/",
    chiiDetaultScriptJs: "//chii.liriliri.io/target.js",
    iframeUrlList: [],
    /**
     * 处理当在iframe内加载时,是否允许执行,如果允许,那么把url添加到菜单中
     */
    handleIframe() {
      if (PopsPanel.isTopWindow()) {
        return true;
      }
      if (!PopsPanel.getValue("allowRunInIframe")) {
        return false;
      }
      this.iframeUrlList.push(window.location.href);
      top.console.log("iframe信息:" + window.location.href);
      GM_Menu.add({
        key: "iframeUrl",
        text: window.location.href,
        autoReload: false,
        isStoreValue: false,
        showText(text) {
          return text;
        },
        callback() {
          GM_setClipboard(window.location.href);
        },
      });
      return true;
    },
    /**
     * 执行当前的调试工具
     */
    runDebugTool() {
      /* 当前的调试工具,默认为eruda */
      let currentDebugTool = PopsPanel.getValue("currentDebug");
      currentDebugTool = currentDebugTool.toString().toLowerCase();
      console.log(`网页调试:当前使用的调试工具【${currentDebugTool}】`);
      if (currentDebugTool === "vconsole") {
        /* vConsole */
        this.$data.isLoadDebugTool = true;
        this.$data.loadDebugToolName = "vconsole";
        this.vConsole();
      } else if (currentDebugTool === "pagespy") {
        /* PageSpy */
        this.$data.isLoadDebugTool = true;
        this.$data.loadDebugToolName = "pagespy";
        this.pageSpy();
      } else if (currentDebugTool === "eruda") {
        /* eruda */
        this.$data.isLoadDebugTool = true;
        this.$data.loadDebugToolName = "eruda";
        this.eruda();
      } else if (currentDebugTool === "chii") {
        /* chii */
        this.$data.isLoadDebugTool = true;
        this.$data.loadDebugToolName = "chii";
        this.chii();
      } else {
        console.error("当前未配置该调试工具的运行");
      }
    },
    /**
     * 在脚本菜单中添加控制当前的调试工具状态的菜单按钮
     */
    addControlDebugToolScriptMenu() {
      if (!PopsPanel.isTopWindow()) {
        console.warn("不在iframe内重复添加菜单按钮");
        return;
      }
      let menuData = {
        key: "debug_tool_show_hide_control",
        text: "☯ 加载并显示调试工具",
        autoReload: false,
        isStoreValue: false,
        showText(text) {
          return text;
        },
        callback: (data) => {
          changeMenu(data);
        },
      };
      /**
       *
       * @param {UtilsGMMenuClickCallBackData} data
       */
      const changeMenu = (data) => {
        if (GlobalDebug.$data.isLoadDebugTool) {
          /* 状态:已加载 */
          if (GlobalDebug.$ele.hideDebugToolCSSNode) {
            /* 状态:已加载且添加了隐藏CSS */
            /* 进行移除隐藏CSS */
            /* 菜单状态:【隐藏调试工具】 */
            this.showDebugTool();
            menuData.text = "🌑 隐藏调试工具";
            GM_Menu.update(menuData);
          } else {
            /* 状态:已加载且未添加隐藏CSS */
            /* 进行添加隐藏CSS */
            /* 菜单状态:【显示调试工具】 */
            this.hideDebugTool();
            menuData.text = "🌕 显示调试工具";
            GM_Menu.update(menuData);
          }
        } else {
          /* 状态:未加载,加载并显示 */
          /* 进行执行调试工具 */
          /* 菜单状态:【隐藏调试工具】 */
          this.showDebugTool();
          menuData.text = "🌑 隐藏调试工具";
          GM_Menu.update(menuData);
        }
      };
      GM_Menu.add(menuData);
    },
    /**
     * 判断页面中是否已存在隐藏调试工具的CSS元素节点
     * @returns
     */
    hasHideDebugToolCSSNode() {
      return document.documentElement.contains(this.$ele.hideDebugToolCSSNode);
    },
    /**
     * 创建隐藏调试工具的CSS元素
     * @returns
     */
    createHideDebugToolCSSNode() {
      let cssNode = document.createElement("style");
      cssNode.setAttribute("type", "text/css");
      cssNode.setAttribute("data-from", "hide-debug-tool");
      cssNode.innerHTML = `
        #eruda{
          display: none !important;
        }
        #__vconsole{
          display: none !important;
        }
        #__pageSpy{
          display: none !important;
        }
        .__chobitsu-hide__ > iframe,
        .__chobitsu-hide__:has(iframe){
          display: none !important;
        }
        `;
      return cssNode;
    },
    /**
     * 隐藏当前的调试工具
     */
    hideDebugTool() {
      if (this.$ele.hideDebugToolCSSNode == null) {
        console.log("未创建隐藏【调试工具】的style元素 => 创建元素");
        this.$ele.hideDebugToolCSSNode = this.createHideDebugToolCSSNode();
      }
      if (!this.hasHideDebugToolCSSNode()) {
        console.log("页面不存在隐藏【调试工具】的style元素 => 添加元素");
        document.documentElement.appendChild(this.$ele.hideDebugToolCSSNode);
      }
    },
    /**
     * 显示当前的调试工具
     */
    showDebugTool() {
      if (this.$ele.hideDebugToolCSSNode) {
        console.log("页面存在隐藏【调试工具】的style元素 => 移除元素");
        document.documentElement.removeChild(this.$ele.hideDebugToolCSSNode);
        this.$ele.hideDebugToolCSSNode = null;
      }
      if (!this.$data.isLoadDebugTool) {
        console.log("尚未运行【调试工具】 => 运行调试工具");
        this.runDebugTool();
      }
    },
    eruda() {
      initEruda("Eruda", currentWin);
      let Eruda = currentWin.Eruda;
      if (!Eruda) {
        alert("调试工具【eruda】注册全局失败,请反馈开发者");
        return;
      }
      let inintPanelList = [];
      if (PopsPanel.getValue("eruda-panel-console")) {
        inintPanelList.push("console");
      }
      if (PopsPanel.getValue("eruda-panel-elements")) {
        inintPanelList.push("elements");
      }
      if (PopsPanel.getValue("eruda-panel-network")) {
        inintPanelList.push("network");
      }
      if (PopsPanel.getValue("eruda-panel-resources")) {
        inintPanelList.push("resources");
      }
      if (PopsPanel.getValue("eruda-panel-sources")) {
        inintPanelList.push("sources");
      }
      if (PopsPanel.getValue("eruda-panel-info")) {
        inintPanelList.push("info");
      }
      if (PopsPanel.getValue("eruda-panel-snippets")) {
        inintPanelList.push("snippets");
      }
      GlobalDebug.erudaVersion = Eruda.version;
      Eruda.init({
        tool: inintPanelList,
      });
      console.log(`eruda当前版本:${Eruda.version}`);
      console.log(`eruda项目地址:https://github.com/liriliri/eruda`);
      console.log("eruda的全局变量名: Eruda");
      if (PopsPanel.getValue("eruda_plugin_Resource_erudaMonitor")) {
        try {
          currentWin.eval(GM_getResourceText("Resource_erudaMonitor"));
          Eruda.add(erudaMonitor);
        } catch (error) {
          console.error("插件【eruda-monitor】加载失败,原因:", error);
        }
      }
      if (PopsPanel.getValue("eruda_plugin_Resource_erudaFeatures")) {
        try {
          currentWin.eval(GM_getResourceText("Resource_erudaFeatures"));
          Eruda.add(erudaFeatures);
        } catch (error) {
          console.error("插件【eruda-features】加载失败,原因:", error);
        }
      }
      if (PopsPanel.getValue("eruda_plugin_Resource_erudaTiming")) {
        try {
          currentWin.eval(GM_getResourceText("Resource_erudaTiming"));
          Eruda.add(erudaTiming);
        } catch (error) {
          console.error("插件【eruda-timing】加载失败,原因:", error);
        }
      }
      if (PopsPanel.getValue("eruda_plugin_Resource_erudaCode")) {
        try {
          currentWin.eval(GM_getResourceText("Resource_erudaCode"));
          Eruda.add(erudaCode);
        } catch (error) {
          console.error("插件【eruda-code】加载失败,原因:", error);
        }
      }
      if (PopsPanel.getValue("eruda_plugin_Resource_erudaBenchmark")) {
        try {
          currentWin.eval(GM_getResourceText("Resource_erudaBenchmark"));
          Eruda.add(erudaBenchmark);
        } catch (error) {
          console.error("插件【eruda-benchmark】加载失败,原因:", error);
        }
      }
      if (PopsPanel.getValue("eruda_plugin_Resource_erudaGeolocation")) {
        try {
          currentWin.eval(GM_getResourceText("Resource_Leaflet"));
          currentWin.eval(GM_getResourceText("Resource_erudaGeolocation"));
          Eruda.add(erudaGeolocation);
        } catch (error) {
          console.error("插件【eruda-geolocation】加载失败,原因:", error);
        }
      }
      if (PopsPanel.getValue("eruda_plugin_Resource_erudaOrientation")) {
        try {
          currentWin.eval(GM_getResourceText("Resource_erudaOrientation"));
          Eruda.add(erudaOrientation);
        } catch (error) {
          console.error("插件【eruda-orientation】加载失败,原因:", error);
        }
      }
      if (PopsPanel.getValue("eruda_plugin_Resource_erudaTouches")) {
        try {
          currentWin.eval(GM_getResourceText("Resource_erudaTouches"));
          Eruda.add(erudaTouches);
        } catch (error) {
          console.error("插件【eruda-touches】加载失败,原因:", error);
        }
      }
      if (PopsPanel.getValue("eruda_plugin_Resource_erudaOutlinePlugin")) {
        try {
          currentWin.eval(GM_getResourceText("Resource_erudaOutlinePlugin"));
          Eruda.add(erudaOutlinePlugin);
        } catch (error) {
          console.error("插件【eruda-outline-plugin】加载失败,原因:", error);
        }
      }
      if (PopsPanel.getValue("eruda_plugin_Resource_erudaPixel")) {
        try {
          currentWin.eval(GM_getResourceText("Resource_erudaPixel"));
          Eruda.add(erudaPixel);
        } catch (error) {
          console.error("插件【eruda-pixel】加载失败,原因:", error);
        }
      }
      if (PopsPanel.getValue("eruda-auto-open-panel")) {
        let defaultShowName = PopsPanel.getValue(
          "eruda-default-show-panel-name",
          ""
        );
        Eruda.show();
        setTimeout(() => {
          Eruda.show(defaultShowName);
        }, 250);
      }
    },
    vConsole() {
      initVConsole("VConsole", currentWin);
      let VConsole = currentWin.VConsole;
      if (!VConsole) {
        alert("调试工具【vConsole】注册全局失败,请反馈开发者");
        return;
      }
      let initPanelList = [];
      if (PopsPanel.getValue("vConsole-panel-system")) {
        initPanelList.push("system");
      }
      if (PopsPanel.getValue("vConsole-panel-network")) {
        initPanelList.push("network");
      }
      if (PopsPanel.getValue("vConsole-panel-element")) {
        initPanelList.push("element");
      }
      if (PopsPanel.getValue("vConsole-panel-storage")) {
        initPanelList.push("storage");
      }
      let theme = "light";
      if (PopsPanel.getValue("vConsole-theme") === "auto") {
        if (utils.isThemeDark()) {
          theme = "dark";
        }
      } else {
        theme = PopsPanel.getValue("vConsole-theme");
      }
      let defaultStorages = [];
      if (PopsPanel.getValue("vConsole-storage-defaultStorages-cookies")) {
        defaultStorages.push("cookies");
      }
      if (PopsPanel.getValue("vConsole-storage-defaultStorages-localStorage")) {
        defaultStorages.push("localStorage");
      }
      if (
        PopsPanel.getValue("vConsole-storage-defaultStorages-sessionStorage")
      ) {
        defaultStorages.push("sessionStorage");
      }
      let vConsole = new VConsole({
        defaultPlugins: initPanelList,
        theme: "light",
        onReady() {
          if (PopsPanel.getValue("vconsole-auto-open-panel")) {
            vConsole.show();
          }
        },
        disableLogScrolling: PopsPanel.getValue("vconsole-disableLogScrolling"),
        log: {
          maxLogNumber: PopsPanel.getValue("vconsole-maxLogNumber", 1000),
          showTimestamps: PopsPanel.getValue("vconsole-showTimestamps"),
          maxNetworkNumber: PopsPanel.getValue(
            "vconsole-maxNetworkNumber",
            1000
          ),
        },
        storage: {
          defaultStorages: defaultStorages,
        },
      });
      GlobalDebug.vConsoleVersion = vConsole.version;
      unsafeWindow.vConsole = vConsole;
      console.log(`VConsole当前版本:${vConsole.version}`);
      console.log(`VConsole项目地址:https://github.com/Tencent/vConsole`);
      console.log("VConsole的实例化的全局变量名: vConsole");
      if (PopsPanel.getValue("vConsole_plugin_Resource_vConsole_Stats")) {
        try {
          vConsolePlugin.State(vConsole, VConsole);
        } catch (error) {
          console.error("插件【vconsole-stats-plugin】加载失败,原因:", error);
        }
      }
      if (PopsPanel.getValue("vConsole_plugin_Resource_vConsole_ExportLog")) {
        try {
          vConsolePlugin.exportLog(vConsole, VConsole);
        } catch (error) {
          console.error(
            "插件【vconsole-outputlog-plugin】加载失败,原因:",
            error
          );
        }
      }
      if (PopsPanel.getValue("vConsole_plugin_Resource_vConsoleVueDevtools")) {
        try {
          currentWin.eval(GM_getResourceText("Resource_vConsoleVueDevtools"));
          const Devtools = currentWin.vueVconsoleDevtools;
          Devtools.initPlugin(vConsole);
        } catch (error) {
          console.error(
            "插件【vconsole-vue-devtools-plugin】加载失败,原因:",
            error
          );
        }
      }

      if (PopsPanel.getValue("vconsole-auto-open-panel")) {
        let defaultShowName = PopsPanel.getValue(
          "vconsole-default-show-panel-name",
          "default"
        );
        vConsole.show();
        setTimeout(() => {
          vConsole.showPlugin(defaultShowName);
        }, 250);
      }
    },
    pageSpy() {
      let api = PopsPanel.getValue(
        "pagespy-api",
        GlobalDebug.pageSpyDefaultApi
      );
      let clientOrigin = PopsPanel.getValue(
        "pagespy-clientOrigin",
        GlobalDebug.pageSpyDefaultCliennOrigin
      );
      if (PopsPanel.getValue("pagespy-disable-run-in-debug-client")) {
        if (window.location.hostname.includes(api)) {
          return;
        }
        if (window.location.origin.includes(clientOrigin)) {
          return;
        }
      }
      let __pageSpy__ = new initPageSpy(currentWin);
      if (!__pageSpy__) {
        alert("调试工具【PageSpy】获取失败,请反馈开发者");
        return;
      }
      let $pageSpy = new __pageSpy__({
        // SDK 会从引入的路径自动分析并决定 Server 的地址(api)和调试端的地址(clientOrigin)
        // 假设你从 https://example.com/page-spy/index.min.js 引入,那么 SDK 会在内部设置:
        //   - api: "example.com"
        //   - clientOrigin: "https://example.com"
        // 如果你的服务部署在别处,就需要在这里手动指定去覆盖。
        api: api,
        clientOrigin: clientOrigin,

        // project 作为信息的一种聚合,可以在调试端房间列表进行搜索
        project: PopsPanel.getValue("pagespy-project", true),

        // title 供用户提供自定义参数,可以用于区分当前调试的客户端
        // 对应的信息显示在每个调试连接面板的「设备id」下方
        title: PopsPanel.getValue("pagespy-title", true),

        // 指示 SDK 初始化完成,是否自动在客户端左下角渲染「圆形白底带 Logo」的控件
        // 如果设置为 false, 可以调用 window.$pageSpy.render() 手动渲染
        autoRender: PopsPanel.getValue("pagespy-autoRender", true),

        // 手动指定 PageSpy 服务的 scheme。
        // 这在 SDK 无法正确分析出 scheme 可以使用,例如 PageSpy 的浏览器插件
        // 是通过 chrome-extension://xxx/sdk/index.min.js 引入 SDK,这会
        // 被 SDK 解析成无效的 "chrome-extension://" 并回退到 ["http://", "ws://"]。
        //   - (默认)传值 undefined 或者 null:SDK 会自动分析;
        //   - 传递 boolean 值:
        //     - true:SDK 将通过 ["https://", "wss://"] 访问 PageSpy 服务
        //     - false:SDK 将通过 ["http://", "ws://"] 访问 PageSpy 服务
        enableSSL: PopsPanel.getValue("pagespy-enableSSL", true),
      });
      unsafeWindow.$pageSpy = $pageSpy;
      console.log($pageSpy);
      GlobalDebug.pageSpyVersion = unsafeWindow.$pageSpy.version;
      console.log("PageSpy全局变量:$pageSpy");
      utils
        .waitPropertyByInterval(
          unsafeWindow.$pageSpy,
          function () {
            return unsafeWindow.$pageSpy.root != null;
          },
          250,
          10000
        )
        .then(() => {
          /**
           * @type {HTMLElement}
           */
          let contentElement =
            unsafeWindow.$pageSpy.root.querySelector(".page-spy-content");
          let goToRoomListElement = document.createElement("div");
          let goToDebugElement = document.createElement("div");
          goToDebugElement.className = "page-spy-content__btn";
          goToDebugElement.innerHTML = "前往调试";
          goToRoomListElement.className = "page-spy-content__btn";
          goToRoomListElement.innerHTML = "前往房间列表";
          goToDebugElement.addEventListener(
            "click",
            function () {
              window.open(
                `${clientOrigin}/#/devtools?version=${encodeURIComponent(
                  unsafeWindow.$pageSpy.name
                )}&address=${encodeURIComponent(
                  unsafeWindow.$pageSpy.address
                )}`,
                "_blank"
              );
            },
            {
              capture: true,
            }
          );
          goToRoomListElement.addEventListener(
            "click",
            function () {
              window.open(`${clientOrigin}/#/room-list`, "_blank");
            },
            {
              capture: true,
            }
          );
          contentElement.appendChild(goToRoomListElement);
          contentElement.appendChild(goToDebugElement);
        });
    },
    chii() {
      let debugUrl = PopsPanel.getValue("chii-debug-url", this.chiiUrl);
      if (
        window.location.href.startsWith(debugUrl) &&
        PopsPanel.getValue("chii-disable-run-in-debug-url", true)
      ) {
        console.log("禁止在调试端运行");
        return;
      }
      ChiiHeight.init();
      if (PopsPanel.getValue("chii-check-script-load")) {
        function checkChiiScriptLoad(event) {
          if (event.target === scriptNode) {
            globalThis.alert(
              `调试工具【Chii】脚本加载失败
              可能原因1:CSP策略阻止了加载第三方域的js文件
              可能原因2:目标js无效`
            );
            unsafeWindow.removeEventListener("error", checkChiiScriptLoad, {
              capture: true,
            });
          }
        }
        unsafeWindow.addEventListener("error", checkChiiScriptLoad, {
          capture: true,
        });
      }
      let scriptJsUrl = PopsPanel.getValue(
        "chii-target-js",
        this.chiiDetaultScriptJs
      );
      let scriptEmbedded = PopsPanel.getValue("chii-script-embedded", true);
      let scriptNode = document.createElement("script");
      scriptNode.src = scriptJsUrl;
      scriptNode.setAttribute("type", "application/javascript");
      if (scriptEmbedded) {
        scriptNode.setAttribute("embedded", true);
      }
      (document.head || document.body || document.documentElement).appendChild(
        scriptNode
      );
    },
  };
  PopsPanel.initMenu();
  if (GlobalDebug.handleIframe()) {
    if (PopsPanel.getValue("autoLoadDebugTool")) {
      GlobalDebug.runDebugTool();
    } else {
      GlobalDebug.addControlDebugToolScriptMenu();
    }
  }
})();